Give your next Arduino project the ability to sense locations with the NEO-6M GPS module that can track 22 satellites and identify locations anywhere in the world. It can serve as a great launch pad for anyone looking to get into the world of GPS.
They are low power (suitable for battery operated devices), affordable, easy to interface and extremely popular with hobbyists.
How does GPS work?
GPS is a system of 30+ navigation satellites orbiting the earth. We know where they are in space because they constantly transmit information about their position and current time to Earth in the form of radio signals.
A GPS receiver listens to these signals. Once the receiver calculates its distance from at least three GPS satellites, it can figure out where you are.
This process is known as Trilateration.

Hardware Overview
NEO-6M GPS Chip
At the heart of the module is a GPS chip from U-blox – NEO-6M. The chip measures less than a postage stamp but packs a surprising amount of features into its tiny frame.

It can track up to 22 satellites over 50 channels and achieve the industry’s highest level of tracking sensitivity i.e. -161 dB, while consuming only 45 mA current.
Unlike other GPS modules, it can perform 5 location updates in a second with 2.5m horizontal position accuracy. The U-blox 6 positioning engine also has a Time-To-First-Fix (TTFF) of less than 1 second.
One of the best features offered by the chip is Power Save Mode (PSM). This allows a reduction in system power consumption by selectively switching certain parts of the receiver on and off. This dramatically reduces the power consumption of the module to just 11mA making it suitable for power sensitive applications such as GPS wristwatches.
The required data pins of the NEO-6M GPS chip are broken out to a 0.1″ pitch headers. It contains the pins needed for communication with the microcontroller over the UART. The module supports baud rates from 4800bps to 230400bps with a default baud of 9600.
Here are the specifications:
Receiver Type | 50 channels, GPS L1(1575.42Mhz) |
Horizontal Position Accuracy | 2.5m |
Navigation Update Rate | 1HZ (5Hz maximum) |
Capture Time | Cool start: 27sHot start: 1s |
Navigation Sensitivity | -161dBm |
Communication Protocol | NMEA, UBX Binary, RTCM |
Serial Baud Rate | 4800-230400 (default 9600) |
Operating Temperature | -40°C ~ 85°C |
Operating Voltage | 2.7V ~ 3.6V |
Operating Current | 45mA |
TXD/RXD Impedance | 510Ω |
For more details, please refer below datasheet.
Position Fix LED Indicator
There is an LED on the NEO-6M GPS module that indicates the status of the ‘Position Fix’. It will blink at different rates depending on which state it is in:
- No blinking – it is searching for satellites.
- Blink every 1s – Position Fix is found (the module can see enough satellites).

3.3V LDO Regulator
The operating voltage of the NEO-6M chip ranges from 2.7 to 3.6V. But the good news is, this module comes with MICREL’s MIC5205 Ultra-Low Dropout 3V3 regulator.
The logic pins are also 5-volt tolerant, so we can easily connect it to Arduino or any 5V logic microcontroller without using a logic level converter.

Battery & EEPROM
The module is equipped with HK24C32 Two Wire Serial EEPROM. It is 4KB in size and is connected via I2C to the NEO-6M chip.
The module also houses a rechargeable button battery that acts as a super-capacitor.

EEPROM and battery together help in retaining the BBR (Battery Backed RAM). BBR contains clock data, latest position data (GNSS orbit data) and module configuration. But it is not for permanent data storage.
The battery charges automatically when power is supplied to the module and retains data for two weeks without power.
Since the battery retains the clock and last position data, Time-To-First-Fix (TTFF) is significantly reduced to 1s. This allows much faster position locks. Without battery the GPS is always cold-started and takes longer for the initial GPS lock.
Antenna
The module comes with -161 dBm sensitivity patch antenna for receiving radio signals from GPS satellites.

You can snap-fit this antenna into the small U.FL connector located on the module.

The patch antenna is great for most of our projects. But if you want to get more sensitivity and accuracy, you can also snap-on any 3V active GPS antenna.
U.FL connectors are small, delicate and are not rated for strain. To prevent damage to the U.FL connection, you can thread the U.FL cable through the mounting hole.
NEO-6M GPS Module Pinout
The NEO-6M GPS module has a total of 4 pins that connect it to the outside world. The connections are as follows:

GND is the ground pin and needs to be connected to the GND pin on the Arduino.
TxD (Transmitter) pin is used for serial communication.
RxD (Receiver) pin is used for serial communication.
VCC supplies power to the module. You can connect it directly to the 5V pin on the Arduino.
Wiring a NEO-6M GPS Module to an Arduino
Now that we know everything about the module, we can start connecting it to our Arduino.
Begin by connecting the patch antenna to the U.FL connector. You can thread the U.FL cable through one of the mounting holes.
The module usually comes with unsoldered header pins. So you will need to solder them first.
Next, connect the VCC pin to the 5V pin on the arduino and GND to ground.
Finally connect the Tx and Rx pins on the module to digital pins #2 and #3 respectively.

Once you have connected everything you are ready to go!
Arduino Code – Reading GPS Data
The best thing about the NEO-6M GPS receiver is that it starts spitting out data as soon as you turn it on. The following sketch simply reads this data and writes to the serial monitor.
#include <SoftwareSerial.h>
// Choose two Arduino pins to use for software serial
int RXPin = 2;
int TXPin = 3;
//Default baud of NEO-6M is 9600
int GPSBaud = 9600;
// Create a software serial port called "gpsSerial"
SoftwareSerial gpsSerial(RXPin, TXPin);
void setup()
{
// Start the Arduino hardware serial port at 9600 baud
Serial.begin(9600);
// Start the software serial port at the GPS's default baud
gpsSerial.begin(GPSBaud);
}
void loop()
{
// Displays information when new sentence is available.
while (gpsSerial.available() > 0)
Serial.write(gpsSerial.read());
}
Upload the program and open the Serial Monitor from the Arduino IDE. Remember to select 9600 baud. You should see text like the following:

NMEA Sentences
The data you are getting on the serial monitor are actually NMEA sentences.
NMEA is an acronym for National Marine Electronics Association. This is a standard message format for almost all GPS receivers.
The NMEA standard is formatted in rows of data called sentences. Each sentence has comma-separated data fields to make it easier to parse by computers and microcontrollers.
These NMEA sentences are sent at an interval called the update rate.
The NEO-6M GPS module updates this information once per second (1Hz frequency) by default. But you can configure it for up to 5 updates per second (5Hz frequency).
Parsing NMEA Sentences
It is common for microcontrollers to read NMEA sentences and parse them in a user-friendly form. Parsing is simply extracting chunks of data from the NMEA sentence.
There are many sentences in the NMEA standard. The most common are:
- $GPRMC provides time, date, latitude, longitude, altitude, and estimated velocity.
- $GPGGA sentence provides essential fix data which provides the 3D location and accuracy data.
$GPRMC NMEA sentence
To understand the NMEA message structure, let’s first examine the popular $GPRMC message.
$GPRMC, 123519, A, 4807.038, N, 01131.000, E,022.4, 084.4, 230394, 003.1, W*6A
$ | Every NMEA sentence starts with $ character. |
GPRMC | Global Positioning Recommended Minimum Coordinates |
123519 | Current time in UTC – 12:35:19 |
A | Status A=active or V=Void. |
4807.038,N | Latitude 48 deg 07.038′ N |
01131.000,E | Longitude 11 deg 31.000′ E |
022.4 | Speed over the ground in knots |
084.4 | Track angle in degrees True |
220318 | Current Date – 22rd of March 2018 |
003.1,W | Magnetic Variation |
*6A | The checksum data, always begins with * |
$GPGGA NMEA sentence
Let’s take an example of $GPGGA NMEA sentence.
$GPGGA, 123519, 4807.038, N, 01131.000, E, 1, 08, 0.9, 545.4, M, 46.9, M, , *47
$ | Starting of NMEA sentence. |
GPGGA | Global Positioning System Fix Data |
123519 | Current time in UTC – 12:35:19 |
4807.038,N | Latitude 48 deg 07.038′ N |
01131.000,E | Longitude 11 deg 31.000′ E |
1 | GPS fix |
08 | Number of satellites being tracked |
0.9 | Horizontal dilution of position |
545.4,M | Altitude in Meters (above mean sea level) |
46.9,M | Height of geoid (mean sea level) |
(empty field) | Time in seconds since last DGPS update |
(empty field) | DGPS station ID number |
*47 | The checksum data, always begins with * |
$GPRMC and $GPGGA are basic GPS NMEA sentences. There are many alternative and companion NMEA sentences that provide similar or additional information. For more information on other NMEA sentences, visit gpsinformation.org
Library Installation
Although the comma delimited format of NMEA sentences makes them extremely easy to parse, there are libraries available that do the heavy lifting. One of the popular libraries is the TinyGPS++ library. This is the library we will use in our examples.
TinyGPS++ library provides compact and easy-to-use methods for extracting position, date, time, altitude, speed, and course from GPS devices.
This library is not included in the Arduino IDE, so you will need to install it first.
To install the library navigate to Sketch > Include Libraries > Manage Libraries… Wait for Library Manager to download the library index and update the list of installed libraries.

Filter your search by typing ‘tinygpsplus‘. Click on the first entry and then select Install.

Arduino Code – TinyGPS++ Library
Once the library is installed you can copy the below sketch to the Arduino IDE.
The following test sketch will print location information (latitude, longitude and altitude) and UTC (date and time) to the serial monitor. Give the sketch a try before we explain it in some detail.
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
// Choose two Arduino pins to use for software serial
int RXPin = 2;
int TXPin = 3;
int GPSBaud = 9600;
// Create a TinyGPS++ object
TinyGPSPlus gps;
// Create a software serial port called "gpsSerial"
SoftwareSerial gpsSerial(RXPin, TXPin);
void setup()
{
// Start the Arduino hardware serial port at 9600 baud
Serial.begin(9600);
// Start the software serial port at the GPS's default baud
gpsSerial.begin(GPSBaud);
}
void loop()
{
// This sketch displays information every time a new sentence is correctly encoded.
while (gpsSerial.available() > 0)
if (gps.encode(gpsSerial.read()))
displayInfo();
// If 5000 milliseconds pass and there are no characters coming in
// over the software serial port, show a "No GPS detected" error
if (millis() > 5000 && gps.charsProcessed() < 10)
{
Serial.println("No GPS detected");
while(true);
}
}
void displayInfo()
{
if (gps.location.isValid())
{
Serial.print("Latitude: ");
Serial.println(gps.location.lat(), 6);
Serial.print("Longitude: ");
Serial.println(gps.location.lng(), 6);
Serial.print("Altitude: ");
Serial.println(gps.altitude.meters());
}
else
{
Serial.println("Location: Not Available");
}
Serial.print("Date: ");
if (gps.date.isValid())
{
Serial.print(gps.date.month());
Serial.print("/");
Serial.print(gps.date.day());
Serial.print("/");
Serial.println(gps.date.year());
}
else
{
Serial.println("Not Available");
}
Serial.print("Time: ");
if (gps.time.isValid())
{
if (gps.time.hour() < 10) Serial.print(F("0"));
Serial.print(gps.time.hour());
Serial.print(":");
if (gps.time.minute() < 10) Serial.print(F("0"));
Serial.print(gps.time.minute());
Serial.print(":");
if (gps.time.second() < 10) Serial.print(F("0"));
Serial.print(gps.time.second());
Serial.print(".");
if (gps.time.centisecond() < 10) Serial.print(F("0"));
Serial.println(gps.time.centisecond());
}
else
{
Serial.println("Not Available");
}
Serial.println();
Serial.println();
delay(1000);
}
The output on the serial monitor looks like this.

Code Explanation:
The sketch begins by including the newly installed TinyGPS++ library and the SoftwareSerial library. Then those arduino pins are declared to which the NEO-6M GPS module is connected and a variable that stores the default GPS baud rate.
Creating a TinyGPSPlus
object will help access special functions related to the library. After this we create a software serial port called gpsSerial
through which we will talk to the module.
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
int RXPin = 2;
int TXPin = 3;
int GPSBaud = 9600;
TinyGPSPlus gps;
SoftwareSerial gpsSerial(RXPin, TXPin);
In the setup function, we initiate the serial communication with the PC as well as the GPS module.
void setup()
{
Serial.begin(9600);
gpsSerial.begin(GPSBaud);
}
In the loop function, the displayInfo()
custom function is called which prints location information (latitude, longitude and altitude) and UTC (date and time) to the serial monitor, each time a new NMEA sentence is encoded correctly.
If 5000 milliseconds elapse and no characters arrive at the software serial port, a ‘No GPS detected’ error message is printed.
void loop()
{
while (gpsSerial.available() > 0)
if (gps.encode(gpsSerial.read()))
displayInfo();
if (millis() > 5000 && gps.charsProcessed() < 10)
{
Serial.println(F("No GPS detected"));
while(true);
}
}
Other Useful Functions In TinyGPS++ Library
There are many useful functions you can use with a TinyGPS++ object. Some of them are listed below:
gps.speed.value()
function returns the current ground speed in 100ths of a knot.gps.course.value()
function returns the current ground course in 100ths of a degree.gps.satellites.value()
function returns the number of visible and participating satellites.gps.hdop.value()
function returns the horizontal loss of precision.gps.age()
function tells how old an object’s data is. It returns the number of milliseconds since its last update. If the value is 1500 or more, it may indicate a ‘lost fix’.- If you want to extract data from another NMEA sentence. You can use the library’s custom extraction functionality by telling TinyGPS++ the name of the sentence and the field number you are interested in. If you want to know the magnetic variation, for example, you can call:
TinyGPSCustom magneticVariation(gps, "GPRMC", 10);
You can then query it like this:magneticVariation.value()
U-center software
The U-center from u-blox is a powerful tool for the evaluation, performance analysis and configuration of u-blox GPS receivers, including the NEO-6M. It is a free tool but it can be used only on Windows platform.
It can display realtime structured and graphical data visualizations from any GPS receiver such as:
- Satellite Summary View
- Navigation Summary View
- Compass, speedometer, clock, altimeter
- Chart view of any two parameters of choice
- Data Recording and Playback Functionality
This software can be downloaded from u-blox website.
Connecting NEO-6M to U-center
To use the U-Center software, you need to connect your NEO-6M to your PC using a USB to TTL converter.
The image below shows the NEO-6M connected to the PC with the PL2303 USB to TTL converter.

Using U-center
After a successful installation, U-Center can be started from the Start Menu (All Programs -> u-blox-> u-center -> u-center), it will start up as shown below.

Locate the Communications toolbar and click the arrow next to the icon. This will show a list of all available COM ports. Select the corresponding COM port where the receiver is connected.

The Text Console button will show you the raw NMEA sentences. This is handy for quickly inspecting visible ASCII coming from the module over USB.

u-center can display position on Google Maps (offline/online) as well.

For more information about U-center software, please refer this user guide.