BLDC Motor not spinning

Hi everybody,
I’m new to the world of Arduino and I’ve been struggling quite a lot to make my BLDC motor spin.

I’m using a SimpleFOC Power Shield with an Arduino UNO with ATMEGA 328P.

I slightly modified the example code “Velocity open loop”. You can find it attached to the end of the post.

The main problem is that the motor doesn’t spin (I also tried other examples). Moreover the trying to communicate through the commander (with the Arduino IDE serial monitor) returns the message “Warn: \r detected” whenever I type a command.

I also tried with the multimeter to measure the voltage output to the motor and it seems fine.

Hope you can help me solve the problem, thank you in advance!

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


// BLDC motor & driver instance
// BLDCMotor motor = BLDCMotor(pole pair number);
  BLDCMotor motor = BLDCMotor(15);
// BLDCDriver3PWM driver = BLDCDriver3PWM(BTN1, BTN2, BTN3, enable1, enable2, enable3);
  BLDCDriver3PWM driver = BLDCDriver3PWM(9, 6, 5, 8, 7, 4);

//target variable
float target_velocity = 0;

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

void setup() {

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

  // limiting motor movements
  motor.voltage_limit = 24;   // [V]
  motor.velocity_limit = 5; // [rad/s] cca 50rpm
 
  // open loop control config
  motor.controller = MotionControlType::velocity_openloop;

  // init motor hardware
  motor.init();

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

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

void loop() {

  // open loop velocity movement
  // using motor.voltage_limit and motor.velocity_limit
  motor.move(target_velocity);

  // user communication
  command.run();
}

I’m also a newbie here and I don’t know the SimpleFOC Power Shield :slight_smile:
I noticed you inverted pins in your BLDCDriver3PWM constructor (phB<=>phC and enable2<=>enable3). Is it on purpose?

Hey @wilwal23
I’m a bit late to the party, but I’m glad that you’ve found the example code.

The issue might be your serial terminal settings. Make sure to only use the new line \n caracter NL.
The warning you’re getting means that the \r character as the end of string which is needs to be configured additionally if you wish to use it. If you do not need this character just change the string termination using the dropdown down in left, if I remember correctly, in the arduino serial terminal.

Thank you @quentin , it was probably wrong, but it still doesn’t work! :frowning:

Thank you @Antun_Skuric !
Now the Serial monitor seems to be working fine, but the motor still doesn’t spin… There must be some alignment problem, do you know what might be the cause?

PS: I tested the hall sensors and they are working fine.

LOG FROM THE SERIAL MONITOR:

MOT: Init
MOT: Enable driver.
MOT: Align sensor.
MOT: Failed to notice movement
MOT: Init FOC failed.

CODE: (basically it is the velocity example code)

#include <SimpleFOC.h>
// software interrupt library
#include <PciManager.h>
#include <PciListenerImp.h>

// BLDC motor & driver instance
BLDCMotor motor = BLDCMotor(15);
BLDCDriver3PWM driver = BLDCDriver3PWM(9, 5, 6, 8, 4 ,7);
// Stepper motor & driver instance
//StepperMotor motor = StepperMotor(50);
//StepperDriver4PWM driver = StepperDriver4PWM(9, 5, 10, 6,  8);
// hall sensor instance

  HallSensor sensor = HallSensor(10, 11, 12, 15);

    // Interrupt routine intialisation
    // channel A, B and C callbacks
  void doA(){sensor.handleA();}
  void doB(){sensor.handleB();}
  void doC(){sensor.handleC();}
    // If no available hadware interrupt pins use the software interrupt
  PciListenerImp listenA(sensor.pinA, doA);
  PciListenerImp listenB(sensor.pinB, doB);
  PciListenerImp listenC(sensor.pinC, doC);

// velocity set point variable
float target_velocity = 0;
// instantiate the commander
Commander command = Commander(Serial);
void doTarget(char* cmd) { command.scalar(&target_velocity, cmd); }


void setup() {

//sensor config
  sensor.pullup = Pullup::USE_EXTERN;
  sensor.init();
  sensor.enableInterrupts(doA, doB, doC); 
// software interrupts
  PciManager.registerListener(&listenA);
  PciManager.registerListener(&listenB);
  PciManager.registerListener(&listenC);
//link sensor
  motor.linkSensor(&sensor);

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

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

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

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

  // velocity PI controller parameters
  motor.PID_velocity.P = 0.2f;
  motor.PID_velocity.I = 20;
  motor.PID_velocity.D = 0;
  // default voltage_power_supply
  motor.voltage_limit = 24;
  // 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.01f;

  // use monitoring with serial
  Serial.begin(115200);
  // comment out if not needed
  motor.useMonitoring(Serial);

  // initialize motor
  motor.init();
  // align sensor and start FOC
  motor.initFOC();

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

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


void loop() {
  // main FOC algorithm function
  // the faster you run this function the better
  // Arduino UNO loop  ~1kHz
  // Bluepill loop ~10kHz
  motor.loopFOC();

  // Motion control function
  // velocity, position or voltage (defined in motor.controller)
  // this function can be run at much lower frequency than loopFOC() function
  // You can also use motor.move() and set the motor.target in the code
  motor.move(target_velocity);

  // function intended to be used with serial plotter to monitor motor variables
  // significantly slowing the execution down!!!!
  // motor.monitor();

  // user communication
  command.run();
}

Do you mean you successfully ran the SimpleFOC hall_sensor_example sample code?

Hey guys,
@quentin you’re right, @wilwal23 please do make sure that your sensor works properly and that you can read the values from it.

Then make sure your motor works in the open loop!
So the code you’ve posted in the post before has to work, the motor has to turn when you set a certain velocity.
But please make sure to lower the voltage limit!!!
24 volt limit for the open loop will burn either your motor or your driver :smiley:
Start with 1, or 2Volts.

motor.voltage_limit = 1;   // [V]

Do you mean you successfully ran the SimpleFOC hall_sensor_example sample code?

“Unfortunately”, yes.

I attach the code below (it’s more or less the same as the one for the example).

With it, I can read as output on the serial monitor the correct angle and the correct velocity.


/**
 *  Hall sensor example code 
 * 
 * This is a code intended to test the hall sensors connections and to demonstrate the hall sensor setup.
 * 
 */

#include <SimpleFOC.h>
// software interrupt library
#include <PciManager.h>
#include <PciListenerImp.h>

  HallSensor sensor = HallSensor(10, 11, 12, 15);

    // Interrupt routine intialisation
    // channel A, B and C callbacks
  void doA(){sensor.handleA();}
  void doB(){sensor.handleB();}
  void doC(){sensor.handleC();}
    // If no available hadware interrupt pins use the software interrupt
  PciListenerImp listenA(sensor.pinA, doA);
  PciListenerImp listenB(sensor.pinB, doB);
  PciListenerImp listenC(sensor.pinC, doC);

  
void setup() {
  // monitoring port
  Serial.begin(115200);

 //sensor config
  sensor.pullup = Pullup::USE_EXTERN;
  sensor.init();
  sensor.enableInterrupts(doA, doB, doC); 
// software interrupts
  PciManager.registerListener(&listenA);
  PciManager.registerListener(&listenB);
  PciManager.registerListener(&listenC);

  Serial.println("Sensor ready");
  _delay(1000);
}

void loop() {
  // iterative function updating the sensor internal variables
  // it is usually called in motor.loopFOC()
  sensor.update();
  // display the angle and the angular velocity to the terminal
  Serial.print(sensor.getAngle());
  Serial.print("\t");
  Serial.println(sensor.getVelocity());
}

Unfortunately, the open loop example doesn’t work either… :sob:
Tomorrow I’ll try to lower the motor voltage :slight_smile:
[The fact is that I’m powering the motor of an electric scooter with its own battery (which supplies 24V), so I guess it should run with that power more or less, right?]