Saturday, June 7, 2014

GPS Location Sensing with the ITEAD GPS Shield and Arduino Uno

Location is a valuable input for many applications. In this project I use the ITEAD GPS Shield v1.1 with a GPS antenna , an Arduino Uno , and an LCD Display to sense location in terms of latitude and longitude coordinates.

With this setup I was able to acquire lat / long coordinates outdoors with a clear view of the sky in 23s to 32s with an average of 28s. Indoors on the bottom floor of a 2 story house I was able to get a location in 61s to 140s with an average of 101s from time of power up to time of first GPS lat / long coordinate acquisition. With this circuit the longer it is given the more accurate the reading. Typically I found the first reading within a hundred or so feet and given more time it would get down to a few feet accuracy.

Below is the picture of the complete circuit.

The wiring of the circuit is fairly straightforward. There are two parts. The first is how to connect the GPS shield. It connects easily on top of the Arduino Uno so thats no problem. You will also need to set the jumpers for the GPS Rx (receive) pin 7 and GPS Tx (transmit) pin 6 parts of the serial interface.

Note that later on in the sketch for the Arduino code you will see the Uno Rx pin is 6 and Uno Tx pin is 7. This is because the Uno (Tx) transmits to the GPS (Rx) on pin 7 and conversely the Uno (Rx) receives from the GPS (Tx) on pin 6.

The second part of the wiring is the LCD display. Your wiring may vary depending on the display you have, so check its instructions. For my wiring I used the hookup below:

 LCD Pin Connect to
 1 (VSS) GND Arduino pin*
 2 (VDD) + 5v Arduino pin
 3 (contrast)  2.2k resistor to GND
 4 RS Arduino pin 12
 5 R/W Arduino pin 11
 6 Enable Arduino pin 10
 7 No connection 
 8 No connection 
 9 No connection 
 10 No connection 
 11 (Data 4) Arduino pin 5
 12 (Data 5) Arduino pin 4
 13 (Data 6) Arduino pin 3
 14 (Data 7) Arduino pin 2
 15 Backlight +
  1.5k resistor to Arduino pin 13
 16 Backlight GND GND Arduino pin*

I found this blog helpful in wiring my display.

Make sure you have a GPS antenna. I was not able to get a location fix without one.

I used a small 9v battery to power the circuit. This was fine for testing the acquisition time in a variety of locations. If you intend to run this circuit for longer periods of time you may need a more powerful power supply.

You will need TinyGPS to run the sketch I used. Specifically you will need the TinyGPS.cpp and TinyGPS.h files to run this. I just dropped them in the same folder as the GPS_LCD_Display.ino Arduino sketch and then when I loaded the sketch the Arduino IDE automatically found these two files and compiled and uploaded them with my sketch to the Uno for testing.

Below is the Arduino sketch I used for testing:

#include <SoftwareSerial.h>
#include <LiquidCrystal.h>

#include "TinyGPS.h"

TinyGPS gps;

int unoRxPin = 6; // connected to Tx pin of the GPS
int unoTxPin = 7; // connected to Rx pin of the GPS
SoftwareSerial ss(unoRxPin, unoTxPin);

LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);
int backLight = 13;    // pin 13 will control the backlight

long startMillis;
long secondsToFirstLocation = 0;

void setup()
{
  ss.begin(9600);
  
  pinMode(backLight, OUTPUT);
  digitalWrite(backLight, HIGH); // turn backlight on. Replace 'HIGH' with 'LOW' to turn it off.
  lcd.begin(20,4); // columns, rows.  use 16,2 for a 16x2 LCD, etc.
  lcd.clear();  // start with a blank screen
  
  startMillis = millis();
}

void loop()
{
  bool newData = false;
  unsigned long chars = 0;
  unsigned short sentences, failed;

  // For one second we parse GPS data and report some key values
  for (unsigned long start = millis(); millis() - start < 1000;)
  {
    while (ss.available())
    {
      int c = ss.read();
      ++chars;
      if (gps.encode(c)) // Did a new valid sentence come in?
        newData = true;
    }
  }

  if (newData)
  {
    // we have a location fix so output the lat / long and time to acquire
    if(secondsToFirstLocation == 0){
      secondsToFirstLocation = (millis() - startMillis) / 1000;
    }
    
    lcd.clear();  // start with a blank screen
    
    float flat, flon;
    unsigned long age;
    gps.f_get_position(&flat, &flon, &age);
    lcd.setCursor(0,0);           // set cursor to column 0, row 0 (the first row)
    lcd.print("Lat=");
    lcd.print(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flat, 6);

    lcd.setCursor(0,1);
    lcd.print("Long=");
    lcd.print(flon == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flon, 6);

    lcd.setCursor(0,2);
    lcd.print("Acquire Time=");
    lcd.print(secondsToFirstLocation);
    lcd.print("s");
  }
  
  if (chars == 0){
    // if you haven't got any chars then likely a wiring issue
    lcd.setCursor(0,0);           // set cursor to column 0, row 0 (the first row)
    lcd.print("No GPS: check wiring");
  }
  else if(secondsToFirstLocation == 0){
    // if you have received some chars but not yet got a fix then indicate still searching and elapsed time
    lcd.clear();  // start with a blank screen

    long seconds = (millis() - startMillis) / 1000;
    
    lcd.setCursor(0,0);           // set cursor to column 0, row 0 (the first row)
    lcd.print("Searching ");
    for(int i = 0; i < seconds % 4; ++i){
      lcd.print(".");
    }
    
    lcd.setCursor(0,1);
    lcd.print("Elapsed time:");
    lcd.print(seconds);
    lcd.print("s");
  }
}

If you are interested in how location sensing can be integrated into a broader solution that includes notification of location and geo-fence alerts on a users Android phone see Geo-Fencing

Hope you found this useful. Let me know if you create any cool enhancements to it. Have fun!

14 comments:

  1. Good day David! Cool stuff! Have you had a chance to try out the Spark Core? I read about it on one of your postings and I have one sitting on my desk :) It would ostensibly be perfect for environment sensing. I'm tempted to control a hydroponic system with it. I'm using XBee parts for automation around the home, but the Spark would provide local processing power. Cheers!
    Louis
    Louis P. Sauve

    ReplyDelete
    Replies
    1. Hi Louis, thanks. I did try a few simple projects with the Spark Core. I like the wifi connectivity built in. Maybe not so much for GPS sensing since most wifi access points are stationary and its not so interesting getting a static GPS reading :-), but for other home sensors and automation could be a great option, and more affordable than purchasing an Arduino controller and wifi shield separately. Sounds like a candidate for an upcoming blog. Regards, David

      Delete
  2. This comment has been removed by a blog administrator.

    ReplyDelete
  3. Hi David, thank you for your work, it has really been helpful. I am working on a similar project that requires the acquisition of GPS coordinates (latitude and longitude data). I just have a small question, how do you set the jumper pins of the shield? Do you physically make the connections between the shield and arduino board pins (ie pin 6 and 7) or do you just specify them in the code as you have done above? I am also using the ITEAD GPS shield v1.1. Your assistance will be greatly appreciated. Regards, Mvuyo

    ReplyDelete
    Replies
    1. Thanks for your comment. Glad you found it helpful. Regarding the GPS shield jumper settings, have a look at the photo above at the link http://4.bp.blogspot.com/-6AAwhm2uvy4/U5OQoGEjjMI/AAAAAAAAAgI/11_Myr83a2o/s1600/20140607_151049.jpg. You may have to click on it and zoom in to see clearly. I put white box call outs to label the jumpers "Rx pin 7" and "Tx pin 6". These are the physical jumper settings. The settings in the sketch correspond to these jumper settings. Have fun.

      Delete
  4. HI David , thank you for your work by the way its great, I am working on your project its fun and useful but i had a problem on GPS coordinates (latitude and longitude data), it seems like he just Searching but nothing else comes on the LCD i did the same circuit u have but i don't know whats the problem please David i need your help thanks

    ReplyDelete
  5. Hi Mussab, do you have a GPS antenna connected? This is critical. Secondly, are you outdoors? I find it helpful to test outdoors initially. Once you are successful you can try getting indoors location fixes. I am able to get a location fix on the bottom floor of a 2 floor house no problem. Third thing to check is how long you are waiting for a location fix. Sometimes it can take a couple of minutes to get an initial fix. Have fun. Let us know how it works out.

    ReplyDelete
  6. Your blog is really helps for my search and amazingly it was on my searching criteria.. Thanks a lot.

    gps antenna manufacturers & cell phone booster antenna

    ReplyDelete
  7. david goodnight Indonesian time. your post is very nice. I tried to make all the same GPS device with you with additional display in serial. then I run for 500 seconds and are outside with a clear sky. But GPS only displays "Searching ..."
    What do you think is wrong? Your help is greatly appreciated

    sorry my english translation results google :)

    ReplyDelete
  8. Hi David, Thanks for your post. Your sketch compiled first time and worked flawlessly

    ReplyDelete
  9. The post is talking about rfid antenna manufacturer.Thanks for this useful post.

    uhf antenna manufacturer & rfid antenna manufacturer

    ReplyDelete
  10. Hi David.
    First of all I'm sorry for my English, it is because I am Brazilian.
    I own an Arduino Mega 2560 and Arduino board like this, but I'm having trouble connecting the GPS to Arduino.
    You have to help me?
    I need only show the current Lat and Long in the serial monitor.

    I thank you for your attention, I hope you can help me.

    ReplyDelete
  11. Hey david!!
    You are good with these stuffs.
    I have done the same as the steps you mentioned above however I am not getting fix lattitude and longitude.
    It keeps on changing and show slightly a little about 50m away from my cuurent place.
    could you please help me this?
    I got SIM28ML gps receiver with antenna.
    Does their is a problem with this??

    ReplyDelete