Hi
I have an ODrive v3.6 (56V) running firmware 0.5.6, controlling two hoverboard BLDC motor (15 pole pairs) with an AS5047P magnetic encoder in ABI mode.
Problem is
- FULL_CALIBRATION_SEQUENCE` completes successfully with all errors = 0x0
- Motor moves correctly in
CLOSED_LOOP_CONTROLafter calibration - After setting
motor.pre_calibrated = Trueandencoder.pre_calibrated = True, then rebooting, the axis faults with: Axis error: 0x40(ERROR_MOTOR_FAILED)Motor error: 0x4000000Encoder error: 0x0
Is this a known issue with incremental encoders on 0.5.6? Should I use a different pre-calibration strategy, or is calibration-on-every-boot the only reliable option?
Hardware Setup
ODrive: v3.6-56V (firmware v0.5.6)
Motor: Hoverboard BLDC (~15 pole pairs, 5-10Ω)
Encoder: AS5047P (ABI mode, CPR = 4096)
Power supply: 50V, 30A capable
Brake resistor: wired
## Configuration Code (Working - No Pre-Cal)
python
import odrive
from odrive.enums import *
import time
odrv0 = odrive.find_any()
axis = odrv0.axis0
Clear and reset
odrv0.clear_errors()
axis.requested_state = AXIS_STATE_IDLE
time.sleep(0.5)
— MOTOR CONFIG —
axis.motor.config.motor_type = 0 # HIGH CURRENT
axis.motor.config.pole_pairs = 15
axis.motor.config.calibration_current = 10
axis.motor.config.current_lim = 15
axis.motor.config.requested_current_range = 25
axis.motor.config.resistance_calib_max_voltage = 25
axis.motor.config.current_control_bandwidth = 100
— ENCODER CONFIG —
axis.encoder.config.mode = ENCODER_MODE_INCREMENTAL
axis.encoder.config.cpr = 4096 # Measured via shadow_count test: -4107 ≈ 4096
axis.encoder.config.use_index = False
axis.encoder.config.pre_calibrated = False # THIS IS KEY - leaving false
axis.encoder.config.bandwidth = 1000
axis.encoder.config.calib_range = 0.05
— CONTROLLER CONFIG —
axis.controller.config.control_mode = CONTROL_MODE_POSITION_CONTROL
axis.controller.config.input_mode = INPUT_MODE_POS_FILTER
axis.controller.config.pos_gain = 20
axis.controller.config.vel_gain = 0.02
axis.controller.config.vel_integrator_gain = 0.05
axis.controller.config.vel_limit = 10
— BOARD CONFIG —
odrv0.config.enable_brake_resistor = False
print(“Saving base configuration…”)
odrv0.save_configuration()
time.sleep(5)
Reconnect after reboot
odrv0 = odrive.find_any()
axis = odrv0.axis0
— CALIBRATION —
print(“Running FULL_CALIBRATION_SEQUENCE…”)
odrv0.clear_errors()
axis.requested_state = AXIS_STATE_FULL_CALIBRATION_SEQUENCE
while axis.current_state != AXIS_STATE_IDLE:
time.sleep(0.1)
print(f"Axis error: {hex(axis.error)}“)
print(f"Motor error: {hex(axis.motor.error)}”)
print(f"Encoder error: {hex(axis.encoder.error)}")
Output: All 0x0 ✓
— ENTER CLOSED LOOP —
axis.requested_state = AXIS_STATE_CLOSED_LOOP_CONTROL
time.sleep(1)
Test motion
axis.controller.input_pos = 2
time.sleep(2)
axis.controller.input_pos = 0
Motor moves correctly ✓
## Configuration Code (Fails - With Pre-Cal)
python
After the above calibration succeeds, add this:
axis.motor.config.pre_calibrated = True
axis.encoder.config.pre_calibrated = True
axis.config.startup_motor_calibration = False
axis.config.startup_encoder_offset_calibration = False
axis.config.startup_closed_loop_control = True
print(“Saving pre-calibrated config…”)
odrv0.save_configuration()
time.sleep(5)
Reboot ODrive manually or reconnect
Now on reconnect:
odrv0 = odrive.find_any()
axis = odrv0.axis0
print(f"Axis state: {axis.current_state}“)
print(f"Axis error: {hex(axis.error)}”)
print(f"Motor error: {hex(axis.motor.error)}“)
print(f"Encoder error: {hex(axis.encoder.error)}”)
Output:
Axis state: 1 (IDLE)
Axis error: 0x40 (ERROR_MOTOR_FAILED)
Motor error: 0x4000000
Encoder error: 0x0
## Measurements & Debug Info
Encoder CPR verification (shadow_count test):
* **1 mechanical turn:** -4107 counts
* **5 mechanical turns:** -20,076 counts → -4015.2 counts/rev
* **Conclusion:** Actual CPR ≈ 4096 ✓ (matches configured value)
Bus voltage: 50.47V ✓
Encoder is counting cleanly ✓
## Questions
1. Is the `pre_calibrated` approach fundamentally incompatible with incremental encoders on firmware 0.5.6?
2. Should I stick with "calibrate at every startup" for reliability? This will be technically a problem .
3. Are there any known workarounds (e.g., specific current limits, gain adjustments) to make pre-calibration work?
4. Would switching the AS5047P to **SPI absolute mode** (`ENCODER_MODE_SPI_ABS_AMS`) solve this without needing pre-calibration?
Best regards
Shaker