EFeru / hoverboard-firmware-hack-FOC

With Field Oriented Control (FOC)
GNU General Public License v3.0
1.15k stars 955 forks source link

Freewheeling after new #define ENABLE_TIMEOUT seconds inactivity #323

Closed RoboDurden closed 1 year ago

RoboDurden commented 2 years ago

Variant

No response

Control type

No response

Control mode

No response

What can we do to make the firmware better?

closed " Freewheel mode? #25 " - to allow freewheeling when motors are not needed.. I had the same problem with automating the rotary crank of my log band saw ( https://youtu.be/PGM7NyRvg-c ) which i still want to operate manually.

Describe suggestions or alternatives you have considered

So i added //#define ENABLE_TIMEOUT 3 // Seconds of not driving will enable=0 for power saving and freewheeling to the DEFAULT SETTINGSin https://github.com/EFeru/hoverboard-firmware-hack-FOC/blob/dbc485bbf480f91cf15851133c9cda170b30e965/Inc/config.h#L177

In main.c:

    #ifdef ENABLE_TIMEOUT   // robo
      enable2 = inactivity_timeout_counter <= (ENABLE_TIMEOUT * 1000) / (DELAY_IN_MAIN_LOOP + 1);
    #endif

after https://github.com/EFeru/hoverboard-firmware-hack-FOC/blob/dbc485bbf480f91cf15851133c9cda170b30e965/Src/main.c#L584

with extern uint8_t enable2; //robo global variable for additional ENABLE_TIMEOUT motor enable after https://github.com/EFeru/hoverboard-firmware-hack-FOC/blob/dbc485bbf480f91cf15851133c9cda170b30e965/Src/main.c#L83

and in bldc.c: uint8_t enable2 = 1; // global variable for additional ENABLE_TIMEOUT and if(ABS(curL_DC) > curDC_max || enable == 0 || enable2 == 0) { and if(ABS(curR_DC) > curDC_max || enable == 0 || enable2 == 0) { and enableFin = enable && enable2 && !rtY_Left.z_errCode && !rtY_Right.z_errCode; // robo

I chose a new variable enable2to not overwrite the enablevariable whichs is also changed in the VARIANT_TRANSPOTTERlines, etc. Maybe someone would like to commit it..

Candas1 commented 2 years ago

Nice, I believe something had requested this but implemented it himself, but it was more for saving battery than for freewheeling. Freewheeling can be also managed by switching to torque mode, in this case the energy could go back to the battery. In your use case it shouldn't be a problem though.

RoboDurden commented 1 year ago

I still have the severe problem that when I set speed to zero when the motors are under full load, then after 5 seconds the motors get disabled with enable2 = 0. Good so far but when I then roll back my car to where it is flat and slowly increase the speed command again, with enable2 = 1, both motors start where they were disabled = full pwm :-(

That does not help:

#ifdef ENABLE_TIMEOUT   //ROBO
      enable2 = inactivity_timeout_counter <= (ENABLE_TIMEOUT * 1000) / (DELAY_IN_MAIN_LOOP + 1);   //YOU
      if (!enable2)
      {
        speedRateFixdt = speedFixdt = 0;    // clear speed when motos disabled.
        pwml = pwmr = 0;
      }
#endif

There must be some runtime variables in black.c or bldc_controller.c that also need to be cleared ?

Maybe someone has an idea.

RoboDurden commented 1 year ago

changing to torque mode instead of setting an enable2 to false does also not work:

    #ifdef ENABLE_TIMEOUT   //ROBO
      //enable2 = inactivity_timeout_counter <= (ENABLE_TIMEOUT * 1000) / (DELAY_IN_MAIN_LOOP + 1); //YOU
      //if (enable2)
      if (inactivity_timeout_counter <= (ENABLE_TIMEOUT * 1000) / (DELAY_IN_MAIN_LOOP + 1))
      {
        ctrlModReq         = VLT_MODE;
      }
      else
      {
        speedRateFixdt = speedFixdt = 0;    // clear speed when motos disabled.
        pwml = pwmr = 0;
        ctrlModReq         = TRQ_MODE;
      }
    #endif

I guess i am missing something obvious as with no enable2 and ctrlModReq = TRQ_MODE; any full pwm before enable2 = 0 should have disolved.

This behavior is really nasty. When i set speed from forward to zero while the motors are under full load, then switch to backwards driving and slowly begin to increase (negative) speed again, the motors wake up at full torque foward :-(

Ideas welcome :-/

RoboDurden commented 1 year ago

Okay i did not clear my own closed loop cmd2Goal to limit the speed :-( So all this here my fault :-((

This now works:

      #ifdef ENABLE_TIMEOUT //ROBO
        if (inactivity_timeout_counter <= (ENABLE_TIMEOUT * 1000) / (DELAY_IN_MAIN_LOOP + 1))
        {
          ctrlModReq         = ctrlModReqRaw;
        }
        else
        {
          cmdR = cmdL = 0;
          #ifdef VARIANT_UARTCAR    // ROBO
            cmd2Goal = 0;
          #endif
          ctrlModReq         = OPEN_MODE;
        }
      #endif

      // ####### SET OUTPUTS (if the target change is less than +/- 100) #######
      #ifdef INVERT_R_DIRECTION
        pwmr = cmdR;
      #else
        pwmr = -cmdR;
      #endif
      #ifdef INVERT_L_DIRECTION
        pwml = -cmdL;
      #else
        pwml = cmdL;
      #endif