> problem
I needed a reliable way to track outdoor assets and visualize them in my Home Assistant dashboard without relying on proprietary cloud services.
> hardware setup
The core of the system is an ESP32 DevKit V1 paired with a Neo-6M GPS module. Communication is handled over HardwareSerial (Serial2) at 9600 baud. It's powered via a standard 5V USB connection.
> key challenges
The primary hurdle was finding the correct baud rate for the Neo-6M, which defaults to 9600 rather than the common 115200. Additionally, indoor GPS signal reception is limited, requiring optimal placement near windows for initial satellite lock.
> architecture
> logic flow
> code: esp32-gps-tracker.ino
Purpose: Primary logic for GPS decoding and MQTT transmission.
#include <TinyGPS++.h>
#include <HardwareSerial.h>
#include <WiFi.h>
#include <PubSubClient.h>
// Configuration
const char* ssid = "YOUR_SSID";
const char* password = "YOUR_PASSWORD";
const char* mqtt_server = "192.168.1.100";
TinyGPSPlus gps;
HardwareSerial SerialGPS(2);
WiFiClient espClient;
PubSubClient client(espClient);
void setup() {
Serial.begin(115200);
SerialGPS.begin(9600, SERIAL_8N1, 16, 17);
Serial.println("Connecting to WiFi...");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWiFi connected.");
client.setServer(mqtt_server, 1883);
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
while (SerialGPS.available() > 0) {
if (gps.encode(SerialGPS.read())) {
if (gps.location.isValid()) {
char msg[50];
snprintf(msg, 50, "Lat: %f, Lng: %f", gps.location.lat(), gps.location.lng());
client.publish("lab/gps/location", msg);
Serial.print("Published: ");
Serial.println(msg);
}
}
}
delay(1000);
}
void reconnect() {
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
if (client.connect("ESP32GPSClient")) {
Serial.println("connected");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
delay(5000);
}
}
}
> result
The system is now fully operational, providing stable coordinates to my Home Assistant setup with a latency of approximately 2 seconds. The use of TinyGPS++ and interrupt-style decoding ensures no data is lost even with the 1-second stabilization delay.