Frsky bidirectional telemetry implementation

two way frsky telemetry has been supported by OpenTX since version 2.2, but ardupilot’s frsky telemetry library did never leverage such functionality.
After working on a new packet scheduler proposal for the frsky passtrough library I gained enough confidence with the code to give it a shot myself.
For a brief introduction on how frsky sport telemetry works please refer to the post linked above.

In designing the two way telemetry protocol I looked at two well established and documented working examples:

  • betaflight msp
  • mavlink

The former is a very good example of a complete lua stack, the latter is the “right” way to interoperate with the ardupilot system.

First goal was to design a protocol on top of sport that could transfer a generic mavlink style container with a variable length payload.
Sport packets have a payload of 6 bytes (by using frame id 0x32) so the new protocol would transfer messages in chunks of 6 bytes.

I added to the passtrough library an sport packet decoder to parse incoming bytes read from the serial port, every time a full 6 packet is received it is checked against it’s crc and if the packet’s sensor id matches the configured uplink sensor id it is passed to the next layer: the rx message parser.
The rx message parser verifies the packet sequence and builds the paylod, packet after packet.
When a complete message is found it’s passed to the message handler which processes the message according to the message id.

Outgoing messages follow a similar path, the tx message parser chunks the message in 6 bytes packets which are sent down the sport bus.

On the receiving lua side an rx parser applies the same logic to build a message from sport packets. A message handler then processes them by message id.

Once I had bidirectional variable length messages working I decided that the parameters microservice was a good candidate for a first implementation.

I implemented a light version of messages 20,22 and 23.
These messages have a variable length string up to 16 bytes for the parameter name and a float for the parameter value.

Handling floats in lua turned out to be harder than I tought since lua 5.2 does not have an IEEE 754 float packer/unpacker so I ended up writing my own in pure lua.

I also wrote a lua library and script to read/write the parameters from an OpenTX radio, I used an Horus X10 for the prototypes but the library works just fine on a Taranis.

I created frame specific tuning pages




The whole system has been bench tested on a Pixhawk1 but with the help of @marco3dr it will be soon “flight” tested.

Right now the link speed is pretty low, both the script and the ardupilot library process one message at the time, I’m sure that there’s room for improvement

First preview of the code is here, kind of rough but it’s working :slight_smile:


@yaapu, now the ArduPilot PR is missing :wink:

@peterbarker @tridge this would be a nice starting point for a Telemetry refactoring with several backends, including Mavlink as one of the backends.

1 Like

Yes Luis, the PR is missing :slight_smile:

I really need some insight from Peter and Tridge on how to access the mavlink backend from inside library code or even if it’s a good idea or not.

Parameters are easy to handle because there’s a dedicated service class but I could not find an elegant way to access for instance the protected function GCS_MAVLINK::handle_command_long_packet in order to implement the command_long message from a lua script.

Nice work Alex! I thought you were a bit too quiet, and now I know you were working away. :slight_smile: That looks very interesting. So you could also send, for example, a heartbeat to trigger a parameter download, or waypoints download.

I also see mentioned the possibility of OpenTX reading native Mavlink. Maybe when the newer, faster uCs show up in Horus et al.

Thanks for the new version of your Maps widget. I tried it a few days ago and it’s working very well for me.

RFDesign were kind enough to send me a pair of RFD900x + txmod modules for testing, so I’ve been playing with those, together with the ESP32 version of Mav2PT. It’s a great way to spend a lot of time.

Hi Eric,
yes, arbitrary parameter download is already possible, accessing the mission microservice or the command microservice is a bit harder for they are buried behind the mavlink backend which is not as simple to call from within a library like the frsky library.

Agree, mavlink would need a faster MCU and a LOT more memory especially to handle it in LUA. There has been some work a while ago to pass up to LUA the messages but it was a POC I guess.

Cool, I’m sure it was the right decision, your code is the de facto standard for long range systems :wink:

I just saw your video with RFD900 + ESP32 and wifi “hack”, very cool WOW.

Thanks Alex. By the way, I found that by enabling CTS/RTS between the Pixhawk and the RFD900x greatly improves the chances of getting parameters and mission WPs down unscathed down to the tablet. I don’t have flow control between the ESP32 and the ground RFD900, but I want to. Apparently only uart0 has flow control, but it’s the usb port and that’s rather inconvenient, so I need to do some more digging.

What baud rates are we talking about?

57600 across the radio link

57600 serial rate + PPM over an air rate of 64k?
Those modems are really nice, too bad bvlos is illegal here :slight_smile:

Great job @yaapu Alessandro, I’m happy to help you in the development.
Full speed ahead!

Alex, register as a commercial UAV concern. Probably will cost a king’s ransom, but might lead to interesting options ahead.

Hi Alex,

I have been busy flying and missed this post. Along with your new mapping feature, this could eliminate the need for a separate APM telemetry link on my Horus X10 for some applications where a ground station is not needed.


Hi Greg,
Very basic GCS functionality has always been the main goal. A complex message protocol is just too slow for regular telemetry, which by the way the current protocol can do just fine.
Now that I have a framework I need help on deciding on what to focus.
Parameters are there, commands are possible once I find a good way to invoke the command handler, missions will be hard to handle but only for their large memory requirement unless I find a way to export missions in a Lua compatible format as an alternative to download them from the vehicle.
Anyway what would you need from such a system?

Thanks Marco,
I could test it on one of my quadcopters but your big slow soaring plane I guess it’s a much safer option :slight_smile:


I fly for hobby fun so I don’t actually need anything. Lately, I have been enabling/disabling AS sensors (ARSPD_USE) for testing but I don’t remember if this can be done without a reboot. Also, it would be nice to be able to change a parameter like (WP_LOITER_RAD) without dedicating a channel or using the GCS. Stuff like that…

1 Like

Yes Greg, I fly for fun too, maybe need was not the correct word, like would have been a better choice :slight_smile:

So on the fly parameters tuning is the one feature that most of us would use…

Well who knows, in Italy rc models will soon not be allowed to have auto flight modes, so unless you’ll register as an uav no “legal” auto missions will be possible…

@LuisVale, @tridge @peterbarker I created a PR for this.

I strongly doubt that there will ever be the need to have payloads any bigget than 127 bytes.
My plan to introduce some kind of command support and (if doable) a selection of mission commands should still lead to much smaller messages.
For instance the MISSION_ITEM message which is quite big is well under 127 bytes.

All sport packets used to encode mavlite messages start with the sequence byte.
Right now this byte can have a value up to 256 which is way too big.
A message with a payload of 127 bytes only needs 26 sport packets which in turn require 5 bits to be encoded leaving 3 bits “free”.
This 3 bits could be used to specify a “magic” prefix to mark packets as mavlite ones.

Just as an example if the msb for mavlite is always 0 when a 1 is detected the packet could be used for something different.

The first simple application is the possibility to create version 2 of the passthrough protocol or to extend the current one with packets which compared to the current implementation have at least 8bits more per packet, this is a 25% boost in bandwidth for free.

Am I missing something or he didn’t understand the PR ?