Hi there,
I got them Both going on the C3, edited the example to add a column for which GPS is sending data , based on Age as Priority GPS-1 or GPS-2
10 1.0 26.041754 -80.220909 267 02/23/2025 10:34:16 769 5.50 0.00 0.00 N 7108 43.06 NE 16160 490 1 GPS 2
10 1.0 26.041754 -80.220909 268 02/23/2025 10:34:17 768 5.50 0.00 0.00 N 7108 43.06 NE 16227 492 1 GPS 2
10 1.0 26.041754 -80.220909 275 02/23/2025 10:34:18 774 5.50 0.00 0.00 N 7108 43.06 NE 16293 494 1 GPS 2
10 1.0 26.041754 -80.220909 276 02/23/2025 10:34:19 776 5.50 0.00 0.00 N 7108 43.06 NE 16360 496 1 GPS 2
10 1.0 26.041754 -80.220909 283 02/23/2025 10:34:20 782 5.50 0.00 0.00 N 7108 43.06 NE 16426 498 1 GPS 2
10 1.0 26.041754 -80.220909 284 02/23/2025 10:34:21 785 5.50 0.00 0.00 N 7108 43.06 NE 16493 500 1 GPS 2
10 1.0 26.041754 -80.220909 289 02/23/2025 10:34:22 790 5.50 0.00 0.00 N 7108 43.06 NE 16559 502 1 GPS 2
7 1.3 26.041683 -80.220894 290 02/23/2025 10:34:23 835 27.80 150.56 0.52 SSE 7108 43.06 NE 14595 321 1 GPS 1
10 1.0 26.041754 -80.220909 296 02/23/2025 10:34:24 796 5.50 0.00 0.00 N 7108 43.06 NE 16692 506 1 GPS 2
10 1.0 26.041754 -80.220909 297 02/23/2025 10:34:25 797 5.50 0.00 0.00 N 7108 43.06 NE 16758 508 1 GPS 2
10 1.0 26.041754 -80.220909 299 02/23/2025 10:34:26 803 5.50 0.00 0.00 N 7108 43.06 NE 16825 510 1 GPS 2
10 1.0 26.041754 -80.220909 299 02/23/2025 10:34:27 800 5.50 0.00 0.00 N 7108 43.06 NE 16891 512 1 GPS 2
10 1.0 26.041754 -80.220909 311 02/23/2025 10:34:28 805 5.40 0.00 0.00 N 7108 43.06 NE 16958 514 1 GPS 2
10 1.0 26.041754 -80.220909 312 02/23/2025 10:34:29 813 5.40 0.00 0.00 N 7108 43.06 NE 17024 516 1 GPS 2
10 1.0 26.041754 -80.220909 317 02/23/2025 10:34:30 818 5.40 0.00 0.00 N 7108 43.06 NE 17091 518 1 GPS 2
7 1.3 26.041712 -80.220924 318 02/23/2025 10:34:31 870 27.70 150.56 0.00 SSE 7108 43.06 NE 15098 337 1 GPS 1
7 1.3 26.041712 -80.22092
Scroll over to the Right most edge…
Hardware Serial on one port and Software Serial on the other. You can swap them too. AFAIK.
#include <TinyGPSPlus.h>
#include <SoftwareSerial.h>
#include <HardwareSerial.h>
// ------------------ GPS Configurations ------------------
// For GPS 1 (HardwareSerial on UART1)
const int gps1RXPin = 9; // Connect GPS1 TX to ESP32 RX (pin 7)
const int gps1TXPin = 10; // Connect GPS1 RX to ESP32 TX (pin 6)
const uint32_t gps1Baud = 9600;
// For GPS 2 (SoftwareSerial)
const int gps2RXPin = D7; // Connect GPS2 TX to ESP32 RX (pin 9)
const int gps2TXPin = D6; // Connect GPS2 RX to ESP32 TX (pin 10)
const uint32_t gps2Baud = 9600;
// ------------------ Objects ------------------
TinyGPSPlus gps1; // For HardwareSerial GPS
TinyGPSPlus gps2; // For SoftwareSerial GPS
// Use UART1 for GPS 1:
HardwareSerial SerialGPS1(1);
// Use SoftwareSerial for GPS 2:
SoftwareSerial SerialGPS2(gps2RXPin, gps2TXPin); // (RX, TX)
// ------------------ Function Prototypes ------------------
static void smartDelay(unsigned long ms);
static void printFloat(float val, bool valid, int len, int prec);
static void printInt(unsigned long val, bool valid, int len);
static void printDateTime(TinyGPSDate &d, TinyGPSTime &t);
static void printStr(const char *str, int len);
static void printGPSSource();
void setup() {
Serial.begin(9600);
delay(2000);
Serial.println("\nFullExample.ino");
Serial.println("An extensive example of many interesting TinyGPSPlus features");
Serial.print("Testing TinyGPSPlus library v. ");
Serial.println(TinyGPSPlus::libraryVersion());
Serial.println("by Mikal Hart, tweaked for 2 GPS by PJG");
Serial.println();
Serial.println("Sats HDOP Latitude Longitude Fix Date Time Date Alt Course Speed Card Distance Course Card Chars Sentences Checksum GPS");
Serial.println(" (deg) (deg) Age Age (m) --- from GPS ---- ---- to London ---- RX RX Fail");
Serial.println("----------------------------------------------------------------------------------------------------------------------------------------");
// Initialize GPS 1 (HardwareSerial) on UART1 with assigned pins.
SerialGPS1.begin(gps1Baud, SERIAL_8N1, gps1RXPin, gps1TXPin);
Serial.println("GPS-1 HardwareSerial initialized on pins 6 (RX) and 7 (TX).");
// Initialize GPS 2 (SoftwareSerial) on pins 9 & 10.
SerialGPS2.begin(gps2Baud);
Serial.println("GPS-2 SoftwareSerial initialized on pins 9 (RX) and 10 (TX).");
Serial.println();
}
void loop() {
// Process incoming GPS data for both GPS units.
// For GPS1 via HardwareSerial:
while (SerialGPS1.available() > 0) {
char c = SerialGPS1.read();
gps1.encode(c);
}
// For GPS2 via SoftwareSerial:
while (SerialGPS2.available() > 0) {
char c = SerialGPS2.read();
gps2.encode(c);
}
// Define a reference location (London in this example).
static const double LONDON_LAT = 51.508131, LONDON_LON = -0.128002;
// We'll decide which GPS to display.
// Priority: If one has valid location and the other doesn't, choose the valid one.
// If both are valid, choose the one with a lower "age" (i.e. more recent fix).
bool valid1 = gps1.location.isValid();
bool valid2 = gps2.location.isValid();
TinyGPSPlus *activeGps = nullptr;
if(valid1 && !valid2) {
activeGps = &gps1;
} else if(valid2 && !valid1) {
activeGps = &gps2;
} else if(valid1 && valid2) {
activeGps = (gps1.location.age() <= gps2.location.age()) ? &gps1 : &gps2;
} else {
activeGps = &gps1; // default to gps1 if none valid
}
// Print output using the active GPS data:
printInt(activeGps->satellites.value(), activeGps->satellites.isValid(), 5);
printFloat(activeGps->hdop.hdop(), activeGps->hdop.isValid(), 6, 1);
printFloat(activeGps->location.lat(), activeGps->location.isValid(), 11, 6);
printFloat(activeGps->location.lng(), activeGps->location.isValid(), 12, 6);
printInt(activeGps->location.age(), activeGps->location.isValid(), 5);
printDateTime(activeGps->date, activeGps->time);
printFloat(activeGps->altitude.meters(), activeGps->altitude.isValid(), 7, 2);
printFloat(activeGps->course.deg(), activeGps->course.isValid(), 7, 2);
printFloat(activeGps->speed.kmph(), activeGps->speed.isValid(), 6, 2);
printStr(activeGps->course.isValid() ? TinyGPSPlus::cardinal(activeGps->course.deg()) : "*** ", 6);
unsigned long distanceKmToLondon = (unsigned long)TinyGPSPlus::distanceBetween(
activeGps->location.lat(),
activeGps->location.lng(),
LONDON_LAT, LONDON_LON) / 1000;
printInt(distanceKmToLondon, activeGps->location.isValid(), 9);
double courseToLondon = TinyGPSPlus::courseTo(
activeGps->location.lat(),
activeGps->location.lng(),
LONDON_LAT, LONDON_LON);
printFloat(courseToLondon, activeGps->location.isValid(), 7, 2);
const char *cardinalToLondon = TinyGPSPlus::cardinal(courseToLondon);
printStr(activeGps->location.isValid() ? cardinalToLondon : "*** ", 6);
printInt(activeGps->charsProcessed(), true, 6);
printInt(activeGps->sentencesWithFix(), true, 10);
printInt(activeGps->failedChecksum(), true, 9);
// Print additional column indicating source: "GPS 1" or "GPS 2".
Serial.print(" ");
if(activeGps == &gps1) {
Serial.print("GPS 1");
} else {
Serial.print("GPS 2");
}
Serial.println();
smartDelay(1000);
if (millis() > 5000 && activeGps->charsProcessed() < 10)
Serial.println(F("No GPS data received: check wiring"));
}
// Modified smartDelay() that feeds both GPS streams.
static void smartDelay(unsigned long ms) {
unsigned long start = millis();
do {
while (SerialGPS1.available() > 0)
gps1.encode(SerialGPS1.read());
while (SerialGPS2.available() > 0)
gps2.encode(SerialGPS2.read());
} while (millis() - start < ms);
}
static void printFloat(float val, bool valid, int len, int prec) {
if (!valid) {
while (len-- > 1)
Serial.print('*');
Serial.print(' ');
} else {
Serial.print(val, prec);
int vi = abs((int)val);
int flen = prec + (val < 0.0 ? 2 : 1); // . and -
flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
for (int i = flen; i < len; ++i)
Serial.print(' ');
}
smartDelay(0);
}
static void printInt(unsigned long val, bool valid, int len) {
char sz[32] = "*****************";
if (valid)
sprintf(sz, "%ld", val);
sz[len] = 0;
for (int i = strlen(sz); i < len; ++i)
sz[i] = ' ';
if (len > 0)
sz[len - 1] = ' ';
Serial.print(sz);
smartDelay(0);
}
static void printDateTime(TinyGPSDate &d, TinyGPSTime &t) {
if (!d.isValid()) {
Serial.print(F("********** "));
} else {
char sz[32];
sprintf(sz, "%02d/%02d/%02d ", d.month(), d.day(), d.year());
Serial.print(sz);
}
if (!t.isValid()) {
Serial.print(F("******** "));
} else {
char sz[32];
sprintf(sz, "%02d:%02d:%02d ", t.hour(), t.minute(), t.second());
Serial.print(sz);
}
printInt(d.age(), d.isValid(), 5);
smartDelay(0);
}
static void printStr(const char *str, int len) {
int slen = strlen(str);
for (int i = 0; i < len; ++i)
Serial.print(i < slen ? str[i] : ' ');
smartDelay(0);
}
HTH
GL
PJ 
This morning ,Rocking a rolling 2 GPS 30+ sats or 15’ish each… LOL
18 0.6 26.041689 -80.220894 403 02/23/2025 15:42:48 769 -6.40 0.00 0.00 N 7108 43.06 NE 13985 37514 1 GPS 2
18 0.6 26.041689 -80.220894 418 02/23/2025 15:42:49 765 -6.30 0.00 0.00 N 7108 43.06 NE 13986 37516 1 GPS 2
18 0.6 26.041689 -80.220894 418 02/23/2025 15:42:50 775 -6.30 0.00 0.00 N 7108 43.06 NE 13987 37518 1 GPS 2
18 0.6 26.041689 -80.220894 426 02/23/2025 15:42:51 780 -6.30 0.00 0.00 N 7108 43.06 NE 13988 37520 1 GPS 2
17 0.6 26.041689 -80.220894 435 02/23/2025 15:42:52 784 -6.30 0.00 0.00 N 7108 43.06 NE 13989 37522 1 GPS 2
17 0.6 26.041689 -80.220894 440 02/23/2025 15:42:53 799 -6.20 0.00 0.00 N 7108 43.06 NE 13989 37524 1 GPS 2
16 0.6 26.041712 -80.220886 433 02/23/2025 15:42:54 799 0.30 241.83 0.00 WSW 7108 43.06 NE 13955 37343 1 GPS 1
17 0.6 26.041691 -80.220894 434 02/23/2025 15:42:55 801 -6.20 0.00 0.00 N 7108 43.06 NE 13991 37528 1 GPS 2
16 0.6 26.041712 -80.220886 443 02/23/2025 15:42:56 806 0.30 241.83 0.00 WSW 7108 43.06 NE 13956 37347 1 GPS 1
16 0.6 26.041691 -80.220894 452 02/23/2025 15:42:57 815 -6.20 0.00 0.00 N 7108 43.06 NE 13993 37532 1 GPS 2
16 0.6 26.041691 -80.220894 457 02/23/2025 15:42:58 814 -6.20 0.00 0.00 N 7108 43.06 NE 13993 37534 1 GPS 2
16 0.6 26.041691 -80.220894 462 02/23/2025 15:42:59 823 -6.20 0.00 0.00 N 7108 43.06 NE 13994 37536 1 GPS 2
15 0.7 26.041712 -80.220886 455 02/23/2025 15:43:00 819 0.20 241.83 0.00 WSW 7108 43.06 NE 13959 37355 1 GPS 1
16 0.6 26.041712 -80.220886 458 02/23/2025 15:43:01 814 0.30 241.83 0.00 WSW 7108 43.06 NE 13960 37357 1 GPS 1
16 0.6 26.041712 -80.220886 464 02/23/2025 15:43:02 810 0.30 241.83 0.00 WSW 7108 43.06 NE 13961 37359 1 GPS 1
16 0.6 26.041712 -80.220886 467 02/23/2025 15:43:03 821 0.30 241.83 0.00 WSW 7108 43.06 NE 13962 37361 1 GPS 1
16 0.6 26.041712 -80.220886 472 02/23/2025 15:43:04 820 0.30 241.83 0.00 WSW 7108 43.06 NE 13963 37363 1 GPS 1
16 0.6 26.041712 -80.220886 468 02/23/2025 15:43:05 829 0.30 241.83 0.00 WSW 7108 43.06 NE 13963 37365 1 GPS 1
16 0.6 26.041712 -80.220886 477 02/23/2025 15:43:06 820 0.30 241.83 0.00 WSW 7108 43.06 NE 13964 37367 1 GPS 1
16 0.6 26.041712 -80.220886 474 02/23/2025 15:43:07 834 0.30 241.83 0.00 WSW 7108 43.06 NE 13965 37369 1 GPS 1
16 0.6 26.041691 -80.220894 484 02/23/2025 15:43:08 846 -6.10 0.00 0.00 N 7108 43.06 NE 14001 37554 1 GPS 2
16 0.6 26.041691 -80.220894 490 02/23/2025 15:43:09 850 -6.10 0.00 0.00 N 7108 43.06 NE 14002 37556 1 GPS 2
16 0.6 26.041691 -80.220894 497 02/23/2025 15:43:10 852 -6.10 0.00 0.00 N 7108 43.06 NE 14003 37558 1 GPS 2
16 0.6 26.041691 -80.220894 499 02/23/2025 15:43:11 864 -6.10 0.00 0.00 N 7108 43.06 NE 14004 37560 1 GPS 2
