Motor gets no power during Index search in motor.initFOC();

Hi!

TLDR;

motor.initFOC() does not activate PWM. The motor does not spin and the Index search fails. Why? Did I miss something?

Used hard and software

What did I test?

1. Sensor test - OK

I tested successfully the SimpleFOC Sensor test <https://docs.simplefoc.com/test_sensor>.
I changed the following lines from the example:

Encoder encoder = Encoder(A_HALL1, A_HALL2, 500, A_HALL3); // adjusted to my encoder
void doIndex(){encoder.handleIndex();                      // line added
encoder.enableInterrupts(doA, doB, doIndex);               // doIndex added
Serial.println(encoder.getVelocity());                     // error in example - to use sensor make no sense here

With these changes the example works like a charm. I turn the rotor manually and get two numbers in the serial console. The first number counts up (or down - dependent of the direction I turn the rotor) and the seconds shows the velocity.

2. Driver test - OK

I tested successfully the SimpleFOC driver test <https://docs.simplefoc.com/test_driver>.
I changed the following lines from the example:

BLDCDriver6PWM driver = BLDCDriver6PWM(A_PHASE_UH, A_PHASE_UL, A_PHASE_VH, A_PHASE_VL, A_PHASE_WH, A_PHASE_WL);
driver.voltage_power_supply = 24;
driver.voltage_limit = 8;

With these changes I got the example running. Without the motor connected I got:

  • phase U: 3.06 V
  • phase V: 6.12 V
  • phase W: 5.09 V

I also tested the second part with the dynamic PWM. It worked, too.

3. Open loop motor - driver test - OK

I tested successfully the SimpleFOC open loop motor driver <https://docs.simplefoc.com/test_motor_driver>.
I changed the following lines from the example:

BLDCMotor motor = BLDCMotor(1, 0.336, 224, 0.000149, 0.000149); // all values from the datasheet
BLDCDriver6PWM driver = BLDCDriver6PWM(A_PHASE_UH, A_PHASE_UL, A_PHASE_VH, A_PHASE_VL, A_PHASE_WH, A_PHASE_WL);
driver.voltage_power_supply = 24; // same as test #2
driver.voltage_limit = 8;         // same as test #2
motor.voltage_limit = 2;

No problems. The motor spins with 60 rpm or 6.28 rad/s. I can see all three PWM on the scope.

4. Closed Loop test - Failed

So far I have a working encoder, driver and motor. But together I can’t get it to work. The closed loop example <https://docs.simplefoc.com/test_closedloop> fails.
I changed the following lines from the example:

BLDCMotor motor = BLDCMotor(1, 0.336, 224, 0.000149, 0.000149); // same as test #3
BLDCDriver6PWM driver = BLDCDriver6PWM(A_PHASE_UH, A_PHASE_UL, A_PHASE_VH, A_PHASE_VL, A_PHASE_WH, A_PHASE_WL); // same as test #3
Encoder encoder = Encoder(A_HALL1, A_HALL2, 500, A_HALL3);      // same as test #1
void doIndex(){encoder.handleIndex();                           // same as test #1
encoder.enableInterrupts(doA, doB, doIndex);                    // same as test #1
driver.voltage_power_supply = 24;                               // same as test #3
driver.voltage_limit = 8;                                       // same as test #3
motor.voltage_sensor_align = 2;

Log from the start:

TIM1-CH1 TIM1-CH1N TIM1-CH2 TIM1-CH2N TIM1-CH3 TIM1-CH3N score: 1
STM32-DRV: best: TIM1-CH1 TIM1-CH1N TIM1-CH2 TIM1-CH2N TIM1-CH3 TIM1-CH3N score: 1
STM32-DRV: Initializing TIM1
STM32-DRV: Timer resolution set to: 3400
STM32-DRV: Configured TIM1_CH1
STM32-DRV: Configured TIM1_CH2
STM32-DRV: Configured TIM1_CH3
STM32-DRV: Synchronising 1 timers
MOT:Monitor enabled!
MOT:Init
MOT:Enable driver.
MOT:Align sensor.
MOT:Index search...
ERR-MOT:Not found!
ERR-MOT:Init FOC fail
FOC init failed!

You can see the index is not found. I can’t see any PWM during the Index search period. The scope shows only flat lines around 0 V.

Did I miss something? Any help would be appreciated.

Trivia: If I turn the rotor manually during the index search period. The index is found and everything comes to live. The motor spins and I can control the voltage via serial commands.

5. Bonus: B-G431B-ESC1 example - failed

I found in the Arduino IDE a B-G431B-ESC1 example

  • File →
    • Examples →
      • Simple FOC →
        • Hardware_specific_examples →
          • B_G431B_ESC1.

I changed the following lines to match my hardware and tested it:

BLDCMotor motor = BLDCMotor(1, 0.336, 224, 0.000149, 0.000149);
Encoder encoder = Encoder(A_HALL1, A_HALL2, 500, A_HALL3);
motor.voltage_sensor_align = 2;
motor.velocity_index_search = 2;

The example uses motor.initFOC(), too. So it failed in the same way as in example #4. No PWM during the index search, flat lines on the scope → init failed.

I hope someone has an idea why initFOC does not send a PWM to the motor.

Best regards,
Tom

Hi @TomE

It would be best if you could upload your whole program. That way we can see everything together. But I think I see a typo in your code.

Your line for creating the encoder has a different name. It’s not your fault, it is how the previous tutorial spelled it.

Your line from sensor test: Encoder encoder = Encoder(A_HALL1, A_HALL2, 500, A_HALL3);

The line from closed loop test: Encoder sensor = Encoder(2, 3, 2048);

Try taking a look at this example in arduino IDE and filling in your specific motor info.

simple FOC examples/motion_control/position_motion_control/encoder/angle_control/angle_control.ino

Hi there!
This is unfortunately a bug in our v2.4 code.

We’ve already had an issue on GitHub and a PR for the dev branch. Issue · GitHub

Sorry about that, it will be fixed for the next release

Hi Antun!

Thanks a lot for your answer. It is good to know that the error wasn’t on my side. I never thought that this could be a bug so I never checked the issues on Github. Sorry for that.

Best regards,
Tom

Hi Rosewill2!

Thanks for your input. I had deliberately chosen to write only the changed rows otherwise I thought the post gets to long. But I see now that this creates more problems than it solves. My bad. I’m sorry.

Here is my complete sketch for #4 closed loop. You can see, every sensor is called encoder so there should not a problem with the name.

#include <SimpleFOC.h>

BLDCMotor motor = BLDCMotor(1, 0.336, 224, 0.000149, 0.000149);

BLDCDriver6PWM driver = BLDCDriver6PWM(A_PHASE_UH, A_PHASE_UL, A_PHASE_VH, A_PHASE_VL, A_PHASE_WH, A_PHASE_WL);

Encoder encoder = Encoder(A_HALL1, A_HALL2, 500, A_HALL3);

void doA(){encoder.handleA();}
void doB(){encoder.handleB();}
void doIndex(){encoder.handleIndex();}

Commander command = Commander(Serial);
void doMotor(char* cmd) { command.motor(&motor, cmd); }

void setup() { 
  
  Serial.begin(115200);
  SimpleFOCDebug::enable(&Serial);

  encoder.init();
  encoder.enableInterrupts(doA, doB, doIndex);
  motor.linkSensor(&encoder);

  driver.voltage_power_supply = 24;
  driver.voltage_limit = 8;
  if(!driver.init()){
    Serial.println("Driver init failed!");
    return;
  }
  motor.linkDriver(&driver);

  motor.voltage_sensor_align = 2;
  motor.torque_controller = TorqueControlType::voltage;
  motor.controller = MotionControlType::torque;
  motor.useMonitoring(Serial);
  if(!motor.init()){
    Serial.println("Motor init failed!");
    return;
  }

  if(!motor.initFOC()){
    Serial.println("FOC init failed!");
    return;
  }
  motor.target = 2; // Volts 

  command.add('M', doMotor, "Motor");

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

void loop() {
  motor.loopFOC();

  motor.move();
  command.run();
}

Thanks for your time!
I will now try to test the PR from Antun’s post and an older version of SimpleFOC.

Best regards
Tom

Hi!
I can confirm both solutions from the GitHub-issue work:

  • either downgrade SimpleFOC to 2.3.5
  • or patch SimpleFOC 2.4.0 with the Pull Request from the GitHub-issue

Thanks for your help!
Best regards,
Tom