Problem with drive maximum speed DRV8302, STM32-F103RB

Hi,
I’m working on an actuator using BLDC motor (24V, 5000rpm bldc motor with hall sensor)
image

I have the following hardware for testing simpleFOC:
-SimpleFOC @2.1.0 with PlatformIO
-STM32-F103RB NUCLEO Board
-DRV8302 driver board from aliexpress
-AMT103 Encoder sensor
-24V, 5000rpm bldc motor with hall sensor

I am trying to drive this motor at maximum speed “motor.velocity_limit = 500 [red / s]” (5000rpm), but I cannot reach the target speed. I achieve speed around 190 [red / sec].
If I increase the “motor.volatile_limit”, the speed increases a little, but a large current (6A) flows through the motor, and after a while, the motor becomes very hot.

Test code:

#include <Arduino.h>
#include <SimpleFOC.h>

#define LED PA5

// DRV8302 pins connections
#define INH_A PA8  //D7
#define INH_B PA9  //D8
#define INH_C PA10 //D2

#define INL_A PB13 //
#define INL_B PB14 //
#define INL_C PB15 //

#define EN_GATE PC11 
#define M_PWM PC10   
#define M_OC PC12    
#define OC_ADJ PC2  

#define ENC_A PA15
#define ENC_B PB7

float target = 0.0;

BLDCMotor motor = BLDCMotor(2);
//BLDCDriver3PWM driver = BLDCDriver3PWM(INH_A, INH_B, INH_C, EN_GATE);
BLDCDriver6PWM driver = BLDCDriver6PWM(INH_A, INL_A, INH_B, INL_B, INH_C, INL_C, EN_GATE);

//  Encoder(int encA, int encB , int cpr, int index)
//  - encA, encB    - encoder A and B pins
//  - ppr           - impulses per rotation  (cpr=ppr*4) 8192
//  - index pin     - (optional input)

Encoder encoder = Encoder(ENC_A, ENC_B, 250);

// Interrupt routine intialisation
// channel A and B callbacks
void doA(){encoder.handleA();}
void doB(){encoder.handleB();}
void serialCommand();

// angle set point variable
float target_angle = 0;

// instantiate the commander
Commander command = Commander(Serial);
void doTarget(char* cmd) { command.scalar(&target_angle, cmd); }

void setup() {
  Serial.begin(115200);
  pinMode(LED,OUTPUT);

  // DRV8302 specific code
  // M_OC  - enable overcurrent protection
  pinMode(M_OC,OUTPUT);
  digitalWrite(M_OC,LOW);

  // //M_PWM  - enable 3pwm mode
  // pinMode(M_PWM,OUTPUT);
  // digitalWrite(M_PWM,HIGH);

  // M_PWM  - disable 3pwm mode
  pinMode(M_PWM,OUTPUT);
  digitalWrite(M_PWM,LOW);

  // OD_ADJ - set the maximum overcurrent limit possible
  // Better option would be to use voltage divisor to set exact value

  pinMode(OC_ADJ,OUTPUT);
  digitalWrite(OC_ADJ,HIGH);

  // initialize encoder sensor hardware
  encoder.init();
  encoder.enableInterrupts(doA, doB); 

  // link the motor to the sensor
  motor.linkSensor(&encoder);
  // driver config
  // pwm frequency to be used [Hz]
  //driver.pwm_frequency = 100000;

  // power supply voltage [V]
  driver.voltage_power_supply = 24;
  driver.voltage_limit = 24;
  driver.init();
  // link the motor and the driver
  motor.linkDriver(&driver);

  // choose FOC modulation
  motor.foc_modulation = FOCModulationType::SinePWM;

  // set control loop type to be used
  motor.controller = MotionControlType::angle;

  // contoller configuration based on the controll type 
  motor.PID_velocity.P = 0.08;  // about 75% of actual vaelocity
  motor.PID_velocity.I = 6.0;
  motor.PID_velocity.D = 0;
  motor.LPF_velocity.Tf = 0.01;  // velocity low pass filtering time constant
  motor.P_angle.P = 1;   // angle loop controller

  // jerk control using voltage voltage ramp
  // default value is 300 volts per sec  ~ 0.3V per millisecond
  motor.PID_velocity.output_ramp = 1000;
  motor.P_angle.output_ramp = 1e6;
  //motor.phase_resistance = 1; // 1 Ohms

  
  // default voltage_power_supply
  motor.voltage_limit = 6; //[V]
  //motor.current_limit = 4;
  motor.velocity_limit = 500; // [red/s] //5000 rpm = 523.59877569118 rad/s
  //motor.voltage_sensor_align = 1;

  motor.useMonitoring(Serial);
  // initialise motor
  motor.init();

  // align encoder and start FOC
  motor.initFOC();

  // add target command T
  //command.add('T', doTarget, "target angle");
  Serial.println(F("Motor ready."));
  // Serial.println(F("Set the target angle using serial terminal:"));

  _delay(1000);
}

void loop() {
  serialCommand();
  // iterative setting FOC phase voltage
  motor.loopFOC();
  motor.move(target);
  motor.monitor();
  // user communication
  //command.run();
}

// utility function enabling serial communication with the user to set the target values
// this function can be implemented in serialEvent function as well

void serialCommand() {
  // a string to hold incoming data
  static String received_chars;
  while (Serial.available()) {
    // get the new byte:
    char inChar = (char)Serial.read();
    // add it to the string buffer:
    received_chars += inChar;
    // end of user input
    if (inChar == '\n') {
      // change the motor target
      target = received_chars.toFloat();
      //Serial.print("Target value: ");
      //Serial.println(target);
      // reset the command buffer 
      received_chars = "";
    }
  }
}

Hey, i know two possible solutions to get more rpm, first instead of sine modulation you could use block commutation, but I don’t know if that’s suitable for your application.

Or look under 7.1 motion controll down sampling https://docs.simplefoc.com/bldcmotor

That could be what you are looking for.

Franz_SchmidtThank you for your reply. I’ve tried trapesoidal120 and 150, but simpleFOC detects the wrong pole pair.I am using only the encoder and the hall sensor is not connected yet. I think for the trapesoidal hall sensor will good.

After that adjust the downsampling of the motion control.

The current sensor is necessary for your target.

@Axe Do you have any recommended board with current sensor?

@Axe why would that be? i assume he can just run it in voltage mode.