Mission Log
Development UpdateTeam Sudofly

Entry 4 – MAVLink Takes Shape & The ELRS Port is Done

This was one of the most productive weeks of the project so far. On the software side, MAVLink is starting to come together — with real sensor data flowing through a Python script for the first time. On the hardware side, the team reached a milestone that seemed daunting just a few weeks ago: the ELRS firmware port is complete, and the drone can now be controlled with a real radio transmitter running iNav.

Software Team – MAVLink and the Challenge of Mission Planning

After wrapping up the MSP chapter in the last entry, the software team has fully committed to MAVLink. This week was about understanding the protocol in depth and pushing towards the real goal: autonomous mission planning.

Sensor Data via MAVLink:
A significant step this week was successfully reading and controlling iNav's sensor data through a Python script using MAVLink. Attitude, position, and other telemetry values are now flowing correctly — something that was a known weak point back in the MSP days, where sensor transmission was unreliable. Having clean, structured sensor data arriving through MAVLink is a much stronger foundation to build on.

iNav Sensor detection
iNav Sensor detection

Mission Planning — The Hard Part:
While sensor access is working well, mission planning is proving to be the real challenge. Uploading a waypoint mission to iNav via MAVLink — telling the drone "fly to point A, then B, then land" — involves a specific sequence of MAVLink messages that need to be sent in exactly the right order and with the right timing. iNav's MAVLink implementation is functional but not as thoroughly documented as, say, ArduPilot's, which means the team is doing a lot of trial and error to understand exactly how iNav expects missions to be structured and uploaded.

This is the current focus and will likely carry into the next weeks as well. Getting mission planning right is the gateway to everything that comes after — autonomous waypoint navigation, sensor-fused trajectory following, and eventually the stretch goals. It is worth getting it right.

Hardware Team – The ELRS Port: Seven Steps to Victory

A few entries ago, we laid out what it would take to port the SPI ELRS driver from Betaflight into iNav. At the time it looked like a significant challenge. This week, after several weeks of focused work, the hardware team completed all seven portierung steps — and it works.

To appreciate what this means, it helps to understand what was actually done. Here is a summary of the seven steps the team worked through:

Step 1 – Adding RX_TYPE_SPI to iNav's receiver enum:
iNav's rx.h had no concept of an SPI-based receiver. The first step was adding RX_TYPE_SPI as a new receiver type to the rxReceiverType_e enum — a small change, but the foundation everything else builds on.

Step 2 – Porting the SPI abstraction layer:
Betaflight has dedicated driver files (rx_spi.c, rx_sx1280.c) that handle low-level SPI communication with the SX1280 chip. iNav had nothing equivalent. These files were carefully ported over, adapting all hardware API calls from Betaflight's conventions to iNav's — different function names, different DMA buffer declarations, different peripheral initialization patterns.

Step 3 – Porting expresslrs_spi.c:
This is the core ELRS driver — the file responsible for initializing the SX1280 chip, processing incoming radio packets (validating CRC, decoding RC channel data, handling sync packets), and managing the connection state machine (DISCONNECTED → TENTATIVE → CONNECTED). Translating this from Betaflight's codebase to iNav's required careful attention to timing-critical sections and interrupt handling differences between the two firmwares.

Step 4 – Integrating into rxInit():
With the driver files in place, a new case was added to iNav's rxInit() function to call expressLrsSpiInit() when the target is configured to use the SPI receiver. This is where iNav is told: on this board, the receiver is not on a UART — it is on SPI, and here is how to talk to it.

Step 5 – Wiring up the update loop:
iNav needs to poll the receiver regularly to check for new packets. The expressLrsDataReceived() function was integrated into iNav's main receiver update loop, ensuring that incoming ELRS packets are processed at the right rate and RC channel values are passed to the flight controller in time.

Step 6 – Adapting the build system and target defines:
The LionBee's target definition was updated to include the new SPI ELRS driver in the build, and the correct SPI bus and pin assignments (cross-referenced from the hardware schematic) were added as target-specific defines. Without this, the compiler would not know which physical pins to use for the SX1280 communication.

Step 7 – Debugging and validation on hardware:
The final step was flashing the modified firmware onto the real LionBee and iterating through the inevitable hardware bugs. Timing issues, SPI initialization quirks, and connection state edge cases all had to be worked through one by one until the SX1280 initialized correctly, bound to the transmitter, and passed RC channel data to iNav reliably.

The Result

The LionBee now runs iNav and responds to a real ELRS radio transmitter. The integrated SX1280 chip — the one that has been sitting unused on the board since the project started — is fully operational. The drone can be armed, controlled, and flown under iNav using a standard ELRS 4-in-1 controller.

This is not just a win for this project. Since iNav has no SPI ELRS support anywhere in its codebase, what the team has built here is genuinely novel — a contribution that could eventually benefit the broader iNav and FPV community.

#mavlink#python#sensor-data#mission-planning#elrs#sx1280#firmware-port#iNav#sitl#betaflight
Entry 4 – MAVLink Takes Shape & The ELRS Port is Done | Sudofly