FrSky S-Port telemetry library - easy to use and configurable - RC Groups
Thread Tools
Sep 14, 2014, 01:13 PM
Makers gonna make...
pawelsky's Avatar
Discussion

FrSky S-Port telemetry library - easy to use and configurable


Hi,

for those having Tarains radios or other system capable of receiving FrSky S-Port telemetry data I've created a library, that allows to emulate and/or decode the FrSky S-Port sensors or using Arduino compatible Teensy 3.x/LC board or 5V/16MHz 328P based boards (e.g. ProMini, Nano, Uno).

If you still use old FrSky telemetry, there is also a library for that as well. You ca fin it here:
https://www.rcgroups.com/forums/show....php?t=2465555

The library initially created to work together with the NazaDecoder or NazaCanDecoder libraries that read telemetry data coming out of DJI Naza Lite/v1/v2 controllers (examples can be found in post #36), but it can be used for other purposes as well.

The main goals that I had when creating this library was to have it:
1) easy to use
2) easy to configure
3) easy to add new sensors

The library consists of 5 main classes:
  1. FrSkySportTelemetry - which is responsible for sending the S.Port data via one of the Teensy serial ports or SoftwareSerial ports on 328P based borads.
  2. FrSkySportDecoder - which is responsible for decoding the data coming from the S.Port line via one of the Teensy serial ports or SoftwareSerial ports on 328P based borads.
  3. FrSkySportPolling - which is emulating data polling (useful when there is no device actively polling the S.Port data such as the receiver).
  4. FrSkySportSingleWireSerial - which is responsible for S-Port-like single wire serial transmission.
  5. FrSkySportSensor - which is a base class for all the sensors. So far following sensors have been implemented (with the exception of the last one all of them can both emulate and decode the data):
    • FrSkySportSensorAss - which emulates ASS-70/ASS-100 airspeed sensors
    • FrSkySportSensorFcs - which emulates FCS-40A/FCS-150A current sensors
    • FrSkySportSensotFlvss - which emulates FLVSS /MLVSS LiPo voltage monitor sensor
    • FrskySportSensorGps - which emulates the GPS v2 sensor
    • FrskySportSensorRpm - which emulates the RPM/temperature sensor
    • FrSkySportSensorSp2uart - which emulates the S.Port to UART Converter type B sensor (analog ADC3/ADC4 inputs only)
    • FrskySportSensorVario - which emulates the high precision variometer sensor
    • FrskySportSensorXjt- which is a special sensor that is only capable of decoding the additional (i.e. other than from the above sensors) data stream coming from the XJT transmitter module's S.Port. This data includes the old type (hub) telemetry and the special data such as ADC1, ADC2, SWR, RSSI and RxBatt.

The library is very easy to use, you can define which sensors to include, you can change their default IDs (e.g. to avoid conflicts or to use 2 FLVSS sensors to 12S batteries). The library makes sure that the sensors respond to correct ID being polled/transmitted (not just any ID or a fixed list of IDs as in some of the existing libraries) so you can even mix the virtual sensors with the real ones without conflicts. You can also define which of the Teensy serial ports to use. In fact you can send/decode different data on different ports by creating multiple telemetry objects.

The library can be used for both emulating the S.Port sensors and decoding the S.Port data, but never at the same time!

Attached you'll find the library itself and a picture showing the encoder code in action. As you can see the data displayed for FCS and FLVSS sensor matches the data set in code.


ENCODER - emulating the S.Port sensor

Here is a quick example on how the library is used to emulate a sensor

Code:
#include "FrSkySportSensor.h"
#include "FrSkySportSensorFlvss.h"
#include "FrSkySportSensorFcs.h"
#include "FrSkySportSingleWireSerial.h"
#include "FrSkySportTelemetry.h"

FrSkySportSensorFlvss flvss1;
FrSkySportSensorFlvss flvss2(FrSkySportSensor::ID15);
FrSkySportSensorFcs fcs;
FrSkySportTelemetry telemetry;

void setup()
{
  telemetry.begin(FrSkySportSingleWireSerial::SERIAL_3, &flvss1, &flvss2, &fcs);
}

void loop()
{

  /* DO YOUR STUFF HERE */

  flvss1.setData(4.10, 4.11, 4.12, 4.13, 4.14, 4.15);
  flvss2.setData(3.10, 3.11, 3.12, 3.13, 3.14, 3.15);
  fcs.setData(25.3, 12.6);
  telemetry.send();
}
As you can see it is super simple, all you need to do is to:
1) create the sensors you want to use and the telemetry object
2) call the begin method of the telemetry object defining the port and pointers to used sensors (up to 28)
3) update the sensor data when necessary
4) call the send method of the telemetry object periodically

For simplicity it is not possible to remotely change data send frequency which every sensor has defined, the values are as specified by FrSky.

Have a look at the FrSkySportTelemetryExample included in the library to have a better understanding on what parameters can be set for each of the sensors.


DECODER - decoding the S.Port data

Here is a quick example on how the library is used to decode a S.Port Sensor data.

Code:
#include "FrSkySportSensor.h"
#include "FrSkySportSensorFlvss.h"
#include "FrSkySportSensorFcs.h"
#include "FrSkySportSingleWireSerial.h"
#include "FrSkySportDecoder.h"

FrSkySportSensorFlvss flvss1;
FrSkySportSensorFlvss flvss2(FrSkySportSensor::ID15);
FrSkySportSensorFcs fcs;
FrSkySportDecoder decoder;

void setup()
{
  decoder.begin(FrSkySportSingleWireSerial::SERIAL_3, &flvss1, &flvss2, &fcs);
}

void loop()
{
  // Call this on every loop
  decoder.decode();

  // Make sure that all the operations below are short or call them periodically otherwise you'll be losing telemetry data
  flvss1.getCell1();  // Read cell 1 voltage from the standard FLVSS sensor and do something with it
  flvss2.getCell2();  // Read cell 2 voltage from the ID15 FLVSS sensor and do something with it
  fcs.getCurrent();  // Read current from the fcs sensor and do something with it

   /* DO YOUR STUFF HERE */

}
As you can see it is super simple, all you need to do is to:
1) create the sensors you want to use and the decoder object
2) call the begin method of the decoder object defining the port and pointers to used sensors (up to 28)
4) call the decode method of the decoder object on every loop
3) read the data from sensors and do something with it

You can decode data from real sensors, my telemetry library, from Taranis serial port that can be found in the battery compartment (make sure it is configured to mirror S.Port data in radio menu)or S-Port connector in the Taranis JR TX module bay.

You'll find more detailed example in the FrSkySportDecoderExample and FrSkySportXjtDecoderExample directory.

Data polling

To send the data the S.Port sensors must be actively polled. Normally that is done by the receiver that the sensor is connected to. If for whatever reason you decide to use this library in a configuration that does not have the receiver (or any other device actively polling) in the S.Port chain you have to enable library's internal polling mechanisms. Note that the polling mechanism the library offer is simplified compared to the one implemented in FrSky receivers and it does not store active sensor IDs to poll them more often. This may cause the data to be updated a bit less frequently.

To enable polling you need to instantiate the FrSkySportTelemetry or FrSkySportDecoder class object passing true as a parameter. If you don't do that false (polling disabled) will be used as a default.

Code:
FrSkySportTelemetry telemetry(true); // Create telemetry object with polling
Code:
FrSkySportDecoder decoder(true); // Create decoder object with polling

In examples, to make things easier polling can be enabled by uncommenting the following line
Code:
//#define POLLING_ENABLED
For the telemetry to be properly decoded on the Taranis radio RSSI data is required, so when polling is enabled the library also sends out RSSI = 100 at regular intervals.

As both encoder and decoder have the polling capability, if you use both in your setup make sure that only one or the other has the polling enabled, not both at the same time.


Connections

Below you can also find attached connection diagrams for both encoder and decoder (note that they are different). Pick one of the Teensy 3.x/LC serial TX or 328P based board 2-12 pins (one that is not used for other purposes) and tell the library to use it in telemetry.begin or decoder.begin function. Depending on the board used you should chose:
  • SERIAL_1, SERIAL_2 or SERIAL_3 for Teensy 3.0/3.1/3.2/LC boards (note that the additional SERIAL_USB shall only be used for debug purposes if you know what you are doing)
  • SERIAL_1, SERIAL_2, SERIAL_3, SERIAL_4, SERIAL_5 or SERIAL_6 for Teensy 3.5/3.6 boards (note that the additional SERIAL_USB shall only be used for debug purposes if you know what you are doing)
  • SOFT_SERIAL_PIN_2 to SOFT_SERIAL_PIN_12 for 328P based boards (e.g. Pro Mini, Nano, Uno)
Note that for 328P based boards you need to include the SoftwareSerial library in your main sketch:
Code:
#include "SoftwareSerial.h"
There were reports that for some reason the library does not work when used with 1.6.0 version of Arduino IDE. This is most likely due to the changed toolchain and modified timings. If you experience problems please upgrade to a newer version where the timing calculation has been modified (1.6.3 has been confirmed working) - that shall help.

Also note that to avoid interrupt conflict with the mentioned SoftwareSerial library you need to disable attitude (roll/pitch) sensing in the NazaDecoder library by uncommenting the following line in NazaDecoder.h file:
Code:
//#define ATTITUDE_SENSING_DISABLED
Make sure you understand Teensy 3.x/LC/328P based board powering options before choosing how to power your board!

When creating my library I used some of the information that I found on this webpage:
https://code.google.com/p/telemetry-...ySPortProtocol


FrSky S.Port Telemetry library changelog
-----------------------------------------------------
Version 20171114
[FIX] Removed unnecessary debug message from FrSkySportDecoder.cpp

Version 20160919
[NEW] Added support for Teensy LC, 3.5 and 3.6 boards and updated examples
[NEW] Added note about MLVSS sensor in the FLVSS sensor class

Version 20160818
[NEW] Added simplified polling to the FrSkySportTelemetry and FrSkySportDecoder class
[NEW] Added POLLING_ENABLED define to examples to simplify switching the polling on/off
[NEW] Removed separate connection diagrams for decoder, as the connection is now the same for both emulator and decoder classes

Version 20160324
[NEW] Increased the max number of sensors from 10 to 28 (to cover all possible sensor IDs)

Version 20160313
[FIX] Added missing getAccX, getAccY and getAccZ function names to keywords file for syntax highlighting
[FIX] Added missing getCell7 - getCell12 function names to keywords file for syntax highlighting
[FIX] Changed the FrSkySportSensorTaranisLegacy decoder class name to FrSkySportSensorXjt
[NEW] Added usage example for the FrSkySportSensorXjt decoder class (FrSkySportXjtDecoderExample)
[NEW] Added decoding of ADC1, ADC2, RSSI, SWR and RxBatt data to FrSkySportSensorXjt
[NEW] Added decoding of vertical speed from FVAS sensor (not documented in FrSky spec, added based on OpenTX sources)

Version 20151108
[FIX] For combined values decoded by the FrSkySportSensorTaranisLegacy sensor the data ID is only returned when complete value has been decoded
[FIX] Fixed handling empty FLVSS data message that was crashing the decoder
[NEW] Added defines for FrSkySportSensorTaranisLegacy sensor decoded values
[NEW] Added decoded value IDs to keywords file for syntax highlighting
[NEW] Added clarification about different IDs used by FCS-40A and FCS-150A sensors in examples and sensor class header file

Version 20151020
[FIX] Stuffing was not used for CRC, fixed
[FIX] Fixed lat/lon calculation in FrSkySportSensorTaranisLegacy sensor

Version 20151018
[NEW] Added Taranis legacy telemetry decoder class (which decodes data that Taranis spits out on teh S.Port mirror when it receives old FrSky Telemetry Hub data)
[NEW] Added CRC checking in decoder class
[NEW] Added return result (decoded appId) to decode methods and updated the decoder example
[FIX] Removed redundant CRC calculations in FrSkySportSingleWireSerial class
[FIX] Simplified cell voltage decoding

Version 20151008
[NEW] Added Decoder class and decoding functions to sensors (plus the decoder usage example)
[FIX] In RPM sensor changed the rpm value type to integer, t1/t2 are now properly rounded
[FIX] Minor editorial corrections

Version 20150921
[NEW] Added airspeed (ASS-70/ASS-100) sensor.

Version 20150725
[NEW] Added data transmission periods to ensure telemetry receiver is not flooded with data
[NEW] Added SP2UART (type B) sensor. Note that only analog ports ADC3 and ADC4 are implemented, not the UART part.

Version 20150319
[FIX] corrected setting the 328p serial pin to the right mode when transmitting/receiving. This shall help when chaining the adapter with other sensors. Note that a 4.7kohm resistor is recommended to protect the S.Port data line.

Version 20141129
[FIX] fixed incorrect display of GPS coordinates on 328p platform (caused by wrong usage of abs function)

Version 20141120
[NEW] added support for 328P based boards (e.g. Pro Mini, Nano, Uno)
[NEW] added connection diagrams

Version 20140914
initial version of the library
Last edited by pawelsky; Nov 13, 2017 at 06:16 PM.
Sign up now
to remove ads between posts
Sep 14, 2014, 01:35 PM
Registered User
Subscribed! Awesome!
Sep 15, 2014, 01:46 AM
Flying Wood For Fun
irun4fundotca's Avatar
Great Stuff Man Thanks
hope to tinker soon just ordered the dual temp and rpm sensor
Sep 15, 2014, 04:20 AM
Makers gonna make...
pawelsky's Avatar
Quote:
Originally Posted by irun4fundotca
Great Stuff Man Thanks
hope to tinker soon just ordered the dual temp and rpm sensor
Thanks!

Let me know once you have it. I may have some questions about this particular sensor.
Sep 15, 2014, 08:04 AM
Flying Wood For Fun
irun4fundotca's Avatar
Quote:
Originally Posted by pawelsky
Thanks!

Let me know once you have it. I may have some questions about this particular sensor.
no probs, I already have the gps v2, lipo cell checker, 40a current sensor that's one I didn't have yet so I figured what the heck, I would never use a vario though at least I don't think so

ill tell you, it would be a large craft to have them all connected at once, to bad they weren't all one module
Sep 15, 2014, 08:09 AM
Makers gonna make...
pawelsky's Avatar
Quote:
Originally Posted by irun4fundotca
no probs, I already have the gps v2, lipo cell checker, 40a current sensor that's one I didn't have yet so I figured what the heck, I would never use a vario though at least I don't think so

ill tell you, it would be a large craft to have them all connected at once, to bad they weren't all one module
Nice, they are all S-Port sensor, right?
Sep 15, 2014, 09:39 AM
Flying Wood For Fun
irun4fundotca's Avatar
Quote:
Originally Posted by pawelsky
Nice, they are all S-Port sensor, right?
yeah correct, I still want an airspeed sensor
was thinking on using an apm type airspeed sensor but its analog so I didn't go for it

they will all fit nicely on my 90" piper cub
Sep 16, 2014, 06:07 PM
Makers gonna make...
pawelsky's Avatar
Got some logs from real sensors from irun4fundotca (thanks for that) and this confirms my understanding of the data rates and the defaults as written on the attached picture from FrSky.

Interesting thing is that COG is by default disabled and not reported by the GPS sensor.

Next version of the library will have the data rates implemented and configurable. I'll also add option for enabling/disabling particular messages.
Sep 22, 2014, 08:49 AM
Makers gonna make...
pawelsky's Avatar
Joined the FrSky Developing Union to get access to the S.Port protocol specification. Looks like the implementation is pretty close to what is expected so other than enabling the data rates and enabling/disabling of particular messages only minor corrections will be necessary.
Sep 25, 2014, 05:33 AM
Registered User
Fantastic work again, Pawelsky!

What would happen if you sent data to the telemetry hub with a PHY_ID that isn't listed in the table? Would the data still be sent over the telemetry link, and how would it appear on the receiver? Can a sensor name label be programmed in, or does the telemetry receiver simply map the PHY_IDs to sensor names?

The reason I ask is that I have some custom sensors that I intend to read and log via a serial port on my Teensy. I'd like to be able to send the values from those sensors over the telemetry link to my receiver. If using a PHY_ID > 7 won't work, I guess I could just send the information with one of the existing PHY_IDs and live with the fact that the label is wrong!
Sep 25, 2014, 05:49 AM
Makers gonna make...
pawelsky's Avatar
Quote:
Originally Posted by monty_mcmont
Fantastic work again, Pawelsky!

What would happen if you sent data to the telemetry hub with a PHY_ID that isn't listed in the table? Would the data still be sent over the telemetry link, and how would it appear on the receiver? Can a sensor name label be programmed in, or does the telemetry receiver simply map the PHY_IDs to sensor names?

The reason I ask is that I have some custom sensors that I intend to read and log via a serial port on my Teensy. I'd like to be able to send the values from those sensors over the telemetry link to my receiver. If using a PHY_ID > 7 won't work, I guess I could just send the information with one of the existing PHY_IDs and live with the fact that the label is wrong!
First of all S.Port bus implements a pull model rather than push (receiver requests particular physical id to respond, and only then the data shall be sent).

There are 28 physical IDs available (FrSkySportSensor::IDxx), so you can use one of these that is not mentioned in the table and is shall be polled by the Taranis no problem (same way as the second FLVSS sensor that has ID15 assigned in the example code). Note that PHY_ID 0 maps to ID1, PHY_ID 1 maps to ID2 etc.

Sensor names cannot be programmed. The type of data that is being sent is determined by the so called APP_ID which is predefined by FrSky. Only these predefined APP_IDs will be understood and displayed by the receiver.
Sep 25, 2014, 07:42 AM
Registered User
Quote:
Originally Posted by pawelsky
First of all S.Port bus implements a pull model rather than push (receiver requests particular physical id to respond, and only then the data shall be sent).

There are 28 physical IDs available (FrSkySportSensor::IDxx), so you can use one of these that is not mentioned in the table and is shall be polled by the Taranis no problem (same way as the second FLVSS sensor that has ID15 assigned in the example code). Note that PHY_ID 0 maps to ID1, PHY_ID 1 maps to ID2 etc.

Sensor names cannot be programmed. The type of data that is being sent is determined by the so called APP_ID which is predefined by FrSky. Only these predefined APP_IDs will be understood and displayed by the receiver.
Great, thanks for this very useful information Pawelsky. I should be able to send the data to my receiver from my custom sensors via the Teensy and the FrSky telemetry link :-D
Sep 25, 2014, 11:54 AM
Registered User
Me again! I was just wondering what the physical connections are. Do you simply connect ground and signal (e.g. serial port Tx) from the Teensy to the Smart Port on the receiver?

Also, does the receiver automatically include RSSI data in with the other telemetry data when it transmits it back to the ground station?
Sep 25, 2014, 12:27 PM
Makers gonna make...
pawelsky's Avatar
Quote:
Originally Posted by monty_mcmont
Me again! I was just wondering what the physical connections are. Do you simply connect ground and signal (e.g. serial port Tx) from the Teensy to the Smart Port on the receiver?
Yes.

Quote:
Originally Posted by monty_mcmont
Also, does the receiver automatically include RSSI data in with the other telemetry data when it transmits it back to the ground station?
The RSSI value is sent back to the Taranis radio (which can display it), but if you are using a built in TX module I don't think you can easily get access to the S.Port telemetry stream and redirect it to your GS. You would need to use the FrSky external X series TX module.

EDIT: Correction - you can get easy access to S.Port telemetry stream on Taranis:
https://github.com/opentx/opentx/wik...is-serial-port
Last edited by pawelsky; Sep 25, 2014 at 06:35 PM.
Sep 25, 2014, 05:53 PM
Registered User
I use a FrSky X8R telemetry enabled receiver and a FrSky DJT JR module with pins on the back, into which I can plug one of the FrSky FLD-02 telemetry displays :-)


Thread Tools