In this guide, you’ll learn how to interface the Arduino board with NEO-M8N GPS module. You’ll learn how to connect the module to the board and how to program it to get GPS data: latitude, longitude, altitude, UTC time, number of visible satellites, and more.

This is what you’ll learn with this guide:
- Wire the NEO-M8N GPS module to the Arduino via serial;
- Get raw GPS data;
- Parse raw data to obtain selected and readable GPS information using the TinyGPSPlus library.
Table of Contents
We’ll cover the following subjects:
- Introducing the NEO-M8N GPS Module
- Wiring the NEO-M8N GPS Module to the Arduino
- Getting Raw GPS Data – Testing the NEO-M8N GPS Module with the Arduino
- Parsing NMEA Sentences with TinyGPSPlus Library
Introducing the NEO-M8N GPS Module
The NEO-M8N GPS module is one of the most popular GPS receivers used with microcontrollers in navigation and tracking projects. It can get data about latitude, longitude, altitude, and time.
It supports multiple satellite systems, including GPS, Galileo, GLONASS, and BeiDou. It offers better satellite tracking than the NEO-6M, making it more reliable in challenging conditions.

According to the datasheet, it has a horizontal position accuracy of 2.5 to 4 meters and quick startup times (1 second for hot start, 26–57 seconds for cold start—expect longer times if you’re close to buildings).
The module includes a backup battery, built-in EEPROM, and an LED indicator that blinks when a position fix is achieved.
This module typically comes with a ceramic GPS antenna. But, you can change it to any other compatible antenna that might suit your project better. For example, I like to use the one at the right in the picture below because it is waterproof, and the antenna comes with a long cable which allows for more flexibility.

The NEO-M8N GPS Module communicates with a microcontroller using Serial communication protocol, and works with standard NMEA sentences. NMEA stands for National Marine Electronics Association, and in the world of GPS, it is a standard data format supported by GPS manufacturers.
Where to buy?
You can check our Maker Advisor Tools page to compare the NEO-M8N GPS receiver module price in different stores:
You can use the preceding links or go directly to MakerAdvisor.com/tools to find all the parts for your projects at the best price!
Wiring the NEO-M8N GPS Module to the Arduino
To communicate with the NEO-6M GPS module, we’ll use software serial, so you can use any available Pins. We’ll use Pin5 (TX –> connects to the module RX) and Pin6 (RX –> connects to the module TX).

NEO-M8N GPS Module | Arduino |
VCC | 5V |
RX | Pin 5 |
TX | Pin 6 |
GND | GND |
Getting Raw GPS Data – Testing the NEO-M8N GPS Module with the Arduino
To get raw GPS data you need to start a serial communication with the GPS module and read the available data.

The following code establishes a serial communication with the GPS module and reads the available data.
/*
Rui Santos & Sara Santos - Random Nerd Tutorials
Complete project details at https://RandomNerdTutorials.com/arduino-neo-m8n-gps-module/
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*/
#include <SoftwareSerial.h>
static const int RXPin = 6, TXPin = 5;
static const uint32_t GPSBaud = 9600;
// The serial connection to the GPS module
SoftwareSerial gpsSerial(RXPin, TXPin);
void setup(){
Serial.begin(9600);
gpsSerial.begin(GPSBaud);
}
void loop(){
while (gpsSerial.available() > 0){
// get the byte data from the GPS
byte gpsData = gpsSerial.read();
Serial.write(gpsData);
}
}
How Does the Code Work?
This sketch assumes you are using Pin 6 and Pin 5 as RX and TX serial pins to establish serial communication with the GPS module. If you’re using other pins you should edit that on the following lines:
static const int RXPin = 6, TXPin = 5;
Also, if your module uses a different default baud rate than 9600 bps, you should modify the code on the following line:
static const uint32_t GPSBaud = 9600;
Then, we create an instance of the SoftwareSerial on the pins defined earlier called gpsSerial.
// The serial connection to the GPS device
SoftwareSerial gpsSerial(RXPin, TXPin);
In the setup(), we initiate the Serial Monitor.
Serial.begin(9600);
Then, we initialize a serial communication with the GPS module.
gpsSerial.begin(GPSBaud);
In the loop(), the code listens to the GPS serial port, and when data is received from the module, it is printed in the serial monitor.
void loop(){
while (gpsSerial.available() > 0){
// get the byte data from the GPS
byte gpsData = gpsSerial.read();
Serial.write(gpsData);
}
}
Testing the Code
Upload the code to your board.

Make sure the antenna is connected and that the module or antenna is placed outside or next to a window so that it can get data from the satellites.

The module’s blue LED will start blinking when it finds a position fix.
The Serial Monitor will display NMEA sentences with GPS data (make sure to select the Serial Monitor baud rate to 9600).
Important: If you’re running this sketch for the first time, it may take a few minutes until the module gets a position fix. You’ll start getting actual data when the blue LED starts blinking. If you’re inside a building, it is very unlikely that you can get GPS data. Go outside or place your antenna outside to maximize your chances of catching a satellite signal.

You should get a bunch of information in the GPS standard language, NMEA. Each line you get in the serial monitor is an NMEA sentence.
NMEA stands for National Marine Electronics Association, and in the world of GPS, it is a standard data format supported by GPS manufacturers.
NMEA Sentences
NMEA sentences start with the $ character, and each data field is separated by a comma.
$GNRMC,115209.00,A,4114.5500,N,00861.4900,W,0.129,,160125,,,D*XX
$GNVTG,,T,,M,0.129,N,0.239,K,D*XX
$GNGGA,115209.00,4114.5500,N,00861.4900,W,2,10,0.93,130.6,M,50.1,M,,0000*XX
$GNGSA,A,3,24,25,28,32,29,,,,,,,,1.65,0.93,1.37*XX
$GNGSA,A,3,78,66,67,77,,86,26,083,20*XX
$GLGSV,3,3,09,87,13,131,*XX
$GNGLL,4114.5500,N,00861.4900,W,115209.00,A,D*XX
There are different types of NMEA sentences. The type of message is indicated by the characters before the first comma.
The GN after the $ indicates it is a GPS position. The $GNGGA is the basic GNSS NMEA message, that provides 3D location and accuracy data.
In the following sentence:
$GNGGA,110827.00,4114.32485,N,00831.79799,W,1,10,0.93,130.6,M,50.1,M,,*5F
Here’s how the fields look for the M8N:
- $GNGGA: Global GNSS location data.
- 110827.00: Time in UTC (11:08:27).
- 4114.32485,N: Latitude.
- 00831.79799,W: Longitude.
- 1: Fix quality (1 = GPS fix, 2 = DGPS, etc.).
- 10: Number of satellites tracked (higher for M8N compared to NEO-6M).
- 0.93: Horizontal dilution of precision (lower is better).
- 130.6,M: Altitude above mean sea level (in meters).
- 50.1,M: Height of geoid above the WGS84 ellipsoid.
- *5F: Recalculated checksum for the NEO-M8N.
The other NMEA sentences provide additional information:
- $GNRMC – Essential GNSS PVT (Position, Velocity, Time) data
- $GNVTG – Velocity and track information
- $GNGGA – GNSS Fix Information
- $GNGSA – GNSS DOP and active satellites
- $GLGSV – Detailed satellite information (GLONASS)
- $GNGLL – Geographic Latitude and Longitude.
For more information about NMEA sentences, I found this website with very detailed information.
You can use this Online NME Analyser and paste your sentences there to interpret the GPS data.
However, the easiest way to get and interpret the GPS data you want is to parse your NMEA sentences directly in the code. For that, we can use the TinyGPSPlus library that provides methods to extract data from the NMEA sentences easily.
Parsing NMEA Sentences with TinyGPSPlus Library

The TinyGPSPlus library makes it simple to get GPS data in a format that is easy to understand. You can click here for more information about the TinyGPSPlus Library.
Installing the TinyGPSPlus Library
In the Arduino IDE, go to Sketch > Include Library > Manage Libraries or click on the Library Manager icon at the left sidebar.
Search for TinyGPSPlus and install the library by Mikal Hart.

Getting GPS Data Using the NEO-6M GPS Module and the TinyGPSPlus Library
The following code shows how to get GPS data using the TinyGPSPlus library. We’ll get date, time, speed, altitude, number of visible satellites, and HDOP (a measurement of how precise the signal is).
/*
Rui Santos & Sara Santos - Random Nerd Tutorials
Complete project details at https://RandomNerdTutorials.com/arduino-neo-m8n-gps-module/
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*/
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
static const int RXPin = 6, TXPin = 5;
static const uint32_t GPSBaud = 9600;
// The TinyGPS++ object
TinyGPSPlus gps;
// The serial connection to the GPS device
SoftwareSerial gpsSerial(RXPin, TXPin);
void setup() {
// Serial Monitor
Serial.begin(9600);
// Start Serial for the GPS module
gpsSerial.begin(GPSBaud);
Serial.println("Software Serial started at 9600 baud rate");
}
void loop() {
// This sketch displays information every time a new sentence is correctly encoded.
unsigned long start = millis();
while (millis() - start < 2000) {
while (gpsSerial.available() > 0) {
gps.encode(gpsSerial.read());
}
if (gps.location.isUpdated()) {
Serial.print("LAT: ");
Serial.println(gps.location.lat(), 6);
Serial.print("LONG: ");
Serial.println(gps.location.lng(), 6);
Serial.print("SPEED (km/h) = ");
Serial.println(gps.speed.kmph());
Serial.print("ALT (min)= ");
Serial.println(gps.altitude.meters());
Serial.print("HDOP = ");
Serial.println(gps.hdop.value() / 100.0);
Serial.print("Satellites = ");
Serial.println(gps.satellites.value());
Serial.print("Time in UTC: ");
Serial.println(String(gps.date.year()) + "/" + String(gps.date.month()) + "/" + String(gps.date.day()) + "," + String(gps.time.hour()) + ":" + String(gps.time.minute()) + ":" + String(gps.time.second()));
Serial.println("");
}
}
}
How Does the Code Work?
You start by importing the TinyGPSPlus library.
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
Then, you define the pins you want to use as RX and TX and the GPS baud rate.
static const int RXPin = 6, TXPin = 5;
static const uint32_t GPSBaud = 9600;
Then, you create a TinyGPSPlus object:
TinyGPSPlus gps;
Create an instance of SoftwareSerial on the pins defined earlier.
SoftwareSerial gpsSerial(RXPin, TXPin);
In the setup(), initialize the Serial Monitor and the serial communication with the GPS module.
void setup() {
// Serial Monitor
Serial.begin(9600);
// Start Serial for the GPS module
gpsSerial.begin(GPSBaud);
Serial.println("Software Serial started at 9600 baud rate");
}
In the loop() is where you request the information. Parse the data from the GPS module into the TinyGPSPlus object using the encode() method as follows.
while (gpsSerial.available() > 0) {
gps.encode(gpsSerial.read());
}
Then, you can query the gps object to see if any data fields have been updated:
if (gps.location.isUpdated()) {
If there is new data, we can get it as follows:
Latitude | gps.location.lat() |
Longitude | gps.location.lng() |
Speed (km/h) | gps.speed.kmph() |
Altitude (meters) | gps.altitude.meters() |
HDOP | gps.hdop.value() |
The number of visible satellites | gps.satellites.value() |
Year | gps.date.year() |
Month | gps.date.month() |
Day | gps.date.day() |
Hour | gps.time.hour() |
Minutes | gps.time.minute() |
Seconds | gps.time.second() |
In the code, we get the data and print all the information in the Serial Monitor.
Serial.print("LAT: ");
Serial.println(gps.location.lat(), 6);
Serial.print("LONG: ");
Serial.println(gps.location.lng(), 6);
Serial.print("SPEED (km/h) = ");
Serial.println(gps.speed.kmph());
Serial.print("ALT (min)= ");
Serial.println(gps.altitude.meters());
Serial.print("HDOP = ");
Serial.println(gps.hdop.value() / 100.0);
Serial.print("Satellites = ");
Serial.println(gps.satellites.value());
Serial.print("Time in UTC: ");
Serial.println(String(gps.date.year()) + "/" + String(gps.date.month()) + "/" + String(gps.date.day()) + "," + String(gps.time.hour()) + ":" + String(gps.time.minute()) + ":" + String(gps.time.second()));
Serial.println("");
Testing the Code
Upload the code to your Arduino board. Open the Serial Monitor at a baud rate of 9600. Make sure your GPS module is placed outside or next to a window to get data from satellites.
Note: you may need to wait a few seconds or minutes until the module can get a position fix.

You’ll get data on the Serial Monitor about your current location, speed, altitude, number of visible satellites HDOP, and time.
HDOP stands for Horizontal Dilution of Precision. This is a measurement of position-fixing accuracy. The higher the HDOP value is, the less accurate the position fix will be. Ideally, you should get a value lower than 2. A lower value means a better accuracy.
Wrapping Up
In this guide, you learned how to use the NEO-M8N GPS module with the Arduino. It is quite similar to the NEO-6M but supports multiple satellite systems, not only GPS. We covered how to get information about location, and time.
We have more guides for Arduino sensors and modules that you may find useful:
- Complete Guide for Ultrasonic Sensor HC-SR04 with Arduino
- Guide for I2C OLED Display with Arduino
- Complete Guide for DHT11/DHT22 Humidity and Temperature Sensor With Arduino
- Guide to NEO-6M GPS Module with Arduino
- Arduino: 39 Free Guides for Sensors and Modules
Learn more about the Arduino with our guides:
Thanks for reading.
The later M10 GPS units (and some earlier) use UBX protocol and there was a statement about phasing out NMEA. I couldn’t find a library that would work with UBX so wrote my own. Do you plan a future article to cover the M10 and UBX protocol.
Many thanks
Les Adams
Hi.
I’m not sure.
But, can you share a link to your library?
It may be useful for others in the future.
Regards,
Sara
Another really great article! Thanks for publishing it.
I was looking at the data sheet and apparently only GPS and GLONASS are enabled by default. ChatGPT provided some code to enable Galileo but I would be interested in your thoughts on including other constellations.
Thanks,
Felix
Your circuit diagram show GPS Module wired to 5V instead of 3.3V
Hi.
You’re right.
I already fixed the table.
Regards,
Sara
Hi Sara,
Great article. Thank you.
By the way, the drawing of the Uno with the GPS module is still showing the power coming from the +5v line instead of the +3.3v, as is the table below it. (someone might not be too happy if they follow these and power up )
Regards
Terry
Hi.
It can be connected to 5V like it’s showing now in the drawing.
Thanks
Regards,
Sara
Hi Sara,
I’m having problems installing the SoftwareSerial library. There seem to be 243 variants on GitHub and none of the those I’ve tried so far compile. I’m using an ESP32 by the way.
Can you tell me please the location of the one you have used?
regards
Terry
Hi.
You don’t need to install any software serial library.
We’re using the default library already included in the Arduino IDE.
Regards,
Sara
Hi Sara,
Thank you for both your replies.
If I compile the code with the board type set to Arduinio Uno it runs through OK.
If I change it to ESP32DevKit then I get a compiler error.
I found a note telling me to avoid SoftwareSerial.h as it’s not designed for ESP32. It recommends ESPSoftwareSerial but this leads to more errors.
Do you have any other recommendations please?
regards
Terry
Hi.
This tutorial is for the Arduino and not for the ESP32.
We’ll publish a similar tutorial for the ESP32 soon.
Meanwhile, you can use this for the NEO-6M as a starting point: https://randomnerdtutorials.com/micropython-esp32-neo-6m-gps/
Regards.
Sara