Servers by jDrones

MSP protocol support

I’ve been working at adding MSP (multiwii serial protocol) support to Ardupilot, right now the code is on a test branch on my github and is very likely to change a lot in the future :slight_smile:

This thread will serve as the base to create proper documentation and as a central point to collect feedback on the implementation.

The protocol decoder is ported from betaflight/inav and supports both MSPV1 and MSPV2.
It also supports iNav MSPV2 sensor messages for lidar and optical flow.
It should work with Matek 3901-L0X but I haven’t tested it yet (hardware yet to arrive).
The protocol stack can work in 2 ways:

  • command mode (the stack responds to external commands) SERIALn_PROTOCOL=29
  • command mode + periodic telemetry (for external OSDs like DJI) SERIALn_PROTOCOL=30

Note the actual SERIAL_PROTOCOL number might change while waiting for the code to get into master, right now we can use 29 and 30

Matek 3901-L0X

Lidar confirmed as working by @Tobias0, flow untested as of now




Not tested yet but should work with minor changes.
This OSD system should work in command mode (the OSD air unit periodically asks for telemetry packets)



DJI goggles are supported both by periodically sending telemetry packets or responding to MSP requests. To periodically send telemetry packets set MSP_OPTIONS = 1 (MSP_OPTIONS is a bitmask, bit 0 is EnbaleTelemetryMode, bit 1 is InvertWindDirection). Telemetry mode allows 1 wire connections between the Air Unit and the flight controller.
The goggles can render 24 OSD items, this implementation should support all of them.
The code has been initially flight tested by @MadRC which is also the main tester since I do not have any hardware to test with :slight_smile:
OSD items can be enabled and moved on screen by using parameters MSP_OSD_*

To enable RSSI set MSP_OSD_RSSI_EN = 1, to move it on screen use MSP_OSD_RSSI_X and MSP_OSD_RSSI_Y.

Coordinate’s ranges on MSP OSDs are different from ardupilot’s one:

  • X range 0 - 27
  • Y range 0 - 15

Note right now it uses custom dedicated parameters but in the future it might share them with the main OSD code.

Supported OSD widgets:

  • MSP_OSD_FMODE shows !FS! when failsafe is triggered (battery, radioi, gcs, ekf)
  • MSP_OSD_VCELL average cell voltage (cell count override MSP_OSD_NCELLS 0:AUTO, 1-N)
  • MSP_OSD VBAT battery voltage
  • MSP_OSD_MAH battery consumed mAh
  • MSP_OSD_BATT battery usage bar %
  • MSP_OSD_CURR battery current
  • MSP_OSD_SATS gps sat count (shows 14 sats when there’s no fix it’s a known DJI issue)
  • MSP_OSD_LAT, MSP_OSD_LON gps coordinates
  • MSP_OSD_HDIST home distance
  • MSP_OSD_HDIR home direction
  • MSP_OSD_ALT altitude
  • MSP_OSD_MSG text area with flight mode shared with status text messages and wind
  • MSP_OSD_ROLL roll
  • MSP_OSD_PITCH pitch
  • MSP_OSD_RSSI rssi
  • MSP_OSD_ARM arming status
  • MSP_OSD_RTC date and time (RTC)
  • MSP_OSD_PWR power in Watts
  • MSP_OSD_VSPD numerical vertical speed
  • MSP_OSD_GSPD ground speed
  • MSP_OSD_ASPD_EN airspeed as override of ground speeed
  • MSP_OSD_WIND_EN wind direction and speed (rendered as text and arrow next to the flightmode)
  • MSP_OSD_TESC blheli ESC temperature
  • MSP_OSD_UNITS 0:Imperial, 1:Metric

Artificial horizon:

  • MSP_OSD_HBARS ladders
  • MSP_OSD_CROSS crosshair
  • MSP_OSD_HORIZ horizon line (does not work)

Ardupilot specific “features” and notes

  • MSP_OSD_MSG enables the display of status text messages as a scrolling 12 chars text (12 is the maximum allowed by the DJI system). Each message is displayed up to MSP_OSD_MSGTIME, then it is hidden. The MSP_OSD_MSG widget is also used to display the current ardupilot flight mode (STAB, MANU, LOIT, etc) when there are no messages displayed. Upon flight mode changes the flightmode name will flash for 3 seconds even if there’s a text message scrolling, after the 3 seconds scrolling will resume for the remaining scrolling time.
    The samee text area is used to display wind speed and direction.
  • MSP_OSD_SATS (gps sats number) will flash if there’s no fix (DJI issue shows 14 sats when no fix)
  • MSP_OSD_HDIR and MSP_OSD_HDIST will flash if HOME is not set.
  • MSP_OSD_ASPD (airspeed) is supported as override of the MSP_OSD_GSPD item, so if you enable airspeed display you’ll loose GSPD display.
    Airspeed will flash if no estimate available.
  • MSP_OSD_RTC will flash id no GPS lock (required for valid date/time)
  • MSP_OSD_VCELL and MSP_OSD_VBAT will flash on battery failsafe

Feedback is really welcome!

If anybody wants to try this code just ask for a build for a specific board or simply build it yourself from my test branch
Test binaries will be available as releases here.



great work Alex, thanks so much for working on this!


great work Alex, thanks so much for working on this!

…I ended up writing an msp python decoder and a very rude python OSD using pygame to test it :slight_smile:

1 Like

Great work.

I’m looking to get the Matek 3901-L0X to work to improve emergency landing features.

Could you compile this for a Matek F765 board to test these features?

Thanks & Best Regards

Hi Tobias, I added binaries here.
Matek Lidar and optical flow is fully untested, let me know if and how it works :slight_smile:

we got support for OSD on SITL, if you want to close the loop !

Hi, I briefly discussed this with @tridge, SITL OSD cannot be driven by a serial protocol at the moment. MSP OSD does not write at screen coordinates but rather sends telemetry info rendered at specific positions by the DJI OSD engine.
Basically MSP sends 2 type of messages, raw telemetry and osd item positions, the OSD engine then renders the telemetry at the coordinates sent by MSP. But MSP has no control on how the information is rendered. I send home direction in degress and the OSD engine can render it as text or a rotating triangle, hope this is clear enough :slight_smile:
Tridge suggested creating an MSP OSD python implementation to actually see stuff and I partially did to test all this. If you think we can go the SITL OSD route I can try.

Finally to properly “close the loop” @peterbarker won’t let this in without a proper test suite :smile:


Will test this on Friday when flying…
I will let you know how does it work. :wink:

Same, I will build some firmwares tonight and test this weekend.

Hay all.

First of all I want to thank Alex for taking this one on, when I was bugging the dev team on this as others have Tridge pointed me in his direction and I have to say Alex has been amazingly fast and has been hitting it out the park with this one. The second we had a chat he got on with it and send me over some builds to try.

I had been trying to collate as much info as i could and I also had reached out to Divimath on the Byte Frost side as well and got some helpful info from them too.

It’s also nice to find someone who sleeps as little as I do :sunglasses:

On the tests.

I had been trying to collate as much info as i could and I also had reached out to Divimath on the Byte Frost side as well and got some helpful info from them too.

On my end of things first of all of the tests were done on a Cube Orange on the bench attached to an F550 with my race quad having open surgery and very bodged cable between them. In what felt like no time at all Alex had some builds getting basic data working.

Next it has been time for the field tests so I did a frankly messy build to test this on as my race quad controller is not supported. This ended up being an F450 with the CUAV V5+.

As I only had one air unit at the moment it meant stripping the race quad and in the process one of the MMCX antenna connections decided to let go :man_facepalming:. After some surgery then it was back in action and ready to test with a spare antenna.

I have been doing some flight tests over the last few days with the laptops and Google’s to make sure things look correct and feeding that back to Alex to tie down some of the more tricky parts of the OSD. Rain has held me back a bit but we are getting there. Something that has become very apparent for me is how hard it is to record what I’m seeing as it’s just a nightmare to get a camera into the Google’s face mask area, sadly the onboard recording does not record what o see so it’s GoPro or phone while trying to fly as well.

Overall it’s amazing how close this is now in such a short period of time. It’s also great that there are some really nice features like the scrolling warning info and flashing icons.

Overall I want to thank Alex for his hard work on this so far.

I will sty and share some video shortly but here are some pics


A little of black magic on SITL : add an osd object backend in SITL like for vision or rangefinder, feed it with your lib,m and make it update the current SITL osd lib… A little of development, but it could be nice!

Anyways, we could do the test later and SITL stuff later
For testing the osd, we could definitely use NASA way : make picture of the output we want, run test and compare pixel by pixel that the output is conform ! Travis will die of overload. People (and github) will complain that our repo weight 1Tb. Everything will be fine !

1 Like

Hi Alex
If you don’t mind to add pixracer binare I would be glad to test too.

1 Like

Thanks to Ian @MadRC we made some progresses and fixed the home direction issue and hopefully the ground speed issue as well :slight_smile:

I updated the binaries to version 0.3

verified working OSD items:

  • average cell voltage
  • battery voltage
  • battery consumed mAh
  • battery usage bar %
  • battery current
  • gps sat count
  • gps coordinates
  • home distance
  • home direction
  • altitude
  • flight modes
  • status text messages
  • roll
  • pitch
  • heading
  • rssi
  • arming status

version 0.3 test binaries are here


Thanks so much; Really nice to have this feature. I will test on Matek-F405 wing. Which setup must be use for telemetry 57k ou 115k like MSP in general ?

Yes baud 115 and protocol 30

1 Like

I flash 0.3 binary for arduplane and I have no display, even after arming. Is there anything special to configure for activate the display? I previsously using the Mavlink to MSP converter from RCGroup thread.

I finally have this working. Some setup not-sync between DJI google power from air unit and goggle - my fault. No I can test.

I wondering why there is ‘ACRO’ just below sat icon (Betaflight trick?)
For now, what I seen is a simple bug with RSSI but have the same on Mission planner with crossfire (as often with ardupilot, the confusion between RSSI/RXRSSI)

I tried to test the the Matek 3901-L0X on Serial6 as “29”.
I used version 0.3

On the stack the red led is on, blue led is flashing.
Unfortunately Ardupilot did not recognize the stack.

Ok good, that ACRO is the DJI specific flightmode that should be hidden unless you have a failsafe or RTL. At least this is what I’m trying, please ignore it for the moment :slight_smile:

can you be more specific?

Hi Tobias,
my fault didn’t write it anywhere, should be



Servers by jDrones