fix(dshot): retry offline serial telemetry channels when disarmed (#27085)

Once a serial telem channel hit 10 consecutive timeouts it was added
to a skip mask and never polled again. Channels that came online late
(e.g. ESC power-cycled after the autopilot boots) stayed permanently
offline, and with both serial and bdshot enabled the motor was
reported offline overall because the combined health check requires
both sources.

Periodically clear the skip mask while disarmed so recovered channels
get another chance. If still broken they are re-skipped after the
normal timeout threshold. Disarmed-only to avoid timeout blips on
healthy channels during flight.
This commit is contained in:
Jacob Dahl
2026-04-14 12:18:12 -08:00
committed by GitHub
parent 5f1eae330b
commit 6bc3e17bd4
2 changed files with 18 additions and 0 deletions
+16
View File
@@ -440,6 +440,22 @@ bool DShot::process_serial_telemetry()
return false;
}
// Periodically retry skipped motors when disarmed so channels that came online late
// (e.g. ESC power-cycled after boot) can recover. We don't retry while armed to avoid
// timeout blips on healthy channels during flight.
bool armed = _esc_status.esc_armed_flags != 0;
if (!armed && _serial_telem_skip_mask != 0
&& hrt_elapsed_time(&_serial_telem_last_retry) > SERIAL_TELEM_RETRY_INTERVAL) {
_serial_telem_skip_mask = 0;
for (int i = 0; i < DSHOT_MAX_MOTORS; i++) {
_serial_telem_consecutive_timeouts[i] = 0;
}
_serial_telem_last_retry = hrt_absolute_time();
}
bool all_telem_sampled = false;
if (!_telemetry.commandResponseFinished()) {
+2
View File
@@ -170,8 +170,10 @@ private:
// Serial telemetry adaptive skip: stop polling motors that never respond
static constexpr int SERIAL_TELEM_SKIP_THRESHOLD = 10; // consecutive timeouts before skipping
static constexpr hrt_abstime SERIAL_TELEM_RETRY_INTERVAL = 3_s; // disarmed retry period
uint16_t _serial_telem_skip_mask = 0; // motors to skip in round-robin
uint8_t _serial_telem_consecutive_timeouts[DSHOT_MAX_MOTORS] = {};
hrt_abstime _serial_telem_last_retry = 0;
// Serial Telemetry
DShotTelemetry _telemetry;