DC_BUS_OVER_CURRENT in AXIS_STATE_CLOSED_LOOP_CONTROL only

I am trying to use a skateboard motor, but when trying to spin up the motor in AXIS_STATE_CLOSED_LOOP_CONTROL:

In [550]: odrv0.axis0.requested_state = AXIS_STATE_CLOSED_LOOP_CONTROL
In [551]: odrv0.axis0.controller.config.control_mode=CONTROL_MODE_VELOCITY_CONTROL
In [553]: odrv0.axis0.controller.input_vel = 50

…it immediately goes into an error:

axis0
  axis: Error(s):
    AXIS_ERROR_BRAKE_RESISTOR_DISARMED
    AXIS_ERROR_MOTOR_DISARMED
  motor: Error(s):
    MOTOR_ERROR_DC_BUS_OVER_CURRENT
  fet_thermistor: no error
  motor_thermistor: no error
  encoder: no error
  controller: no error

What I don’t understand is that when I set odrv0.axis0.requested_state = AXIS_STATE_LOCKIN_SPIN:

In [562]: odrv0.axis0.config.general_lockin.vel = 2000

In [563]: odrv0.axis0.config.general_lockin.accel = 600

In [560]: odrv0.axis0.requested_state = AXIS_STATE_LOCKIN_SPIN

…the motor spins up fine and stays at the requested velocity - no overcurrent error in this case.

Here is the controller config. Anything you see wrong with it?

In [555]: odrv0.axis0.controller.config
Out[555]: 
gain_scheduling_width = 10.0 (float)
enable_vel_limit = True (bool)
enable_current_mode_vel_limit = True (bool)
enable_gain_scheduling = False (bool)
enable_overspeed_error = True (bool)
control_mode = 2 (int)
input_mode = 1 (int)
pos_gain = 20.0 (float)
vel_gain = 0.1666666716337204 (float)
vel_integrator_gain = 0.3333333432674408 (float)
vel_limit = 2000.0 (float)
vel_limit_tolerance = 1.2000000476837158 (float)
vel_ramp_rate = 0.5 (float)
torque_ramp_rate = 0.009999999776482582 (float)
circular_setpoints = False (bool)
circular_setpoint_range = 1.0 (float)
homing_speed = 0.25 (float)
inertia = 0.0 (float)
axis_to_mirror = 255 (int)
mirror_ratio = 1.0 (float)
load_encoder_axis = 0 (int)
input_filter_bandwidth = 2.0 (float)
anticogging:
  index = 0 (int)
  pre_calibrated = False (bool)
  calib_anticogging = False (bool)
  calib_pos_threshold = 1.0 (float)
  calib_vel_threshold = 1.0 (float)
  cogging_ratio = 1.0 (float)
  anticogging_enabled = True (bool)

…and the odrive burned out :frowning: .

I tried to reduce the odrv0.axis0.motor.config.requested_current_range from 20 to 10 and tried again, after which the motor spun up for a second and then the odrive was just gone.

In [647]: odrv0.axis0.motor.config.requested_current_range = 10

In [648]: odrv0.save_configuration()

In [649]: odrv0.reboot()
In [650]: odrv0.axis0.requested_state = AXIS_STATE_FULL_CALIBRATION_SEQUENCE

In [651]: odrv0.axis0.requested_state = AXIS_STATE_CLOSED_LOOP_CONTROL

In [652]: odrv0.axis0.controller.input_vel = 30

Oh no odrv0 disappeared

Still don’t understand why, but oh well, that’s the end of this project I guess… the odrive also took my microcontroller with it, which was connected via GPIO but is dead now, too.

For reference, this was the motor config before.

In [592]: odrv0.axis0.motor.config
Out[592]: 
pre_calibrated = True (bool)
pole_pairs = 7 (int)
calibration_current = 5.0 (float)
resistance_calib_max_voltage = 2.0 (float)
phase_inductance = 0.00011160678695887327 (float)
phase_resistance = 0.2178153097629547 (float)
torque_constant = 0.03999999910593033 (float)
direction = 1 (int)
motor_type = 0 (int)
current_lim = 25.0 (float)
current_lim_margin = 8.0 (float)
torque_lim = inf (float)
inverter_temp_limit_lower = 100.0 (float)
inverter_temp_limit_upper = 120.0 (float)
requested_current_range = 20.0 (float)
current_control_bandwidth = 1000.0 (float)
acim_slip_velocity = 14.706000328063965 (float)
acim_gain_min_flux = 10.0 (float)
acim_autoflux_min_Id = 10.0 (float)
acim_autoflux_enable = False (bool)
acim_autoflux_attack_gain = 10.0 (float)
acim_autoflux_decay_gain = 1.0 (float)

Jeez, sorry to hear that. Was this a genuine ODrive you got from the odriverobotics.com store? Can you share the wiring between the ODrive and the microcontroller?

My best guess is that there was some encoder issue here – if this was running 0.5.1 firmware or earlier (which seems to be the case from the particular config you shared), it has no way of checking for encoder issues (“spinout”).