Frsky bidirectional telemetry implementation

Thanks Alex …

1 Like

Hi Eric,
I prepared a debug version of the lua script.
This sends a mavlite message 22 (param request read) every 5 seconds and decodes all incoming mavlite messages

image

first packet structure:
1 byte for sequence
1 byte for payload length
1 byte for message id
3 bytes payload

all other packets
1 byte sequence
5 bytes paylod

at the end of the message a CRC i calculated which is not counter in the payload length

In this example the uplink message requires 4 sport packets (seq: 1 - 4) since the payload is just the string “SERIAL1_PROTOCOL” (parameters names are max 16 chars with dynamic length.

the value message requires 4 extra bytes to encode the parameter value as an IEEE 754 float.
The float is always encoded before the string since the latter has a variable length.

By looking at the code this should be much clearer :slight_smile:

ardupilotlua_debug_ver_0.1.ZIP (23.5 KB)

Thank you Alex. This will be very useful. I got a chunk of work done yesterday, but long way to go.

How do you determine that you have a mavlite message, rather than a frsky sensor message?

uplink = TX → RX (master)
single sensor i.e. responds to poll only for ID 0x0D, uses frame:0x30

downlink= RX → TX (slave)
responds to polls for IDs 0x1B, 0x67, 0x34. uses frame: 0x32

All downlink traffic is using frame 0x32, this is a special frame that OpenTX passes untouched to lua.

All uplink traffic is using frame 0x30.

Note: I will eventually switch to f.port convetions
image

where uplink (master traffic) is separated between read/write

Ok, got it. Thanks…

you’re welcome,

…did a little editing of the previous answer

Sorry, one more thing. Where can I get your ardupilot side repo / firmware? Is it the one on your git?

yes, here

Starting .... C:\Users\Eric\Documents\GitHub\+esp32_wip\Mav2PT_TwoWay_v2.45c\Mav2PT_TwoWay_v2.45c
Target Board is ESP32 / Variant is Dev Module
Air Mode
Battery_mAh_Source = 3 - Define battery capacities in the LUA script
Using Serial_1 for S.Port
RSSI Automatic Select
Mavlink Serial In
Waiting for telemetry
ESP32 S.Port pins NOT inverted for Air or Relay Modes. Must use a converter
hb_count=1
hb_count=2
hb_count=3
mavgood=true
FrSky from S.Port: 0x0D:0x30:1000:52455314
FrSky from S.Port: 0x0D:0x30:4901:5F314C41
FrSky from S.Port: 0x0D:0x30:5002:4F544F52
FrSky from S.Port: 0x0D:0x30:4303:00EC4C4F
FrSky from S.Port: 0x0D:0x30:1000:52455314
FrSky from S.Port: 0x0D:0x30:4901:5F314C41
FrSky from S.Port: 0x0D:0x30:5002:4F544F52
FrSky from S.Port: 0x0D:0x30:4303:00EC4C4F
FrSky from S.Port: 0x0D:0x30:1000:52455314
FrSky from S.Port: 0x0D:0x30:4901:5F314C41
FrSky from S.Port: 0x0D:0x30:5002:4F544F52
FrSky from S.Port: 0x0D:0x30:4303:00EC4C4F
FrSky from S.Port: 0x0D:0x30:1000:52455314
FrSky from S.Port: 0x0D:0x30:4901:5F314C41
FrSky from S.Port: 0x0D:0x30:5002:4F544F52
FrSky from S.Port: 0x0D:0x30:4303:00EC4C4F
FrSky from S.Port: 0x0D:0x30:1000:52455314
FrSky from S.Port: 0x0D:0x30:4901:5F314C41
FrSky from S.Port: 0x0D:0x30:5002:4F544F52
FrSky from S.Port: 0x0D:0x30:4303:00EC4C4F
FrSky from S.Port: 0x0D:0x30:1000:52455314
FrSky from S.Port: 0x0D:0x30:4901:5F314C41
FrSky from S.Port: 0x0D:0x30:5002:4F544F52
FrSky from S.Port: 0x0D:0x30:4303:00EC4C4F
FrSky from S.Port: 0x0D:0x30:1000:52455314
FrSky from S.Port: 0x0D:0x30:4901:5F314C41
FrSky from S.Port: 0x0D:0x30:5002:4F544F52
FrSky from S.Port: 0x0D:0x30:4303:00EC4C4F

:sunglasses: yesss, looking good!

1 Like

Another small step. We could use the param index rather than the id string.

Did I mention we are off to Australia for a month, leaving tomorrow? I have to pause this project now, but will work from there.

S.Port Read raw: 0D 30 00 10 14 53 45 52 	0x0D:0x30:1000:52455314
S.Port Read raw: 0D 30 01 49 41 4C 31 5F 	0x0D:0x30:4901:5F314C41
S.Port Read raw: 0D 30 02 50 52 4F 54 4F 	0x0D:0x30:5002:4F544F52
S.Port Read raw: 0D 30 03 43 4F 4C EC 00 	0x0D:0x30:4303:00EC4C4F
Mavlite #20 Request_Param_Read :SERIAL1_PROTOCOL:
Mavlink from FC #22 Param_Value: param_id=SERIAL1_PROTOCOL  param_value=2.0000  param_count=802  param_index=65535

great Eric :+1: the mavlite decoder is working!

[Q] are you doing your testing in air mode or ground mode?

yes I know but to get the index I’d have to query the param first and cache the response.
In a regular GCS I’d do it this way but in lua I’m already using memory to store paramenter names and I opted to trade some memory vs speed, but I’m open to change it, actually it would improve speed quite a bit but only after the first pass with full parameter names.

yes you did :slight_smile: have a nice trip Eric!

Air mode right now. Thank you. :slight_smile:

@yaapu I’ve done a PR for an implementation of FPort here:


This support FPort for RC input. I’m hoping you can give me some assistance with the 2nd part of this, which is to use FPort for the SPort pass-through output as well.
What I need to know is how to deal with the “prim” and “appid” fields that come in with a FPort control packet and how they relate to the sport IDs in the ArduPilot sport passthru code.

Hi @tridge,
prim_id is the frame type, ardupilot as of current (no bidirectional) only used 0x10, so each packet sent down the link had 0x10 as prim_id.
app_id is used by regular frsky sensors to distinguish “instances”, but ardupilot used it to mark packets with prim_id 0x10 as passthrough by using for app_id a “special” range above 0x5000 known as the DIY packet range.
By using 0x10 as prim_id and 0x5000 ad app_id the payload is only 4 bytes, OpenTX passes to LUA all 0x10 packets with app_id in the DIY range.
downlink/control traffic (master → slave) should use prim_id 0x00/0x10(R/W), 0x30(RO), 0x31(WO)
uplink traffic (slave → master) should use 0x10 and 0x32 where 0x32 is special because OpenTX always passes 0x32 up to the lua stack irregardless of the app_id, in this case the payload is 6 bytes, app_id + data.

  • every time we receive 0x10 or 0x00 we have a chance to send passtrough telemetry data

  • every time we receive 0x30,0x31 we should invoke the bidirectional passthrough packet decoder by passing app_id and data (6 bytes) (we will eventually respond with prim_id 0x32)

  • we respond to 0x00/0x10 with 0x10, and to 0x30,0x31 with 0x32, so for 0x00,0x10,0x30,0x31 the passthrough packet scheduler should be invoked.

hope this makes sense, later tonight I will have the time to check your code,

great stuff :slight_smile:

Edit: I got your branch working on a Pixhawk1 + X4R, I wired the X4R sport pint to the RCIN pin
To process incoming packets from LUA (master->slave) you provide the decode_downlink() method, what we need is a method to write to the bus an fport_frame, something like send_uplink()

I hacked together something for the F765-Wing which works with yaapu telem over fport. It is pretty ugly at the moment, but I think I can clean it up.
One thing that is wrong is the uart pin is idling high, whereas it should idle low as the fport signal is inverted (using a X4R). I checked with inav on the same board and it idles low. Something wrong in the uart config.

great! If you think I can be of any help, let me know!

I’ve updated the PR with first working version. To use it you need to set some serial port with:
SERIALn_PROTOCOL=23
which sets the serial port as RCIN. You will also need:
SERIALn_OPTIONS=7
to enable half-duplex inverted. After that the passthru telem output should work.
I’m looking at the possibility of supporting the output using soft-serial so it can work with a uart. FPort input does work in the PR for input without a UART, but not yet for output.

I’ve got a test patch that allows FPort including telemetry without a UART, using soft-serial to output the SPort data. It does work, but is not suitable for merging in it’s current form.
One of the key issues is that when we don’t use a UART the RC protocol decoder doesn’t get told about a new frame until after it is too late to send the reply. The problem is that the SoftSigReader and SoftSigReaderInt implementations gather level transitions in pairs. So it can sit waiting for the first transition for the next packet before it passes the data to the RC decoder. I put in a hack to work around this just to test the soft-serial send part, but we need to fix this properly if we want to use a non-UART implementation for sport.

Hi Alex and tridge

Very nice progress, by the sounds of it! Alex I enjoyed your explanation of the FrSky sensor protocols. You illuminated some of the dark corners that have eluded me.

Tridge, it’s a pleasure to hear/see your insights into the workings of the ardupilot eco system. Awesome.

Alex I have bi-directional mavlite working in my modest little protocol translator, but I need to tidy up before I give you something to test. I don’t have a Horus here with me, so I hacked a spare esp32 board to send and read test data similar to openTX. It might not represent real life. Also, after reading your treatise above, I want to relook at how I respond to ids. :roll_eyes:

The Dragonlink boards arrived today, so I also look forward to playing with those. In between my vacation duties, of course. :grin: