Community project
ESP32 GPS Tracker
casasanta
Published August 8, 2026 · Updated August 11, 2026
Generated with AIThis project turns an ESP32 microcontroller into a GPS tracker that reads location data from a NEO-6M GPS module. The tracker reports latitude, longitude, altitude, speed, satellite count, and signal quality through the serial monitor, making it useful for logging position data, building location-aware applications, or understanding how GPS receivers work.
The guide includes a complete wiring diagram showing how to connect the GPS module to the ESP32's UART pins, a full parts list, and ready-to-upload firmware based on the TinyGPS++ library. Assembly takes just a few minutes: power down before wiring, connect the GPS module's power and serial lines to the ESP32, position the antenna outdoors or near a window, and upload the code to start receiving fixes.
Wiring diagram
Interactive · read-only
Pan and zoom to explore the wiring. Remix the project to edit it in your own workspace.
Parts list
Bill of materials| Component | Qty | Notes |
|---|---|---|
| NEO-6M GPS ModuleNEO-6M | 1 | u-blox NEO-6M based GPS receiver module. Outputs NMEA sentences (GGA, RMC, etc.) over UART at 9600 baud by default. Provides latitude, longitude, altitude, speed, and time. The NEO-6M module itself is a 3.3V-class device; many GY-NEO6MV2 breakout boards accept 5V on their VCC header through an onboard regulator, but UART I/O remains 3.3V-domain and must not be driven above 3.6V. Features an on-board patch antenna footprint and an SMA/IPEX connector for external active antenna (preferred for faster lock acquisition). Supply current ~45 mA in acquisition, ~11 mA in tracking. |
Assembly
4 stepsPower off before wiring
Disconnect the ESP32 DevKit v1 from USB while you make the connections.
- Tip: Use short jumper wires and keep the GPS antenna facing upward.
- ⚠ Do not connect the GPS module VCC to the ESP32 5V pin unless your exact breakout explicitly states it accepts 5V. This design uses 3.3V.
Connect GPS power
Connect gps_1 VCC to the ESP32 3V3 pin. Connect gps_1 GND to an ESP32 GND pin.
- Tip: GPS and ESP32 must share ground for UART data to work.
- ⚠ Check the VCC and GND labels carefully; reversing power can damage the GPS module.
Connect the GPS UART
Connect gps_1 TX to ESP32 GPIO16. Connect gps_1 RX to ESP32 GPIO17. TX and RX are crossed because each device transmits to the other device's receiver.
- Tip: The tracker only requires TX-to-GPIO16 to receive location data; RX-to-GPIO17 is included for future GPS configuration.
- Tip: Leave the PPS pin unconnected.
- ⚠ Use only 3.3V UART logic. Do not connect a 5V serial signal to ESP32 GPIO16 or GPIO17.
Position the antenna
Place the GPS module where its patch antenna has a clear view of the sky, ideally outdoors. Then reconnect USB power to the ESP32.
- Tip: The first satellite fix can take several minutes, especially after the module has been unused or moved a long distance.
- Tip: After Deploy, view the USB serial output at 115200 baud to see the readings.
- ⚠ Indoor operation or metal enclosures can prevent a satellite fix.
Pin assignments
Board wiring reference| Pin | Connection | Type |
|---|---|---|
| 3V3 | gps_1 VCC | power |
| GND | gps_1 GND | ground |
| GPIO 16 | gps_1 TX | uart |
| GPIO 17 | gps_1 RX | uart |
Firmware
ESP32#include <Arduino.h>
#include <TinyGPS++.h>
// Forward declarations
void printLocation();
constexpr int GPS_RX_PIN = 16; // ESP32 RX2 <- GPS TX
constexpr int GPS_TX_PIN = 17; // ESP32 TX2 -> GPS RX
constexpr uint32_t GPS_BAUD = 9600;
constexpr uint32_t REPORT_INTERVAL_MS = 1000;
TinyGPSPlus gps;
HardwareSerial gpsSerial(2);
unsigned long lastReportMs = 0;
void printLocation() {
if (gps.location.isValid()) {
Serial.print("Latitude: ");
Serial.println(gps.location.lat(), 6);
Serial.print("Longitude: ");
Serial.println(gps.location.lng(), 6);
} else {
Serial.println("Location: waiting for a GPS fix");
}
if (gps.altitude.isValid()) {
Serial.print("Altitude: ");
Serial.print(gps.altitude.meters(), 1);
Serial.println(" m");
}
if (gps.speed.isValid()) {
Serial.print("Speed: ");
Serial.print(gps.speed.kmph(), 1);
Serial.println(" km/h");
}
if (gps.satellites.isValid()) {
Serial.print("Satellites: ");
Serial.println(gps.satellites.value());
}
if (gps.hdop.isValid()) {
Serial.print("HDOP: ");
Serial.println(gps.hdop.hdop(), 1);
}
Serial.println("---");
}
void setup() {
Serial.begin(115200);
gpsSerial.begin(GPS_BAUD, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN);
Serial.println();
Serial.println("ESP32 GPS tracker starting");
Serial.println("Place the GPS antenna outdoors or beside a clear window.");
}
void loop() {
while (gpsSerial.available() > 0) {
gps.encode(gpsSerial.read());
}
const unsigned long now = millis();
if (now - lastReportMs >= REPORT_INTERVAL_MS) {
lastReportMs = now;
printLocation();
if (millis() > 5000 && gps.charsProcessed() < 10) {
Serial.println("No GPS serial data received. Check TX-to-GPIO16, power, and ground.");
}
}
}“Deploy to device” opens this project in Schematik, where you can flash it to your board over USB.
Remix this project
Make it yours in one click
Open a full copy of this project in your own Schematik workspace — diagram, code, parts, and assembly steps included. Swap the sensor, add features, or redesign the whole thing with AI. The author's original stays untouched.