EFeru / hoverboard-firmware-hack-FOC

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

How to increase Field Weaking at runtime when flat road allows for higher speed ? #388

Closed RoboDurden closed 1 year ago

RoboDurden commented 1 year ago

Variant

None

Control type

FOC

Control mode

None

What can we do to make the firmware better?

Hello again :-)

My solar camper (max speed 10 kmh at 150-200 Watt flat) now has pedal assist so i would like to go faster when less then 10A (250 Watt) are drawn. So when my https://pionierland.de/hoverhack/?p=uartCar recieves a target speed of 15 kmh and current < 10A, the field weakening should be activated.

Describe suggestions or alternatives you have considered

I guess that is rtP_Left.b_fieldWeakEna and rtP_Right.b_fieldWeakEna :-)

Will this activate field weakening softly ???

And anyway, i would like to increase rtP_Left.id_fieldWeakMax and rtP_Right.id_fieldWeakMax up to 10 (amps) until the motors current (5s average) reaches 10A. (Don't want to waste my 2-3 kWh on not so efficient higher speed..)

So a little closed loop for rtP_X.id_fieldWeakMax :-)

Would id_fieldWeakMax = 0 (amps) be zero field Weakeing ? Then i would set FIELD_WEAK_ENA to 1 and let the closed loop control id_fieldWeakMax from 0 to 5 (or 10)

Should i also change FIELD_WEAK_LO and FIELD_WEAK_HI in that closed loop, or will 750-1000 be fine ? What is 750 anyway ? Milli seoncds ? A scalar number ?

I am currently on the road and 300 km far from home. So i do not want to kill my motors or the board.

Ideas welcome :-)

RoboDurden commented 1 year ago

Well that does not seem to work: config.h:

// Field Weakening / Phase Advance
#define FIELD_WEAK_ENA  1               // [-] Field Weakening / Phase Advance enable flag: 0 = Disabled (default), 1 = Enabled
#define FIELD_WEAK_MAX  5               // [A] Maximum Field Weakening D axis current (only for FOC). Higher current results in higher maximum speed. Up to 10A has been tested using 10" wheels.
#define PHASE_ADV_MAX   25              // [deg] Maximum Phase Advance angle (only for SIN). Higher angle results in higher maximum speed.
#define FIELD_WEAK_HI   1000            // (1000, 1500] Input target High threshold for reaching maximum Field Weakening / Phase Advance. Do NOT set this higher than 1500.
#define FIELD_WEAK_LO   750             // ( 500, 1000] Input target Low threshold for starting Field Weakening / Phase Advance. Do NOT set this higher than 1000.

main.c:

        iFieldWeakMax = CLAMP(iFieldWeakMax-1,0,500);
        rtP_Left.id_fieldWeakMax = rtP_Right.id_fieldWeakMax = iFieldWeakMax/100;

That param seems to be used in BLDC_controller_data.c:

      if (rtP->z_ctrlTypSel == 2) {
        rtb_Saturation1 = rtP->id_fieldWeakMax;
      } else {
        rtb_Saturation1 = rtP->a_phaAdvMax;
      }

If i do not touch that value by commenting out:

//rtP_Left.id_fieldWeakMax = rtP_Right.id_fieldWeakMax = iFieldWeakMax/100;

I can easily speed up to 12 kmh. With that line hover, i stay at 10-11 kmh.

Will do some more test driving today. Ideas welcome !

RoboDurden commented 1 year ago

Okay i had forgotten about that (FIELD_WEAK_MAX * A2BIT_CONV) << 4 integer to float conversion stuff that Emanuel had introduced with his great firmware here :-/ Instead of 5A i must set the id_fieldWeakMax to 4000. So no wonder nothing happened.

This code now works for my VARIANT_UARTCAR:

#ifdef VARIANT_UARTCAR // ROBO
  int16_t cmd2Goal; // 10* goal speed for VARIANT_UARTCAR
  int32_t iFieldWeakMax = 0;
  #define INPUTMAX 9900  // +-1000 do cause vibrations in my 350+ Watt motor :-(
  #define INPUTMIN -9900
#endif
 if (cmd2Goal < INPUTMIN)   // pwm at negativ full speed
    cmd2Goal = INPUTMIN;
  else if (cmd2Goal > iInputMax)    // pwm at full speed
  {
    cmd2Goal = iInputMax;
    long iSpeedKmh = (iSpeed * 36) / 1000;  // 60 = 6 kmh
    if (    (fCurrent < 12.0) && (iSpeedKmh >= 80)  )
    {
      iFieldWeakMax += 2;
    }
  }
 iFieldWeakMax = CLAMP(iFieldWeakMax-1,0,FIELD_WEAK_MAX*100);   // 300 = max 3A field weakening
 rtP_Left.id_fieldWeakMax = rtP_Right.id_fieldWeakMax = ((iFieldWeakMax * A2BIT_CONV) << 4 ) / 100;
 // rtP_Left.id_fieldWeakMax      = (FIELD_WEAK_MAX * A2BIT_CONV) << 4;   // fixdt(1,16,4)
 // #define A2BIT_CONV             50     // A to bit for current conversion on ADC. Example: 1 A = 50, 2 A = 100, etc

Have not tested it on the street but with my two wheels spinning freely i now reach max speed of 15 kmh at 5A field weakening and 14 kmh at 3A.

Thanks for this great firmware.