#include <TinyGPS++.h>
// Use ESP32's HardwareSerial (more reliable than SoftwareSerial)
static const int GPS_RX_PIN = 18; // ESP32 receives on 18 (connect to GPS TX)
static const int GPS_TX_PIN = 5; // ESP32 transmits on 5 (connect to GPS RX)
static const uint32_t GPS_BAUD = 9600;
#define btn 35 // single button
int btnOld = 1; // default HIGH (because of INPUT_PULLUP)
int btnNew;
bool gpsStreaming = false; // flag to toggle ON/OFF
TinyGPSPlus gps;
void setup() {
Serial.begin(115200);
Serial.println("Hello, ESP32 + GPS!");
pinMode(btn, INPUT_PULLUP);
// Map Serial1 to your chosen pins (RX=18, TX=5) at 9600 8N1
Serial1.begin(GPS_BAUD, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN);
Serial.println("GPS UART (Serial1) started at 9600 baud");
}
void loop() {
// Always feed GPS parser
while (Serial1.available() > 0) {
gps.encode(Serial1.read());
}
// Read button
btnNew = digitalRead(btn);
// Detect falling edge (button press)
if (btnOld == HIGH && btnNew == LOW) {
gpsStreaming = !gpsStreaming; // toggle flag
Serial.println(gpsStreaming ? "📡 GPS Streaming STARTED" : "🛑 GPS Streaming STOPPED");
delay(200); // debounce
}
btnOld = btnNew;
// If streaming enabled, print GPS data
if (gpsStreaming) {
if (gps.location.isUpdated()) {
Serial.print("LAT: ");
Serial.println(gps.location.lat(), 6);
Serial.print("LON: ");
Serial.println(gps.location.lng(), 6);
}
static uint32_t last = 0;
if (millis() - last > 1000) {
last = millis();
Serial.print("Sats: ");
Serial.print(gps.satellites.value());
Serial.print(" HDOP: ");
Serial.print(gps.hdop.hdop());
Serial.print(" Valid: ");
Serial.println(gps.location.isValid() ? "yes" : "no");
}
}
}