OVER_REGEN_CURRENT problem

Hi, I got some error after motor and encoder calibration. two 2804 motors with odrive V3.6 firmware 0.5.1. Please help to solve the errors.Thanks a lot.
Is there any configration mistake? BTW, I use a 12V mingwell power supply.

In [173]: odrv0.config.max_regen_current
Out[173]: 5.0

In [174]: odrv0.config.dc_max_negative_current
Out[174]: 0.0

In [175]: odrv0.config.brake_resistance
Out[175]: 0.4699999988079071

In [135]: odrv0.axis1.controller.config.control_mode = CONTROL_MODE_POSITION_CONTROL

In [136]: odrv0.axis0.controller.config.control_mode = CONTROL_MODE_POSITION_CONTROL

In [137]: odrv0.axis1.controller.config.vel_limit = 2

In [138]: odrv0.axis0.controller.config.vel_limit = 2

In [139]: odrv0.axis1.controller.config.pos_gain = 15

In [140]: odrv0.axis0.controller.config.pos_gain = 15

In [141]: odrv0.axis1.controller.config.vel_gain = 0.01

In [142]: odrv0.axis0.controller.config.vel_gain = 0.01

In [143]: odrv0.axis1.controller.config.vel_integrator_gain = 0.1

In [144]: odrv0.axis0.controller.config.vel_integrator_gain = 0.1

In [145]: odrv0.axis1.controller.config.input_mode = INPUT_MODE_TRAP_TRAJ

In [146]: odrv0.axis0.controller.config.input_mode = INPUT_MODE_TRAP_TRAJ

In [147]: odrv0.axis1.trap_traj.config.vel_limit = 2

In [148]: odrv0.axis0.trap_traj.config.vel_limit = 5

In [149]: odrv0.axis1.trap_traj.config.accel_limit = 2

In [150]: odrv0.axis0.trap_traj.config.accel_limit = 2

In [151]: odrv0.axis1.trap_traj.config.vel_limit = 5

In [152]: odrv0.axis1.trap_traj.config.decel_limit = 2

In [153]: odrv0.axis0.trap_traj.config.decel_limit = 2

In [154]: odrv0.save_configuration()

In [155]: odrv0.reboot()
Reconnected to ODrive 358A387A3335 as odrv0

In [156]: dump_errors(odrv0)
axis0
axis: no error
motor: no error
fet_thermistor: no error
motor_thermistor: no error
encoder: no error
controller: no error
axis1
axis: no error
motor: no error
fet_thermistor: no error
motor_thermistor: no error
encoder: no error
controller: no error

In [157]: odrv0.axis1.requested_state = AXIS_STATE_MOTOR_CALIBRATION

In [159]: odrv0.axis0.requested_state = AXIS_STATE_MOTOR_CALIBRATION

In [160]: odrv0.axis1.motor.config.phase_resistance
Out[160]: 4.987849712371826

In [161]: odrv0.axis0.motor.config.phase_resistance
Out[161]: 3.382427215576172

In [162]: odrv0.axis1.motor.config.phase_inductance
Out[162]: 0.0013441413175314665

In [163]: odrv0.axis0.motor.config.phase_inductance
Out[163]: 0.0009417851106263697

In [164]: odrv0.axis1.requested_state = AXIS_STATE_ENCODER_OFFSET_CALIBRATION

In [165]: odrv0.axis0.requested_state = AXIS_STATE_ENCODER_OFFSET_CALIBRATION

In [166]: odrv0.axis1.config.startup_encoder_offset_calibration = True

In [167]: odrv0.axis0.config.startup_encoder_offset_calibration = True

In [168]: odrv0.axis1.config.startup_closed_loop_control = True

In [169]: odrv0.axis0.config.startup_closed_loop_control = True

In [170]: odrv0.save_configuration()

In [171]: odrv0.reboot()
Reconnected to ODrive 358A387A3335 as odrv0

In [172]: dump_errors(odrv0)
axis0
axis: Error(s):
AXIS_ERROR_BRAKE_RESISTOR_DISARMED
AXIS_ERROR_MOTOR_DISARMED
motor: Error(s):
MOTOR_ERROR_DC_BUS_OVER_REGEN_CURRENT
fet_thermistor: no error
motor_thermistor: no error
encoder: no error
controller: no error
axis1
axis: Error(s):
AXIS_ERROR_INVALID_STATE
AXIS_ERROR_BRAKE_RESISTOR_DISARMED
motor: Error(s):
MOTOR_ERROR_DC_BUS_OVER_REGEN_CURRENT
fet_thermistor: no error
motor_thermistor: no error
encoder: no error
controller: no error

In [178]: odrv0.axis1.motor.error
Out[178]: 16384

In [179]: odrv0.axis1.error
Out[179]: 17

In [180]: odrv0.axis1.encoder.error
Out[180]: 0

In [181]: odrv0.axis1.motor.error
Out[181]: 16384

In [182]: odrv0.axis0.error
Out[182]: 304

In [183]: odrv0.axis0.encoder.error
Out[183]: 128

In [184]: odrv0.axis0.motor.error
Out[184]: 16384

The key error is BRAKE_RESISTOR_DISARMED – as of firmware 0.5.1 the brake resistor has to be explicitly enabled, so right now the current regenerated when the motors decelerate during calibration has nowhere to go. And dc_max_negative_current = 0.0 means the ODrive trips the instant any current flows back towards the supply.

Assuming you have the brake resistor physically connected, ensure you have:

odrv0.config.enable_brake_resistor = True
odrv0.config.max_regen_current = 0
odrv0.config.dc_max_negative_current = -0.01
odrv0.save_configuration()
odrv0.reboot()

Note max_regen_current = 5 was telling the ODrive it’s allowed to push 5A back into your Meanwell before using the resistor – those supplies can’t sink current, so leave it at 0 and let the resistor take everything.

Also, your last dump shows axis0 encoder error 128 = ABS_SPI_COM_FAIL – what encoders are you using, and how long are the SPI wires?

Thanks for reply, it is very helpful!
I try “odrv0.config.enable_brake_resistor = True”,but get below error info.
I use MT6701 encoder, add a STM32f103C8T6 as encoderbrige to transfer position reading (MT6701 can not be use directly with odrive?). SPI wires are 20cm long.

In [22]: odrv0.config.enable_brake_resistor = True

AttributeError Traceback (most recent call last)
File :1
----> 1 odrv0.config.enable_brake_resistor = True

File c:\users\thinkpad\appdata\local\programs\python\python39\lib\site-packages\fibre\remote_object.py:258, in RemoteObject.setattr(self, name, value)
256 object.getattribute(self, “dict”)[name] = value
257 else:
→ 258 raise AttributeError(“Attribute {} not found”.format(name))

AttributeError: Attribute enable_brake_resistor not found

1 Like

Which ODrive is this? Is it a v3.6?

Note that any encoder reading needs to be extremely low latency (e.g. propagation delay); if the STM32 bridge is delaying the actual encoder position, that can easily lead to poor motor control. Why not just use the incremental A/B/Z outputs of the MT6701?

The AttributeError is because the ODrive is on 0.5.1, which is older than the 0.5.6 firmware release for the v3.6. Consider updating?

However, the root cause is the combination of max_regen_current = 5 with dc_max_negative_current = 0. max_regen_current = 5 lets up to 5A flow back into your power supply before the brake resistor starts shunting, but dc_max_negative_current = 0 forbids the supply from sinking anything at all – so the instant the motors regen (e.g. decelerating at the end of calibration), you get DC_BUS_OVER_REGEN_CURRENT. The BRAKE_RESISTOR_DISARMED errors are just fallout from that fault.

odrv0.config.max_regen_current = 0
odrv0.config.dc_max_negative_current = -0.01
odrv0.save_configuration()
odrv0.reboot()

That makes the resistor take all the braking current – right for a Meanwell, since those can’t sink current at all.

1 Like