Motor Vibrates and Spins Unexpectedly When Using Angle Control + FOC Current in SimpleFOC

Hello,

First of all, thank you very much for developing and maintaining SimpleFOC. It is a great and very useful project, and I really appreciate the opportunity to learn from it.

I have been using SimpleFOC for about three months, so I am still a beginner. I am currently learning about BLDC motor position control, and I have encountered an issue that I have not been able to identify the cause of. I would really appreciate any advice or guidance.

Hardware

  • ESP32-WROOM-32E
  • SimpleFOC Shield V3.2
  • AS5600
  • BLDC motor

Current Situation

I have confirmed that the following two control configurations work correctly.

1. Angle Control

The following SimpleFOC example works correctly:

Arduino-FOC/examples/motion_control/position_motion_control/magnetic_sensor/angle_control/angle_control.ino

2. Torque Control + FOC Current Control

The following configuration also works correctly:

motor.controller = MotionControlType::torque;
motor.torque_controller = TorqueControlType::foc_current;

However, I encounter a problem when I change MotionControlType::torque to MotionControlType::angle:

motor.controller = MotionControlType::angle;
motor.torque_controller = TorqueControlType::foc_current;

With this configuration, the motor starts vibrating strongly and then suddenly attempts to spin at a very high speed in an unintended direction.

Questions

I realize that this could very well be caused by my own misunderstanding or an incorrect configuration. With that in mind, I would be very grateful if you could advise me on the following points:

  1. Is the combination of MotionControlType::angle and TorqueControlType::foc_current a supported and commonly used configuration in SimpleFOC?
  2. When using this combination, are there any additional settings or PID parameters that need to be configured differently from the standard Angle Control setup?
  3. If a motor vibrates and attempts to spin rapidly as described above, are there any particular settings, measurements, or diagnostic information that you would recommend checking first?

I am still learning about electronics and motor control, so I have not yet been able to determine whether the problem is caused by my code, the wiring or power supply, the hardware configuration, or simply my understanding of how SimpleFOC works.

Initialization Log

When motor.initFOC() is executed, I get the following output:

MOT:Align sensor.
MOT:sensor dir: CW
MOT:PP check: OK!
Skip dir calib.
MOT:Zero elec. angle: 6.02
MOT:Align current sense.
MOT:Success: 1
MOT:Ready.
Motor ready.

Since MOT:Ready. is displayed, it appears that the initialization itself is completing successfully.

If there are any additional logs, settings, or measurements that would be useful for diagnosing this issue, I would greatly appreciate your suggestions.

Thank you very much for your time and for your work on SimpleFOC.


Code That Causes the Problem

#include <SimpleFOC.h>

BLDCMotor motor = BLDCMotor(7);
BLDCDriver3PWM driver = BLDCDriver3PWM(25, 26, 27, 33);
MagneticSensorI2C sensor = MagneticSensorI2C(AS5600_I2C);
InlineCurrentSense current_sense = InlineCurrentSense(185.0f, 34, 35);

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

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

  Wire.begin(21, 22);
  sensor.init();
  motor.linkSensor(&sensor);

  driver.voltage_power_supply = 12;
  driver.init();
  motor.linkDriver(&driver);

  motor.voltage_sensor_align = 4.0f;
  current_sense.linkDriver(&driver);

  motor.controller = MotionControlType::angle;
  motor.torque_controller = TorqueControlType::foc_current;
  motor.foc_modulation = FOCModulationType::SpaceVectorPWM;

  motor.voltage_limit = 6;
  motor.current_limit = 1.0f;
  motor.velocity_limit = 3;

  motor.PID_current_q.P = 0.05f;
  motor.PID_current_q.I = 100.0f;

  motor.PID_current_d.P = 0.05f;
  motor.PID_current_d.I = 100.0f;

  motor.LPF_current_q.Tf = 0.01f;
  motor.LPF_current_d.Tf = 0.01f;

  motor.useMonitoring(Serial);

  current_sense.init();
  motor.linkCurrentSense(&current_sense);

  motor.init();
  motor.initFOC();

  motor.target = 0.0f;

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

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

void loop() {
  motor.loopFOC();
  motor.move();
  command.run();
}

For Comparison: This Configuration Works Correctly

In contrast, the following configuration works correctly with MotionControlType::torque and TorqueControlType::foc_current:

#include <SimpleFOC.h>

BLDCMotor motor = BLDCMotor(7);
BLDCDriver3PWM driver = BLDCDriver3PWM(25, 26, 27, 33);
MagneticSensorI2C sensor = MagneticSensorI2C(AS5600_I2C);
InlineCurrentSense current_sense = InlineCurrentSense(185.0f, 34, 35);

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

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

  Wire.begin(21, 22);
  sensor.init();
  motor.linkSensor(&sensor);

  driver.voltage_power_supply = 12;
  driver.init();
  motor.linkDriver(&driver);

  motor.voltage_sensor_align = 4.0f;
  current_sense.linkDriver(&driver);

  motor.controller = MotionControlType::torque;
  motor.torque_controller = TorqueControlType::foc_current;
  motor.foc_modulation = FOCModulationType::SpaceVectorPWM;

  motor.voltage_limit = 6;
  motor.current_limit = 1.0f;

  motor.PID_current_q.P = 1.0f;
  motor.PID_current_q.I = 100.0f;

  motor.PID_current_d.P = 1.0f;
  motor.PID_current_d.I = 100.0f;

  motor.LPF_current_q.Tf = 0.01f;
  motor.LPF_current_d.Tf = 0.01f;

  motor.useMonitoring(Serial);

  current_sense.init();
  motor.linkCurrentSense(&current_sense);

  motor.init();
  motor.initFOC();

  motor.target = 0.0f;

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

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

void loop() {
  motor.loopFOC();
  motor.move();
  motor.monitor();
  command.run();
}

1 Answer

1

Hi,
the symptoms you described indicate a runaway situation. You also didn’t mention anything about velocity PID tuning.
I guess you went from torque-mode to angle-mode directly?
If you want to bypass velocity tuning, you should try angle_nocascade-mode.

Hi, thank you very much for your comment! It was really helpful. Just as you pointed out, I was missing the velocity PID tuning. After adding the following settings, it worked perfectly. motor.P_angle.P = 0.5f; motor.P_angle.I = 0.0f; motor.P_angle.D = 0.0f; motor.PID_velocity.P = 0.1f; motor.PID_velocity.I = 0.0f; motor.LPF_velocity.Tf = 0.01f; Thank you so much for pointing me in the right direction!