bipropellant / bipropellant-hoverboard-firmware

OpenSource Hoverboard firmware based on Niklas Fauth's one https://github.com/NiklasFauth/hoverboard-firmware-hack
GNU General Public License v3.0
173 stars 73 forks source link

Arduino/ESP8266 control. #98

Closed pav18 closed 4 years ago

pav18 commented 4 years ago

Hello. I would really appreciate if you publish small instruction how to control hoverboard with Arduino. I flashed the firmware to the board with UART3 control and now trying to send commands via SoftwareSerial. I understand that I am close to result but... Main qustions: 1 Which control type shall I choose to control via Arduino?
Is it Ok to change only here?

ifndef CONTROL_TYPE

define CONTROL_TYPE USART3_CONTROLLED

endif

2 Shall I use API or I can send commands setHoverboardPWM( int32_t pwm1, int32_t pwm2 ) 3 May I use SoftwareSerial? SoftwareSerial oSerial(14,12); oSerial.write(ups.UART_Packet,sizeof(UART_Packet_t));

Thank you.

P.S. I found library and example for Arduino. PLEASE PLEASE PLEASE write comments. I understand everything looks pretty simple but for newbee it is so complicated. More examples...moreee ;)

hoverboard.sendPWM(100, 30, PROTOCOL_SOM_NOACK); There are no info that 100 is a speed in % and 30 is steering!!!! How to go backward? -100 in speed or 180 in steer?

pav18 commented 4 years ago

Who will go after me:
Compile with option #define CONTROL_TYPE USART3_CONTROLLED Or UART2 as you wish. You shall use API https://github.com/bipropellant/bipropellant-hoverboard-api/tree/master_arduino You shall use library #include Add this into the scetch https://github.com/bipropellant/bipropellant-hoverboard-api/blob/master_arduino/examples/PWMsimple/PWMsimple.ino In the loop you send speed every cycle (not only when you need to chage it) hoverboard.sendPWM(100, 30, PROTOCOL_SOM_NOACK); 100 - is a speed from 0 to 1000 30 is a steer from 0 to 1000 To understand what the hell is steer see formula below: writespeed->pwm[0] = pwm + steer; writespeed->pwm[1] = pwm - steer;

SO when you send (100,30) it means 100+30 = 130 to left wheel and 100 - 30 = 70 to the right. Basic steps, but I have spent few hours to get it work ;)

pav18 commented 4 years ago

Everything works but!!!! The speed of the hoverboard is 4 Km/h Are any ways how to increase the speed?

NickLD commented 4 years ago

@pav18 Nice to hear it's driving. What are the values you are sending? Also what method call are you using? I typically do something like hoverboard.sendPWMData(targetV, (steering, say 0), 1000, -1000, (minPWM, say 10), PROTOCOL_SOM_NOACK);

If you are trying to reach very high speeds, also ensure you have Phase Advance / Field Weaking enabled

pav18 commented 4 years ago

Thank you for your attention. Would you be so kind to go the proccess with me step by step. I just feel that I am so close....

I use ESP8266 to control the hoverboard (Wemos D1 mini)

I have compiled the firmware via online compiler pionierland.de/hoverhack/ and changed ONLY - #define CONTROL_TYPE USART3_CONTROLLED

I use API for Arduino as mentioned above.

Added everything from the example.

In the loop I send hoverboard.sendPWM(100, 0, PROTOCOL_SOM_NOACK);
Where the 100 is 10% of the max speed and 0 is steering. (I think so)

I would appreciate if you tell me exactly what to change and what to send. Sorry but I am not a programmer guy and can easily miss something important.

For example: What changes I shall make prior to compile firmware? I now firmwares which allow hoverboard speed up to 30 km/h. I make 4WD.

What shall I send to hoverboard exactly if I need to tell him drive forward 70% speed? (my guess was hoverboard.sendPWM(700, 0, PROTOCOL_SOM_NOACK); ) How to brake? How to brake smooth? Is it possible to activate free drive for wheels when you do not push accelerator? Is it possible to activate brake by pushing button, not only by release accelerator? Is it possible to send necessary speed not every loop but only when I need to change it? I believe that less info exchange between Arduino and Mainboard is better

Thank you very much for your project and for help!!!! The picture and test code of my project below

    #define REMOTEXY_MODE__ESP8266WIFI_LIB_POINT
    #include <ESP8266WiFi.h>
    #include <RemoteXY.h>
    #define DEBUG_RX
    #include <SoftwareSerial.h>
    #include <HoverboardAPI.h>
    SoftwareSerial oSerial(14,12); // RX, TX  D5 D6
    #define PIN_POT     A0
    #define ButPin     13

    int serialWrapper(unsigned char *data, int len) {
     return (int) oSerial.write(data,len);
    }
    HoverboardAPI hoverboard = HoverboardAPI(serialWrapper);

    // настройки соединения  
    #define REMOTEXY_WIFI_SSID "PAV_GoKart" 
    #define REMOTEXY_WIFI_PASSWORD "" 
    #define REMOTEXY_SERVER_PORT 6377 

    // конфигурация интерфейса   
    #pragma pack(push, 1) 
    uint8_t RemoteXY_CONF[] = 
      { 255,3,0,22,0,54,0,10,13,1,
      3,2,3,2,8,22,2,26,4,0,
      47,62,11,33,2,26,2,0,23,2,
      22,11,2,26,31,31,79,78,0,79,
      70,70,0,67,4,5,35,20,5,2,
      26,11,67,4,5,58,20,5,2,26,
      11 }; 

    // структура определяет все переменные и события вашего интерфейса управления  
    struct { 

        // input variables
      uint8_t Button1; // =0 если переключатель в положении A, =1 если в положении B, =2 если в положении C, ... 
      int8_t Slider; // =0..100 положение слайдера 
      uint8_t Switch1; // =1 если переключатель включен и =0 если отключен 

        // output variables
      char Text1[11];  // =строка UTF8 оканчивающаяся нулем 
      char Text2[11];  // =строка UTF8 оканчивающаяся нулем 

        // other variable
      uint8_t connect_flag;  // =1 if wire connected, else =0 

    } RemoteXY; 
    #pragma pack(pop) 

    long iSpeed = 0;
    int steer = 0; 
    int gas = 0;
    int gas_old = 0;
    int Switch = 0;
    int Switch_old = 0;
    int Button = 0;
    int Button_old = 0;
    int operate = 0;
    int operate_old = 0;
    char txt[11];
    //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!SETUP
    void setup() 
    {
      Serial.begin(115200);
      Serial.println("GoKart v1.0");

      oSerial.begin(115200);
      pinMode(LED_BUILTIN, OUTPUT);
      pinMode(PIN_POT, INPUT);
      pinMode(ButPin, INPUT);
      RemoteXY_Init ();
    } //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!Setup end

    //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!LOOP
    void loop(void)
    { 
      RemoteXY_Handler ();

      hoverboard.requestRead(HoverboardAPI::Codes::sensHall, PROTOCOL_SOM_NOACK);
      itoa (hoverboard.getSpeed_kmh(), RemoteXY.Text2, 11);

      unsigned long start = millis();
      while (millis() < start + 30){

        // Read and Process Incoming data
        int i=0;
        while(oSerial.available() && i++ < 1024) { // read maximum 1024 bytes at once.
          hoverboard.protocolPush( oSerial.read() );
        }

        // Send Messages from queue, re-send failed messages and process scheduled transmissions
        hoverboard.protocolTick();
        delayMicroseconds(100);
      }

      if (Button > 0){
        gas = RemoteXY.Slider * -10;
        } else {
        gas = RemoteXY.Slider * 10;
        }
        //if (operate < 1 && gas > 1019){ // if emergency stop than wait for deacceleration  Potenc
        if (operate < 1 && abs(gas) < 40 && Switch > 0){
          operate = 1;
      }

      Switch = RemoteXY.Switch1;
      if (Switch != Switch_old){
        Serial.print("Switch - ");
        Serial.println(Switch);
        Switch_old=Switch;
        if (Switch == 0){
          gas = 0; 
          operate = 0;
          itoa (abs(gas), RemoteXY.Text1, 11);

      } else if (Switch == 1){
          operate = 1;
      }
      }

      if (operate > 0){
        Button = RemoteXY.Button1;
        if (Button != Button_old){
          Serial.print("Button - ");
          Serial.println(Button);
          Button_old=Button;
          gas = 0;
          operate = 0;
          itoa (abs(gas), RemoteXY.Text1, 11);
          hoverboard.sendPWM(gas, 0, PROTOCOL_SOM_NOACK);
          delay(2000); //tmp remove
        }

        if (gas > gas_old + 20 || gas < gas_old - 20){
          gas_old=gas;
          if (Button == 0){
            //gas = map(gas,1024,5,0,1000); 

          } else if (Button == 1){
            //gas = map(gas,1024,5,0,-1000); 
            gas = map(gas,0,1000,0,-1000); 

          }

          if (gas > 999) {
            gas = 999;
          }
              if (gas < -999) {
            gas = -999;
          }

          if (gas > -25 && gas < 25){
              gas =0; //stop
            }
          Serial.print("Gas - ");
          Serial.println(gas);
          RemoteXY.Slider = abs(gas/10);
          //RemoteXY.Speed = abs(gas/10);
          itoa (abs(gas), RemoteXY.Text1, 11);

        }//gas
        }//operate

    hoverboard.sendPWM(gas, 0, PROTOCOL_SOM_NOACK);
    delay(30);

    }

PAVGoKart

NickLD commented 4 years ago

@pav18 Firstly, I love the kart you are building! looks great :) Before we go too deep, let me mention something. If you want to support "freewheel mode (aka, Torque control)" then I'm afraid you will need to switch to another firmware from Bipropellant. I don't think BiPropellant supports Torque control as of yet. The only firmware I'm aware of that does support this is: https://github.com/EmanuelFeru/hoverboard-firmware-hack-FOC

This firmware offers many advantages which will be more ideal for your Kart (such as Torque control, FOC drive, improved efficiency, etc.) but most of all has a simpler UART interface to work with for your application I believe.

If you would like to use EmanuelFeru's firmware for FOC and Torque control(Very useful for a Kart), then I'd be happy to follow up with you on it's respective Repo. If you want to continue development with this firmware then I'd be glad to help too, though I feel the other firmware would be better suited for your application.

pav18 commented 4 years ago

@NickLD WOW. I have to look throug the project. Thank you very much. The only thing is that now I can compile your firmware online, but here I will have to go deep into firmware compilation process ;)) I would appreciate if you follow up with me on the Repo. Thank you in advance.

I can give you my cell number for whatsapp communication. Would you send me test message to pav18inbox@gmail.com?

P.S. I just tested hoverboard.sendPWMData(gas, 0, 1000, -1000, 20, PROTOCOL_SOM_NOACK); It works but after approx 700 the hoverboard starts beeping and then just switches off.

NickLD commented 4 years ago

No problem, happy to help :)

Just to be clear, I did NOT write this firmware, infact, I haven't contributed any code to this as of yet. I certainly dont deserve credit for the hard work the real creators have put into this project.

I'll try to follow up with you later (today), I must get some rest now as I have classes and work in just a few hours..

Also, if you don't mind, when you feel the issues are completed remember to close them. Start a new issue if you have more questions, especially if the topic is different(or beginning to differ) from the original issue/topic :)

pav18 commented 4 years ago

Thank you very much. I would be happy if you can help me in case of problems. Of course I will try to do everything by myself. I will close the issue but unfortunately GitHub doesn't have personal messages so it is the only way to communicate with you ;)