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");
}
}
seems you walked that path already 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.
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.