Motor smoke when locked

Hello, I’m making some tests with odrive. My BLDC motor runs without any problem when there is no load at high current mode. But when there is some heavy load that locked the motor, the motor begins to smoke and the motor become very hot immediately. Then I have to cut off power as soon as possible.

My motor is 8308 KV100. My config is:

odrv0.config.brake_resistance = 2.4
odrv0.config.dc_bus_undervoltage_trip_level = 8
odrv0.config.dc_bus_overvoltage_trip_level = 56
odrv0.axis0.motor.config.pole_pairs = 20
odrv0.axis0.motor.config.calibration_current = 5
odrv0.axis0.motor.config.resistance_calib_max_voltage = 2

odrv0.axis0.motor.config.motor_type = MOTOR_TYPE_HIGH_CURRENT
odrv0.axis0.motor.config.current_lim = 30
odrv0.axis0.motor.config.requested_current_range = 30

odrv0.axis0.encoder.config.mode = ENCODER_MODE_INCREMENTAL
odrv0.axis0.encoder.config.use_index = True
odrv0.axis0.encoder.config.cpr = 16384
odrv0.axis0.encoder.config.bandwidth = 3000
#odrv0.axis0.encoder.config.bandwidth = 6000
#odrv0.axis0.encoder.config.calib_range = 0.05
odrv0.axis0.encoder.config.calib_range = 0.02

odrv0.axis0.config.calibration_lockin.current = 5
odrv0.axis0.config.calibration_lockin.ramp_time = 0.4
odrv0.axis0.config.calibration_lockin.ramp_distance = 3.1415927410125732
odrv0.axis0.config.calibration_lockin.accel = 20
odrv0.axis0.config.calibration_lockin.vel = 40

odrv0.axis0.controller.config.control_mode = CTRL_MODE_POSITION_CONTROL

odrv0.axis0.controller.config.vel_limit = 16384*40
odrv0.axis0.controller.config.pos_gain = 20
odrv0.axis0.controller.config.vel_gain = 0.0001
odrv0.axis0.controller.config.vel_integrator_gain = 0.0005

Is there any way to solve this problem?


ODrive should not be exceeding 30A phase current. Please log the motor.current_control.Iq_setpoint and motor.current_control.Iq_measured when this happens. You can use the liveplotter to generate a graph, if you’d like.

I googled your motor and it says not to exceed 25A continuous current. And I wouldn’t trust the datasheet, these hobby motors are always way over-rated. IMO it’s probably just sitting at 30A and burning, as designed.


Having used 8308 motors I can tell you that 30A is way too high for a continuous current limit on this motor. I use 20A and they get hot. Use an 8318 instead if the load is too big for the motor.

BLDC motors can take huge overcurrents for short bursts - they are only really limited by heat - but remember that power and heat goes with the square of current. By increasing 20A to 30A you are more than doubling the heating power going into the coils.

However, ODrive only has a continuous rating. You cannot set different continuous & peak ratings. I think it would be a good feature for the firmware to include a peak value and “I^2 t” value in the config.
(this wouldn’t help you hold any heavier load, it would just improve dynamic performance a bit / a lot)

Thanks Wetmelon, I’m preparing my new experiment platform to reproduce this issue more safer. Will try to plot this graph.

I have anthoer question, if I set the max current to 30A, is it possible that the current in motor will exceed 30A for seconds?

Thanks towen, I’m thinking is it possible to add a current safe guard to the firmware that if the current is bigger than a threshold and holds for sometime the current will cut off automatically.

Yes, that’s what I meant by having a ‘peak current’ in the config. Industrial drives do this, so it would be a good feature to have. Most don’t use a fixed time but instead compute I^2t (I squared t) or rather I^2 dt, which is the time integral of the square of the current as it exceeds the continuous rating. Once this value is exceeded it will drop back to the continuous current rating or cut out with an error, whichever the user prefers.

Cool, I misunderstood the “peak current” as just square of current. Is there any branch or patch working for this feature?

No. Feel free to create one. :stuck_out_tongue:

Ah no, I meant that you would have two current limits. So you might set your continuous current to 20A and the peak to 30A, and an I^2t value of say 10A^2 s. So you could drive the motor at 21A for 10s or 30A for 0.1s, but never more than 30A.

I’m interesting to this work. Have a quick go through the main logic.

We need to maintain a window of historical current^2 to do the integration of current^2 over time. Have some questions:

1, Is it enought to use the ictrl.Iq_measured as a measure of current in this window?
2, Are the intervals between every interupt / timer control in run_control_loop are homogeneous ? How long is it?
3, What size of this window should be good enough?

No, I would use the sum of Id_measured and Iq_measured, or ideally the raw current which should be available inside the firmware.

Yes. This is controlled by the scheduler, FreeRTOS. The control loop runs at 8kHz IIRC.

Short enough that a sudden spike doesn’t fry your motor before you get a chance to back off. Running at the mainloop rate would be plenty, but perhaps excessive. 1kHz might be a reasonable minimum rate (because that’s the default current control bandwidth), but then if it’s easy to compute as part of the 8KHz loop (which it should be), then I’d do it.

If running below 8kHz, you could use an EMA (Exponential Moving Average) which is an extremely memory-efficient and CPU-efficient moving average filter. It has an infinite impulse response, but provides a good enough approximation of the average over the last N cycles without needing an array.

I’d try to compute the integral of current^2 since the (EMA filtered) continuous current limit was exceeded, up to the point where it fell below 90% of the continuous current.
You could approximate that very simply with EMA(current^2) * (time since continuous limit exceeded)