Community project

ESP32 GPS Tracker

casasanta

Published August 8, 2026 · Updated August 11, 2026

ESP321 component4 assembly steps
Remix this project
Photo of ESP32 GPS TrackerGenerated with AI

This 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
Wiring diagram for ESP32 GPS Tracker

Pan and zoom to explore the wiring. Remix the project to edit it in your own workspace.

Parts list

Bill of materials
ComponentQtyNotes
NEO-6M GPS ModuleNEO-6M1u-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 steps
  1. Power 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.
  2. 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.
  3. 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.
  4. 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
PinConnectionType
3V3gps_1 VCCpower
GNDgps_1 GNDground
GPIO 16gps_1 TXuart
GPIO 17gps_1 RXuart

Firmware

ESP32
main.cppDeploy to device
#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.

Open in Schematik