Current spikes on a brushless motor bench fail good motors, hide bad ones and can damage the ESC or the supply. Most of them come from the way the test drives the motor or measures it, not from the motor. Learn how to tell the five usual causes apart, fix each one, and record the evidence in a TofuPilot procedure so the next spike is diagnosed from the run data.
Quick Diagnosis
Look at when the spike happens and what the bus voltage does at the same time:
| Symptom | Likely cause | Check |
|---|---|---|
| Spike at every throttle change, up then decays | Stepped throttle, acceleration current | Does it disappear with a ramp? |
| Spike at every restart of a flight controller motor test | Stop and restart of MAV_CMD_DO_MOTOR_TEST | Count restarts against spikes |
| Negative current and bus voltage rising on throttle down | Regenerative braking | Bus voltage above the supply setpoint |
| Bus voltage dips at the spike, ESC beeps or re-arms | Supply current limit or foldback | Supply in constant-current mode |
| Isolated high samples with no link to throttle | Sampling aliasing or pickup | Do they vanish with averaging on? |
Example values measured on a 3115-size, 1250 KV motor with a 4-in-1 BLHeli_32 ESC on a 6S bus, without propeller, give the scale: about 2.65 A steady at 70 % throttle, current spikes up to about 10 A per motor on throttle steps, and the bus raised to 36.6 V on throttle down with a switching bench supply.
Cause 1: Stepped Throttle
A throttle step asks for a speed change in zero time. The ESC delivers the maximum current the motor will take until the speed catches up, so every step produces a current peak, and the higher the step, the higher the peak.
Flight controller motor tests make steps unavoidable. ArduPilot's MAV_CMD_DO_MOTOR_TEST takes a throttle and a duration, and the throttle cannot be changed while the test runs. A profile of 25 %, 50 %, 70 % therefore runs as three separate tests, each one starting the motor from rest. Each restart is a full acceleration, and each one shows up as a spike.
Fixes:
- Drive DShot from a microcontroller and execute ramps there, so throttle changes at a bounded rate (for example 20 %/s without propeller).
- If the flight controller must stay in the loop, run one test per level and exclude the first seconds after each start from the measurement window.
- Never measure steady-state current during the transient. Wait for the speed to settle, then sample.
Cause 2: Acceleration Current
Even a ramp draws more current than steady state, because accelerating the rotor takes torque, and torque takes current:
T_accel = J x alpha J: rotor + propeller inertia (kg m^2), alpha: rad/s^2Kt = 60 / (2 x pi x KV) torque constant (N m/A), KV in rpm/VI_accel = T_accel / Kt current added on top of the steady current1250 KV motor: Kt = 60 / (2 x pi x 1250) = 0.00764 N m/AThe extra current scales with the inertia and with the ramp rate. A propeller adds far more inertia than the bare rotor, so the same ramp rate that is invisible without propeller produces a large overshoot with one.
This current is expected. It becomes a problem only when the limit does not account for it. Fixes:
- Choose the ramp rate from the current overshoot you accept, and keep it the same for every unit so the peaks are comparable.
- Put the steady-state limit on the mean during a hold, and a separate, wider limit on the peak during the ramp.
- Use the same rate in production and in the golden-unit runs that set the limits.
Cause 3: Regenerative Braking on Deceleration
When throttle drops, the ESC brakes the motor actively and the motor works as a generator. The recovered energy flows back into the DC bus. With a battery, the battery absorbs it. With a switching bench supply, nothing does: most bench supplies can source current but not sink it, so the bus capacitors charge and the voltage rises. On the example bench, a throttle step down raised a 6S nominal (22.2 V) bus to 36.6 V, well above the 25.2 V of a full 6S pack.
On a bidirectional current monitor such as the INA228, regen shows as negative current. On a supply readback it shows as nothing at all, which is why it is often missed.
The overvoltage stresses the ESC capacitors and MOSFETs and every other device on the bus. Check the voltage ratings in the ESC datasheet against the highest bus voltage you record.
Fixes, from simplest to most robust:
| Fix | How it works | Limits |
|---|---|---|
| Ramped deceleration | Lowers the braking power, so less energy returns per second | Still some rise; set the rate from the measured bus peak |
| Battery in parallel with the supply | The battery absorbs the returned current | Check that the supply tolerates a battery on its output; a blocking diode protects the supply and leaves the battery to absorb regen |
| Brake resistor with a voltage clamp | Dumps energy into a resistor above a set voltage | Size the resistor for the braking power |
| Bidirectional (source and sink) supply | The supply absorbs the current itself | Cost |
Cause 4: Supply Current Limit and Foldback
A bench supply in constant-voltage mode switches to constant-current mode when the load demands more than its current limit. During a spike the bus voltage drops. If it drops low enough, the ESC browns out and restarts, and the restart is a new acceleration from rest with its own spike. Supplies with foldback protection reduce their output current further after an overload, which makes the sag deeper and longer.
Signs: the bus voltage dips exactly when the current peaks, the supply front panel shows CC, the ESC plays its startup tones in the middle of a test.
Fixes:
- Size the source for the peak, not the mean:
P = V x I_peak x motors, plus margin. Four motors at 10 A peaks on 22.2 V already need about 890 W. - Raise the current limit to cover the peak, and disable foldback if the supply allows it.
- Add bulk capacitance close to the ESC input, or use a battery, which delivers peaks a supply cannot.
Cause 5: Sampling Aliasing and Pickup
Some spikes exist only in the data. The ESC current carries ripple at the ESC PWM frequency, tens of kHz. A monitor set to a short conversion time with no averaging, polled at irregular instants from Python, catches random points on that ripple. The highest of them look like spikes. Long, unshielded sense lines routed next to the motor phase leads add pickup from the switching edges.
Test: switch on averaging. With the INA228, a conversion time of 540 µs and 16 averages integrates over about 8.6 ms per channel. Aliased spikes vanish; real ones survive and still line up with throttle changes or bus voltage events.
Fixes: set conversion time and averaging for the quantity you want, route the Kelvin sense pair twisted and away from the phase leads, and do not poll faster than the result register updates.
Record the Evidence in the Test
A spike diagnosed once is useful. A spike recorded on every run, with the bus voltage next to it, is a diagnosis waiting on the dashboard. Record current and bus voltage on the same time axis and put limits on their extremes:
procedure.yaml37 lines
main: - name: Throttle Profile key: profile python: phases.profile:run_profile timeout: 90s measurements: - name: Current and Bus key: current_bus description: INA228, VSHCT 540 us, AVG 16. Negative current is regen. x_axis: legend: Time unit: s y_axis: - legend: Current key: current unit: A aggregations: - type: max validators: - operator: "<=" expected_value: 4.0 - type: min validators: - operator: ">=" expected_value: -1.0 - legend: Bus Voltage key: bus unit: V aggregations: - type: max validators: - operator: "<=" expected_value: 26.0 - type: min validators: - operator: ">=" expected_value: 21.0phases/profile.py33 lines
import timePROFILE = [(25, 5.0), (50, 5.0), (70, 5.0), (0, 0.0)] # (throttle %, hold s)RATE_PCT_S = 20def run_profile(motor, current_monitor, measurements, log): times, current, bus = [], [], [] t0 = time.monotonic() def sample_for(duration_s): end = time.monotonic() + duration_s while time.monotonic() < end: times.append(round(time.monotonic() - t0, 3)) current.append(current_monitor.read_current()) bus.append(current_monitor.read_bus_voltage()) time.sleep(0.02) previous = 0 for target, hold_s in PROFILE: motor.ramp_to(1, target, RATE_PCT_S) sample_for(abs(target - previous) / RATE_PCT_S + hold_s + 0.5) previous = target m = measurements.current_bus m.x_axis = times m.y_axis.current = current m.y_axis.bus = bus m.y_axis.current.aggregations.max = max(current) m.y_axis.current.aggregations.min = min(current) m.y_axis.bus.aggregations.max = max(bus) m.y_axis.bus.aggregations.min = min(bus) log.info(f"Bus {min(bus):.2f} to {max(bus):.2f} V, current {min(current):.2f} to {max(current):.2f} A")Each limit points at one cause when it fails:
| Failing aggregation | Points at |
|---|---|
| Current max | Steps, ramp rate too high, or a motor fault |
| Current min (negative) | Regenerative braking on deceleration |
| Bus max | Regen with nowhere to go |
| Bus min | Supply current limit or foldback |
The motor and current_monitor plugs are the bench's throttle driver and INA228 monitor; set workers: 1 in execution so no other phase drives the motor at the same time, and stop the motor in a teardown phase. On the dashboard, the failure Pareto per measurement shows which of the four aggregations fails most, which tells you which cause dominates on that station.
Common Pitfalls
Raising the current limit until the spikes pass. The limit then hides real faults. Remove the cause first.
Reading the bench supply display to look for spikes. It averages over hundreds of milliseconds and cannot show regen. Measure at the ESC input.
Treating negative current as a sensor error. On a bidirectional monitor, negative current during deceleration is regen, and it is real.
Ignoring bus overvoltage because the motor passed. The ESC took the stress. Put a limit on the bus maximum.
Comparing peaks measured with different ramp rates or averaging settings. Keep the profile and the monitor configuration fixed, and write them in the measurement description.
Key Points
- Most spikes come from the test: throttle steps, flight controller motor test restarts, acceleration at too high a rate.
- Throttle down sends energy back into the bus; a switching bench supply cannot absorb it and the voltage rises (36.6 V on a 6S bus in the example).
- A supply in current limit sags the bus, can reset the ESC and causes a new spike at restart.
- Aliased spikes vanish with averaging; real spikes stay correlated with throttle or bus voltage.
- Record current and bus voltage on one time axis with limits on max and min, so each failing aggregation names its cause.
For the wider picture of motor and actuator test benches, see Motor and Actuator Testing with TofuPilot.
