Skip to content

Commit e8ced3b

Browse files
feat: Integrate GPS functionality for Lilygo with TinyGPS++ support
1 parent b6ae084 commit e8ced3b

File tree

1 file changed

+86
-0
lines changed

1 file changed

+86
-0
lines changed

ultrasonic_radar_tx/ultrasonic_radar_tx.ino

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#if defined(ESP32)
22
#include <WiFi.h>
33
#include <ESP32Servo.h>
4+
#include <TinyGPSPlus.h>
45
#elif defined(ESP8266)
56
#include <ESP8266WiFi.h>
67
#include <Servo.h>
@@ -62,6 +63,26 @@ unsigned long lastStepMs = 0;
6263
unsigned long lastWifiAttempt = 0;
6364
unsigned long lastWsAttempt = 0;
6465

66+
#if defined(ESP32)
67+
HardwareSerial SerialGPS(1);
68+
TinyGPSPlus gps;
69+
constexpr int GPS_RX_PIN = 34;
70+
constexpr int GPS_TX_PIN = 12;
71+
constexpr uint32_t GPS_BAUD_RATE = 9600;
72+
constexpr unsigned long GPS_MAX_AGE_MS = 5000;
73+
double gpsLastLat = 0.0;
74+
double gpsLastLon = 0.0;
75+
double gpsLastAlt = 0.0;
76+
double gpsLastSpeedMps = 0.0;
77+
double gpsLastHdop = 0.0;
78+
uint8_t gpsLastSatellites = 0;
79+
unsigned long gpsLastFixMs = 0;
80+
81+
void beginGps();
82+
void pollGps();
83+
bool gpsHasFix();
84+
#endif
85+
6586
void connectToWifi();
6687
void ensureWebsocket();
6788
void publishRadarSample(int angleDeg, float distanceCm, bool valid);
@@ -86,6 +107,10 @@ void setup() {
86107
waitingForServo = true;
87108
servoCommandMs = millis();
88109

110+
#if defined(ESP32)
111+
beginGps();
112+
#endif
113+
89114
connectToWifi();
90115

91116
radarSocket.onEvent([](WebsocketsEvent event, String data) {
@@ -107,6 +132,10 @@ void setup() {
107132
}
108133

109134
void loop() {
135+
#if defined(ESP32)
136+
pollGps();
137+
#endif
138+
110139
if (WiFi.status() != WL_CONNECTED) {
111140
ensureWebsocket(); // ensures disconnect handling
112141
connectToWifi();
@@ -198,6 +227,21 @@ void publishRadarSample(int angleDeg, float distanceCm, bool valid) {
198227
payload += RADAR_SOURCE_ID;
199228
payload += "\",\"timestamp_ms\":";
200229
payload += millis();
230+
#if defined(ESP32)
231+
if (gpsHasFix()) {
232+
payload += ",\"gps\":{";
233+
payload += "\"lat\":"; payload += String(gpsLastLat, 6);
234+
payload += ",\"lon\":"; payload += String(gpsLastLon, 6);
235+
payload += ",\"alt_m\":"; payload += String(gpsLastAlt, 1);
236+
payload += ",\"speed_mps\":"; payload += String(gpsLastSpeedMps, 2);
237+
payload += ",\"hdop\":"; payload += String(gpsLastHdop, 1);
238+
payload += ",\"satellites\":"; payload += gpsLastSatellites;
239+
payload += ",\"fix_age_ms\":"; payload += (millis() - gpsLastFixMs);
240+
payload += "}";
241+
} else {
242+
payload += ",\"gps\":null";
243+
}
244+
#endif
201245
payload += "}";
202246

203247
if (!radarSocket.send(payload)) {
@@ -274,3 +318,45 @@ void updateSweep() {
274318
waitingForServo = true;
275319
}
276320
}
321+
322+
#if defined(ESP32)
323+
void beginGps() {
324+
SerialGPS.begin(GPS_BAUD_RATE, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN);
325+
Serial.println("[GPS] Serial initialized for TinyGPS++");
326+
}
327+
328+
void pollGps() {
329+
bool sentenceCompleted = false;
330+
while (SerialGPS.available()) {
331+
sentenceCompleted |= gps.encode(SerialGPS.read());
332+
}
333+
334+
if (!sentenceCompleted) {
335+
return;
336+
}
337+
338+
const unsigned long now = millis();
339+
if (gps.location.isValid()) {
340+
gpsLastLat = gps.location.lat();
341+
gpsLastLon = gps.location.lng();
342+
gpsLastFixMs = now;
343+
}
344+
if (gps.altitude.isValid()) {
345+
gpsLastAlt = gps.altitude.meters();
346+
}
347+
if (gps.speed.isValid()) {
348+
gpsLastSpeedMps = gps.speed.mps();
349+
}
350+
if (gps.hdop.isValid()) {
351+
gpsLastHdop = gps.hdop.hdop();
352+
}
353+
if (gps.satellites.isValid()) {
354+
gpsLastSatellites = static_cast<uint8_t>(gps.satellites.value());
355+
}
356+
}
357+
358+
bool gpsHasFix() {
359+
const unsigned long age = gps.location.isValid() ? gps.location.age() : GPS_MAX_AGE_MS + 1;
360+
return gps.location.isValid() && age <= GPS_MAX_AGE_MS;
361+
}
362+
#endif

0 commit comments

Comments
 (0)