Custom FrSky telemetry for Helicopter

OK, so I taught myself how to do basic lua scripting for OpenTX/FrSky and created my first script for piston helicopters that actually works. I didn’t want any fancy widgets or anything - just the numeric readout for critical telemetry parameters for piston engines, plus whatever I want to add from the ArduPilot FrSky telemetry library and other Smart Port sensors.

The telemetry screen will be arranged in two columns and I think I have room to display 12 things on the X9D without making the screen cluttered. All the current scripts I could find are electric-centric, and it does no good to display a picture of a battery gauge for a piston heli equipped with a generator to keep the battery charged. So I wanted the critical need-to-know mechanical stuff, plus I’ll probably add things like Altitude, Ground Speed, Heading, Flight Mode, GPS status, or whatever, from the ArduPilot library.

This is what the initial part of the script looks like on the screen in the OpenTx Companion simulator with some simulated numbers to make sure it looks right. I used “F” for the temp in the code. In the metric countries I think zero degrees is based on when water freezes. In the US zero degrees is based on when JetA freezes. I prefer to know the status relative to JetA. If somebody wants to take this script and build on it you can change it to “C” if you want.


My github repo is here. If somebody has a Horus or QX7 please feel free to change it to fit the screen on those and PR it. If you do that, please put each type of radio in it’s only folder, as each one will require a different script, especially for the Horus. I’d rather not have a bunch of if-else statements in the code to fit the screen on different radios, as the Horus can do a lot more things than the QX7 or X9D Plus.

I named this first script heli-g.lua for piston heli’s. If somebody wants to change it for electric based on the same simple layout, then create a new one and call it heli-e.lua. You can only have six characters in the file name in OpenTx 2.2

1 Like


Chris, do you ever sleep ?

ps: you’re using standard FrSky sensors, so it might not be what we have on ArduPilot, but no problem with these sensors

I have improvements now


I made a few more tweaks, added the helicopter name and a Total Time Engine (TTE) timer, flight timer, changed some of the fields to my liking. It all works in a real radio on a test flight, gives me everything I need on the RC if the ground station gets run over by the truck. And gives me some info the ground station doesn’t.

For the timers I’m just calling timer1 and timer2 from the radio. I have timer1 set up for total time on the engine. Timer2 set up for flight time on the current flight. Timer 3 is my runup timer and is a countdown timer for spoolup - it has an audio announcement when it expires. So I didn’t put that one on the screen.


I might add some enhancements with sound files for low headspeed warning, low batt voltage if the generator quits, maybe engine over-temp.

I’m not sold on the FrSky passthru telemetry. And I’m not using it for this telemetry script. That pass-thru telemetry saturates the RC link and shortens the range of the radio.

Do you mean the pass-thru telemetry shortens an upstream control range? Or it is about a downstream telemetry data range?

Sure of this @ChrisOlson ?

I was getting dropped frames at 700 meters on the RC link with the passthru script. That doesn’t happen with my custom script on the same flight plan. I haven’t max range tested the X9D yet but 2-3 km is no problem with my FS-i10.

So I wouldn’t say it reduced range, rather more errors occurred ? On the passthrough Alex has some test code to check that.
Also strange that you say was on the RC link…

I got dropped or late frames on the RC control link. Which tells me the allowed bandwidth on the signal is saturated. You can only shove so much data down the pipe on a radio link. In ham radio if we want to talk to South Pole Station reliably we don’t use Single Side Band at 3 kHz bandwidth. We use PSK at 31Hz. Or one of the MFSK digital protocols like Olivia that has FEC. Getting the bandwidth down and shoving less data down the pipe we can reliably communicate with stations on the other side of the earth on 5 watts EIRP and decode signals 15dB before the noise floor. It is one of the basic concepts in radio range. If you want to shove a fat signal with a lot of data it takes a lot of power and antenna gain to do it.

I’m lost in how the native s-port telemetry differs from pass-thru in a rate/saturation.
In both cases RC does poll requests to the sensors that are alive (so the RC drives the rate?)
The sensor IDs are different and the data returned is different but why the stream rate and saturation are different?

I’m only polling a limited number of sensors. There’s no room to add more stuff to the passthru - the pipe is full. I got all kinds of room to add more stuff on what I’m using.

The whole problem with the passthru scripts is that they don’t have the information I need on the screen for gas helicopters. And that information is not available thru ArduPilot even if the scripts did display the right stuff.

So my thinking was when the pipe is already full, why try to stack more stuff on ArduPilot? You can mix and match, pull from the FrSky sensors what you need that ArduPilot doesn’t have, and use from ArduPilot what you want - and if the software don’t exist to do it, write your own.

One problem I had is that somebody in ArduPilot decided the temp sensors aren’t important because the baro has temp. So the temp sensors got repurposed for other things. Except if you fly a gas engine aircraft and want engine temp, now what? In order to get it to work you either have to change the ArduPilot code or plug your sensor into the SPort pins on the back of the radio and re-program with a Custom ID.

So the SPort code in ArduPilot could use a couple changes to fix some problems.

Wouldn’t the easiest be adding a adc temp sensor on ArduPilot ?

Except for the issue that I don’t have an analog sensor laying around with the right impedance to work. My Gas Suite came with two thermistor type sensors that are very accurate with no calibration required, so why not use those? Plug those in and they “just work” :grinning:

My idea is that we should try to get as much sensor data available to ArduPilot, even that initially we don’t use it and as a minimum only report it, but in time we can start adding automation on ArduPilot to what makes sense using those sensors

There is some advantage to doing that with more generic sensors like hall effect or thermistor sensors. I actually am pretty sure hall effect sensors are already supported in the code. But they aren’t output to the FrSky telemetry.

one thing is sure, the frsky passthru library fills all polling slots for sensor 1B with some data, if there’s nothing to send it sends attitude info, so it always saturates all the slots reserved to sensor 1B
It would be interesting to check if regular frsky sensors behave different.

The only difference I can see in the ardupilot code is the number of sensors used.
Passthru uses only 1 sensor, 0x1B.
Repurposed sport uses 4 sensors

#define SENSOR_ID_VARIO             0x00 // Sensor ID  0
#define SENSOR_ID_FAS               0x22 // Sensor ID  2
#define SENSOR_ID_GPS               0x83 // Sensor ID  3
#define SENSOR_ID_SP2UR             0xC6 // Sensor ID  6

from what Chris observed using more sensors gives a higher link quality, maybe by using the same sensor IDs in the library would yield the same results, this would in turn prevent the usage of proper frsky sensors with the same IDs or we could try to use 3 unused sensor IDs to obtain the same effect?

I like the SPort better than the passthru. You can pick and choose what you want to display on a custom telemetry screen pretty easily. The passthru seems to saturate it and degrade the link quality. It uses too much bandwidth on the link.

Hi Chris,
you made me curious :slight_smile:

I recompiled arducopter to use 3 sensors instead of 1 on the passthru library, it works as OpenTX does not check the sensor ID

then I checked with a logic probe what gets sent

the rx polls in trains of 3 sensors in a row followed by the unused sensors one per train
In this configuration there’s a 25% slot loss (1 out of 4)

I then enabled SERIAL_PROTOCOL = 4 to check what happens in the other mode
this is the capture

here sensors are polled in trains of 4 in a row followed by the unused sensors one per train
In this configuration there’s a 20% slot loss (1 out of 5)

I reverted to standard passthru with 1 sensor

and as expected only 1 slot every other is used with a bandwidth loss of 50%

in theory the 1 sensor approach should be the safest with the least saturated link!

I have no explanation for what you observe, perhaps in your tests OpenTX is caching sensors even in case of packet loss

maybe Luis has an explanation!


I had it on my spectrum analyzer to see what was being used per channel in the 2.4 GHz spectrum. The receiver (XR8R) appeared to be hopping 50 channels @ ~95KHz per channel with passthru. With regular SPort with the Gas Suite plus some ArduPilot ID’s it was using ~58KHz per channel.

Which is still quite a bit wider than the old 20KHz channel spacing used to be with 72MHz radios. But those old 72MHz radios had range. The new 2.4GHz ones don’t. I still have my old JR radio on 50.8MHz (6m ham) with a 56" stainless steel whip on it and that radio has a range of 10 miles, no problem. But it’s pushing less than 10Khz of bandwidth too.