Skip to content

srxl2: never send an Avian exactly 20 % throttle - #12136

Open
MrScothh wants to merge 1 commit into
iNavFlight:maintenance-10.xfrom
MrScothh:fix/srxl2-avian-20pct
Open

MrScothh wants to merge 1 commit into
iNavFlight:maintenance-10.xfrom
MrScothh:fix/srxl2-avian-20pct

Conversation

@MrScothh

@MrScothh MrScothh commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

A Spektrum Avian driven over SRXL2 can stop its motor in flight and keep it stopped until the throttle goes back to zero. I traced it to one throttle value: exactly 20.0 %.

What happens

On an Avian 70 A calibrated from INAV, with the propeller off:

  • brought up to exactly 1200 us from below, or from a stop, and held there for about two seconds, the ESC treats the next increase as a failed start, even an increase of one microsecond (1201 us). The motor stops and stays stopped whatever the throttle, until it returns to zero. Telemetry keeps reporting the new throttle as received and delivered, while rpm freezes and the current drops to idle.
  • 1199 and 1201 us never do it, nor does 1200 us reached from above, nor 1200 us held for only one second.
  • it does not depend on the ESC's settings: same result with soft and normal start-up, with the brake disabled or on reverse, and with reverse thrust engaged.
  • another SRXL2 master (smart-esc-tool, INAV's driver idle) gets the same stop, so it is the ESC, not INAV's frames. Over PWM, in 5 % and 10 us steps, the same ESC never stopped.

It behaves like the start-up protection the Avian manual describes ("If the throttle is more than 20%, the throttle stick must be moved back to the bottom position before the ESC will allow a restart"), firing on a motor that is already running.

Shifting the raw channel value one unit at a time, the trap covers raw 13558 to 13620: the ESC's 20.0 % step, 64 units wide. With INAV's calibration endpoints, 1200 us (13568) is the only microsecond inside it; 1199 us is 13504 and 1201 us is 13632.

Why it matters for INAV

nav_fw_min_thr defaults to 1200. A navigation mode that starts from a stopped motor and sits at minimum throttle for two seconds before asking for more would leave the aircraft gliding.

The change

srxl2MotorUpdate() sends 1200 us as 1199 us (19.9 %). The value comes from the calibration endpoints, so the dependency is visible in the code. The Smart ESC page gets a short section on it, including what is not covered: an ESC calibrated to other endpoints has its 20 % somewhere else, which I did not measure.

Tests (bench, Avian 70 A, propeller off, throttle through MSP with the board disarmed)

without the change with it
1150 us, then 1200 us for 5 s, then 1201 us stops every time runs (3/3 on this commit)
from stop to 1200 us for 4 s, then 1250 us stops every time runs (3/3 on this commit)

I also reproduced the stop in a HITL flight with this ESC connected (X-Plane driving INAV, INAV driving the real ESC), holding 1200 us and then raising it, and saw the fix keep the motor running in the same flight.

Size: MATEKF405 and BLUEBERRYF435WING +16 B of flash, MATEKH743 +0, RAM unchanged. The driver is not built on F7. Unit tests pass; the SRXL2 driver has none of its own.

An Avian calibrated to INAV's endpoints, brought up to exactly 20 % and held
there for about two seconds treats any rise after that, even one microsecond,
as a failed start: the motor stops until the throttle goes back to zero.
1200 us is the only motor value on that step, and the default nav_fw_min_thr,
so it goes out as 1199. The Smart ESC page says why and what is not covered.
@qodo-code-review

Copy link
Copy Markdown
Contributor

ⓘ Qodo reviews are paused because the subscription is no longer active. Ask your workspace admin to reactivate the subscription to resume reviews. Manage billing

@qodo-free-for-open-source-projects

Copy link
Copy Markdown

PR Summary by Qodo

Avoid Avian motor cutoff at 20% SRXL2 throttle

🐞 Bug fix 📝 Documentation 🕐 10-20 Minutes

Grey Divider

AI Description

• Sends 1200 µs as 1199 µs to avoid an Avian throttle step that can stop the motor.
• Documents the observed failure and limits the workaround to ESCs calibrated to INAV’s endpoints.
Diagram

graph TD
    Mixer["Motor throttle"] --> Check{"Equals 1200 us?"} -->|yes| Shift["Use 1199 us"] --> Scale["Scale to SRXL2"] --> Send["Send control"] --> ESC["Avian ESC"]
    Check -->|no| Scale
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Avoid 20% using each ESC’s stored calibration
  • ➕ Could cover ESCs calibrated to endpoints other than INAV’s.
  • ➖ Requires a reliable way to know each ESC’s endpoints and further validation of its 20% behavior.

Recommendation: Keep the narrow substitution for the measured INAV-calibrated case. A calibration-aware approach would broaden coverage, but the required endpoint information and behavior have not been established; the documentation makes that limitation explicit.

Files changed (3) +24 / -0

Bug fix (1) +6 / -0
motor_srxl2.cAvoid staging the affected throttle value +6/-0

Avoid staging the affected throttle value

• Derives the 20% value from the driver's calibration endpoints and substitutes 1199 µs for a 1200 µs motor command before SRXL2 conversion.

src/main/io/motor_srxl2.c

Documentation (2) +18 / -0
Spektrum Smart ESC.mdDocument the Avian 20% throttle cutoff +17/-0

Document the Avian 20% throttle cutoff

• Describes when the Avian stops, why 1200 µs is affected with INAV calibration, and the 1199 µs workaround. Notes that other calibration endpoints were not measured or covered.

docs/Spektrum Smart ESC.md

motor_srxl2.hClarify the throttle staging contract +1/-0

Clarify the throttle staging contract

• Documents that a 1200 µs command is transmitted as 1199 µs to avoid the Avian's 20% step.

src/main/io/motor_srxl2.h

@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider

Great, no issues found!

Qodo reviewed your code and found no material issues that require review

Grey Divider

Tip of the day
💡 Did you know, you can keep summaries lean with Findings visible per group, which tucks the rest behind a View link

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown

RAM / Flash usage vs. base commit e87050f — commit f3fadd0

Using the nearest available size baseline — the PR's exact base commit has no stored baseline yet.

Target Flash Δ RAM Δ
MATEKF405 -16 B (-0.00%) CCM: ±0 B (±0.00%)
RAM: +8 B (+0.01%)
MATEKF722 +56 B (+0.01%) ITCM_RAM: ±0 B (±0.00%)
RAM: ±0 B (±0.00%)
TCM: ±0 B (±0.00%)
MATEKF765 +104 B (+0.01%) DTCM_RAM: ±0 B (±0.00%)
SRAM1: ±0 B (±0.00%)
MATEKH743 +32 B (+0.00%) D2_RAM: ±0 B (±0.00%)
DTCM_RAM: ±0 B (±0.00%)
ITCM_RAM: ±0 B (±0.00%)
RAM: ±0 B (±0.00%)

See RAM/flash optimization guide for techniques to reduce usage.

@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown

Test firmware build ready — commit f3fadd0

Download firmware for PR #12136

251 targets built. Find your board's .hex file by name on that page (e.g. MATEKF405SE.hex). Files are individually downloadable — no GitHub login required.

Development build for testing only. Use Full Chip Erase when flashing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant