B-G431B-ESC1 - Screeching at High RPM

Hi All,

Thank you for this great community and project! I have got my hands on a B-G431B-ESC1 and have run through the getting started examples. Everything seems to be working well at low speeds, however when I go above ~15rad/s in velocity mode, I can hear an increasing sound of electrical oscillations and then the motor will completely stop and make a loud screeching sound and the PSU will go to maximum current.

I am looking for some suggestions on what might be causing this. I have turned off all monitoring (incase it was slowing the loop), increased the minimum motor voltage and tried turning off quadrature however there seems to be minimal change in the results.

Has anyone experienced anything similar and have any suggestions?

Setup:
B-G431B-ESC1
Eagle power LA8398 KV90
AMT102-V (2021cpr)
PSU 12V (10A)
Arduino IDE - STMduinocore

Thanks for your help.
Lewis

Code:

/** 
 * B-G431B-ESC1 position motion control example with encoder
 *
 */
#include <SimpleFOC.h>



// Motor instance
BLDCMotor motor = BLDCMotor(20);
BLDCDriver6PWM driver = BLDCDriver6PWM(A_PHASE_UH, A_PHASE_UL, A_PHASE_VH, A_PHASE_VL, A_PHASE_WH, A_PHASE_WL);
LowsideCurrentSense currentSense = LowsideCurrentSense(0.003f, -64.0f/7.0f, A_OP1_OUT, A_OP2_OUT, A_OP3_OUT);


// encoder instance
Encoder encoder = Encoder(A_HALL1, A_HALL2, 2048, A_HALL3);

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



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




void setup() {

  // enable/disable quadrature mode
  encoder.quadrature = Quadrature::ON;
  
  // initialize encoder sensor hardware
  encoder.init();
  encoder.enableInterrupts(doA, doB, doIndex); 

  // link the motor to the sensor
  motor.linkSensor(&encoder);
  
  // driver config
  // power supply voltage [V]
  driver.voltage_power_supply = 12;
  driver.init();
  // link the motor and the driver
  motor.linkDriver(&driver);
  // link current sense and the driver
  currentSense.linkDriver(&driver);

  // current sensing
  currentSense.init();
  // no need for aligning
  currentSense.skip_align = false;
  motor.linkCurrentSense(&currentSense);

  // aligning voltage [V]
  motor.voltage_sensor_align = 3;
  // index search velocity [rad/s]
  motor.velocity_index_search = 3;

  // set motion control loop to be used
  //motor.controller = MotionControlType::velocity;
  //motor.controller = MotionControlType::velocity_openloop;
  //motor.controller = MotionControlType::velocity_openloop;
   // set motion control loop to be used
  //motor.torque_controller = TorqueControlType::voltage;
  motor.controller = MotionControlType::velocity;

  driver.voltage_limit = 12;
  motor.voltage_limit = 0.5 * driver.voltage_limit;



  // contoller configuration 
  // default parameters in defaults.h

  // velocity PI controller parameters
  motor.PID_velocity.P = 0.3;
  motor.PID_velocity.I = 20;

  // jerk control using voltage voltage ramp
  // default value is 300 volts per sec  ~ 0.3V per millisecond
  motor.PID_velocity.output_ramp = 1000;
 
  // velocity low pass filtering time constant
  motor.LPF_velocity.Tf = 0.01;

  // angle P controller
  motor.P_angle.P = 20;
  //  maximal velocity of the position control
  motor.velocity_limit = 40;


  // use monitoring with serial 
  Serial.begin(115200);
  
  // initialize motor
  motor.init();
  // align encoder and start FOC
  motor.initFOC();
  
  motor.target = 0.5; // Volts 

  // add target command T
  command.add('T', doTarget, "target velocity");


  Serial.println(F("Motor ready."));
  Serial.println(F("Set the target angle using serial terminal:"));
  _delay(1000);
}

void loop() {
  // main FOC algorithm function
  motor.loopFOC();

  // Motion control function
  motor.move();

  //motor.monitor();

  // user communication
  command.run();
}

It seems you have taken an angle-control example and modified it to be velocity control.
I can’t point a finger to a wrong line, but maybe something is missing for velocity control?

It could be pid oscillations. In that case you would reduce the P gain. You can do a quick test, reduce it and see if it changes any.

Is the AMT configured for 2048PPR? The number to the constructor is the PPR, not the CPR…

Is it possible it is missing interrupts? Although 15rad/s is not really very fast…
You could try the STM3HardwareEncoder from our drivers library, it does not need interrupts, and may be more reliable.

Hello,

Did you do the pole test?
https://github.com/simplefoc/Arduino-FOC/tree/master/examples/utils/calibration/find_pole_pair_number

You say motor is Eagle power LA8398 KV90
I guess it’s Eagle power LA8308 KV90 ?
if I look at the pictures on the internet and count the poles I count 36 ==> 3*12?

BLDCMotor motor = BLDCMotor(12);

You might be right, however, I am not sure what I have missed. It seems changing the control mode is all that needs to be changed from what I have seen in the examples. I will have a closer look tonight. Thanks for your help.

Yes, I was thinking something along those lines because it seems to get to the set point but after while you slowly hear oscillations building. Which made me think it could have something to do with the I component of the PID, slowly accumulating until it breaks. I will try playing around with the values tonight and see what results I get.

I will also print out the target and measured velocity to see if I am not reaching my set point.

Thanks for your suggestion

I think it is configured for 2048 (PPR), as I did the sensor test and got the correct value of 6.28radians per rev, which would point to it being set correctly?

I will have a go at playing around with that tonight and report back. Thanks for the suggestion.

Yes that looks like the same motor I am using. I counted 40 magnets on the rotor which I understand means 20 pole pairs. It also says PP success, which I am guessing is the Pole Pair test during init.

Thanks for your help

Reference:
How to Calculate Motor Poles & Motor Kv - Tyto Robotics.

1 Like

You are right in counting magnets.
What I found interesting is that it’s not a classic BLDC motor
It has 36 stator teeth and 40 magnets, while it should have 42 (3x 14) or 30 (3x 10)…

Yes, that does sound like you set it right.

Possible perhaps, but I think you’d discover this quite quickly when tuning the PID values.

This sound more like you’re losing the correct electrical zero position, for example do to dropped interrupts on the encoder or the shaft slipping in the encoder

So I got a chance to have a play around again. I tried using the STM3HardwareEncoder but couldn’t get it to init.

I think all the issues were just down to power supply. I tried the same code powering the board with a 4S lipo this time and everything worked smoothly. Maybe a noisy power supply or voltage sag during accelerations was causing the encoder or MCU to miss a count?

Thanks for all your help! On wards to building the Ball Bot :slight_smile: