Summary
On a CUAV X7 with AM32 4-in-1 ESC, DShot motors do not initialize on cold boot (battery power-up). The ESC plays only the power-on tone and never reaches the arming/ready tone, motors do not spin. They start working only after I re-assign the output functions — either manually in QGC Actuators (set MAIN1-4 to Disable, then back to Motor 1-4), or via param set of the PWM_MAIN_FUNC* parameters in the MAVLink console.
The exact same ESC + wiring + motors work perfectly on ArduPilot (motors spin on power-up, no workaround needed). So the hardware is confirmed good.
I would like to understand the correct fix rather than rely on the workaround. Is this a known DShot initialization issue, and is there a proper solution (parameter, startup order, or fix)?
Hardware
- FC: CUAV X7 (FMUv5-based, has IO processor)
- ESC: Pilotix 90A AM32 4-in-1, firmware 2.20, MCU ARTERY F421, EEPROM v3
- ESCs configured in AM32 Configurator: protocol DShot (also tried AUTO), Motor poles 14, KV 900, timing 15°, all 4 written identically
- Signal wires S1-S4 on MAIN 1-4 (PWM_MAIN outputs)
- Single battery powers FC and ESC together (simultaneous power-up)
- Motors: 12N14P
Firmware
- Reproduces identically on PX4 v1.16.0 and v1.17 stable
- NuttX 11.0.0
- Airframe: Generic Quadrotor X
- Output protocol: DShot300 (PWM_MAIN_TIM0 = -4, PWM_MAIN_TIM1 = -4, both saved)
DSHOT_CONFIGparameter does not exist on this build (config is via Actuators / PWM_MAIN_TIMx)SYS_USE_IOparameter does not exist on this build
Behavior
Cold boot (does NOT work)
On battery power-up, ESC plays only the initial power-on tone (“turum”), never the signal-recognition / arming tone. Motors do not spin, including via actuator_test.
dshot status after cold boot looks correct:
INFO [dshot] Outputs initialized: yes
INFO [dshot] Outputs used: 0xf
INFO [dshot] Outputs on: yes
dshot: cycle: ... bdshot rpm: 0 events, dshot telem: 0 events
INFO [mixer_module] Param prefix: PWM_MAIN
Channel 0: func: 103, value: 0, disarmed: 0, min: 109, max: 1999
Channel 1: func: 102, value: 0, disarmed: 0, min: 109, max: 1999
Channel 2: func: 101, value: 0, disarmed: 0, min: 109, max: 1999
Channel 3: func: 104, value: 0, disarmed: 0, min: 109, max: 1999
actuator_test set -m 1 -v 0.25 sets value: 649 on the channel (so the driver is outputting), but the motor does not spin.
After re-assigning output functions (WORKS)
Either of these makes the motors initialize and spin correctly:
Option A — QGC Actuators: set MAIN1-4 to Disable, then back to Motor 1-4.
Option B — MAVLink console:
param set PWM_MAIN_FUNC1 0
param set PWM_MAIN_FUNC2 0
param set PWM_MAIN_FUNC3 0
param set PWM_MAIN_FUNC4 0
sleep 1
param set PWM_MAIN_FUNC1 103
param set PWM_MAIN_FUNC2 102
param set PWM_MAIN_FUNC3 101
param set PWM_MAIN_FUNC4 104
After this, the ESC plays the full init/arming sequence and actuator_test set -m 1 -v 0.25 spins the motor.
This strongly suggests the DShot driver does not send the correct initial stop/zero command sequence to the ESC on cold boot, and the re-assignment forces a proper re-init. (Looks related to the discussion in PX4-Autopilot issue #17381 about the initial stop command.)
What I have already ruled out
- Hardware — same ESC/wiring/motors spin fine on ArduPilot
- ESC settings — protocol DShot/AUTO, poles 14, all 4 channels written identically, verified by read-back
- Signal + ground continuity — checked with multimeter, S1-S4 on correct signal pins, ground common
- DSHOT_BIDIR_EN — set to 0 and saved
- Firmware version — identical behavior on v1.16 and v1.17
- Protocol speed — DShot300 on both FC and ESC (ArduPilot also uses 300)
Questions
- Is this a known DShot cold-boot initialization issue on FMUv5 / CUAV X7?
- Is there a correct fix (parameter, startup configuration) rather than the re-assignment workaround?
- If a startup workaround in
etc/extras.txtis the recommended path, what is the safe way to do it (correct timing relative to the dshot driver start, without writing PWM_MAIN_FUNC params on every boot)? - Is there a console command that re-initializes the dshot output the same way the function re-assignment does, that I could investigate?
Any pointers appreciated. Happy to provide more logs (dshot status, dmesg, parameter dump) on request.