Background:
I have a BLDC motor control system using SimpleFOC. The system is installed in a location where power cycling is inconvenient, so I need to perform sensor recalibration (specifically zero_electric_angle and sensor_direction) on-demand while the MCU remains powered.
What I’m trying to do:
I’ve implemented a command doCalib() that should re-run the calibration procedure to determine the electrical angle offset and sensor direction. The idea is to reset the motor’s calibration state and call motor.initFOC() again to trigger the full alignment routine.
My current approach:
cpp
void doCalib(char* cmd) {
motor.disable();
// Reset calibration parameters
motor.zero_electric_angle = 0;
motor.sensor_direction = Direction::UNKNOWN;
motor.motor_status = FOCMotorStatus::motor_uninitialized;
// Re-initialize hardware components
driver.init();
current_sense.init();
sensor.init();
motor.linkDriver(&driver);
motor.linkCurrentSense(¤t_sense);
motor.linkSensor(&sensor);
if (motor.initFOC()) {
foc_initialized = true;
motor.enable();
}
}
The problem:
-
If I skip re-initializing
driver,current_sense, andsensor(calling onlymotor.initFOC()after resetting calibration params), the control loop becomes confused after calibration - the motor starts rotating unexpectedly without receiving a command. -
If I do re-initialize them,
driver.init()fails in the middle of operation and I got “STM32-DRV: no workable combination found on these pins” -
According to this Pull Request discussion,
motor.initFOC()will run calibration ifzero_electric_angleandsensor_directionare set to zero andUNKNOWN. But it seems the motor’s internal state isn’t fully reset.
My questions:
-
Is there a documented or recommended procedure to safely force a re-calibration without a full hardware re-initialization?
-
Are there internal motor state variables beyond
motor_statusthat need to be reset before callinginitFOC()again? -
Could the “confused control loop” issue be related to
motor.enable()being called after calibration without properly resetting the target values or PID controllers? I’m controlling the motor in torque mode, but after recalibration, it spins without a command.
Hardware details:
-
MCU: STM32
-
Sensor: Magnetic encoder AS5147 - I understand absolute encoders can store calibration values and skip the routine , but I specifically want to re-run the full alignment.
What I’ve tried:
-
Resetting
motor.zero_electric_angle = 0andmotor.sensor_direction = Direction::UNKNOWN(works in theory per the API docs ) -
Resetting
motor.motor_status = FOCMotorStatus::motor_uninitialized -
Calling
motor.disable()before andmotor.enable()after calibration -
Re-initializing the hardware modules, which fails
Any guidance would be greatly appreciated!