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:
- Is the combination of
MotionControlType::angleandTorqueControlType::foc_currenta supported and commonly used configuration in SimpleFOC? - When using this combination, are there any additional settings or PID parameters that need to be configured differently from the standard Angle Control setup?
- 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(¤t_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(¤t_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();
}
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!
– colapunch