I am trying to capture GPS NMEA sentences from two devices connected at two different SoftwareSerial ports.
The sketch is adapted from TinyGPS++ Custom Fields for a single GPS.
It works fine if one of instances of capture is commented but does not work at all if both instances are enabled.
Could someone point to me what I shoud do to could encode from both ports , one followed by the other ?
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
// The TinyGPS++ object
TinyGPSPlus gps;
// The serial connection to the GPS device
SoftwareSerial ss(2, 3); // GPS PINS RX TX
SoftwareSerial ss2(8, 9);// GPS PINS RX TX
TinyGPSCustom A(gps, "GNRMC", 3); // $GNRMC sentence, 3th element Latitude
TinyGPSCustom B(gps, "GNRMC", 4); // $GNRMC sentence, 4th element N /S
TinyGPSCustom C(gps, "GNRMC", 5); // $GNRMC sentence, 5th element Longitude
TinyGPSCustom D(gps, "GNRMC", 6); // $GNRMC sentence, 6th element W/ E
void setup()
{
Serial.begin(115200);
ss.begin(9600);
ss2.begin (9600);
Serial.println(F("UsingCustomFields.ino"));
Serial.println();
}
void loop()
{
////////////////GPS ONE
ss.begin(9600);
ss.listen();
while (ss.available() > 0)
gps.encode(ss.read());
if (A.isUpdated() || B.isUpdated() ||
C.isUpdated() || D.isUpdated())
{
Serial.print(F("A=")); Serial.print(A.value());
Serial.print(F(" ")); Serial.println(B.value());
Serial.print(F("C=")); Serial.print(C.value());
Serial.print(F(" ")); Serial.println (D.value());
Serial.println();
}
/////////////// GPS TWO
//ss2.begin(9600);
//ss2.listen();
//while (ss2.available() > 0)
// gps.encode(ss2.read());
//
// if (A.isUpdated() || B.isUpdated() ||
// C.isUpdated() || D.isUpdated())
// {
// Serial.print(F("A1=")); Serial.print(A.value());
// Serial.print(F(" ")); Serial.println(B.value());
// Serial.print(F("C1=")); Serial.print(C.value());
// Serial.print(F(" ")); Serial.println (D.value());
// Serial.println();
//
// }
}
Indeed using two instances of software serial is not a good idea, you ought to be able to make it work, but it never seems to be reliable in my experience.
In any case the logic of your code is flawed.
You turn on software serial for one GPS and before a character can arrive you check if one has (it wont have) and then move onto the next GPS.
I understand that GPS output of each GPS may be at the same time (about 1Hz each). No problem if I capture the GPS outputs interleaved. 1,2,1,2,.. at 0.5Hz each...
The sentences of my example are the same, but the main problem is how switch the input ports after each capture with TinYGPS++
I have tryed with two objects but still not working.
Had also ended the serial instance with ss.end(); before switch to other GPS but also not work.
The code works if any of GPS sections are commented.
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
// The TinyGPS++ object
TinyGPSPlus gps;
TinyGPSPlus gps2;
// The serial connection to the GPS device
SoftwareSerial ss(2, 3); // GPS PINS RX TX
SoftwareSerial ss2(8, 9);// GPS PINS RX TX
TinyGPSCustom A(gps, "GNRMC", 3); // $GNRMC sentence, 3th element Latitude
TinyGPSCustom B(gps, "GNRMC", 4); // $GNRMC sentence, 4th element N /S
TinyGPSCustom C(gps, "GNRMC", 5); // $GNRMC sentence, 5th element Longitude
TinyGPSCustom D(gps, "GNRMC", 6); // $GNRMC sentence, 6th element W/ E
TinyGPSCustom E1(gps2, "GNRMC", 3); // $GNRMC sentence, 3th element Latitude
TinyGPSCustom F1(gps2, "GNRMC", 4); // $GNRMC sentence, 4th element N /S
TinyGPSCustom G1(gps2, "GNRMC", 5); // $GNRMC sentence, 5th element Longitude
TinyGPSCustom H1(gps2, "GNRMC", 6); // $GNRMC sentence, 6th element W/ E
void setup()
{
Serial.begin(115200);
ss.begin(9600);
ss2.begin (9600);
Serial.println(F("UsingCustomFields.ino"));
Serial.println();
}
void loop()
{
////////////////GPS ONE
//ss.begin(9600);
ss.listen();
while (ss.available() > 0)
gps.encode(ss.read());
if (A.isUpdated() || B.isUpdated() ||
C.isUpdated() || D.isUpdated())
{
Serial.print(F("A=")); Serial.print(A.value());
Serial.print(F(" ")); Serial.println(B.value());
Serial.print(F("C=")); Serial.print(C.value());
Serial.print(F(" ")); Serial.println (D.value());
Serial.println();
ss.end();
}
/////////////// GPS TWO
//ss2.begin(9600);
ss2.listen();
while (ss2.available() > 0)
gps2.encode(ss2.read());
if (E1.isUpdated() || F1.isUpdated() ||
G1.isUpdated() || H1.isUpdated())
{
Serial.print(F("A1=")); Serial.print(E1.value());
Serial.print(F(" ")); Serial.println(F1.value());
Serial.print(F("C1=")); Serial.print(G1.value());
Serial.print(F(" ")); Serial.println (H1.value());
Serial.println();
ss2.end();
}
}
acjacques:
The project is read custom NMEA style sentences from 2 different devices. Hw may be the Uno or Nano (328p)
Uno or Nano is a very poor choice. Myself I would not even consider it.
It might work if you could arrange to have one GPS on the hardware serial port normally used for the Serial Monitor and program upload and the other GPS on a single software instance. But that setup would make debugging a chalenge.
A bare bones ATmega1284P would work, that has two hardware serial ports and you could run a software serial instance at tha same time, so two GPSs and the serial monitor.
The problem should be not solved by changing the hardware. By this aproach I could easily add an analog swicth like CD4053 SPDT and redirect the input to wanted GPS device.
But this is not the case.
I can't understand why it is not possible in the same program to change the input pin.
Can't you close one object and start another on another input pin?
There has to be a way to do this.
acjacques:
I can't understand why it is not possible in the same program to change the input pin.
Can't you close one object and start another on another input pin?
There has to be a way to do this.
You can switch between pins but it could introduce what would be significant delays between reading each GPSs.
With the actual project not revealed, I guess the volunteers that provide help in this forum dont want to waste their time suggesting stuff that may innapropriate.