Teensy 4.0 Serial2 and Serial4 issue with S-Port Frsky Telemetry

pierrotm777

Well-known member
Hello,

I use a Teensy 4.0 as Telemetry simulator. I have no issue with Serial1 and Serial3 but the FrSkySportTelemetry library not work with the Serial2 and Serial4.
I use this example as test:
Code:
/*
  FrSky S-Port Telemetry library example
  (c) Pawelsky 20210509
  Not for commercial use
 
  Note that you need Teensy LC/3.x/4.x, ESP8266, ATmega2560 (Mega) or ATmega328P based (e.g. Pro Mini, Nano, Uno) board and FrSkySportTelemetry library for this example to work
*/

// Uncomment the #define below to enable internal polling of data.
// Use only when there is no device in the S.Port chain (e.g. S.Port capable FrSky receiver) that normally polls the data.
//#define POLLING_ENABLED

#include "FrSkySportSensor.h"
#include "FrSkySportSensorAss.h"
#include "FrSkySportSensorEsc.h"
#include "FrSkySportSensorFcs.h"
#include "FrSkySportSensorFlvss.h"
#include "FrSkySportSensorGasSuite.h"
#include "FrSkySportSensorGps.h"
#include "FrSkySportSensorRpm.h"
#include "FrSkySportSensorSp2uart.h"
#include "FrSkySportSensorVario.h"
#include "FrSkySportSingleWireSerial.h"
#include "FrSkySportTelemetry.h"
#if !defined(TEENSY_HW)
#include "SoftwareSerial.h"
#endif

FrSkySportSensorAss ass;                               // Create ASS sensor with default ID
FrSkySportSensorEsc esc;                               // Create ESC sensor with default ID
FrSkySportSensorFcs fcs;                               // Create FCS-40A sensor with default ID (use ID8 for FCS-150A)
FrSkySportSensorFlvss flvss1;                          // Create FLVSS sensor with default ID
FrSkySportSensorFlvss flvss2(FrSkySportSensor::ID15);  // Create FLVSS sensor with given ID
FrSkySportSensorGasSuite gas;                          // Create Gas Suite sensor with default ID
FrSkySportSensorGps gps;                               // Create GPS sensor with default ID
FrSkySportSensorRpm rpm;                               // Create RPM sensor with default ID
FrSkySportSensorSp2uart sp2uart;                       // Create SP2UART Type B sensor with default ID
FrSkySportSensorVario vario;                           // Create Variometer sensor with default ID
#ifdef POLLING_ENABLED
  #include "FrSkySportPollingDynamic.h"
  FrSkySportTelemetry telemetry(new FrSkySportPollingDynamic()); // Create telemetry object with dynamic (FrSky-like) polling
#else
  FrSkySportTelemetry telemetry;                                 // Create telemetry object without polling
#endif

void setup()
{
  // Configure the telemetry serial port and sensors (remember to use & to specify a pointer to sensor)
#if defined(TEENSY_HW)
  //telemetry.begin(FrSkySportSingleWireSerial::SERIAL_1, &ass, &esc, &fcs, &flvss1, &flvss2, &gas, &gps, &rpm, &sp2uart, &vario);//Teensy 4.0 OK
  //telemetry.begin(FrSkySportSingleWireSerial::SERIAL_2, &ass, &esc, &fcs, &flvss1, &flvss2, &gas, &gps, &rpm, &sp2uart, &vario);//Teensy 4.0 not OK
  //telemetry.begin(FrSkySportSingleWireSerial::SERIAL_3, &ass, &esc, &fcs, &flvss1, &flvss2, &gas, &gps, &rpm, &sp2uart, &vario);//Teensy 4.0 OK
  telemetry.begin(FrSkySportSingleWireSerial::SERIAL_4, &ass, &esc, &fcs, &flvss1, &flvss2, &gas, &gps, &rpm, &sp2uart, &vario);//Teensy 4.0 not OK
  //telemetry.begin(FrSkySportSingleWireSerial::SERIAL_2, &ass, &esc, &fcs, &flvss1, &flvss2, &gas, &gps, &rpm, &sp2uart, &vario);//LC OK
#else
  telemetry.begin(FrSkySportSingleWireSerial::SOFT_SERIAL_PIN_12, &ass, &esc, &fcs, &flvss1, &flvss2, &gas, &gps, &rpm, &sp2uart, &vario);//Uno OK
#endif
}

void loop()
{
  // Set airspeed sensor (ASS) data
  ass.setData(76.5);  // Airspeed in km/h

  // Set ESC sensor data
  esc.setData(12.6,   // ESC voltage in volts
              22.1,   // ESC current draw in amps
              10900,  // ESC motor rotations per minute
              20000,  // ESC current consumtion in mAh
              45.6,   // ESC temperature in degrees Celsius (can be negative, will be rounded)
              6.7,    // ESC SBEC voltage in volts
              0.10);  // ESC SBEC current draw in amps

  // Set current/voltage sensor (FCS) data
  // (set Voltage source to FAS in menu to use this data for battery voltage,
  //  set Current source to FAS in menu to use this data for current readins)
  fcs.setData(25.3,   // Current consumption in amps
              12.6);  // Battery voltage in volts

  // Set LiPo voltage sensor (FLVSS) data (we use two sensors to simulate 8S battery
  // (set Voltage source to Cells in menu to use this data for battery voltage)
  flvss1.setData(4.07, 4.08, 4.09, 4.10, 4.11, 4.12);  // Cell voltages in volts (cells 1-6)
  flvss2.setData(4.13, 4.14);                          // Cell voltages in volts (cells 7-8)

  // Set Gas Suite sensor data
  gas.setData(-10.3, // Temperature #1 in degrees Celsuis (can be negative, will be rounded)
              200.6, // Temperature #2 in degrees Celsuis (can be negative, will be rounded)
              80000, // Rotations per minute
              55000, // Residual volume in ml
              73,    // Residual percentage (0-100)
              1230,  // Flow in ml/min
              1500,  // Maximum flow in ml/min
              1111); // Average flow in ml/min

  // Set GPS sensor data
  gps.setData(48.858289, 2.294502,  // Latitude and longitude in degrees decimal (positive for N/E, negative for S/W)
              245.5,                // Altitude in m (can be negative)
              100.0,                // Speed in m/s
              90.23,                // Course over ground in degrees (0-359, 0 = north)
              14, 9, 14,            // Date (year - 2000, month, day)
              12, 00, 00);          // Time (hour, minute, second) - will be affected by timezone setings in your radio

  // Set RPM/temperature sensor data
  // (set number of blades to 2 in telemetry menu to get correct rpm value)
  rpm.setData(200,    // Rotations per minute
              25.6,   // Temperature #1 in degrees Celsuis (can be negative, will be rounded)
              -7.8);  // Temperature #2 in degrees Celsuis (can be negative, will be rounded)

  // Set SP2UART sensor data
  // (values from 0.0 to 3.3 are accepted)
  sp2uart.setData(1.5,   // ADC3 voltage in volts
                  3.3);  // ADC4 voltage in volts

  // Set variometer data
  // (set Variometer source to VSpd in menu to use the vertical speed data from this sensor for variometer).
  vario.setData(250.5,  // Altitude in meters (can be negative)
                -1.5);  // Vertical speed in m/s (positive - up, negative - down)

#ifdef POLLING_ENABLED
  // Set receiver data to be sent in case the polling is enabled (so no actual receiver is used)
  telemetry.setData(90,    // RSSI value (0-100, 0 = no telemetry, 100 = full signal)
                    4.9);  // RxBatt (voltage supplied to the receiver) value in volts (0.0-13.2)
#endif

  // Send the telemetry data, note that the data will only be sent for sensors
  // that are being polled at given moment
  telemetry.send();
}

I use the Teensy core 1.57.3 and not the last 1.59.0 because I have some issues with the library TeensyVariablePlayBack 1.0.16, TeensyVariablePlayBack 1.1 and Core 1.59.0 crash my Teensy 4.0.

Thanks for your help,

Pierre
 
Hello, I have tried to compile with options Serial, Dual and Triple but Serial4 don't accept to send my telemetry.
Need help please.
 
compile with options Serial, Dual and Triple
Those options apply only to the USB interfaces presented, nothing to do with UART Serial# ports.

Serial# pins are hardcoded to default pins and unless moved to ALT (grey on PJRC card) they present on the indicated default pins and must have no other use withing the code.

SoftwareSerial is shown as being used - that changes from the hardware supported serial and ideally is best avoided, not ever used here - Paulhas made various notes on its usage, not sure any notes apply to specific use case though.
 
I see possible use of SoftwareSerial in this program, but it depends on whether TEENSY_HW is defined.

As a first quick check, try adding a syntax error inside this:

Code:
#if !defined(TEENSY_HW)
#include "SoftwareSerial.h"
#endif

If you get no error, please just delete all this stuff about SoftwareSerial. If you do get an error, then maybe we're looking at a SoftwareSerial problem... maybe it has an issue with the pin numbers on MicroMod? But before anyone wastes time speculation, please do this quick check so we can know which part of that example code you're actually using.
 
Like that ?
Code:
#if !defined(TEENSY_HW)
#include "SoftwareSerial.h"
#else
#error "An error is find !"
#endif

If I compile for an Uno, I haven't error.
If I compile for my teensy, I have well my message error.
 
Yes, with Teensy that message would appear.
Removing the #else and #error - does it compile and work?
If there are requirements for SoftwareSerial it will present messages from those areas.
 
SofwareSerial, is only used by avr cpu which don't have hardware serial port.
This code compile very well but don't work if I use SERIAL_1 or something like SERIAL_4. But it work very well with SERIAL_1 and SERIAL_3.
 
That I don't understand is why Serial1 et Serial3 accept to work with this lib and not Serial2 and Serial4.
 
Maybe it has something to do with the fact that the actual LPUART hardware used for Serial2 and Serial4 are swapped on MicroMod compared to regular Teensy 4.0 and Teensy 4.1?

For background material, look at page 2915 in the annotated IMXRT1062 reference manual.

I tried briefly looking at the library code, specifically FrSkySportSingleWireSerial.cpp at line 47, but it seems to be using the MicroMod registers. Is there any chance you're using the core library built for Teensy 4.0 or Teensy 4.1 rather than MicroMod? Seems extremely unlikely with Arduino IDE, but if you're using other software like PlatformIO which is highly configurable... well, we hear problems all the time where things don't work on PlatformIO because configuration was wrong.

Must admit, I'm just blind guessing about the cause of the problem. But you did ask "why Serial1 et Serial3 accept to work with this lib and not Serial2 and Serial4" and the only at least partial explanation I can offer is the LPUART ports actually used for Serial2 and Serial4 are swapped on MicroMod as you can see documented on page 2915. So my blind guess is perhaps when you try to use Serial2, perhaps some part of the libraries you're using are accessing LPUART3 and other parts are accessing LPUART4.
 
Thanks for your explanations, I use Arduino 2.3.4 withe core 1.57.3.
I have tried the 1.59.0 with the same result.
I keep the 1.57.3 version with TeensyVariablePlayBack 1.0.16. Teensy 1.59 and TeensVariablePlayBack 1.1 crash my Teensy.
 
If I understand well serial2 and 4 are swapped. So if I connect something on serial4, I must define a serial2 object?
 
Normally you would just use Serial2 or Serial4 and the pins as documented for MicroMod. Simple stuff.

But if you use both Serial2 / Serial4 code from the core library and also add other code which directly accesses LPUART hardware registers, you need to be careful to make them match. I looked only briefly at FrSkySportSingleWireSerial.cpp and it seems to match for MicroMod (but would definitely be wrong for use with regular Teensy 4.0 or Teensy 4.1).

You also need to physically connect to the correct pin. Maybe this problem could be as "simple" as just connecting wires to wrong pin on MicroMod for Serial2?
 
I looked only briefly at FrSkySportSingleWireSerial.cpp and it seems to match for MicroMod (but would definitely be wrong for use with regular Teensy 4.0 or Teensy 4.1).
Could be wrong, but after having a very quick look into Teensyduino code, I'm afraid it also has the LPUART registers swapped for Serial 2 and 4.

See here for HardwareSerial2.cpp

and here for HardwareSerial4.cpp

Looks to me that there should be an #ifdef rather than #ifndef when checking for presence of ARDUINO_TEENSY_MICROMOD
 
Hi pawelsky,

If I understand well, I just need to change #ifndef by #ifdef into HardwareSerial2.cpp and HardwareSerial4.cpp ?
 
Hi pawelsky,

If I understand well, I just need to change #ifndef by #ifdef into HardwareSerial2.cpp and HardwareSerial4.cpp ?
Rather than changing the core files try using Serial 2 instead of Serial 4 in your code (and vice vera) but keep the physical connections unchanged.

Also use the latest version of the FrskySportTelemetry library, the one you linked to on someone's github is outdated.
 
I have already tried to use Serial2 as define and have used hardware Serial4 connection without success.
For now, I use Serial3 with sucess.
 
After another look the HW Serial inits in the core seem to be OK, but the annotations in the reference manual seems to be swapped.

@PaulStoffregen this seems mixed up compared to the code
1743703360117.png
 
Back
Top