displayInfo() is probably causing a stand still with 2x GPS

Hello! Can somebody point me in the right direction please?

I copy-pasted and multiplied some code from the internet, with the idea that I can read/compare two GPS signals. I learned along the way that there can be only one Serial, but can overcome this by using Softwareserial. I understand that Arduino can only read one serial at a time.

My code runs for 5 data acquisitions and then says 'No GPS connected'... I think displayInfo() is the culprit but I can't figure out why it stops running my code.

The goal is to compare local GPS coordinates (Where I stand) with GPS signals transmitted to me via a RS485 433Mhz radio. (This works quite well actually, already tried) >> Simply connect TxRx of the GPS to the TXRx of the radio and voila, wireless GPS. https://nl.aliexpress.com/item/32382673340.html

#include <TinyGPS++.h>
#include <SoftwareSerial.h>

TinyGPSPlus gps1;
TinyGPSPlus gps2;

SoftwareSerial gpsSerial1(10, 11);
SoftwareSerial gpsSerial2(8, 9);

void setup() {

  // Open serial communications and wait for port to open:

  Serial.begin(9600);

  while (!Serial) {

    ;
  }
  // Start each software serial port

  gpsSerial1.begin(9600);
  gpsSerial2.begin(9600);
}

void loop() {

  gpsSerial1.listen();

  while (gpsSerial1.available() > 0)
    if (gps1.encode(gpsSerial1.read()))
      displayInfo1();

  // If 5000 milliseconds pass and there are no characters coming in
  // over the software serial port, show a "No GPS detected" error
  if (millis() > 5000 && gps1.charsProcessed() < 10)
  {
    Serial.println("No GPS detected");
    while (true);
  }
}

void displayInfo1()
{
  if (gps1.location.isValid())
  {
    Serial.print("Latitude: ");
    Serial.println(gps1.location.lat(), 6);
    Serial.print("Longitude: ");
    Serial.println(gps1.location.lng(), 6);
    Serial.print("Altitude: ");
    Serial.println(gps1.altitude.meters());
  }
  else
  {
    Serial.println("Location: Not Available");
  }

  {
    Serial.println();
    delay(1000);
  }

  gpsSerial2.listen();

  while (gpsSerial2.available() > 0)
    if (gps2.encode(gpsSerial2.read()))
      displayInfo2();

  // If 5000 milliseconds pass and there are no characters coming in
  // over the software serial port, show a "No GPS detected" error
  if (millis() > 5000 && gps2.charsProcessed() < 10)
  {
    Serial.println("No GPS detected");
    while (true);
  }
}

void displayInfo2()
{
  if (gps2.location.isValid())
  {
    Serial.print("Latitude: ");
    Serial.println(gps2.location.lat(), 6);
    Serial.print("Longitude: ");
    Serial.println(gps2.location.lng(), 6);
    Serial.print("Altitude: ");
    Serial.println(gps2.altitude.meters());
  }
  else
  {
    Serial.println("Location: Not Available");
  }

  {
    Serial.println();
    delay(1000);
  }
}

your 2 GPS will talk all the time, it's going to be a rough ride with SoftwareSerial. Can't you get a board with multiple hardware Serial lines like the Mega (or Mega Mini if physical dimensions are an issue)

if you stick to your approach, look at the example with 2 ports. listen for both signals in the loop (one after another, possibly only get 1 byte out of the buffer to avoid the other getting stuck) and once one of the GPS is ready with data, then handle it. The handling part needs to be short so that you can come back to listening quickly

Try this. It switches between inputs each time a full message is received. Switching in the middle of a message is likely to lose characters in each messsage.

#include <TinyGPS++.h>
#include <SoftwareSerial.h>

TinyGPSPlus gps1;
TinyGPSPlus gps2;

SoftwareSerial gpsSerial1(10, 11);
SoftwareSerial gpsSerial2(8, 9);

int WhichInput = 1;
unsigned long LastReceiveTime = 0;

void setup()
{
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {}

  // Start each software serial port
  gpsSerial1.begin(9600);
  gpsSerial2.begin(9600);

  // SoftwareSerial can only listen to one port at a time so
  // we alternate between the two.
  WhichInput = 1;
  gpsSerial1.listen();
}

void loop()
{
  // Check for failure to receive.
  if (millis() - LastReceiveTime > 5000)
  {
    Serial.println("Error: No input for 5 seconds.");
    while(true){}
  }
  
  switch (WhichInput)
  {
    case 1:
      if (gpsSerial1.available() > 0)
      {
        LastReceiveTime = millis();
        if (gps1.encode(gpsSerial1.read()))
        {
          // Received a complete message
          displayInfo1();
          gpsSerial2.listen();
          WhichInput = 2;
        }
      }
      break;

    case 2:
      if (gpsSerial2.available() > 0)
      {
        LastReceiveTime = millis();
        if (gps2.encode(gpsSerial2.read()))
        {
          // Received a complete message
          displayInfo2();
          gpsSerial1.listen();
          WhichInput = 1;
        }
      }
      break;
      
  } // end switch
}

void displayInfo1()
{
  if (gps1.location.isValid())
  {
    Serial.print("GPS-1 Latitude: ");
    Serial.println(gps1.location.lat(), 6);
    Serial.print("GPS-1 Longitude: ");
    Serial.println(gps1.location.lng(), 6);
    Serial.print("GPS-1 Altitude: ");
    Serial.println(gps1.altitude.meters());
  }
  else
  {
    Serial.println("GPS-1 Location: Not Available");
  }
}

void displayInfo2()
{
  if (gps2.location.isValid())
  {
    Serial.print("GPS-2 Latitude: ");
    Serial.println(gps2.location.lat(), 6);
    Serial.print("GPS-2 Longitude: ");
    Serial.println(gps2.location.lng(), 6);
    Serial.print("GPS-2 Altitude: ");
    Serial.println(gps2.altitude.meters());
  }
  else
  {
    Serial.println("GPS-2 Location: Not Available");
  }
}

yeah possibly but if the bytes come in at 9600 bauds it's worth trying, isn't it? the switching time should not be that bad

I don't think it will work well but I encourage you to write a sketch that works that way so the OP can try both.

seems you walked that path already :wink: and I can see where it can fail indeed

the challenge with you approach is that you'll be missing some communications but hopefully if it's only GPS positions every second the next one won't be too far away from the one you missed

My apologies to all for not replying earlier, i got busy with work.

@johnwasser ,Thank you for the code! I'll try it a.s.a.p

@J-M-L, I had no idea such Mega Mini existed. I'll look into it! Might be perfect! I also pondered an ESP32 but that might be a bridge too far from me at this point.

ESP32 would work too - with plenty of memory to play with. It’s a different architecture but the same principles apply.

Although the Mega / MegaPro has the required hardware serial ports, you can also consider an Arduino Micro or SparkFun ProMicro if size is important.

USB for communication with PC (Serial), one HardwareSerial (Serial1) and the 3rd port can be SoftwareSerial.

Disclaimer: I don't know anything about GPS.

Your code works amazingly well on my UNO! I can work towards my end goal with this. THANK YOU.

@sterretje: I have an bona fide Mega 2560 but no succes yet to get anything* working on it. But the code Johnwasser provided is a very good push in the right direction.

i suspect the 3.3V rail not working. Edit And... pin 10, 11 are also shot it seems. I got it for free, but... I now can guess why.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.