Reading Gibberish from Serial2 on Serial

I am trying to read data from Serial2 on Serial and I’m only getting nonsense. I am reading an SHT-30 Humidy sensor from an Adafruit Feather nRF52840 Sense with an Adafruit Feather M0 RFM96 LoRa Radio - 433MHz. I am trying to write it to Serial2 and then read it from Serial to learn how to use multiple Serial ports on one MCU.

#include <Arduino.h>   // required before wiring_private.h
#include "wiring_private.h" // pinPeripheral() function
#include <Wire.h>
#include <Adafruit_SHT31.h>
#include "avr/dtostrf.h"

Adafruit_SHT31 sht30;  // humidity

Uart Serial2 (&sercom2, 3, 4, SERCOM_RX_PAD_1, UART_TX_PAD_0);
void SERCOM2_Handler()
{
  Serial2.IrqHandler();
}
 
void setup() {
  sht30.begin(); 
  
  Serial.begin(115200);
  Serial2.begin(115200);
  
  // Assign pins 3 & 4 SERCOM functionality
  pinPeripheral(3, PIO_SERCOM_ALT);
  pinPeripheral(4, PIO_SERCOM_ALT);
}

float incomingByte = 0;

void loop() {

  char c[1] = {};
  dtostrf(sht30.readHumidity(), 5, 2, c);
  Serial2.write(c);
  incomingByte = Serial2.read();
  Serial.println(incomingByte);
  Serial.println("Regular Serial Print");
  Serial.println(sht30.readHumidity());
  delay(500);
}

Serial Monitor Output
12:15:18.457 → -1.00
12:15:18.457 → Regular Serial Print
12:15:18.504 → 46.80
12:15:19.018 → -1.00
12:15:19.018 → Regular Serial Print
12:15:19.018 → 46.77

It’s only reading “-1.00” from the Serial2 but reading accurately on Serial. I followed the tutorial for making a second Serial port for my MCU but I still can’t get reads from Serial2. I’m assuming there is some formatting error but I haven’t found it yet. I want it to read the same on Serial and Serial2. My end goal is to have a GPS module on Serial2 but I am starting with the humidity sensor since its easier to work with and gives me data faster.

The GPS is probably easier to work with, it will be producing serial ‘data’ all the time indoors or out, no library needed, that you can copy from the GPS (Serial2) to the IDE monitor (Serial).

I’m not clear from your description; have you got Serial 2 looped and want to read back what you send to it?
You are not giving any time for the data to be sent then received and you are not checking to see if there is any data to read.

Try this tutorial: Serial Input Basics - updated

You’re right I should just use the GPS. However I’ve tried a couple different ways and Serial2 is still giving nonsense.

#include <Arduino.h>   // required before wiring_private.h
#include "wiring_private.h" // pinPeripheral() function
#include <Wire.h>
#include <Adafruit_SHT31.h>
#include "avr/dtostrf.h"
#include <Adafruit_GPS.h>
#define GPSECHO false

Adafruit_SHT31 sht30;  // humidity

Uart Serial2 (&sercom2, 3, 4, SERCOM_RX_PAD_1, UART_TX_PAD_0);
void SERCOM2_Handler()
{
  Serial2.IrqHandler();
}

#define GPSSerial Serial2
Adafruit_GPS GPS(&GPSSerial);
 
void setup() {
  sht30.begin(); 
  
  Serial.begin(115200);
  Serial2.begin(9600);
  GPS.begin(9600);
  GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
  GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ); // 1 Hz update rate
  delay(1000);
  GPSSerial.println(PMTK_Q_RELEASE);
  
  // Assign pins 3 & 4 SERCOM functionality
  pinPeripheral(3, PIO_SERCOM_ALT);
  pinPeripheral(4, PIO_SERCOM_ALT);
}

float incomingByte = 0;

void loop() {

  char c = GPS.read();
  if (GPS.newNMEAreceived()) {
    Serial.println(GPS.lastNMEA()); // this also sets the newNMEAreceived() flag to false
    if (!GPS.parse(GPS.lastNMEA())) // this also sets the newNMEAreceived() flag to false
      return; // we can fail to parse a sentence in which case we should just wait for another
  }
  if (GPS.fix) {
    Serial.print(GPS.latitude, 4); Serial.print(GPS.lat);
    Serial.print(", ");
    Serial.print(GPS.longitude, 4); Serial.println(GPS.lon);
    Serial.print(GPS.speed); Serial.println("kn");
    Serial.print(GPS.altitude); Serial.println("m");
  }  

  //char Lat[1] = {};
  //dtostrf(GPS.latitude, 9, 4, Lat);
  Serial2.write(GPS.latitude);
  Serial.println(Serial2.read());
  Serial.println("Regular Serial Print");
  Serial.println(GPS.latitude);
  delay(1000);
}

Serial Monitor
13:02:36.081 → ⸮
13:02:36.081 → Regular Serial Print
13:02:36.081 → 0.00
13:02:37.067 → ⸮
13:02:37.067 → Regular Serial Print
13:02:37.067 → 0.00

Perry I have Serial2 in my main voidloop if thats what you mean. I would like to read back what I send to it. Whenever I use something like “while (Serial2.available() > 0) {” a Serial print of a Serial2 read never shows up. So I’m assuming Serial2 is never available.

Well I’m still not sure if I have understood what you are doing, do you have Tx connected to Rx? If not then please clarify.

What board are you using? Does it even have 3 serial ports?

Adafruit Feather M0 RFM96 LoRa Radio - 433MHz

It has multiple SERCOM ports as per this tutorial. I have everything connected with this so the pins are all connected accordingly.

Then I don’t know, I’ll leave it for someone else. Good luck!

So do that, do not add extra libraries and stuff and attempt to use the serial data from the GPS to decode position data, not yet.

Just copy the GPS data to the serial monitor as I suggested, what does the data look like in the IDE serial monitor ?

#include <Arduino.h>   // required before wiring_private.h
#include "wiring_private.h" // pinPeripheral() function
#include "avr/dtostrf.h"
#include <Adafruit_GPS.h>
#define GPSECHO false


Uart Serial2 (&sercom2, 3, 4, SERCOM_RX_PAD_1, UART_TX_PAD_0);
void SERCOM2_Handler()
{
  Serial2.IrqHandler();
}

#define GPSSerial Serial2
Adafruit_GPS GPS(&GPSSerial);
 
void setup() {
  Serial.begin(115200);
  Serial2.begin(9600);
  GPS.begin(9600);
  GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
  GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ); // 1 Hz update rate
  delay(1000);
  GPSSerial.println(PMTK_Q_RELEASE);
  
  // Assign pins 3 & 4 SERCOM functionality
  pinPeripheral(3, PIO_SERCOM_ALT);
  pinPeripheral(4, PIO_SERCOM_ALT);
}

float incomingByte = 0;

void loop() {

  char c = GPS.read();
  if (GPS.newNMEAreceived()) {
    Serial.println(GPS.lastNMEA()); // this also sets the newNMEAreceived() flag to false
    if (!GPS.parse(GPS.lastNMEA())) // this also sets the newNMEAreceived() flag to false
      return; // we can fail to parse a sentence in which case we should just wait for another
  }
  if (GPS.fix) {
    Serial.print(GPS.latitude, 4); Serial.print(GPS.lat);
    Serial.print(", ");
    Serial.print(GPS.longitude, 4); Serial.println(GPS.lon);
    Serial.print(GPS.speed); Serial.println("kn");
    Serial.print(GPS.altitude); Serial.println("m");
  }  

  //char Lat[1] = {};
  //dtostrf(GPS.latitude, 9, 4, Lat);
  Serial2.write(GPS.latitude);
  Serial.println(char(Serial2.read()));
  Serial.println("Regular Serial Print");
  Serial.println(GPS.latitude);
  delay(1000);
}

I got rid of the humidity sensor code and am writing GPS data to Serial2 and the Serial Monitor gives this

13:41:57.164 → ⸮
13:41:57.164 → Regular Serial Print
13:41:57.164 → 0.00
13:41:58.147 → ⸮
13:41:58.147 → Regular Serial Print
13:41:58.147 → 0.00

GPSs do not send out data like that on their serial ports.

What do you mean by that? Do you mean all zeros? My gps module sends all zeros for all data points until it gets a fix. Or do you mean something else?

No it does not.

The GPS actually sends out NMEA sentences, that even indoors will look something like this;

$GPGSV,1,1,01,03,,,19*73
$GPGLL,,,,,,V,N*64
$GPRMC,,V,,,,,,,,,,N*53
$GPVTG,,,,,,,,,N*30
$GPGGA,,,,,,0,00,99.99,,,,,,*48
$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30

If your GPS, or how you have setup the serial ports, is broken and you then feed that broken output into a GPS library, then that libray might well report ‘all zeros’.

Ah you’re right, I remember that from when I was first trying to set this up. Either way, at this point I would be happy with a 0.00 instead of the backwards question mark. I’m mostly looking to get the same thing on Serial2 as Serial. Even if the data is inaccurate, as long as they are the same, I will know how to format it correctly and move on.

Once you have setup the Serial ports, allocated the pins etc, all the code you need to see if the GPS can indeed be read and the Serial ports are working is this;

while (Serial2.available())
  {
    Serial.write(Serial2.read());
  }

According to the Adafruit GPS thing you linked, you need to physically cut the Tx and Rx pins on the GPS. You are probably also getting cryptic symbols on serial monitor because you’re not reading it as numbers. You have “char” on the serial print.

You need to serial.print Serial2.read(), DEC or HEX or something like that so you get numbers.

cheers