ESP32 UNO - GPS

Where exactly is your project right now? Hook a NEO-6M module to the ESP32 Uno form board and get a live ESP32 Uno GPS position from the satellites. The board prints GPS coordinates, ground speed and UTC date and time on the Serial Monitor, and a second sketch tells you how many kilometers lie between you and London.

What you will do:

  1. Learn what each of the four NEO-6M GPS module pins does.
  2. Wire the GPS module to a hardware UART on the ESP32 Uno.
  3. Add the TinyGPSPlus parser through the Arduino IDE Library Manager.
  4. Print latitude, longitude, altitude, speed and time from GPS data.
  5. Measure the distance between your spot and a fixed place.
ESP32 Uno GPS

Components You Need

1×ESP32 Uno-form Board
1×USB Cable Type-A to Type-C (for USB-A PC)
1×USB Cable Type-C to Type-C (for USB-C PC)
1×NEO-6M GPS module
1×Jumper Wires

Or you can buy the following kits:

1×DIYables Sensor Kit (18 sensors/displays)
Disclosure: Some of the links provided in this section are Amazon affiliate links. We may receive a commission for any purchases made through these links at no additional cost to you.
Additionally, some of these links are for products from our own brand, DIYables .

NEO-6M GPS Module Basics

After this part, you know what the receiver sends and which pin does what.

The NEO-6M is a cheap satellite receiver from u-blox. It streams NMEA text lines (like $GPRMC,...) over a serial link about once per second. The TinyGPSPlus library reads that text and hands you plain numbers.

Item Value
Receiver chip u-blox NEO-6M
Output format NMEA text over UART
Default baud rate 9600
Update rate 1 time per second (default)
Position accuracy about 2.5 m in open sky
Cold start time roughly 27 seconds to a few minutes

Good to know: the antenna must see the sky. Under a roof or inside a metal box, the module may never lock onto the satellites.

Pinout

Four pins: two for power and two for data.

Pin Role Connect To
VCC Power input 5V of the board (the module has its own regulator)
GND Ground GND of the board
TX Sends GPS text out An RX pin on the ESP32 Uno
RX Takes commands in A TX pin on the ESP32 Uno
NEO-6M GPS module Pinout

ESP32 Uno Pinout

On the ESP32 Uno form board, every Uno header label stands for a GPIO number, and the sketch needs that number. Look up D3 and D4 on the picture below before you plug in the wires.

ESP32 Uno pinout diagram

How to Connect

When you finish this part, the GPS module sends its data straight into UART2 of the ESP32 Uno.

The lines cross over: the module's TX goes to the board's receive pin, and the module's RX goes to the board's transmit pin.

The wiring diagram between ESP32 Uno GPS module

This image is created using Fritzing. Click to enlarge image

GPS Module Pin ESP32 Uno Pin
VCC 5V
GND GND
TX D4 (GPIO17)
RX D3 (GPIO25)

Good to know: ESP32 Uno pins use 3.3V logic, so D3 (GPIO25) already sends a 3.3V signal. That level is safe for the RX pin of the NEO-6M, and no voltage divider is needed.

The second diagram adds a voltage divider on the board's TX line. On the ESP32 Uno it is optional. It does no harm, so you can keep it if your module is already wired that way.

The wiring diagram between ESP32 Uno GPS

This image is created using Fritzing. Click to enlarge image

WARNING

ESP32 Uno pins are NOT 5V tolerant. The TX pin of most NEO-6M boards sends 3.3V, which is fine. If your module has a 5V level on its TX pin, put a voltage divider (for example 1kΩ and 2kΩ) between GPS TX and D4 (GPIO17).

ESP32 Uno Code

This part gives you two sketches: one prints the position, speed and time, and one prints the distance to London.

The ESP32 Uno has no SoftwareSerial library. The sketches use the hardware port Serial2 instead and route it to GPIO17 (RX) and GPIO25 (TX) with Serial2.begin(9600, SERIAL_8N1, RX_PIN, TX_PIN). A hardware UART does not drop characters, so the GPS text arrives clean.

Sketch 1 - Position, Ground Speed and UTC Clock

The sketch passes every byte from the module to TinyGPSPlus and prints a block of values each time a full NMEA sentence is decoded.

/* * This ESP32 Uno code was developed by newbiely.com * * This ESP32 Uno code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/esp32-uno/esp32-uno-gps */ #include <TinyGPS++.h> #define RX_PIN 17 // D4 (GPIO17) listens to the TX line of the NEO-6M #define TX_PIN 25 // D3 (GPIO25) talks to the RX line of the NEO-6M TinyGPSPlus gps; // parser that turns NMEA text into numbers HardwareSerial &gpsSerial = Serial2; // hardware UART2 is used in place of SoftwareSerial void setup() { Serial.begin(9600); gpsSerial.begin(9600, SERIAL_8N1, RX_PIN, TX_PIN); // the NEO-6M sends at 9600 baud out of the box Serial.println(F("ESP32 Uno - GPS module")); } void loop() { if (gpsSerial.available() > 0) { if (gps.encode(gpsSerial.read())) { if (gps.location.isValid()) { Serial.print(F("- latitude: ")); Serial.println(gps.location.lat()); Serial.print(F("- longitude: ")); Serial.println(gps.location.lng()); Serial.print(F("- altitude: ")); if (gps.altitude.isValid()) Serial.println(gps.altitude.meters()); else Serial.println(F("INVALID")); } else { Serial.println(F("- location: INVALID")); } Serial.print(F("- speed: ")); if (gps.speed.isValid()) { Serial.print(gps.speed.kmph()); Serial.println(F(" km/h")); } else { Serial.println(F("INVALID")); } Serial.print(F("- GPS date&time: ")); if (gps.date.isValid() && gps.time.isValid()) { Serial.print(gps.date.year()); Serial.print(F("-")); Serial.print(gps.date.month()); Serial.print(F("-")); Serial.print(gps.date.day()); Serial.print(F(" ")); Serial.print(gps.time.hour()); Serial.print(F(":")); Serial.print(gps.time.minute()); Serial.print(F(":")); Serial.println(gps.time.second()); } else { Serial.println(F("INVALID")); } Serial.println(); } } if (millis() > 5000 && gps.charsProcessed() < 10) Serial.println(F("No GPS data received: check wiring")); }

Upload and Test

  1. First time with this board? Set it up with ESP32 Uno - Getting Started before you continue.
  2. Build the circuit by following the wiring table above.
  3. Plug in the USB Type-C cable between the ESP32 Uno and your computer.
  4. Select the board in Arduino IDE: pick ESP32 Dev Module and the COM port of the board (CH340).
  5. Open the Library Manager with the Libraries icon in the left bar of the Arduino IDE.
  6. Find the library: enter TinyGPSPlus in the search field and look for the one by Mikal Hart.
  7. Click Install and wait until it finishes.
  • Search for TinyGPSPlus created by Mikal Hart and click the Install button.
∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
ESP32 Dev Module
Library Manager
Type:
All
Topic:
All
TinyGPSPlus by Mikal Hart
NMEA is the standard format GPS devices use to report location, time, altitude, etc. TinyGPSPlus is a compact, resilient library that parses the most common NMEA 'sentences' used: GGA and RMC. It can also be customized to extract data from *any* compliant sentence. More info
1.0.3
INSTALL
Newbiely.ino
···
1 void setup() {
Output
Serial Monitor
Ln 1, Col 1
ESP32 Dev Module on COM15
1
  1. Paste the code into a new sketch in the Arduino IDE.
  2. Press Upload and wait for "Done uploading".
  3. Open the Serial Monitor, set it to 9600 baud, and put the antenna by a window or outdoors.
  4. Pro tip: watch the small LED on the NEO-6M. It stays dark or solid while searching and starts blinking once per second when it has a fix, so you know when to expect real numbers.
∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
ESP32 Dev Module
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'ESP32 Dev Module' on 'COM15')
New Line
9600 baud
ESP32 Uno - GPS module - location: INVALID - speed: INVALID - GPS date&time: INVALID - latitude: 43.65 - longitude: -79.38 - altitude: 86.20 - speed: 1.48 km/h - GPS date&time: 2026-9-14 17:4:9
Ln 11, Col 1
ESP32 Dev Module on COM15
2

The first blocks often say INVALID. That is normal until the module locks onto enough satellites.

Sketch 2 - How Far Away Is London?

This sketch takes your current position and works out how far it is to London (latitude 51.508131, longitude -0.128002).

/* * This ESP32 Uno code was developed by newbiely.com * * This ESP32 Uno code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/esp32-uno/esp32-uno-gps */ #include <TinyGPS++.h> #define RX_PIN 17 // D4 (GPIO17) listens to the TX line of the NEO-6M #define TX_PIN 25 // D3 (GPIO25) talks to the RX line of the NEO-6M TinyGPSPlus gps; // parser that turns NMEA text into numbers HardwareSerial &gpsSerial = Serial2; // hardware UART2 is used in place of SoftwareSerial const double LONDON_LAT = 51.508131; const double LONDON_LON = -0.128002; void setup() { Serial.begin(9600); gpsSerial.begin(9600, SERIAL_8N1, RX_PIN, TX_PIN); // the NEO-6M sends at 9600 baud out of the box Serial.println(F("ESP32 Uno - GPS module")); } void loop() { if (gpsSerial.available() > 0) { if (gps.encode(gpsSerial.read())) { if (gps.location.isValid()) { double latitude = gps.location.lat(); double longitude = gps.location.lng(); unsigned long distanceKm = TinyGPSPlus::distanceBetween(latitude, longitude, LONDON_LAT, LONDON_LON) / 1000; Serial.print(F("- latitude: ")); Serial.println(latitude); Serial.print(F("- longitude: ")); Serial.println(longitude); Serial.print(F("- distance to London: ")); Serial.println(distanceKm); } else { Serial.println(F("- location: INVALID")); } Serial.println(); } } if (millis() > 5000 && gps.charsProcessed() < 10) Serial.println(F("No GPS data received: check wiring")); }

Upload and Test

  1. Paste the code into the Arduino IDE.
  2. Press Upload to flash it to the ESP32 Uno.
  3. Check the result in the Serial Monitor (9600 baud).
  4. Pro tip: keep the board still for a minute after the first fix. The position settles, and the distance stops jumping by a few hundred meters.
∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
ESP32 Dev Module
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'ESP32 Dev Module' on 'COM15')
New Line
9600 baud
ESP32 Uno - GPS module - latitude: 43.65 - longitude: -79.38 - distance to London: 5710
Ln 11, Col 1
ESP32 Dev Module on COM15
2

Video Tutorial

See the ESP32 Uno build in action in the video below.

Code Explanation

Both sketches share the same core. The table lists the main parts.

Code Part What It Does
HardwareSerial &gpsSerial = Serial2 Gives UART2 the name gpsSerial, so the rest of the code stays short
gpsSerial.begin(9600, SERIAL_8N1, RX_PIN, TX_PIN) Starts UART2 at 9600 baud on GPIO17 (RX) and GPIO25 (TX)
gps.encode(gpsSerial.read()) Feeds one character to TinyGPSPlus and returns true when a sentence is complete
gps.location.isValid() Tells you if the module has a real position fix
TinyGPSPlusdistanceBetween() Returns the great-circle distance in meters, which the code divides by 1000
gps.charsProcessed() < 10 After 5 seconds with almost no data, it prints a wiring warning

The result is a new block of values in the Serial Monitor about once per second.

Good to know: Serial.println() shows a double with two decimals. Write Serial.println(gps.location.lat(), 6) to see six decimals.

ESP32 Uno vs UNO R4 for This Project

Here is what changes when you move this GPS project from the UNO R4 to the ESP32 Uno.

Item Arduino UNO R4 ESP32 Uno
Logic voltage 5V 3.3V
GPS TX wire D4 D4 (GPIO17)
GPS RX wire D3 D3 (GPIO25)
Serial port for GPS SoftwareSerial Hardware Serial2 on any pins
Voltage divider on board TX Recommended Not needed
Arduino IDE board Arduino UNO R4 WiFi or Minima ESP32 Dev Module
WiFi and Bluetooth WiFi only on the WiFi model WiFi plus Bluetooth Classic and BLE

The wires stay on the same header positions, so the same circuit works. Only the code changes, from SoftwareSerial to Serial2.

Go Wireless: Track Your Position on a Phone

After this part, you have an idea for viewing GPS data without a USB cable.

The ESP32 Uno has WiFi and Bluetooth built in. Send the latitude, longitude, speed and time to a phone or browser and you get a small tracker you can carry around. A table view fits GPS well, because you have several values that change together.

Useful guides:

Troubleshooting

Problem Possible Cause Solution
No COM port shows up in the Arduino IDE CH340 driver missing or a charge-only USB cable Install the CH340 driver and try a USB cable that carries data
Upload stops at "Failed to connect" or "Waiting for download" Board did not enter download mode Hold the BOOT button when the upload starts, then let go
"No GPS data received - check wiring" appears TX and RX lines swapped or loose GPS TX must go to D4 (GPIO17) and GPS RX to D3 (GPIO25), then check VCC and GND
Module LED never lights up No power on VCC Feed VCC from the 5V pin and check the GND wire
Values stay INVALID for over 10 minutes Antenna cannot see the satellites Move outdoors, keep the patch antenna facing up and away from metal
Random symbols instead of numbers Baud rate mismatch Keep the GPS port at 9600 and set the Serial Monitor to 9600 too
Error "SoftwareSerial.h - No such file" Sketch written for another board Use the ESP32 Uno sketch above with Serial2
Error "TinyGPS++.h - No such file" TinyGPSPlus not installed Install TinyGPSPlus by Mikal Hart in the Library Manager

FAQ

Which serial port should the NEO-6M use on the ESP32 Uno?

Use Serial2 (UART2). The ESP32 Uno can route a hardware UART to almost any GPIO, so the code puts it on GPIO17 and GPIO25. Leave Serial (D0/D1) free, because it handles uploads and the Serial Monitor.

Can I power the NEO-6M from the 3.3V pin instead of 5V?

Many NEO-6M boards accept 3.3V to 5V, because they have their own regulator. Check the label on your module. If you are not sure, use 5V, since the data pins still work at 3.3V levels.

How accurate is the NEO-6M position?

In open sky, it is about 2 to 3 meters. Near tall buildings or trees, the error can grow to 10 meters or more, because the signals bounce.

Why does the GPS show a time that is hours off?

GPS gives UTC time. Add your time zone offset to gps.time.hour() in the code, and handle the day change when the hour goes past 23.

How can I print more decimals for latitude and longitude?

Pass a second number to Serial.println(), for example Serial.println(gps.location.lat(), 6). Six decimals is the usual format for maps.

Can I change the London coordinates to another place?

Yes. Edit LONDON_LAT and LONDON_LON with the latitude and longitude of any place, for example your home. The sketch then prints the distance to that point in kilometers.

Is the CH340 driver needed for the ESP32 Uno?

This board uses a CH340 USB-to-serial chip. Windows and macOS often install the driver by themselves, but if no COM port appears, install the CH340 driver by hand.

Can I use a GPS shield made for the Uno on the ESP32 Uno?

Often yes, because the header shape is the same. Check that the shield does not send 5V signals into the board, and change the TX and RX pins in the code to the GPIO numbers of the pins the shield uses.

What if this GPS build needs more pins than the Uno headers offer?

The ESP32 Uno has extra holes near the power header: GPIO32 and GPIO33 (I/O, PWM, analog on ADC1, so they also work while WiFi is on) and GPIO15 (I/O, PWM, analog on ADC2). Solder pin headers to them and use the GPIO number in code. For a GPS tracker, GPIO32 and GPIO33 are good for a button or a battery voltage reading. Two warnings: GPIO15 and GPIO0 (the IO0 pin at the unused Uno NC position) are boot strapping pins, and a wrong connection can stop the board from booting or uploading, so use GPIO32 and GPIO33 first. Also never use the six holes under the digital header (SD0 to SD3, CMD, CLK = GPIO6 to GPIO11). They connect to the flash chip, and using them crashes the board.

Can I show my GPS position on a web page with the ESP32 Uno?

Yes. The ESP32 Uno has WiFi, so it can serve a page with the latitude and longitude. See the Go Wireless section above for ready guides.

Learn More

※ OUR MESSAGES

  • As freelancers, We are AVAILABLE for HIRE. See how to outsource your project to us
  • Please feel free to share the link of this tutorial. However, Please do not use our content on any other websites. We invested a lot of effort and time to create the content, please respect our work!