- Introducing the NEO-6M GPS Module
- Getting GPS Raw Data
- Parsing NMEA Sentences with TinyGPS++ Library
- Wrapping Up
This guide shows how to use the NEO-6M GPS module with the Arduino to get GPS data. GPS stands for Global Positioning System and can be used to determine position, time, and speed if you’re travelling.
You’ll learn how to:
- Wire the NEO-6M GPS module to the Arduino UNO
- Get raw GPS data
- Parse raw data to obtain selected and readable GPS information
- Get location
Introducing the NEO-6M GPS Module
The NEO-6M GPS module is shown in the figure below. It comes with an external antenna, and does’t come with header pins. So, you’ll need to get and solder some.
- This module has an external antenna and built-in EEPROM.
- Interface: RS232 TTL
- Power supply: 3V to 5V
- Default baudrate: 9600 bps
- Works with standard NMEA sentences
The NEO-6M GPS module is also compatible with other microcontroller boards. To learn how to use the NEO-6M GPS module with the Raspberry Pi, you can read: Email Alert System on Location Change with Raspberry Pi and GPS Module.
Where to buy?
You can get the NEO-6M GPS module for a price between $5 to $20. We recommend checking the NEO-6M GPS module page on Maker Advisor to compare the price in different stores and find the best one.
The NEO-6M GPS module has four pins: VCC , RX , TX , and GND . The module communicates with the Arduino via serial communication using the TX and RX pins, so the wiring couldn’t be simpler:
|NEO-6M GPS Module||Wiring to Arduino UNO|
|RX||TX pin defined in the software serial|
|TX||RX pin defined in the software serial|
Getting GPS Raw Data
To get raw GPS data you just need to start a serial communication with the GPS module using Software Serial. Continue reading to see how to do that.
For testing this example you’ll need the following parts:
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!
Wire the NEO-6M GPS module to your Arduino by following the schematic below.
- The module GND pin is connected to Arduino GND pin
- The module RX pin is connected to Arduino pin 3
- The module TX pin is connected to Arduino pin 4
- The module VCC pin is connected to Arduino 5V pin
Copy the following code to your Arduino IDE and upload it to your Arduino board.
This sketch assumes you are using pin 4 and pin 3 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 line:
Also, if your module uses a different default baud rate than 9600 bps, you should modify the code on the following line:
This sketch listen to the GPS serial port, and when data is received from the module, it is sent to the serial monitor.
Open the Serial Monitor at a baud rate of 9600.
You should get a bunch of information in the GPS standard language, NMEA. Each line you get int 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.
Understanding NMEA Sentences
NMEA sentences start with the $ character, and each data field is separated by a comma.
There are different types of NMEA sentences. The type of message is indicated by the characters before the first comma.
The GP after the $ indicates it is a GPS position. The $GPGGA is the basic GPS NMEA message, that provides 3D location and accuracy data. In the following sentence:
- 110617 – represents the time at which the fix location was taken, 11:06:17 UTC
- 41XX.XXXXX,N – latitude 41 deg XX.XXXXX’ N
- 00831.54761,W – Longitude 008 deg 31.54761′ W
- 1 – fix quality (0 = invalid; 1= GPS fix; 2 = DGPS fix; 3 = PPS fix; 4 = Real Time Kinematic; 5 = Float RTK; 6 = estimated (dead reckoning); 7 = Manual input mode; 8 = Simulation mode)
- 05 – number of satellites being tracked
- 2.68 – Horizontal dilution of position
- 129.0, M – Altitude, in meters above the sea level
- 50.1, M – Height of geoid (mean sea level) above WGS84 ellipsoid
- empty field – time in seconds since last DGPS update
- empty field – DGPS station ID number
- *42 – the checksum data, always begins with *
The other NMEA sentences provide additional information:
- $GPGSA – GPS DOP and active satellites
- $GPGSV – Detailed GPS satellite information
- $GPGLL – Geographic Latitude and Longitude
- $GPRMC – Essential GPS pvt (position, velocity, time) data
- $GPVTG – Velocity made good
To know what each data field means in each of these sentences, you can consult NMEA data here.
Parsing NMEA Sentences with TinyGPS++ Library
You can work with the raw data from the GPS, or you can convert those NMEA messages into a readable and useful format, by saving the characters sequences into variables. To do that, we’re going to use the TinyGPS++ library.
This library makes it simple to get information on location in a format that is useful and easy to understand. You can click here for more information about the TinyGPS++ Library.
Installing the TinyGPS++ Library
Follow the next steps to install the TinyGPS++ library in your Arduino IDE:
- Click here to download the TinyGPSPlus library. You should have a .zip folder in your Downloads folder
- Unzip the .zip folder and you should get TinyGPSPlus-master folder
- Rename your folder from TinyGPSPlus-master to TinyGPSPlus
- Move the TinyGPSPlus folder to your Arduino IDE installation libraries folder
- Finally, re-open your Arduino IDE
The library provides several examples on how to use it. In your Arduino IDE, you just need to go to File Examples TinyGPS++, and choose from the examples provided.
Note: the examples provided in the library assume a baud rate of 4800 for the GPS module. You need to change that to 9600 if you’re using the NEO-6M GPS module.
Getting Location Using the NEO-6M GPS Module and the TinyGPS++ Library
You can get the location in a format that is convenient and useful by using the TinyGPS++ library. Below, we provide a code to get the location from the GPS. This is a simplified version of one of the library examples.
Then, you define the software serial RX and TX pins, as well as the GPS baud rate. If you are using other pins for software serial you need to change that here. Also, if your GPS module uses a different default baud rate, you should also modify that.
Then, you create a TinyGPS++ object:
And start a serial connection on the pins you’ve defined earlier
In the setup() , you initialize serial communication, both to see the readings on the serial monitor and to communicate with the GPS module.
In the loop is where you request the information. To get TinyGPS++ to work, you have to repeatedly funnel the characters to it from the GPS module using the encode() method.
Then, you can query the gps object to see if any data fields have been updated:
Upload the code to your Arduino, and you should see the location displayed on the serial monitor. After uploading the code, wait a few minutes while the module adjusts the position to get a more accurate data.
Getting More GPS Information Using the TinyGPS++ Library
The TinyGPS++ library allows you to get way more information than just the location, and in a simple way. Besides the location, you can get:
The code below exemplifies how you can get all that information in a simple way.
The TinyGPS++ library is well commented on how to use all its functionalities.
We hope you’ve found this guide useful. We intend to make a GPS data logger with the NEO-6M GPS module and the SD card module, so stay tuned.
If you liked this project you may also like:
Thanks for reading.
[eBook] Build Web Servers with ESP32 and ESP8266 (2nd Edition)
Build a Home Automation System from Scratch » With Raspberry Pi, ESP8266, Arduino, and Node-RED.
Home Automation using ESP8266 eBook and video course » Build IoT and home automation projects.
Arduino Step-by-Step Projects » Build 25 Arduino projects with our course, even with no prior experience!
What to Read Next…
ESP8266 NodeMCU Setting a Custom Hostname (Arduino IDE)
ESP32 I2C Communication: Set Pins, Multiple Bus Interfaces and Peripherals (Arduino IDE)
ESP32 HTTP POST with Arduino IDE (ThingSpeak and IFTTT.com)
Enjoyed this project? Stay updated by subscribing our newsletter!
137 thoughts on “Guide to NEO-6M GPS Module with Arduino”
I haven’t researched it yet, but it would be convenient to get m/ft relative to an initial point.
Yes, getting the distance to an initial point can be convenient.
You can do that with the library.
Check the example called “Distance and Course” at the library documentation here: http://arduiniana.org/libraries/tinygpsplus/
They give an example on how to do that.
I hope this helps.
why this void setup() <
erlier you said 9600
what makes the number 6 ?
Howe can I write to get the readings in “Degrees minutes seconds formats (DDD MM SS)”
1. It is 9600. I’ve already corrected that. Thanks for noticing.
2. The 6 specifies the number of decimal places.
3. You can get the location in that format in the $GPGLL NMEA sentence, when you get the raw data. To do that with the library, check the “Custom NMEA Sentence Extraction” in the library documentation here http://arduiniana.org/libraries/tinygpsplus/
NEO-6M can do upto 14 decimal places for Lat Lon
= (gps.location.lat(), 14)
= (gps.location.lng(), 14)
and 7 decimal places for Altitude
Thanks for wonderful tutorials Rui Santos
Those extra decimals in output are just noise. One degree in earth surface means about 110km. So 6th decimal (in latitude) means 10cm which is for standard GPS just enough. For high precision GPS (which this is not) you can achieve cm level accuracy. And of course for altitude you don’t get real micrometer accuracy 😉
Thank you very much for this Guide. I have had this module for several weeks now and followed many guides but I could not get it to receive GPS DATA, yet alone to display it in the Serial Monitor. The I found your Guide to the NEO-6M GPS Module.
When I first ran the “Getting GPS Raw Data” code, I was excited that it worked first time.
I then tried the “Getting Location ” code. After 5 seconds it started to display the Lat Long location. Two successes.
Thirdly, I had a go at the “Getting More GPS Information” code. After several tries I was disappointed that I was seeing no GPS DATA on the monitor. I spent the next 5 minutes looking over the code, trying to find out where I had gone wrong. Then suddenly, the monitor came to life and there was the GPS DATA being displayed and updating. I was impressed. You had done what many other codes could not do, you enabled me to receive the GPS DATA.
Next project – Add a 0.96” OLED display and make the PGS portable.
Kudos for this guide..
We always do our best to make our guides easy to follow, so that anyone is able to follow along.
We’re happy to hear that you’ve found this guide useful, and that your GPS module is working perfectly.
We also intend to make a new GPS project – a GPS datalogger – in a near future, so stay tuned.
Thank you for the tutorial!
Can I get a signal to synchronize time with my DS3231? Are new sentences sent in 00 seconds?
What do you mean with synchronize with DS3231?
The GPS module allows you to get information about the time too.
Hello! I need a clock that contains the RTC block DS3231 to be precisely tuned to the other, which is several kilometers away. In my opinion, the only way through the GPS. How do i do this?
We don’t have any tutorial on that subject.
Maybe you need to read the time through the GPS module, and then, parse that time to the DS3231,
In this post you can see how to get GPS data. An on the following link, you can see how to set the time for the DS3231 real time clock: https://randomnerdtutorials.com/guide-for-real-time-clock-rtc-module-with-arduino-ds1307-and-ds3231/
I hope this helps.
Hi how can i stop that infinite loop? I just need to scan data once. Any adice? thanks!!
You can create a separate function that is called once in the setup function, for example
Hi, I have a NEO6M GPS board from Wish, following this guide does not give me the NMEA sentences, all I get on the serial monitor is
UBX-G60xx 00040007 FF47FFFFp)Z⸮b*ROM CORE 7.03 (45969) Mar 1
repeating over and over again. My baud rate is set at 57600. My board is connected to the arduino 3.3V out and I have a voltage divider between Arduino TX and the module RX. The red light on the board is always on, and it does feel hot to the touch.
I’ve never encountered that error before, so I don’t know how to fix it. Sorry about that.
it is restarting because it is powered with 5V.
Yet another well presented tutorial – Thank You.
Why is some data reported as zero: altitude = 0.00, number of satellites = 0?
Is there an equivalent SoftwareSerial library for the ESP32?
Why do several of the items have “double” in the comments in the code? Is the data presented half of the real value or twice the real value?
Hi Stew! Thanks for your kind words. The variable declared as double simply means “Double variable = Double precision floating point number. On the Uno and other ATMEGA based boards, this occupies 4 bytes. That is, the double implementation is exactly the same as the float, with no gain in precision.” More information here: arduino.cc/reference/en/language/variables/data-types/double/
I guess that happens (altitude = 0) when the requests fails to retrieve the data properly…
how gps module cab fetch location without internet.
Hi Faruq, the GPS module makes a request to satellites that provide the current location. No need for an Internet connection.
Hey! Thanks for such a useful tutorial. I was wondering if there is any way to reduce the time taken by the GPS module before it starts displaying data?
I think, you would need to optimize the library for a faster GPS readings… Or use a more powerful board with the module.
do you by any chance have a code that also saves it to a SD card? I am trying to figure that out but it not going well.
We have some examples on how to save data to microSD card. You can modify those examples to save GPS data.
Take a look at these guides:
Guide to SD Card Module with Arduino
Arduino Temperature Data Logger with SD Card Module
I hope this helps. 🙂
Great tutorial you got here..I would like to take this project a step further and turn on and off a relay once a certain speed is output. How can this be achieved? do you already have any tutorial to demonstrate this? Thanks in advance!
We don’t have any tutorial on that subject. But we do have a tutorial about the relay and the Arduino that may be useful: https://randomnerdtutorials.com/guide-for-relay-module-with-arduino/
my ss.read() function not working properly its not return GPGGA values please help me?
ss.read() function not work properly can you please help me?
What do you mean by not working properly? Can you provide more details?
ss.read() function is reading character but they are not valid so the location is not show can you provide your email so that i can contact you.
We receive lots of questions everyday. Unfortunately, we’re not able to provide email support to all our readers.
Have you tried both codes on our tutorial?
The one with the TinyGPS++ Library??
Are you wiring your GPS module correctly? Our sketch assumes you are using pins 4 and 3 as RX and TX serial pins to establish serial communication with the GPS module.
Try swapping the RX with the TX wires and see if you’re able to get the right information.
I hope this helps.
The code that provide location from the GPS noting print any thing in serial monitor
static const int RXPin = 4, TXPin = 3;
static const uint32_t GPSBaud = 9600;
// The TinyGPS++ object
// The serial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);
void setup() <
void loop() <
// This sketch displays information every time a new sentence is correctly encoded.
while (ss.available() 0) <
if (gps.location.isUpdated()) <
Serial.print(” Longitude= “);
this code always return else statement not return if?
That means that your Arduino is not receiving any information from the GPS module.
Please double check the wiring and try to change the RX with the TX pins and the other way around and see if you can get something.
If not, maybe your GPS module is broken or something 🙁
Which board are you using?
Wow, great tutorial, really helped a lot but the problem I am facing is that, when I tried to use this code with the GSM module, trying to send the coordinates in a message to a specified number, the line
does not allow my message to be sent. Message will send if I comment that line out. Anyone who can help?
Did you enter the country code in the number? What’s the error that is happening?
I’ve a problem with my GPS module. After connecting it to Uno, a red LED on the GPS module blinks once, and then nothing. There is no further blinking, and no data is received on the serial monitor.
I tried it outside in open sky, waited for around an hour, still no fix.
I connected VCC of the module directly to the 5V pin of the Uno, no pull-up resistors were used.
Is it a wiring/connection problem? I’ve soldered header pins to the Neo 6M GPS module, and there is no shorting.
Please reply asap.
Thanks and regards,
I’m not sure, to be honest I’ve never had that problem before, so I don’t know why that’s happening.
1. Re the accuracy/stability of the NEO-6M itself.
In the example the longitude is given as 8.525774 with variations in the last digit – my experience with the device over several hours the variation could be in the last 3 figures. Reading two devices at the same time they did not give the same result and they did not track.
2.Re the TinyGPS++ in general I obtained the same results as the example except every 10 seconds or so the display had a glitch. By lowering the baud rate of the output to 9600 – the same as the GPS – the issue went away. Going to higher baud rates the issue became worse. I wonder if the output was “catching” up to the input – I think one would really need to know the nuts and bolts of the TinyGPS++ and Serial Libraries to really figure it out.
Tried the same code ..the softwareserial code but didn’t get any output,tried several times but the code is not working
Can you check you have the TX and RX cables correctly wired?
Also check you are setting the right baud rate on the Serial monitor.
If you don’t get any response from the sensor, it may be something wrong with the sensor itself.
If precise readings are required I think there is an issue with the GPS examples due to the limited precision of the Arduino UNO. In the Uno using double only gives the same precision as float – ie 4 bytes which from the Arduino reference is approximately 6-7 decimal digits. Since in Rui/Sara’s example the longitude is only 8 degrees their example has only 7 digits so does not appear to run into problems.
However I’m at 145.073736 which is 9 digits. Using TinyGPS++ always gives a “0” in that 6th decimal place – I suspect the 5th place is also subject to some error. I’ve looked at the TinyGPS++ code and the only issue is they convert their readings into double. The problem then is that for the Arduino Uno double precision is the same as float and is only 4 bytes – not sufficient for the GPS. Refer to Arduino Reference for “double” – they warn about being aware when importing code into the Arduino. Note for the Due double is 8 bytes so will be OK.
Having said all that – using the GPS can give some fun projects but don’t expect to drive a robot down the centre line of the highway!
How to support the Neo-6M GPS and Arduino into a Google app?
I don’t have any project about that subject.
Great tutorial guys and a great code. I have a problem with the altitude it is showing always as zero. Does it need some calibration first or there is some other fix? All other data are showing nicely (altitude, longitude, date, time, number of satellites, speed…)
It doesn’t need any calibration. At least, in our example, we’ve just uploaded the sample code, and everything worked nicely.
Did you experiment the simple example sketch that returns NMEA sentences? And using TinyGPS library? Do you get the same results using both methods?
Hi, I have try for the second code that display longitude and latitude, but nothing come out from serial monitor….Can help me ? Thank you
What about the first code? Did it worked well?
It’s weird that the code with the library is not working :/
Hey guys! Great tutorial!
I tried out the code and everything was working perfectly fine at first. Unfortunately, the only values that seem to be updating are those for Latitude and Longitude, all other values display 0. Is there any way to solve this?
Other readers reported the same problem.
Unfortunately I have no idea why that is happening.
If you find a solution please let as know.
In the final code you have RXPin = 4, TXPin = 3; but above the first code with serial it says RXPin is pin 3 and TXPin is pin 4 ? Please explain! The first code works, but not the final code
I don’t understand your question. The RX pin is 4, and the TX pin is 3 in both codes.
I want to connect neo 6 with Esp and plot the coordinates in realtime over wifi, can you please help? pleaseeeeeeeeeeeeeeee
At the moment, we don’t have a specific tutorial about that subject.
The altitude is 0.00m
Sometimes the number of sattelites is also 0 . all the other are right.
The altitude is 0.00 and the number of satellites is allways less than 4
Other readers have reported the same issue.
Do you get that issue with the first or second example sketch?
am using ublox-neo 6m and arduino uno am getting imformation but time is behinde by 2hrs… How can I correct my code to get the right time am in Malawi (Africa) below is my code am using
This sample code demonstrates the normal use of a TinyGPS++ (TinyGPSPlus) object.
It requires the use of SoftwareSerial, and assumes that you have a
4800-baud serial GPS device hooked up on pins 4(rx) and 3(tx).
static const int RXPin = 11, TXPin = 10;
static const uint32_t GPSBaud = 9600;
// The TinyGPS++ object
// The serial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);
Serial.println(F(“An extensive example of many interesting TinyGPS++ features”));
Serial.print(F(“Testing TinyGPS++ library v. “)); Serial.println(TinyGPSPlus::libraryVersion());
Serial.println(F(“by Rodrick Custom Dzonzi”));
Serial.println(F(“Sats HDOP Latitude Longitude Fix Date Time Date Alt Course Speed Card Distance Course Card Chars Sentences Checksum”));
Serial.println(F(” (deg) (deg) Age Age (m) — from GPS —- —- to London —- RX RX Fail”));
static const double LONDON_LAT = 0.00, LONDON_LON = 0.00;
printInt(gps.satellites.value(), gps.satellites.isValid(), 5);
printFloat(gps.hdop.hdop(), gps.hdop.isValid(), 6, 1);
printFloat(gps.location.lat(), gps.location.isValid(), 11, 6);
printFloat(gps.location.lng(), gps.location.isValid(), 12, 6);
printInt(gps.location.age(), gps.location.isValid(), 5);
printFloat(gps.altitude.meters(), gps.altitude.isValid(), 7, 2);
printFloat(gps.course.deg(), gps.course.isValid(), 7, 2);
printFloat(gps.speed.kmph(), gps.speed.isValid(), 6, 2);
printStr(gps.course.isValid() ? TinyGPSPlus::cardinal(gps.course.deg()) : “*** “, 6);
unsigned long distanceKmToLondon =
LONDON_LON) / 1000;
printInt(distanceKmToLondon, gps.location.isValid(), 9);
double courseToLondon =
printFloat(courseToLondon, gps.location.isValid(), 7, 2);
const char *cardinalToLondon = TinyGPSPlus::cardinal(courseToLondon);
printStr(gps.location.isValid() ? cardinalToLondon : “*** “, 6);
printInt(gps.charsProcessed(), true, 6);
printInt(gps.sentencesWithFix(), true, 10);
printInt(gps.failedChecksum(), true, 9);
if (millis() 5000 gps.charsProcessed() 10)
Serial.println(F("No GPS data received: check wiring"));
// This custom version of delay() ensures that the gps object
// is being "fed".
static void smartDelay(unsigned long ms)
unsigned long start = millis();
> while (millis() – start 1)
int vi = abs((int)val);
int flen = prec + (val = 1000 ? 4 : vi = 100 ? 3 : vi = 10 ? 2 : 1;
for (int i=flen; ilen; ++i)
static void printInt(unsigned long val, bool valid, int len)
char sz = "*****************";
sprintf(sz, "%ld", val);
sz[len] = 0;
for (int i=strlen(sz); i 0)
sz[len-1] = ‘ ‘;
static void printDateTime(TinyGPSDate d, TinyGPSTime t)
sprintf(sz, “%02d/%02d/%02d “, d.month(), d.day(), d.year());
sprintf(sz, “%02d:%02d:%02d “, t.hour(), t.minute(), t.second());
printInt(d.age(), d.isValid(), 5);
static void printStr(const char *str, int len)
int slen = strlen(str);
for (int i=0; ilen; ++i)
Serial.print(islen ? str[i] : ‘ ‘);
please help me how I can edit my code to have correct time
Take a look at the following example.
It might help. instructables.com/id/Adjusting-GPS-Date-and-Time-to-your-Time-Zone/
I cannot get your sketch to display gps data frommy neo-6m.
I know the gps unit has a fix and generating NMEA sentences with full location data by using the u-blox u-center software. When I disconnect U-center from the gps unit and try to read the messages with your sketch it displays zeros, not valid data.
I have baud rates correct. I have the pin connection correct.
Can you advise me what I can do to learn why the sketch is not seeing the gps data,please?
I’m not sure, I’ve tried this code with multiple NEO-6M modules and it worked for me. Do you have another module that you can use to see if it works?
Thank you so much – a perfect set of examples and clearly written instructions to follow.
Hi I’m still having difficulty downloading TinyGPSPlus from github. I’ve tried downloading by ZIP and recently by cloning and it downloads all but the .CPP and .H files. So far Github has been unable to help. Is there any other source besides Github for this library? Thanks
I’ve tried to download the library by .zip from the github page, and it is working fine.
Click the “Clone or Download” button and then select “Download ZiP”.
See this image: https://randomnerdtutorials.com/wp-content/uploads/2019/01/download-tiny-gs.png
Then, you just need to follow the instructions on the “Installing the TinyGPS++ Library” section of this tutorial .
I hope this helps.
How can i get the longitude, latitude and altitude gata of gps on my mobile phone sms using sim 900