MOT: init FOC Failed

Hi, I’m trying to run the BLDC motor using simpleFOCSheied and Arduino Mega. When I combined and operated simpleFOCSheied with Arduino Uno, the motor turned, but when I connected to Mega and operated it, it did not work with the following results.

MOT: Monitor enabled!
MOT: Init
MOT: Enable driver.
MOT: Align sensor.
MOT: Failed to notice movement
MOT: Init FOC failed.
Motor ready.

So I don’t think it’s an Arduino code issue and it seems to be a hardware connection issue. The BLDC motor I am using is EC 45 flat. The only difference from the code I used when connecting to Uno is that I changed the pin number of the 3PWM and encoder.

BLDCDriver3PWM driver = BLDCDriver3PWM(9, 10, 11,8);
Encoder encoder = Encoder(18, 19, 2048);

I used pins like this. I connected the common ground and the power source. What’s the problem?

Hey, welcome @sdkancknxld ,

The PWM pins used look ok, I am not sure about the encoder. Are 18 and 19 interrupt-capable pins on the Mega?

The output you show means the initialisation cannot detect the motor movement - was the motor in fact moving?
If yes, then this is very likely a sensor problem.

image

Looking at the picture above, it seems that 18 or 19 interrupt pins are available in Arduino Mega. Also, the motor didn’t move. So what’s the problem?

Unfortunately it is hard to say from this description…

Could you share details about how you configured the SimpleFOCShield, which solder-bridges you have used?
Perhaps some pictures of your setup could help, as well as the complete code you’re trying to run…

The serial monitor now outputs a success message and the motor is still not running.

I’m trying to run a BLDC motor using Arduino Mega and a simpleFOCShield. The motor I’m using is an EC 45 flat+Encoder. I used the example code from the Writing Code → Motion Control → Closed-Loop Control → Torque Control → FOC Current Mode tab, and only three codes were modified as shown below. But the motor didn’t turn.

BLDC motor motor = BLDC motor (9);
encoder encoder = encoder (2, 3, 2048);
driver.voltage_power_supply = 12;

Here’s the code I used.

=====================================================

#include <SimpleFOC.h>

// BLDC motor & driver instance
BLDCMotor motor = BLDCMotor(9);
BLDCDriver3PWM driver = BLDCDriver3PWM(9, 5, 6, 8);

// encoder instance
Encoder encoder = Encoder(2, 3, 2048);
// channel A and B callbacks
void doA(){encoder.handleA();}
void doB(){encoder.handleB();}

// current sensor
InlineCurrentSense current_sense = InlineCurrentSense(0.01, 50, A0, A2);

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

void setup() {

// initialize encoder sensor hardware
encoder.init();
encoder.enableInterrupts(doA, doB);
// link the motor to the sensor
motor.linkSensor(&encoder);

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

// current sense init hardware
current_sense.init();
// link the current sense to the motor
motor.linkCurrentSense(&current_sense);

// set torque mode:
motor.torque_controller = TorqueControlType::foc_current;
// set motion control loop to be used
motor.controller = MotionControlType::torque;

// foc current control parameters (Arduino UNO/Mega)
motor.PID_current_q.P = 5;
motor.PID_current_q.I= 300;
motor.PID_current_d.P= 50;
motor.PID_current_d.I = 300;
motor.LPF_current_q.Tf = 0.01;
motor.LPF_current_d.Tf = 0.01;

// 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 current”);

Serial.println(F(“Motor ready.”));
Serial.println(F(“Set the target current using serial terminal:”));
_delay(1000);
}

void loop() {
motor.loopFOC();

motor.move(motor.target);

command.run();
}

=====================================================

The following messages were printed on the serial monitor.

MOT: Monitor enabled!
MOT: Init
MOT: Enable driver.
MOT: Align sensor.
MOT: sensor_direction==CCW
MOT: PP check: OK!
MOT: Zero elec. angle: 6.28
MOT: Align current sense.

Can you tell me what kind of problem you have?

  • There seems to be no hardware problem because the motor rotated when operating using other example codes.

This sounds like good progress, sensor is now working :slight_smile: and pole pair check is passing.

Did you set a speed via the commander in the serial terminal? As is, this code won’t move the motor, because the motor.target starts at 0…

Thank you for your reply!

Are you asking me to modify the codes below? If so, please let me know how to modify it.

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

// add target command T
command.add(‘T’, doTarget, “target current”);

++++ Oh, and I put the code below into the setup() function, but the message is not outputting.

Serial.println(F(“Motor ready.”));
Serial.println(F(“Set the target current using serial terminal:”));

============================================================================

In addition, messages are repeatedly printed on the serial monitor as shown below. As the motor initializes, the initial position seems to continue to change. Why does the motor not work and only print messages repeatedly…?

MOT: Monitor enabled!
MOT: Init
MOT: Enable driver.
MOT: Align sensor.
MOT: sensor_direction==CCW
MOT: PP check: OK!
MOT: Zero elec. angle: 6.24
MOT: Align current sense.
MOT: Monitor enabled!
MOT: Init
MOT: sensor_direction==CCW
MOT: PP check: OK!
MOT: Zero elec. angle: 0.01
MOT: Align current sense.
MOT: Monitor enabled!
MOT: Init
MOT: Enable driver.
MOT: Align sensor.
MOT: sensor_direction==CCW
MOT: PP check: OK!
MOT: Zero elec. angle: 0.01
MOT: Align current sense.

============================================================================

  • Please let me know if you have any more code to add or modify…!

I’m getting the following error in motor.initFOC(). I’m using an ESP32S3-devkitc-1 microcontroller. I’m using current_sense (inline) and added analogRead(A0) to my code because of bug in esp32_adc_driver.c/.h. Can someone tell me why I’m getting a core dump?

MOT: Monitor enabled!
MOT: Init
MOT: Enable driver.
MOT: Align sensor.
MOT: sensor_direction==CCW
MOT: PP check: OK!
MOT: Zero elec. angle: 5.15
MOT: Align current sense.
Guru Meditation Error: Core 1 panic’ed (LoadProhibited). Exception was unhandled.

Core 1 register dump:
PC : 0x4200330a PS : 0x00060a30 A0 : 0x8200214f A1 : 0x3fce2c40
A2 : 0x3fc94384 A3 : 0x00000001 A4 : 0xffffcfc7 A5 : 0x00000000
A6 : 0x00000000 A7 : 0x00000000 A8 : 0x00000001 A9 : 0x3fce2c70
A10 : 0x00000000 A11 : 0x40400000 A12 : 0x40866666 A13 : 0x40866666
A14 : 0x00000002 A15 : 0x00000bb8 SAR : 0x00000020 EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000000 LBEG : 0x400556d5 LEND : 0x400556e5 LCOUNT : 0xfffffff9

Decoding stack results
0x42003307: InlineCurrentSense::driverAlign(float) at C:\Users\mmaheshwari\Documents\Arduino\libraries\Simple_FOC\src\current_sense*InlineCurrentSense.cpp* line 89
0x4200214c: BLDCMotor::alignCurrentSense() at C:\Users\mmaheshwari\Documents\Arduino\libraries\Simple_FOC\src*BLDCMotor.cpp* line 155
0x420026c7: BLDCMotor::initFOC(float, Direction) at C:\Users\mmaheshwari\Documents\Arduino\libraries\Simple_FOC\src*BLDCMotor.cpp* line 130
0x42001aaf: setup() at C:\Users\mmaheshwari\Documents\Arduino\Inline Current Sense\inline_current_sense_motor/inline_current_sense_motor.ino line 99
0x4200604a: loopTask(void) (C:\Program Files* at x86)\Arduino\hardware\espressif\esp32\cores\esp32*main.cpp* line 42

Looks like it is crashing while initialising the current sensing. Not sure what is wrong, because the pins you are using, A0, and A1 are obviously analog pins on the Mega.

No, the code does not get this this point. Looks like it is crashing in current sense alignment.

I think you are missing a current_sense.linkDriver(&driver); before the current_sense.init();
Please add it and see if it gets rid of the crashing…

Have you got the current_sense.linkDriver(&driver); in your code?

Also, please don’t call analogRead() if you’re using the current sensing. It won’t work. There is a new function adcRead() to let you use the other analog pins when using the current sensing.

  1. yes, current_sense.linkDriver(&driver) is in my code.
  2. there seems to be an issue with ESP32S3 using adcRead() according to this post. [BUG] ESP32 S3 compiles error in Platformio · Issue #198 · simplefoc/Arduino-FOC · GitHub. The example code inline_current_sense_test.ino compiles, but no output if I don’t use analogRead(A0) in setup().

The problem that occurs has changed, so I delete the previous reply and post it again!

The motor works. But the current is too large. When operating the following code, we found that the power supply giving the input voltage was very unstable. What’s the problem? Which value should I change to make the motor work stably?

#include <SimpleFOC.h>

// BLDC motor & driver instance
BLDCMotor motor = BLDCMotor(9);
BLDCDriver3PWM driver = BLDCDriver3PWM(9, 5, 6, 8);

// encoder instance
Encoder encoder = Encoder(2, 3, 2048);
// channel A and B callbacks
void doA(){encoder.handleA();}
void doB(){encoder.handleB();}

// current sensor
InlineCurrentSense current_sense = InlineCurrentSense(0.01, 50, A0, A2);

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

void setup() {

// initialize encoder sensor hardware
encoder.init();
encoder.enableInterrupts(doA, doB);
// link the motor to the sensor
motor.linkSensor(&encoder);

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

current_sense.linkDriver(&driver);
// current sense init hardware
current_sense.init();
// link the current sense to the motor
motor.linkCurrentSense(&current_sense);

// set torque mode:
motor.torque_controller = TorqueControlType::foc_current;
// set motion control loop to be used
motor.controller = MotionControlType::torque;

// foc current control parameters (Arduino UNO/Mega)
motor.PID_current_q.P = 5;
motor.PID_current_q.I= 300;
motor.PID_current_d.P= 5;
motor.PID_current_d.I = 300;
motor.LPF_current_q.Tf = 0.01;
motor.LPF_current_d.Tf = 0.01;

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

// invert phase b gain
current_sense.gain_b *=-1;
// skip alignment
current_sense.skip_align = true;

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

// add target command T
command.add(‘T’, doTarget, “target current”);

Serial.println(F(“Motor ready.”));
Serial.println(F(“Set the target current using serial terminal:”));
_delay(1000);
}

void loop() {

motor.loopFOC();

motor.move();

command.run();

}

============================================================================

We also used the motor.monitor() function to check both values of _MON_CURR_Q | _MON_CURR_D | _MON_VEL | _MON_ANGLE. _MON_VEL, _MON_ANGLE were outputting negatively. What is the problem with this?

image

Hi,

There is no problem here. Angle and velocity can be positive or negative, it depends on the direction you want the motor to turn.
If you set a positive target, and the direction is negative, then it is a problem…

Probably this means the power supply cannot deliver enough current…

You are using foc-current control - have you tuned the PID parameters?
You can set a motor.current_limit to keep the current below a specific level.

Hello, thank you for your reply!!

I am testing again by changing the PID parameter. I don’t know how to change it, so I’m trying to change various values. But there is still a problem. Either way, too much current is used. So the motor heats up quickly and the power supply is unstable.

I wrote the code for driver.voltage_power_supply = 24; and applied a voltage of 24V to the power supply. However, the current is too high and the voltage is applied only at 6-8 volts.

How do I adjust the PID parameters? Also, why is the current too high?

Hello.

The motor is not turned in FOC_Current mode, so I’m turning the motor in velocity control mode first. The message displayed on the serial monitor says successful, but the motor moves about 30 degrees at first and then does not turn continuously. The code I am using is as follows. I really want to solve this problem…!!

#include <SimpleFOC.h>

// motor instance
BLDCMotor motor = BLDCMotor(9, 1);
// driver instance
BLDCDriver3PWM driver = BLDCDriver3PWM(9, 5, 6, 8);

// encoder instance
Encoder encoder = Encoder(2, 3, 2048);
// channel A and B callbacks
void doA(){encoder.handleA();}
void doB(){encoder.handleB();}

void setup() {
 
  // initialize encoder sensor hardware
  encoder.init();
  encoder.enableInterrupts(doA, doB);
  // link the motor to the sensor
  motor.linkSensor(&encoder);

  // power supply voltage
  driver.voltage_power_supply = 24; // default 12V

  // driver config
  driver.init();
  motor.linkDriver(&driver);

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

  // controller configuration based on the control type 
  // velocity PID controller parameters
  // default P=0.5 I = 10 D =0
  motor.PID_velocity.P = 0.5;
  motor.PID_velocity.I = 5;
  motor.PID_velocity.D = 0.001;
  // 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
  // default 5ms - try different values to see what is the best. 
  // the lower the less filtered
  motor.LPF_velocity.Tf = 0.001;  
  
  // since the phase resistance is provided we set the current limit not voltage
  // default 0.2
  motor.current_limit = 1; // Amps

  // 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(); 

  Serial.println("Motor ready.");
  _delay(1000);

}

// velocity set point variable
float target_velocity = 5; // 2Rad/s ~ 20rpm

void loop() {

  // main FOC algorithm function
  motor.loopFOC();

  // Motion control function
  motor.move(target_velocity);

}

Hi,

Did you solve this?

One question: your encoder - is it 2048 PPR (=8192CPR) or 2048 CPR (=512PPR) ?

I sympathize because you guys sound kind of like me when I started, but unfortunately I think if your problems are to ever end you need to take a more methodical approach, check every system component one by one and assemble them step by step. A lot of people jump in thinking things are going to be nearly plug and play and we only have disappointment for them :(. Progress is being made though.