Diagnosing ESC Desync Events in ArduPilot RCOU Logs
ardupilotescmotor-failurelog-analysisthrust-loss

Diagnosing ESC Desync Events in ArduPilot RCOU Logs

LogHat Engineering TeamMarch 25, 20265 min read

Key Takeaway

ArduPilot writes ERR Subsys=25 ECode=1 when its Thrust Loss Check fires: the autopilot has been commanding >90% throttle for 1 second with attitude error within 15 degrees, but the vehicle is descending. The matching 'Potential Thrust Loss (N)' MSG names the motor. RCOU.Cn saturation on the affected motor with the diagonal opposite throttled down is the visual signature.

TL;DR: ESC desync events on ArduPilot Copter trigger the firmware’s Thrust Loss Check, which writes ERR Subsys=25 ECode=1 plus a MSG line reading "Potential Thrust Loss (N)" with the suspected motor number. The trigger criteria are specific: the vehicle has been descending for at least 1 second, throttle is above 90%, and attitude error is within 15 degrees. When this fires, plot RCOU.C1C4: the desyncing motor is the one saturated at maximum while the autopilot tries to compensate.

What ArduPilot writes when thrust is lost

The thrust loss check runs continuously while armed and not in ap.land_complete state. It increments an internal counter every loop iteration that meets all three criteria:

  • Descending despite high throttle. The autopilot has been commanding more than 90% throttle output for the last second but altitude is dropping.
  • Attitude under control. Roll and pitch error is within 15° (so the descent isn’t just because the airframe is tipped over).
  • One full second of the above. Brief transients don’t qualify.

When the counter trips, ArduPilot logs ERR Subsys=25 ECode=1 (THRUST_LOSS_CHECK, FAILSAFE_OCCURRED), emits the MSG line naming the suspected motor index, and engages the motor library’s thrust-boost compensation. The compensation uses the remaining motors to maintain altitude with the lost motor saturated.

The RCOU pattern that names the failed motor

Without ESC telemetry, the autopilot can’t directly measure RPM — it infers thrust loss from the attitude controller’s behaviour. Plot RCOU.C1, RCOU.C2, RCOU.C3, RCOU.C4 on one chart:

  • The desyncing motor will be saturated at SERVOn_MAX (typically 2000 µs).
  • The motor diagonally opposite it will be at or near SERVOn_MIN (~1000 µs) — the autopilot is throttling it down to compensate for the yaw the saturated motor creates.
  • The other two motors will sit between hover and saturation.

That diagonal-imbalance pattern is the firmware-confirmed signature of motor failure on a quadcopter. On hex and octocopter frames, the pattern shifts — the affected motor and its symmetric counterpart show the saturation.

Confirming it in Mission Planner

Open the log, plot RCOU.C1C4, and look for the saturation pattern at the timestamp of the ERR Subsys=25 line. Cross-reference against ATT.Roll, ATT.Pitch, RATE.R, RATE.P to confirm the attitude controller was working against the unbalanced thrust.

Confirming it in MAVExplorer

MAV> graph RCOU.C1 RCOU.C2 RCOU.C3 RCOU.C4
MAV> graph RATE.RDes RATE.R RATE.PDes RATE.P
MAV> messages ERR MSG

The MSG stream will contain the "Potential Thrust Loss" line naming the motor. The frame layout (see FRAME_CLASS and FRAME_TYPE) tells you which physical motor that number refers to on the airframe.

With ESC telemetry, the picture is clearer

If your ESCs report telemetry over DSHOT bidirectional or a separate UART, ArduPilot logs an ESC message family with RPM and ESC temperature per motor. The desyncing motor shows RPM crashing to zero or oscillating while RCOU.Cn is still commanding high — conclusive evidence that the ESC is no longer driving the motor at the commanded duty cycle.

Enabling ESC telemetry is worth the half-hour of setup for any operator running a fleet — the post-incident analysis goes from inference to direct measurement.

Why ESCs desync — ranked by what we see most often

  1. High-throttle commutation failure. The ESC’s sensorless commutation algorithm loses track of the rotor position at high RPM, especially after a sudden throttle change. BLHeli_S ESCs with older firmware are particularly prone. Flash to current BLHeli_32 or AM32 firmware and the rate drops sharply.
  2. Voltage sag below the ESC’s startup threshold. A battery dipping under load below the ESC’s minimum operating voltage can cause one ESC to drop and not recover. Coincident with BAT.Volt dips. See our power module post.
  3. Mechanical bind. A bearing failure or debris in the motor briefly stalls the rotor; the ESC sees current spike and loses sync. Often correlates with a sudden VIBE spike on one axis.
  4. Prop strike. Impact damage to a propeller unbalances the rotor; the ESC’s sync timing tolerates much less imbalance than the airframe’s vibration tolerance.
  5. ESC firmware bug. Rare but real. Update to the latest firmware for your ESC family before chasing harder explanations.

Preventing it

  • Update ESC firmware — current BLHeli_32, AM32, or the manufacturer’s latest. Many desync events are firmware-fixable bugs.
  • Calibrate ESC range using Mission Planner’s ESC calibration sequence. An ESC seeing a 1500-1700 µs range will desync differently than one calibrated for 1000-2000 µs.
  • Set MOT_PWM_MIN and MOT_PWM_MAX carefully — matching the ESC’s expected range.
  • Avoid prop strikes — trivial sounding, but a chipped prop is the most common precursor.
  • Enable ESC telemetry for ongoing visibility — you catch a developing bearing problem before it becomes a flight failure.
  • Soft-mount ESCs away from the main harmonic of the airframe — reduces sustained vibration to the ESC PCB.

When this isn’t actually ESC desync

  • Motor unplugged or wire broken. RCOU saturates the same way, but ESC telemetry (if enabled) shows zero RPM with zero current. The cause is electrical, not the ESC’s sync algorithm.
  • Bearing failure. The motor still spins but with high friction; RPM stays low while ESC current climbs. Distinguishable from desync only with telemetry.
  • Wrong FRAME_CLASS. Mixing assignments are off; the autopilot is commanding the wrong motors. RCOU patterns look chaotic from the start, not after a clean takeoff. See our takeoff-flip post.
  • Voltage failsafe kicked in and reduced power to all ESCs. RCOU.C1C4 all drop together rather than one saturating.

When LogHat helps — and when it doesn’t

LogHat flags every ERR Subsys=25 event and highlights the corresponding RCOU saturation pattern in the 3D replay, with the motor number annotated. When ESC telemetry is present, we also surface the RPM-versus-RCOU trace for each motor so you can see the sync failure directly. What we can’t tell you is whether the ESC’s firmware version is the latest — that’s information the autopilot doesn’t capture. Check it manually before assuming the problem is hardware.

About the author

LE

LogHat Engineering Team

The LogHat engineering team — drone-systems engineers who build and operate the LogHat flight analytics platform. Posts in this byline are written and reviewed by team members working on the parsers, analysis engine, and Vector AI that the post describes.

Tagged

ardupilotescmotor-failurelog-analysisthrust-loss

Try LogHat

Analyze your flight logs in seconds

Upload a .bin, .tlog, .log, or .ulg file. Get AI crash analysis, 3D replay, and forensic PDF reports instantly.

Try LogHat Free