SimpleFOCmini open-loop position example / sensorless bldc / back and forth movement

Hi @simpleFOC forum,

I ran into a weird behavior, resulting in a back and forth movement of the motor.
After searching the web I am still not able to figure it out.
Any helpful push in the right direction would be just great - thanks.

Hardware: Arduino Uno R3 + SimpleFOCmini + iFlight GM5208-24 BLDC *sensorless
https://shop.iflight.com/ipower-motor-gm5208-24-brushless-gimbal-motor-pro1347

Problem: Testing the hardware by using the open-loop position example I ran into a weird motor movement; it jiggles back and forth. When inputting “T 1” it moves back+forth one time. When I input “T 10” it moves 10x times back and forth. Now when inputting “T 1” again it moves x10 times again - I assume it’s the position 1, moves to 10 and then back to 1. Instead of rotating to a point; it jiggles back and forth, within a ~5-10 degree window.

Any idea what I’ve messed up here?

// Open loop motor control example
 #include <SimpleFOC.h>


// BLDC motor & driver instance
// BLDCMotor motor = BLDCMotor(pole pair number);
BLDCMotor motor = BLDCMotor(7, 13.5, 20); 
// BLDCDriver3PWM driver = BLDCDriver3PWM(pwmA, pwmB, pwmC, Enable(optional));
BLDCDriver3PWM driver = BLDCDriver3PWM(3, 5, 6, 19);

// Stepper motor & driver instance
//StepperMotor motor = StepperMotor(50);
//StepperDriver4PWM driver = StepperDriver4PWM(9, 5, 10, 6,  8);

//target variable
float target_position = 0;
int poles = 7; 

// instantiate the commander
Commander command = Commander(Serial);
void doTarget(char* cmd) { command.scalar(&target_position, cmd); }
void doLimit(char* cmd) { command.scalar(&motor.voltage_limit, cmd); }
void doVelocity(char* cmd) { command.scalar(&motor.velocity_limit, cmd); }

void setup() {

  // driver config
  // power supply voltage [V]
  driver.voltage_power_supply = 12;
  // limit the maximal dc voltage the driver can set
  // as a protection measure for the low-resistance motors
  // this value is fixed on startup
  driver.voltage_limit = 12;
  driver.init();
  // link the motor and the driver
  motor.linkDriver(&driver);

  // limiting motor movements
  // limit the voltage to be set to the motor
  // start very low for high resistance motors
  // currnet = resistance*voltage, so try to be well under 1Amp
  
  motor.voltage_limit = 6;   // [V]
  // limit/set the velocity of the transition in between 
  // target angles
  motor.velocity_limit = 3; // [rad/s] cca 50rpm
  // open loop control config
  motor.controller = MotionControlType::angle_openloop;

  // init motor hardware
  motor.init();

  // add target command T
  command.add('T', doTarget, "target angle");
  command.add('L', doLimit, "voltage limit");
  command.add('V', doLimit, "movement velocity");

  Serial.begin(115200);
  Serial.println("Motor ready!");
  Serial.println("Set target position [rad]");
  _delay(1000);
}

void loop() {
  // open  loop angle movements
  // using motor.voltage_limit and motor.velocity_limit
  // angles can be positive or negative, negative angles correspond to opposite motor direction
  motor.move(target_position);
  
  // user communication
  command.run();
}

My guess is that one of your phases isn’t being energised. The symptoms of this is that the motor can’t move onto the next pole pair and it’s stuck oscillating on one poll pair.

Reasons for phase not being energised could be bad pin selection (e.g a pin not capable of pwm or on different timer), bad pin configuration (e.g the gpio/timer setup code hasn’t switched it correctly to pwm gen), wiring issue e.g. loose connection, or driver configuration e.g not setting an enable pin or spi config.

I’d start by trying to see which phase is problematic. Either using an oscilloscope looking for pwm waveform or by disconnecting one motor phase at a time - if you disconnect motor phase and the motor stops oscillating then phase a was ok, if motor continues oscillating then that phase wasnt doing it’s job and is problematic

1 Like