GPS Shield Quickstart Guide


GPS Shield

GPS is a powerful tool that can be fun and easy to use with the help of Arduino. Projects ranging from logging a trip in your car, all the way to navigating autonomously are all possible with GPS.

 

This quickstart guide will tell you everything you need to know about how to get time and position data with a GPS module. All you need is a GPS module, the GPS Shield, and an Arduino.

 

 

What do you do with GPS?

We all know GPS can show your immediate location, similar to what you would find in a hand held unit or automobile console. GPS is also good for everything from tracking and logging, extremely accurate time keeping, to autonomous navigation and geocaching. These types of applications rely on more than just simple latitude and longitude, but elevation, time, heading, ground speed, and signal strength from the satellites. This guide will show you how to get started writing code that will parse or pick out meaningful information from the data that comes out of the TX pin on a GPS module.

For a detailed explanation on how GPS works, please refer to the GPS Tracking Comparisons Tutorial.

Where to start?

The first thing you want to do is assemble the GPS shield as shown above. See the GPS Shield Assembly Guide for detailed assembly instructions.

Next, choose a GPS module that will work with the GPS Shield (see the product page for compatible GPS modules). The GPS Shield has a connector for an EM-406, so the EM-406 is the easiest option to get moving.

Here are the configuration options for the GPS Shield.

There are two slide switches, one push button switch, and two solder jumpers on the GPS Shield as shown above.

 

1 - Power Switch: Controls power to the GPS module

2 - UART Selection Switch: If the UART is selected, the GPS module will be connected to Arduino digital pins 0 and 1. If DLINE is selected, the GPS will be connected to digital pins 2 and 3 (default) or potentially any other digital pin. DLINE must be selected in order to upload code. The reason for this is because the UART selection uses the same lines that are used for programming. If UART is selected and you load code, you will probably get errors in the Arduino IDE, but nothing should get damaged. This is called bus contention. For this tutorial, you can leave the switch in the DLINE position for both loading code and running code.

3 - Solder Jumpers: These jumpers, when disabled (solder removed), will disconnect the GPS communication lines (TX and RX) from the Arduino. This allows for the user to connect any digital line to the GPS communication lines. To use, simply disconnect the jumpers, then wire the TX and RX labeled pins on the shield to any one of the digital pins 2-13 on the shield.

4 - Reset Switch: This button is directly tied to the Arduino reset switch, so hitting this button will restart your Arduino sketch.

Finally, plug in the GPS module into the Shield, then plug the Shield into an unpowered Arduino as shown above. Now you are ready to read and manipulate GPS NMEA data.

 

How do I make it work?

Once you have everything assembled, you are almost ready to load the example project on the Arduino. But first, you will need to create a directory called libraries within your arduino sketchbook, if you don't already have one. Then, download the TinyGPS and NewSoftSerial libraries and unzip them into the libraries folder.

 

This is what my libraries folder looks like. Once you have put the new libraries in the correct locations, the example code should compile with no errors. Also, Make sure the UART Selection Switch is moved to DLINE and proceed to load the example code onto your Arduino.

If everything has gone as planned, your code compiles without errors and you can successfully load your code, you should be able to open the serial monitor to see what the Arduino is outputting.

Here is what you should see if you just turned on your GPS after it has been powered off for a while.

If your GPS does not have a lock, you should see this.

 

Here is what it looks like after the GPS has sat for about a minute:

If you see this, your GPS has a valid lock.

No, I am not moving at 5km per hour, I am just inside an office building and not moving. It's sometimes hard for GPS to know if you are completely still, especially if you are inside.

Using the example code

All of the parsing and complicated stuff goes on in the TinyGPS and NewSoftSerial libraries, the only thing we need to do is invoke the functions available in the libraries. To see how this is done, refer to the guide below. For a complete list of available TinyGPS functions look in the keyword.txt file in the TinyGPS library folder located in your Arduino directory.

NOTE: This sketch will only work with Arduino 0018 and above.

Be sure to include the newly added libraries TinyGPS and NewSoftSerial

In order for this sketch to compile without errors, you will need to download the NewSoftSerial and TinyGPS libraries and include them in your sketch. These libraries contain all of the code that allows us to parse the GPS NMEA string and receive it through any digital pin on the Arduino.

#include SoftwareSerial.h

The NewSoftSerial library allows us to define any digital pin to work as a serial UART pin.

#include TinyGPS.h

The TinyGPS library is where the GPS parsing takes place. The library has many cool features beyond the scope of this tutorial, so be sure to check out arduiniana.org for more examples.

Define the pins you are using and the baud rate of your GPS

#define RXPIN 2   
#define TXPIN 3

Since we are using the GPS Shield with the DLINE setting, then we need to define which pins on the Arduino the GPS will connect to. The GPS Shield uses these pins as the default connections.

#define GPSBAUD 4800

We also need to define the baud rate for the GPS module. The EM-406 works at 4800bps, but if you are using another type of GPS, be sure to check what baud rate the GPS is using to communicate.

Create instances of the objects from the new libraries

TinyGPS gps;
SoftwareSerial nss(RXPIN, TXPIN);

These lines of code basically initialize the new libraries, TinyGPS and NewSoftSerial, and define how we will use the libraries.

Create function prototypes

We will only use one function to help us grab the data.

void getgps(TinyGPS &gps);

The getgps function will organize and print the values we want into the serial monitor.

Setup or initialize the hardware

Serial.begin(115200);

Set the baud rate of the outgoing data from the Arduino board that will be received by the Arduino serial monitor. It must be at least 115200 bps, because we need to print everything before a new sentence comes in. If you slow it down, the messages might not be valid and you will get errors.

uart_gps.begin(GPSBAUD);

Then set the baud rate for the NewSoftSerial library. This is the baud rate of your GPS.

Main loop

The main loop constantly runs as long as your Arduino is powered. Here is where we want to check to see if there is any serial data coming out of the GPS, check to see if that data is valid, and if so, jump to the getgps function and print the data we want.

while(uart_gps.available())     
 {
      int c = uart_gps.read();    
      if(gps.encode(c))      
      {
        getgps(gps);         
      }
 }

Here is the step through: While there is data on the RX pin, nss.available() is TRUE, so jump into the while loop and read one byte off of the RX pin with nss.read() and load it into variable 'c'. Then check to see if variable 'c' is a finish to a new valid GPS NMEA sentence with gps.encode(c). If there is a new valid sentence, gps.encode(c) is TRUE and we jump into getgps(gps).

GetGPS function

The GetGPS function simply calls the TinyGPS functions which automatically load the data into variables then prints them out in a readable format.

To get latitude and longitude you need to define variables and call the TinyGPS function responsible for grabing that data.

float latitude, longitude;
gps.f_get_position(&latitude, &longitude);

Why float and not int or byte?Think about the data you want and if that data will need to have fractional precision. In other words, will the values be whole numbers, like the day or month, or will the values be decimals, like latitude or elevation (i.e. 40.06477 N)? If you want to print decimal numbers you will need to define float variables.

Serial.print(latitude, 5);
Serial.print(longitude, 5);

This will print the latitude and longitude with 5 decimal precision, which looks like: 40.06477.

If the data you want is a whole number, you need to define them as either int or byte. However, if using the crack_datetime function, you need to define the variables in exactly this way.

int year;
byte month, day, hour, minute, second, hundredths;
gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths);

Then print the value with Serial.print.

Serial.print(year);
Serial.print(hour, DEC);
Serial.print(minute, DEC);

Be sure to print byte defined variables as decimals (hour, minutes, or seconds). Since year is defined already as a integer, you can just print.

To test to see if your location is valid, simply highlight and copy the latitude and longitude values from the serial monitor and paste them into Google Maps. A map with your location pin pointed should be visible.

If you want to know more about how these functions are working, keep looking around in the library folders, all of the information is there, it just might not be that easy to interpret. But I hope the example code and this tutorial will serve as a start to get you up and running with GPS.

 

Have a suggestion for how we can improve this quickstart guide? Concepts not explained clearly? Need more example code? Please let us know. You can leave a comment below or email us spark@sparkfun.com. Also let us know if this is the most awesome Quickstart guide you have ever encountered and we will stop trying to improve it.

Comments 32 comments

  • Can anyone suggest how to get this example sketch working with the Mega? It works fine for me with the Uno using Arduino 1.0 and the new TinyGPS library. Obviously I’m missing something, but I naively assumed that the apparent pin compatibility would allow the shield to be supported directly. The Mega’s extra serials are on other pins, right?

  • if I use the just EM406 and Atmega328 the library works? how could I connect?

  • Is this compatible with netduino plus 2 ?

  • hi friend i hv a problem in using the gps shield that it take long time to connect the sat meant sometime it connect it in a min or sometime it need a day for searching in same place so plz tell me guys what to do if i not able to get signal ??????

  • can I use this same code with other GPS shield? thanks

  • quote “"The NewSoftSerial library allows us to define any digital pin to work as a serial UART pin” how can i use multiple UART (3) ?

  • I did put the new ‘libraries’ folder in the place you described, and run the example code, but it doesn’t work as expected.. still can’t find the file or directory…. I’m very frustrated..
    save me… I also put the libraries 1.In the hardware folder as described in the example code. 2.In the sketchbook folder as described above 3.In the libraries folder directly None of them work.. save me !!!!!

    • Which version of Arduino are you using? This is an older tutorial, so it’s more likely to work with Arduino 0.2x than 1.0.

      Also, if you didn’t know, you need to quit and restart the Arduino IDE for new libraries to show up.

  • Any one wired this to the mega? I cant get it to work. Ive heard the mega doesn’t use the newsoft serial?

    • I got this working with the Mega 2560 just now. I jumpered the GPS shield pin 2 (TX pin of GPS chip) to Pin 19 on the Mega 2560 (RX1), and updated the program to use the built-in Serial1 instead of soft pins defined by SoftwareSerial.

      Eg I initialise it using “Serial1.begin(GPSBAUD);” check the status with Serial1.available() and so on. The modified code I used is here:

      http://jcox-fatboy.blogspot.co.uk/2012/11/arduino-gps-hello-world-program.html

      Another way to achieve this, using SoftwareSerial is to connect the GPS shield pin2 to pin 10, and use pin 10 as the RXPIN. The sample code from Sparkfun works almost unchanged. You’d set RXPIN to 10, and you need to add the line “pinMode(RXPIN, INPUT);” to the setup() function.

      HTH.

  • Can you only use pins 2 and 3 of the Arduino Uno to connect the GPS Shield?

  • Is there any possible that I can activate my GPS module (FV-M8) without use the shield? Mean that, I just jump the GND, Vin and TX1 (from the GPS module) to the RX pin (from Arduino 328) wire directly?

  • Can someone tell me what the exact size is of the height of the shield and the Arduino IDE on top of each-other? I only have limited space. (Have to built in the size of a can, not the best dimensions in such a thing)
    Look like a very cool shield! And lovely that there is such a good guide to help me out!

  • I also needed to switch the TX and RX pins in the example sketch when using it with the EM406.
    Also: Be sure to set your terminal (or the Arduino’s serial monitor) to 115200 baud even though the EM406 itself is communicating at 4800 baud.

    • Sorry about that. I made the changes to the source code. Here is what has changed:
      hardware v13 uses TXPIN = 2, RXPIN = 3
      hardware v14 and v15 uses TXPIN = 3, RXPIN = 2

    • I had trouble getting anything - even “waiting for lock”, just two characters of garble. I followed the suggestions here in the comment section:<br />
      <br />
      1. Set Serial Monitor to 115200<br />
      <br />
      2. Swap RXPIN and TXPIN (RXPIN 2, TXPIN 3)<br />
      <br />
      I works now. Thanks.

      • By the way, the JohnBoxall tutorial is excellent, as well. I was able to get his running first, then came back to this one.

  • Alok: Hello,
    I never get valid sentences , all I get is
    ….
    waiting for lock,
    and it prints nothing, I see my red led on GPS blinking , it never becomes solid red, what I need to do to get valid gps sentences, I am using arduino 18
    -Thanks
    -Alok Kumar Mishra

    In this case I would just test the serial communication with the GPS chip with a terminal emulator, like Tera Term Pro or Hyperterminal, connected to the Shield. I just did that with the EM-406A (using the uUSB-MB5 - http://www.sparkfun.com/commerce/product_info.php?products_id=8531), and saw that the chip keeps sending NMEA strings, even though I am inside and cannot receive GPS signals. This way I am sure that the basics works, before introducing additional layers such as GPS API etc.

  • Here is my own getting started guide if anyone is interested - http://wp.me/pQmjR-Ty

  • Hello,
    I never get valid sentences , all I get is
    ….
    waiting for lock,
    and it prints nothing, I see my red led on GPS blinking , it never becomes solid red, what I need to do to get valid gps sentences, I am using arduino 18
    -Thanks
    -Alok Kumar Mishra

    • I had the same problem while using the EM-406 and GPS shield. Then I switched RX and TX pins (#define RXPIN 2, #define TXPIN 3) in the example sketch and it worked.

      • Switching TX and RX solved my problem as well. Hey Sparkfun might be a good idea to fix the sample code.

      • also using gps shield and arduino18.
        I tried switching RX and TX define as well, but it didn’t work for me :( was there anything else you changed to make the em406 output valid sentences?

  • I followed this tutorial with the recommended hardware and software. The code compiles and runs, however:
    gps.encode© in loop() never returns a non-zero value (always false) even if my EM406a obtains a lock (red led blinking). Everything seems to be connected properly.

    • Are you using the latest version of Arduino? If not make sure you are using Arduino 18.

  • the GPS Shield Assembly Guide link just takes you to an empty page - no tutorial
    Is this a dead link? Or a “Coming Soon” thing?