BLOG > Tutorial 15 for Arduino: GPS Tracking

This tutorial was featured on the Cooking-Hacks website on 07/18/2012

This was easily the most time I’ve spent producing an Arduino Tutorial.  I’ve been sporadically walking around NYC with this GPS for weeks as I’ve tweaked the code and gotten it just right.  If it wasn’t obvious from the title, this tutorial will teach you how to use an Arduino paired with a GPS Module and an SD Card Module to log your latitude and longitude over the course of a day.  As a bonus, I’ll also show you how to easily overlay this data onto a map using services like Google Earth and Google Fusion Tables (NOTE: Fusion Tables is being phased out by Google, so I recommend against using it – Edit from February 2019). I added a short “history lesson” to this episode to explain how GPS came to be; it’s the first time I’ve done that, so please let me know if you like the extra knowledge. Grab some popcorn and your Arduino, because this tutorial is pretty long – GPS is complicated! The schematics, programs, parts list, sample data, and important links are available for download below.

I used the tinyGPS library to decode the NMEA GPS Data.  Cooking-Hacks generously supplied both the GPS shield and SD Card shield that I used in this tutorial.

You can download the files associated with this episode here: Arduino Tutorial 15 Files

Source materials for all my Arduino tutorials can be found in my github repository.
GNU GPL License Distributed under the GNU General Public (Open-Source) License.
Please Attribute and Share-Alike.

This video can also be viewed at element14.com.

250 comments

  1. Hi,
    I just made the tutorial entirely but i have one problem:
    The setup procedure start all over again for several times and then all the serial monitor printout stops and nothing more happens. The only difference between your example script and my script is that i use SoftwareSerial on Port 2 and 3 for the GPS. And i use an skylab GPS Module that needs a bauderate of 9600. Also my chipselectpin for the SD is on pin 4 since i am using an Ethernet Shield because i have no separate SD Shield. That are the only changes i made to the workshop scirpt. But as mentioned i only get a couple repeats of the setup part. What am i doing wrong? Here is the code (actually your code with small changes):

    //Jeremy Blum’s Arduino Tutorial Series – Episode 15 – GPS Tracking
    //Sample Code 2 – Logging GPS Data to an SD Card
    //https://www.jeremyblum.com
    //TinyGPS Library and Helper Functions by Mikal Hart http://arduiniana.org/libraries/tinygps/

    #include
    #include
    #include
    #include

    /* This sample code demonstrates the normal use of a TinyGPS object.
    It uses an Arduino UNO with a GPS (Skylab) attached to nss at 9600 buad.
    */

    TinyGPS gps;
    SoftwareSerial nss(2, 3);

    static char dtostrfbuffer[20];
    int CS = 4;
    int LED = 13;

    //Define String
    String SD_date_time = “invalid”;
    String SD_lat = “invalid”;
    String SD_lon = “invalid”;
    String dataString =””;

    static void gpsdump(TinyGPS &gps);
    static bool feedgps();
    static void print_float(float val, float invalid, int len, int prec, int SD_val);
    static void print_int(unsigned long val, unsigned long invalid, int len);
    static void print_date(TinyGPS &gps);
    static void print_str(const char *str, int len);

    void setup()
    {
    pinMode(CS, OUTPUT); //Chip Select Pin for the SD Card
    pinMode(LED, OUTPUT); //LED Indicator
    pinMode(10, OUTPUT);

    //Serial interfaces
    Serial.begin(9600);
    nss.begin(9600);

    //Connect to the SD Card
    if(!SD.begin(CS))
    {
    Serial.println(“Card Failure”);
    return;
    }

    Serial.print(“Testing TinyGPS library v. “); Serial.println(TinyGPS::library_version());
    Serial.println(“by Mikal Hart”);
    Serial.println();
    Serial.print(“Sizeof(gpsobject) = “); Serial.println(sizeof(TinyGPS));
    Serial.println();
    Serial.println(“Sats HDOP Latitude Longitude Fix Date Time Date Alt Course Speed Card Distance Course Card Chars Sentences Checksum”);
    Serial.println(” (deg) (deg) Age Age (m) — from GPS —- —- to London —- RX RX Fail”);
    Serial.println(“————————————————————————————————————————————–“);
    }

    void loop()
    {
    bool newdata = false;
    unsigned long start = millis();

    // Every second we print an update
    while (millis() – start < 1000)
    {
    if (feedgps())
    newdata = true;
    }

    gpsdump(gps);

    //Write the newest information to the SD Card
    dataString = SD_date_time + "," + SD_lat + "," + SD_lon;
    if(SD_date_time != "invalid")
    digitalWrite(LED, HIGH);
    else
    digitalWrite(LED, LOW);

    //Open the Data CSV File
    File dataFile = SD.open("LOG.csv", FILE_WRITE);
    if (dataFile)
    {
    dataFile.println(dataString);
    Serial.println(dataString);
    dataFile.close();
    }
    else
    {
    Serial.println("
    Couldn't open the log file!");
    }
    }

    static void gpsdump(TinyGPS &gps)
    {
    float flat, flon;
    unsigned long age, date, time, chars = 0;
    unsigned short sentences = 0, failed = 0;
    static const float LONDON_LAT = 51.508131, LONDON_LON = -0.128002;

    print_int(gps.satellites(), TinyGPS::GPS_INVALID_SATELLITES, 5);
    print_int(gps.hdop(), TinyGPS::GPS_INVALID_HDOP, 5);
    gps.f_get_position(&flat, &flon, &age);
    print_float(flat, TinyGPS::GPS_INVALID_F_ANGLE, 9, 5, 1); //LATITUDE
    print_float(flon, TinyGPS::GPS_INVALID_F_ANGLE, 10, 5, 2); //LONGITUDE
    print_int(age, TinyGPS::GPS_INVALID_AGE, 5);

    print_date(gps); //DATE AND TIME

    print_float(gps.f_altitude(), TinyGPS::GPS_INVALID_F_ALTITUDE, 8, 2, 0);
    print_float(gps.f_course(), TinyGPS::GPS_INVALID_F_ANGLE, 7, 2, 0);
    print_float(gps.f_speed_kmph(), TinyGPS::GPS_INVALID_F_SPEED, 6, 2, 0);
    print_str(gps.f_course() == TinyGPS::GPS_INVALID_F_ANGLE ? "*** " : TinyGPS::cardinal(gps.f_course()), 6);
    print_int(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0UL : (unsigned long)TinyGPS::distance_between(flat, flon, LONDON_LAT, LONDON_LON) / 1000, 0xFFFFFFFF, 9);
    print_float(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : TinyGPS::course_to(flat, flon, 51.508131, -0.128002), TinyGPS::GPS_INVALID_F_ANGLE, 7, 2, 0);
    print_str(flat == TinyGPS::GPS_INVALID_F_ANGLE ? "*** " : TinyGPS::cardinal(TinyGPS::course_to(flat, flon, LONDON_LAT, LONDON_LON)), 6);

    gps.stats(&chars, &sentences, &failed);
    print_int(chars, 0xFFFFFFFF, 6);
    print_int(sentences, 0xFFFFFFFF, 10);
    print_int(failed, 0xFFFFFFFF, 9);
    Serial.println();
    }

    static void print_int(unsigned long val, unsigned long invalid, int len)
    {
    char sz[32];
    if (val == invalid)
    strcpy(sz, "*******");
    else
    sprintf(sz, "%ld", val);
    sz[len] = 0;
    for (int i=strlen(sz); i 0)
    sz[len-1] = ‘ ‘;
    Serial.print(sz);
    feedgps();
    }

    static void print_float(float val, float invalid, int len, int prec, int SD_val)
    {
    char sz[32];
    if (val == invalid)
    {
    strcpy(sz, “*******”);
    sz[len] = 0;
    if (len > 0)
    sz[len-1] = ‘ ‘;
    for (int i=7; i<len; ++i)
    sz[i] = ' ';
    Serial.print(sz);
    if(SD_val == 1) SD_lat = sz;
    else if(SD_val == 2) SD_lon = sz;
    }
    else
    {
    Serial.print(val, prec);
    if (SD_val == 1) SD_lat = dtostrf(val,10,5,dtostrfbuffer);
    else if (SD_val == 2) SD_lon = dtostrf(val,10,5,dtostrfbuffer);
    int vi = abs((int)val);
    int flen = prec + (val = 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
    for (int i=flen; i<len; ++i)
    Serial.print(" ");
    }
    feedgps();
    }

    static void print_date(TinyGPS &gps)
    {
    int year;
    byte month, day, hour, minute, second, hundredths;
    unsigned long age;
    gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
    if (age == TinyGPS::GPS_INVALID_AGE)
    {
    Serial.print("******* ******* ");
    SD_date_time = "invalid";
    }
    else
    {
    char sz[32];
    sprintf(sz, "d/d/d d:d:d ",
    month, day, year, hour, minute, second);
    Serial.print(sz);
    SD_date_time = sz;
    }
    print_int(age, TinyGPS::GPS_INVALID_AGE, 5);
    feedgps();
    }

    static void print_str(const char *str, int len)
    {
    int slen = strlen(str);
    for (int i=0; i<len; ++i)
    Serial.print(i<slen ? str[i] : ' ');
    feedgps();
    }

    static bool feedgps()
    {
    while (nss.available())
    {
    if (gps.encode(nss.read()))
    return true;
    }
    return false;
    }

    I have an self build version of the script that functions a little better (i can post it if you like) but in that script i have the problem that i cant convert the month, year, etc values to put it on the SD String. I get 2-3 good readings and after that i got nonsense from all parameters. If i put the date and time lines under comment the script gives me good readings for a long time. i tested the thing on a 9 volt battery on my day today and i got a pretty precise gps track made with this tool: http://www.gpsvisualizer.com/map_input?form=google (only with latitude and lontitude colums).

    Maybe you can help me to make this work. I am not (yet) a real pro in this thing. i started this a couple of months ago and bought all kind of weird sensors and switches and i think its a great hobby and fun. But now i am a little stuck with this gps thing.

    at last: i wanna thank you for your tutorials. i did follow thorough most of them and succeeded and learned a lot about the background of what am i sketching.

    greetings Stephan

    1. Hi me again,

      I Just commented out the Hole Part:

      /*
      Serial.print(“Testing TinyGPS library v. “); Serial.println(TinyGPS::library_version());
      Serial.println(“by Mikal Hart”);
      Serial.println();
      Serial.print(“Sizeof(gpsobject) = “); Serial.println(sizeof(TinyGPS));
      Serial.println();
      */
      // Serial.println(“Sats HDOP Latitude Longitude Fix Date Time Date Alt Course Speed Card Distance Course Card Chars Sentences Checksum”);
      // Serial.println(” (deg) (deg) Age Age (m) — from GPS —- —- to London —- RX RX Fail”);

      // Serial.println(“————————————————————————————————————————————–“);

      And now i got good readings. i am really confused what the reason could be for that….

  2. Hi Jeremy

    I solved the first problem with the weird output but now I have another problem.

    This is my code at the moment, i’m using an Arduino Uno:

    #include

    #include
    #include
    #include

    /* This sample code demonstrates the normal use of a TinyGPS object.
    It requires the use of SoftwareSerial, and assumes that you have a
    4800-baud serial GPS device hooked up on pins 3(rx) and 4(tx).
    */

    TinyGPS gps;
    SoftwareSerial nss(3, 4);
    static char dtostrfbuffer[20];
    int CS = 53;
    int LED = 13;

    //Define String
    String SD_date_time = “invalid”;
    String SD_lat = “invalid”;
    String SD_lon =”invalid”;
    String dataString =””;

    static void gpsdump(TinyGPS &gps);
    static bool feedgps();
    static void print_float(float val, float invalid, int len, int prec);
    static void print_int(unsigned long val, unsigned long invalid, int len);
    static void print_date(TinyGPS &gps);
    static void print_str(const char *str, int len);

    void setup()
    {
    pinMode(CS, OUTPUT);//Chip Select Pin for the SD Card
    pinMode(LED, OUTPUT);//LED Indicator

    Serial.begin(115200);
    nss.begin(4800);

    //Connect to the SD Card
    if(!SD.begin(4))
    {
    Serial.println(“Card Failure”);
    }

    Serial.print(“Testing TinyGPS library v. “); Serial.println(TinyGPS::library_version());
    Serial.println(“by Mikal Hart”);
    Serial.println();
    Serial.print(“Sizeof(gpsobject) = “); Serial.println(sizeof(TinyGPS));
    Serial.println();
    Serial.println(“Sats HDOP Latitude Longitude Fix Date Time Date Alt Course Speed Card Distance Course Card Chars Sentences Checksum”);
    Serial.println(” (deg) (deg) Age Age (m) — from GPS —- —- to London —- RX RX Fail”);
    Serial.println(“————————————————————————————————————————————–“);
    }

    void loop()
    {
    bool newdata = false;
    unsigned long start = millis();

    // Every second we print an update
    while (millis() – start < 1000)
    {
    if (feedgps())
    newdata = true;
    }

    gpsdump(gps);

    //Write the newest information to the SD Card
    dataString = SD_date_time + "," + SD_lat + "," + SD_lon;
    if(SD_date_time != "invalid")
    {
    digitalWrite(LED, HIGH);

    }
    else
    {
    digitalWrite(LED, LOW);
    }

    //Open the Data CSV File
    File dataFile = SD.open("LOG.csv", FILE_WRITE);
    if (dataFile)
    {
    dataFile.println(dataString);
    Serial.println(dataString);
    dataFile.close();
    }
    else
    {
    Serial.println("\nCouldn't open the log file!");
    }
    }
    static void gpsdump(TinyGPS &gps)
    {
    float flat, flon;
    unsigned long age, date, time, chars = 0;
    unsigned short sentences = 0, failed = 0;
    static const float LONDON_LAT = 51.508131, LONDON_LON = -0.128002;

    print_int(gps.satellites(), TinyGPS::GPS_INVALID_SATELLITES, 5);
    print_int(gps.hdop(), TinyGPS::GPS_INVALID_HDOP, 5);
    gps.f_get_position(&flat, &flon, &age);
    print_float(flat, TinyGPS::GPS_INVALID_F_ANGLE, 9, 5); //LATITUDE
    print_float(flon, TinyGPS::GPS_INVALID_F_ANGLE, 10, 5);//LONGITUDE
    print_int(age, TinyGPS::GPS_INVALID_AGE, 5);

    print_date(gps); //DATE AND TIME

    print_float(gps.f_altitude(), TinyGPS::GPS_INVALID_F_ALTITUDE, 8, 2);
    print_float(gps.f_course(), TinyGPS::GPS_INVALID_F_ANGLE, 7, 2);
    print_float(gps.f_speed_kmph(), TinyGPS::GPS_INVALID_F_SPEED, 6, 2);
    print_str(gps.f_course() == TinyGPS::GPS_INVALID_F_ANGLE ? "*** " : TinyGPS::cardinal(gps.f_course()), 6);
    print_int(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0UL : (unsigned long)TinyGPS::distance_between(flat, flon, LONDON_LAT, LONDON_LON) / 1000, 0xFFFFFFFF, 9);
    print_float(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : TinyGPS::course_to(flat, flon, 51.508131, -0.128002), TinyGPS::GPS_INVALID_F_ANGLE, 7, 2);
    print_str(flat == TinyGPS::GPS_INVALID_F_ANGLE ? "*** " : TinyGPS::cardinal(TinyGPS::course_to(flat, flon, LONDON_LAT, LONDON_LON)), 6);

    gps.stats(&chars, &sentences, &failed);
    print_int(chars, 0xFFFFFFFF, 6);
    print_int(sentences, 0xFFFFFFFF, 10);
    print_int(failed, 0xFFFFFFFF, 9);
    Serial.println();
    }

    static void print_int(unsigned long val, unsigned long invalid, int len)
    {
    char sz[32];
    if (val == invalid)
    strcpy(sz, "*******");
    else
    sprintf(sz, "%ld", val);
    sz[len] = 0;
    for (int i=strlen(sz); i 0)
    sz[len-1] = ‘ ‘;
    Serial.print(sz);
    feedgps();
    }

    static void print_float(float val, float invalid, int len, int prec)
    {
    char sz[32];
    if (val == invalid)
    {
    strcpy(sz, “*******”);
    sz[len] = 0;
    if (len > 0)
    sz[len-1] = ‘ ‘;
    for (int i=7; i<len; ++i)
    sz[i] = ' ';
    Serial.print(sz);
    }
    else
    {
    Serial.print(val, prec);
    int vi = abs((int)val);
    int flen = prec + (val = 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
    for (int i=flen; i<len; ++i)
    Serial.print(" ");
    }
    feedgps();
    }

    static void print_date(TinyGPS &gps)
    {
    int year;
    byte month, day, hour, minute, second, hundredths;
    unsigned long age;
    gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
    if (age == TinyGPS::GPS_INVALID_AGE)
    Serial.print("******* ******* ");
    else
    {
    char sz[32];
    sprintf(sz, "%02d/%02d/%02d %02d:%02d:%02d ",
    month, day, year, hour, minute, second);
    Serial.print(sz);
    }
    print_int(age, TinyGPS::GPS_INVALID_AGE, 5);
    feedgps();
    }

    static void print_str(const char *str, int len)
    {
    int slen = strlen(str);
    for (int i=0; i<len; ++i)
    Serial.print(i<slen ? str[i] : ' ');
    feedgps();
    }

    static bool feedgps()
    {
    while (nss.available())
    {
    if (gps.encode(nss.read()))
    return true;
    }
    return false;
    }

    I do get an output like you do but again I get some weird output beneath: Course Speed Card, Distance Course Card, Chars RX, Sentences RX and Checksum Fail. This output looks like some weird symbols again with some squares in between (I can't copy paste the weird output and can't post an image).

    Hopefully you can give me some help

    Thanks

  3. car tracking with gps skylap + arduino2560 + sim 300 + (16*2 lcd)
    can any one help me to give me the code of this project please???
    i interfaced gsm but the i cant interface gps
    and i want the code please and thank you Very Happy

  4. Zett,
    I am using an Adafruit Ultimate GPS Logger Shield with an Arduino Uno, and I had similar inconsistent problems. It turned out that I had used up all of the SRAM. I discovered this by searching the Web and found the following routine

    int freeRam () // SRAM Testing
    {
    extern int __heap_start, *__brkval;
    int v;
    return (int) &v – (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
    }

    If you call it like this
    Serial.println(freeRam());

    then you will see the amount of free SRAM available.
    So to get this tutorial to work I had to comment out all of the calls to Serial.print and Serial.println, especially the ones with the text in them. This increased the amount of free SRAM to 489 and the program runs fine.

    Regards

    Jasea

  5. iam student and that apart of my graduation project
    i want arduino code
    car tracking with gps skylap + arduino2560 + sim 300
    can any one help me to give me the code of this project please???
    i interfaced gsm but the i cant interface gps
    and i want the code please and thank you Very much

  6. I just implemented and tested this GPS tracker while walking around on my balcony . I mapped it using Google’s fusion and visualization tools but it seems like the error surrounding my movements are pretty large (about a 100 feet). I’ll be fiddling with it some more to see where the problem could be. In general, my application of the tutorial went without a hitch. The background behind the fundamentals of GPS was informative and interesting. Great job, Jeremy!

  7. The errors that I observed were strictly in the longitude readings – I had some blockage that probably reduced the triangulation properties along that axis. I went out into into an open field and the accuracy improved tremendously. More satellites did the trick! Next up, I’m going to modify the telemetry outputs and mount it on my RC plane to see more dimensions to analyze (like altitude and speed).

      1. Still trying to get a video of what I’ve been working on – I’m in tweak mode. In addition to recording gps telemetry, I added a gyroscope module to simultaneously record rate of change in pitch, roll, and yaw. Using the student edition of Matlab, I put together a rudimentary 3D animation of all of the telemetry and I got a pretty good playback of my flight for the 3D spatial parameters. Regarding orientation, my gyro interpretations are kind of twitchy but maybe I could improve the post processing and then work towards onboard filtering. This has been nothing but fun – there are so many directions that I’d like to go with this. So much to do. So little time. Thanks for getting me started, Jeremy!

        1. Jeremy and Quitoxer

          please may you give me the codes for IMU Shield and GPS…..i want to get the readings of yaw roll and pitch. also gps cordinates (long, lat, alti, speed, heading) and be able to send them through my GPRS shield. thamk you. Am in Kenya, Africa

  8. Dear All, good morning!!

    I am working hard to understand my gps antenna.
    I do have an Arduino Uno which will be replace by an Arduino Mini Pro 5V
    I also have a GPRS module connected to the arduino Uno.

    On Pin 4 and 5 I connected a GPS antena. First, I tried with this one:
    https://www.sparkfun.com/products/465
    then I ordered and try this one
    https://www.sparkfun.com/products/11571

    Both are connected through this connector breakout
    https://www.sparkfun.com/products/10402

    On my Sketch I define pin4 as RX and pin5 as TX
    SoftwareSerial uart_gps(4, 5);

    I have now the RX wire of the breakout connected to the pin 5 and TX wire connected to pin 4.
    I also try to invert it. RX wire of the breakout, connected to the 4, and TX wire tp pin5.

    Finaly I am using a simple code to display position
    [code]
    /*
    6-8-10
    Aaron Weiss
    SparkFun Electronics

    Example GPS Parser based off of arduiniana.org TinyGPS examples.

    Parses NMEA sentences from an EM406 running at 4800bps into readable
    values for latitude, longitude, elevation, date, time, course, and
    speed.

    For the SparkFun GPS Shield. Make sure the switch is set to DLINE.

    Once you get your longitude and latitude you can paste your
    coordinates from the terminal window into Google Maps. Here is the
    link for SparkFun’s location.
    http://maps.google.com/maps?q=40.06477,+-105.20997

    Uses the NewSoftSerial library for serial communication with your GPS,
    so connect your GPS TX and RX pin to any digital pin on the Arduino,
    just be sure to define which pins you are using on the Arduino to
    communicate with the GPS module.

    REVISIONS:
    1-17-11
    changed values to RXPIN = 2 and TXPIN = to correspond with
    hardware v14+. Hardware v13 used RXPIN = 3 and TXPIN = 2.

    */

    // In order for this sketch to work, you will need to download
    // TinyGPS library from arduiniana.org and put them
    // into the hardware->libraries folder in your ardiuno directory.
    #include
    #include

    // Define which pins you will use on the Arduino to communicate with your
    // GPS. In this case, the GPS module’s TX pin will connect to the
    // Arduino’s RXPIN which is pin 3.
    #define RXPIN 4
    #define TXPIN 5
    //Set this value equal to the baud rate of your GPS
    #define GPSBAUD 4800

    // Create an instance of the TinyGPS object
    TinyGPS gps;
    // Initialize the NewSoftSerial library to the pins you defined above
    SoftwareSerial uart_gps(RXPIN, TXPIN);

    // This is where you declare prototypes for the functions that will be
    // using the TinyGPS library.
    void getgps(TinyGPS &gps);

    // In the setup function, you need to initialize two serial ports; the
    // standard hardware serial port (Serial()) to communicate with your
    // terminal program an another serial port (NewSoftSerial()) for your
    // GPS.
    void setup()
    {
    // This is the serial rate for your terminal program. It must be this
    // fast 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 likely get checksum errors.
    Serial.begin(4800);
    //Sets baud rate of your GPS
    uart_gps.begin(GPSBAUD);

    Serial.println(F(“”));
    Serial.println(F(“GPS Shield QuickStart Example Sketch v12″));
    Serial.println(F(” …waiting for lock… “));
    Serial.println(F(“”));
    }

    // This is the main loop of the code. All it does is check for data on
    // the RX pin of the ardiuno, makes sure the data is valid NMEA sentences,
    // then jumps to the getgps() function.
    void loop()
    {
    //while(Serial.available())
    while(uart_gps.available()) // While there is data on the RX pin…
    {
    // int c = Serial.read();
    byte c = uart_gps.read(); // load the data into a variable…

    if(gps.encode(c)) // if there is a new valid sentence…
    {

    getgps(gps); // then grab the data.
    }
    }
    }

    // The getgps function will get and print the values we want.
    void getgps(TinyGPS &gps)
    {
    Serial.println(“getGPS”);
    // To get all of the data into varialbes that you can use in your code,
    // all you need to do is define variables and query the object for the
    // data. To see the complete list of functions see keywords.txt file in
    // the TinyGPS and NewSoftSerial libs.

    // Define the variables that will be used
    float latitude, longitude;
    // Then call this function
    gps.f_get_position(&latitude, &longitude);
    // You can now print variables latitude and longitude
    Serial.print(“Lat/Long: “);
    Serial.print(latitude,5);
    Serial.print(“, “);
    Serial.println(longitude,5);

    // Same goes for date and time
    int year;
    byte month, day, hour, minute, second, hundredths;
    gps.crack_datetime(&year,&month,&day,&hour,&minute,&second,&hundredths);
    // Print data and time
    Serial.print(“Date: “); Serial.print(month, DEC); Serial.print(“/”);
    Serial.print(day, DEC); Serial.print(“/”); Serial.print(year);
    Serial.print(” Time: “); Serial.print(hour, DEC); Serial.print(“:”);
    Serial.print(minute, DEC); Serial.print(“:”); Serial.print(second, DEC);
    Serial.print(“.”); Serial.println(hundredths, DEC);
    //Since month, day, hour, minute, second, and hundr

    // Here you can print the altitude and course values directly since
    // there is only one value for the function
    Serial.print(“Altitude (meters): “); Serial.println(gps.f_altitude());
    // Same goes for course
    Serial.print(“Course (degrees): “); Serial.println(gps.f_course());
    // And same goes for speed
    Serial.print(“Speed(kmph): “); Serial.println(gps.f_speed_kmph());
    Serial.println();

    // Here you can print statistics on the sentences.
    unsigned long chars;
    unsigned short sentences, failed_checksum;
    gps.stats(&chars, &sentences, &failed_checksum);
    //Serial.print(“Failed Checksums: “);Serial.print(failed_checksum);
    //Serial.println(); Serial.println();
    }

    [/code]

    As well with the fist antena, than with the second, it very rarely works!

    [b]When it works:[/b]
    Last week, I was in my sofa. I am leaving on 7th floor. I was seeting at 3m of the big window. The fix/positions were not displayed.
    Then I put my module on the table whihc is a 0.2m from thew window, and the module start displaying fix. OK, I understand the the building can stop the signal. But it not beacuse it works once, that it always work. It’s not working each time. Also a Cellular antena/provder is close to my building. may be it can make interference

    [b]When it does not work (While I am not at home)[/b]
    What it frustred me, and when I am teaveling in the train. Right now I am maming 2hour train. Then I am moving. I am seeting close to the window. The Antenna is at 1cm of the window and it never display fix!!!!!

    Once I will try to be in a midlle of a field, but my goal is to provide a tool which work any where.

    Is there someone who can provide me some advice.

    For exemple:
    Is correct to connect the antena from RX to TX, or the wire should be connect RX to RX?
    IS correct to define pin 4 and 5, instead of 0 and 1, or 2 and 3
    Someone know the best and correct use of this antenna : https://www.sparkfun.com/products/11571

    Many thnak for any advise you can provide and I hope I provided enougth information

    Cheers

  9. Hi Jeremy

    I retried making this program work but i still have the same problems. still getting a weird output once in a while and I don’t know why but the program stays repeating “Sats, HDOP, Latitude, Longitute,… ” until “by Mikal Hart” over and over again.

    I’m using an Arduino Uno, maybe you can help me changing the code a little bit so it works on the Arduino Uno?

    Here is the code I use:

    #include

    #include
    #include
    #include

    /* This sample code demonstrates the normal use of a TinyGPS object.
    It requires the use of SoftwareSerial, and assumes that you have a
    4800-baud serial GPS device hooked up on pins 3(rx) and 4(tx).
    */

    TinyGPS gps;
    SoftwareSerial nss(3, 4);
    static char dtostrfbuffer[20];
    //int CS = 4;
    int LED = 13;

    //Define String
    String SD_date_time = “invalid”;
    String SD_lat = “invalid”;
    String SD_lon = “invalid”;
    String dataString =””;

    static void gpsdump(TinyGPS &gps);
    static bool feedgps();
    static void print_float(float val, float invalid, int len, int prec, int SD_val);
    static void print_int(unsigned long val, unsigned long invalid, int len);
    static void print_date(TinyGPS &gps);
    static void print_str(const char *str, int len);

    void setup()
    {
    pinMode(4,OUTPUT); //ChipSelect Pin for the SD Card
    pinMode(LED, OUTPUT); //LED Indicator

    //Serial interfaces
    Serial.begin(115200);
    nss.begin(4800);

    //Connect to the SD Card
    if(!SD.begin(4))
    {
    Serial.println(“Card Failure”);
    return;
    }

    Serial.print(“Testing TinyGPS library v. “); Serial.println(TinyGPS::library_version());
    Serial.println(“by Mikal Hart”);
    Serial.println();
    Serial.print(“Sizeof(gpsobject) = “); Serial.println(sizeof(TinyGPS));
    Serial.println();
    Serial.println(“Sats HDOP Latitude Longitude Fix Date Time Date Alt Course Speed Card Distance Course Card Chars Sentences Checksum”);
    Serial.println(” (deg) (deg) Age Age (m) — from GPS —- —- to London —- RX RX Fail”);
    Serial.println(“————————————————————————————————————————————–“);
    }

    void loop()
    {
    bool newdata = false;
    unsigned long start = millis();

    // Every second we print an update
    while (millis() – start < 1000)
    {
    if (feedgps())
    newdata = true;
    }

    gpsdump(gps);

    //Write the newest information to the SD Card
    dataString = SD_date_time + "," + SD_lat + "," + SD_lon;
    if(SD_date_time != "invalid")
    digitalWrite(LED, HIGH);
    else
    digitalWrite(LED, LOW);

    //Open the Data CSV File
    File dataFile = SD.open("LOG.csv", FILE_WRITE);
    if (dataFile)
    {
    dataFile.println(dataString);
    Serial.println(dataString);
    dataFile.close();
    }
    else
    {
    Serial.println("\nCouldn't open the log file!");
    }

    }

    static void gpsdump(TinyGPS &gps)
    {
    float flat, flon;
    unsigned long age, date, time, chars = 0;
    unsigned short sentences = 0, failed = 0;
    static const float LONDON_LAT = 51.508131, LONDON_LON = -0.128002;

    print_int(gps.satellites(), TinyGPS::GPS_INVALID_SATELLITES, 5);
    print_int(gps.hdop(), TinyGPS::GPS_INVALID_HDOP, 5);
    gps.f_get_position(&flat, &flon, &age);
    print_float(flat, TinyGPS::GPS_INVALID_F_ANGLE, 9, 5, 1); //LATITUDE
    print_float(flon, TinyGPS::GPS_INVALID_F_ANGLE, 10, 5, 2); //LONGITUDE
    print_int(age, TinyGPS::GPS_INVALID_AGE, 5);

    print_date(gps); //DATE AND TIME

    print_float(gps.f_altitude(), TinyGPS::GPS_INVALID_F_ALTITUDE, 8, 2, 0);
    print_float(gps.f_course(), TinyGPS::GPS_INVALID_F_ANGLE, 7, 2, 0);
    print_float(gps.f_speed_kmph(), TinyGPS::GPS_INVALID_F_SPEED, 6, 2, 0);
    print_str(gps.f_course() == TinyGPS::GPS_INVALID_F_ANGLE ? "*** " : TinyGPS::cardinal(gps.f_course()), 6);
    print_int(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0UL : (unsigned long)TinyGPS::distance_between(flat, flon, LONDON_LAT, LONDON_LON) / 1000, 0xFFFFFFFF, 9);
    print_float(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : TinyGPS::course_to(flat, flon, 51.508131, -0.128002), TinyGPS::GPS_INVALID_F_ANGLE, 7, 2, 0);
    print_str(flat == TinyGPS::GPS_INVALID_F_ANGLE ? "*** " : TinyGPS::cardinal(TinyGPS::course_to(flat, flon, LONDON_LAT, LONDON_LON)), 6);

    gps.stats(&chars, &sentences, &failed);
    print_int(chars, 0xFFFFFFFF, 6);
    print_int(sentences, 0xFFFFFFFF, 10);
    print_int(failed, 0xFFFFFFFF, 9);
    Serial.println();
    }

    static void print_int(unsigned long val, unsigned long invalid, int len)
    {
    char sz[32];
    if (val == invalid)
    strcpy(sz, "*******");
    else
    sprintf(sz, "%ld", val);
    sz[len] = 0;
    for (int i=strlen(sz); i 0)
    sz[len-1] = ‘ ‘;
    Serial.print(sz);
    feedgps();
    }

    static void print_float(float val, float invalid, int len, int prec, int SD_val)
    {
    char sz[32];
    if (val == invalid)
    {
    strcpy(sz, “*******”);
    sz[len] = 0;
    if (len > 0)
    sz[len-1] = ‘ ‘;
    for (int i=7; i<len; ++i)
    sz[i] = ' ';
    Serial.print(sz);
    if(SD_val == 1) SD_lat = sz;
    else if(SD_val == 2) SD_lon = sz;
    }
    else
    {
    Serial.print(val, prec);
    if (SD_val == 1) SD_lat = dtostrf(val,10,5,dtostrfbuffer);
    else if (SD_val == 2) SD_lon = dtostrf (val,10,5,dtostrfbuffer);
    int vi = abs((int)val);
    int flen = prec + (val = 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
    for (int i=flen; i<len; ++i)
    Serial.print(" ");
    }
    feedgps();
    }

    static void print_date(TinyGPS &gps)
    {
    int year;
    byte month, day, hour, minute, second, hundredths;
    unsigned long age;
    gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
    if (age == TinyGPS::GPS_INVALID_AGE)
    {
    Serial.print("******* ******* ");
    SD_date_time = "invalid";
    }
    else
    {
    char sz[32];
    sprintf(sz, "%02d/%02d/%02d %02d:%02d:%02d ",
    month, day, year, hour, minute, second);
    Serial.print(sz);
    SD_date_time = sz;
    }
    print_int(age, TinyGPS::GPS_INVALID_AGE, 5);
    feedgps();
    }

    static void print_str(const char *str, int len)
    {
    int slen = strlen(str);
    for (int i=0; i<len; ++i)
    Serial.print(i<slen ? str[i] : ' ');
    feedgps();
    }

    static bool feedgps()
    {
    while (nss.available())
    {
    if (gps.encode(nss.read()))
    return true;
    }
    return false;
    }

    Hopefully you can help me let it work

    thanks in advance

  10. Hi Jeremy,

    your tutorial was very helpful.I want to directly use the gps data output and plot it in google earth real-time rather than logging it in the SD card and making the path later.Can you help me with this?

    Thanks

  11. Great tutorial Jeremy, thanks for posting.
    I have built a few of these and everything works perfectly. I have changed the string being saved to SD card to include speed, course etc etc…
    I am not a programmer, but I seem to be able to get things working, but I cannot work out how to change the date string to change the date to my timezone? I need date and time in GMT+10. I am assuming that the date I am seeing is UTC?

    Also, I was trying to output the speed to a serial, 4 digit, 7 seg display? From the way I am reading the documentation, I think I have to break down the variable “speed” into separate digits, and output them separately to the 7 seg display?

    Any advice would be awesome.

  12. HI,

    How do I log the gps data into a kml file directly in the computer than to the SD card. I am new to arduino so i dont know how to implement that.Your help would be greatly appreciated.

    thanks

  13. Hello jeremy,
    I’m using a skylab SKM53 GPS module connected to Arduino Mega 2560, the data coming from the module is always “Latitude : 0.0000000 :: Longitude : 0.0000000”
    I don’t know what the problem is, i check the code and the connections.

    This is the code :

    #include
    #include

    unsigned long fix_age;

    SoftwareSerial nss(2,3);
    TinyGPS gps;
    void gpsdump(TinyGPS &gps);
    bool feedgps();
    void getGPS();
    long lat, lon;
    float LAT, LON;

    void setup()
    {
    nss.begin(9600);
    Serial.begin(9600);
    }

    void loop()
    {
    long lat, lon;
    unsigned long fix_age, time, date, speed, course;
    unsigned long chars;
    unsigned short sentences, failed_checksum;

    // retrieves +/- lat/long in 100000ths of a degree
    gps.get_position(&lat, &lon, &fix_age);

    getGPS();
    Serial.print(“Latitude : “);
    Serial.print(LAT/100000,7);
    Serial.print(” :: Longitude : “);
    Serial.println(LON/100000,7);
    }

    void getGPS()
    {
    bool newdata = false;
    unsigned long start = millis();
    // Every 1 seconds we print an update
    while (millis() – start < 1000)
    {
    if (feedgps ())
    {
    newdata = true;
    }

    }
    if (newdata)
    {
    gpsdump(gps);
    }
    }

    bool feedgps(){
    while (nss.available())
    {
    if (gps.encode(nss.read()))
    return true;
    }
    return 0;
    }

    void gpsdump(TinyGPS &gps)
    {
    //byte month, day, hour, minute, second, hundredths;
    gps.get_position(&lat, &lon);
    LAT = lat;
    LON = lon;
    {
    feedgps(); // If we don't feed the gps during this long routine, we may drop characters and get checksum errors
    }
    }

    Hope you can help
    Thank you

  14. please Jeremy What is Serial3 that you wrote what is it for whe i wrote it the compiler says it is not declared?

    1. That’s the third hardware serial port on the Arduino Mega 2560. If you aren’t using the mega, you need to use the software serial library instead.

  15. Hi Jeremy,

    I have a little question about your tutorial 15.

    I used this tutorial with the same GPS that you have used and it works.But, i would like to use an other GPS (EM406A) more sensitive and I would like to know if your code into tutorial 15 can be adapted for this second GPS??
    I need really your help asap. Thanks!

    Reading from you soon.

  16. Hi jeremy , i need program to receive the coordinates between 2 cities when the car is go and back between them and save it in SD Card , when its recieve the coordinates it is sends to the google map (using GPS ) .

  17. i used your code to test my Skylab GPS module but my result shown like this..

    Latitude : 0.0000000 :: Longitude : 0.0000000
    Latitude : 0.0000000 :: Longitude : 0.0000000
    Latitude : 0.0000000 :: Longitude : 0.0000000

    do you know what is the problem? i tried with another code but it still not working..i need your help here..
    I still got the same result. so, what is the problem actually? I read on website that we should stay outside to get the satellite fix.
    I tried that way but still no luck..help me please..
    thanks

  18. Hi Jeremy

    The GPS tutorial was very informative. I have a question, would it be possible to use the GPS data thats stored on the SD card to program a route for a RC car/truck to follow. In the tutorial about the SD card you retrieved the data from the card to change the refresh rate of the string.

    Regards
    Pat

  19. Hello, great tutorial by the way

    I copied your program for my arduino UNO and I setted up the sd card but Arduino gives me in the serial monitor the error: “Couldn’t open the log file”.

    What do I need to do???

  20. I’m using arduino mega and EB365 gps module and i’m unable to get the latitude and longitude information even after walking for a long distance in open fields. I followed your procedure on Tuitorial 15 but with a little modifications and all i get printed on the SD card is these characters ( *******) what could be the problem?

  21. hi Jeremy..am using GPS shield 1.1 from ITEAD STUDIO but am not receiving any data from the GPS. please help.??

    1. You’ll need to be more specific. Are you getting no communication at all from the module, or is it just invalid? It probably doesn’t have a lock. It may take a long time to get one.

  22. Hello, First of all, your tutorial is great

    but I’m getting the error that he can’t access my log file…
    I use a micro-sd card
    and this is my program:

    #include

    #include

    #include

    //Jeremy Blum’s Arduino Tutorial Series – Episode 15 – GPS Tracking
    //Sample Code 2 – Logging GPS Data to an SD Card
    //https://www.jeremyblum.com
    //TinyGPS Library and Helper Functions by Mikal Hart http://arduiniana.org/libraries/tinygps/

    #include

    /* This sample code demonstrates the normal use of a TinyGPS object.
    It uses an Arduino Mega with a GPS attached to nss at 4800 buad.
    */

    TinyGPS gps;
    SoftwareSerial nss(2,3);
    static char dtostrfbuffer[20];
    int CS = 8;
    int LED = 13;

    //Define String
    String SD_date_time = “invalid”;
    String SD_lat = “invalid”;
    String SD_lon = “invalid”;
    String dataString =””;

    static void gpsdump(TinyGPS &gps);
    static bool feedgps();
    static void print_float(float val, float invalid, int len, int prec, int SD_val);
    static void print_int(unsigned long val, unsigned long invalid, int len);
    static void print_date(TinyGPS &gps);
    static void print_str(const char *str, int len);

    void setup()
    {
    pinMode(CS, OUTPUT); //Chip Select Pin for the SD Card
    pinMode(LED, OUTPUT); //LED Indicator

    //Serial interfaces
    Serial.begin(9600);
    nss.begin(4800);

    //Connect to the SD Card
    if(!SD.begin(CS))
    {
    Serial.println(“Card Failure”);
    return;
    }

    Serial.println(“Sats HDOP Latitude Longitude Fix Date Time Date Alt Course Speed Card Distance Course Card Chars Sentences Checksum”);
    Serial.println(” (deg) (deg) Age Age (m) — from GPS —- —- to London —- RX RX Fail”);

    }

    void loop()
    {
    bool newdata = false;
    unsigned long start = millis();

    // Every second we print an update
    while (millis() – start < 1000)
    {
    if (feedgps())
    newdata = true;
    }

    gpsdump(gps);

    //Write the newest information to the SD Card
    dataString = SD_date_time + "," + SD_lat + "," + SD_lon;
    if(SD_date_time != "invalid")
    digitalWrite(LED, HIGH);
    else
    digitalWrite(LED, LOW);

    //Open the Data CSV File
    File dataFile = SD.open("LOG.csv", FILE_WRITE);
    if (dataFile)
    {
    dataFile.println(dataString);
    Serial.println(dataString);
    dataFile.close();
    }
    else
    {
    Serial.println("\nCouldn't open the log file!");
    }
    }

    static void gpsdump(TinyGPS &gps)
    {
    float flat, flon;
    unsigned long age, date, time, chars = 0;
    unsigned short sentences = 0, failed = 0;
    static const float LONDON_LAT = 51.508131, LONDON_LON = -0.128002;

    print_int(gps.satellites(), TinyGPS::GPS_INVALID_SATELLITES, 5);
    print_int(gps.hdop(), TinyGPS::GPS_INVALID_HDOP, 5);
    gps.f_get_position(&flat, &flon, &age);
    print_float(flat, TinyGPS::GPS_INVALID_F_ANGLE, 9, 5, 1); //LATITUDE
    print_float(flon, TinyGPS::GPS_INVALID_F_ANGLE, 10, 5, 2); //LONGITUDE
    print_int(age, TinyGPS::GPS_INVALID_AGE, 5);

    print_date(gps); //DATE AND TIME

    print_float(gps.f_altitude(), TinyGPS::GPS_INVALID_F_ALTITUDE, 8, 2, 0);
    print_float(gps.f_course(), TinyGPS::GPS_INVALID_F_ANGLE, 7, 2, 0);
    print_float(gps.f_speed_kmph(), TinyGPS::GPS_INVALID_F_SPEED, 6, 2, 0);
    print_str(gps.f_course() == TinyGPS::GPS_INVALID_F_ANGLE ? "*** " : TinyGPS::cardinal(gps.f_course()), 6);
    print_int(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0UL : (unsigned long)TinyGPS::distance_between(flat, flon, LONDON_LAT, LONDON_LON) / 1000, 0xFFFFFFFF, 9);
    print_float(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : TinyGPS::course_to(flat, flon, 51.508131, -0.128002), TinyGPS::GPS_INVALID_F_ANGLE, 7, 2, 0);
    print_str(flat == TinyGPS::GPS_INVALID_F_ANGLE ? "*** " : TinyGPS::cardinal(TinyGPS::course_to(flat, flon, LONDON_LAT, LONDON_LON)), 6);

    gps.stats(&chars, &sentences, &failed);
    print_int(chars, 0xFFFFFFFF, 6);
    print_int(sentences, 0xFFFFFFFF, 10);
    print_int(failed, 0xFFFFFFFF, 9);
    Serial.println();
    }

    static void print_int(unsigned long val, unsigned long invalid, int len)
    {
    char sz[32];
    if (val == invalid)
    strcpy(sz, "*******");
    else
    sprintf(sz, "%ld", val);
    sz[len] = 0;
    for (int i=strlen(sz); i 0)
    sz[len-1] = ‘ ‘;
    Serial.print(sz);
    feedgps();
    }

    static void print_float(float val, float invalid, int len, int prec, int SD_val)
    {
    char sz[32];
    if (val == invalid)
    {
    strcpy(sz, “*******”);
    sz[len] = 0;
    if (len > 0)
    sz[len-1] = ‘ ‘;
    for (int i=7; i<len; ++i)
    sz[i] = ' ';
    Serial.print(sz);
    if(SD_val == 1) SD_lat = sz;
    else if(SD_val == 2) SD_lon = sz;
    }
    else
    {
    Serial.print(val, prec);
    if (SD_val == 1) SD_lat = dtostrf(val,10,5,dtostrfbuffer);
    else if (SD_val == 2) SD_lon = dtostrf(val,10,5,dtostrfbuffer);
    int vi = abs((int)val);
    int flen = prec + (val = 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
    for (int i=flen; i<len; ++i)
    Serial.print(" ");
    }
    feedgps();
    }

    static void print_date(TinyGPS &gps)
    {
    int year;
    byte month, day, hour, minute, second, hundredths;
    unsigned long age;
    gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
    if (age == TinyGPS::GPS_INVALID_AGE)
    {
    Serial.print("******* ******* ");
    SD_date_time = "invalid";
    }
    else
    {
    char sz[32];
    sprintf(sz, "%02d/%02d/%02d %02d:%02d:%02d ",
    month, day, year, hour, minute, second);
    Serial.print(sz);
    SD_date_time = sz;
    }
    print_int(age, TinyGPS::GPS_INVALID_AGE, 5);
    feedgps();
    }

    static void print_str(const char *str, int len)
    {
    int slen = strlen(str);
    for (int i=0; i<len; ++i)
    Serial.print(i<slen ? str[i] : ' ');
    feedgps();
    }

    static bool feedgps()
    {
    while (nss.available())
    {
    if (gps.encode(nss.read()))
    return true;
    }
    return false;
    }

  23. This is the code am using but i cant receive any data in terms of latitude and longitude.

    #include

    #include

    TinyGPS gps;
    SoftwareSerial nss(2, 3);

    static void gpsdump(TinyGPS &gps);
    static bool feedgps();
    static void print_float(float val, float invalid, int len, int prec);
    static void print_int(unsigned long val, unsigned long invalid, int len);
    static void print_date(TinyGPS &gps);
    static void print_str(const char *str, int len);

    void setup()
    {
    Serial.begin(4800);
    nss.begin(4800);

    Serial.print(“Testing TinyGPS library v. “); Serial.println(TinyGPS::library_version());
    Serial.println(“by the himuselefu”);
    Serial.println();
    Serial.print(“Sizeof(gpsobject) = “); Serial.println(sizeof(TinyGPS));
    Serial.println();
    Serial.println(“Sats HDOP Latitude Longitude Fix Date Time Date Alt Course Speed Card Distance Course Card Chars Sentences Checksum”);
    Serial.println(” (deg) (deg) Age Age (m) — from GPS —- —- to London —- RX RX Fail”);
    Serial.println(“————————————————————————————————————————————–“);
    }

    void loop()
    {
    bool newdata = false;
    unsigned long start = millis();

    // Every second we print an update
    while (millis() – start < 1000)
    {
    if (feedgps())
    newdata = true;
    }

    gpsdump(gps);
    }

    static void gpsdump(TinyGPS &gps)
    {
    float flat, flon;
    unsigned long age, date, time, chars = 0;
    unsigned short sentences = 0, failed = 0;
    static const float LONDON_LAT = 51.508131, LONDON_LON = -0.128002;

    print_int(gps.satellites(), TinyGPS::GPS_INVALID_SATELLITES, 5);
    print_int(gps.hdop(), TinyGPS::GPS_INVALID_HDOP, 5);
    gps.f_get_position(&flat, &flon, &age);
    print_float(flat, TinyGPS::GPS_INVALID_F_ANGLE, 9, 5);
    print_float(flon, TinyGPS::GPS_INVALID_F_ANGLE, 10, 5);
    print_int(age, TinyGPS::GPS_INVALID_AGE, 5);

    print_date(gps);

    print_float(gps.f_altitude(), TinyGPS::GPS_INVALID_F_ALTITUDE, 8, 2);
    print_float(gps.f_course(), TinyGPS::GPS_INVALID_F_ANGLE, 7, 2);
    print_float(gps.f_speed_kmph(), TinyGPS::GPS_INVALID_F_SPEED, 6, 2);
    print_str(gps.f_course() == TinyGPS::GPS_INVALID_F_ANGLE ? "*** " : TinyGPS::cardinal(gps.f_course()), 6);
    print_int(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0UL : (unsigned long)TinyGPS::distance_between(flat, flon, LONDON_LAT, LONDON_LON) / 1000, 0xFFFFFFFF, 9);
    print_float(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : TinyGPS::course_to(flat, flon, 51.508131, -0.128002), TinyGPS::GPS_INVALID_F_ANGLE, 7, 2);
    print_str(flat == TinyGPS::GPS_INVALID_F_ANGLE ? "*** " : TinyGPS::cardinal(TinyGPS::course_to(flat, flon, LONDON_LAT, LONDON_LON)), 6);

    gps.stats(&chars, &sentences, &failed);
    print_int(chars, 0xFFFFFFFF, 6);
    print_int(sentences, 0xFFFFFFFF, 10);
    print_int(failed, 0xFFFFFFFF, 9);
    Serial.println();
    }

    static void print_int(unsigned long val, unsigned long invalid, int len)
    {
    char sz[32];
    if (val == invalid)
    strcpy(sz, "*******");
    else
    sprintf(sz, "%ld", val);
    sz[len] = 0;
    for (int i=strlen(sz); i 0)
    sz[len-1] = ‘ ‘;
    Serial.print(sz);
    feedgps();
    }

    static void print_float(float val, float invalid, int len, int prec)
    {
    char sz[32];
    if (val == invalid)
    {
    strcpy(sz, “*******”);
    sz[len] = 0;
    if (len > 0)
    sz[len-1] = ‘ ‘;
    for (int i=7; i<len; ++i)
    sz[i] = ' ';
    Serial.print(sz);
    }
    else
    {
    Serial.print(val, prec);
    int vi = abs((int)val);
    int flen = prec + (val = 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
    for (int i=flen; i<len; ++i)
    Serial.print(" ");
    }
    feedgps();
    }

    static void print_date(TinyGPS &gps)
    {
    int year;
    byte month, day, hour, minute, second, hundredths;
    unsigned long age;
    gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
    if (age == TinyGPS::GPS_INVALID_AGE)
    Serial.print("******* ******* ");
    else
    {
    char sz[32];
    sprintf(sz, "%02d/%02d/%02d %02d:%02d:%02d ",
    month, day, year, hour, minute, second);
    Serial.print(sz);
    }
    print_int(age, TinyGPS::GPS_INVALID_AGE, 5);
    feedgps();
    }

    static void print_str(const char *str, int len)
    {
    int slen = strlen(str);
    for (int i=0; i<len; ++i)
    Serial.print(i<slen ? str[i] : ' ');
    feedgps();
    }

    static bool feedgps()
    {
    while (nss.available())
    {
    if (gps.encode(nss.read()))
    return true;
    }
    return false;
    }

  24. Hi Jeremy. I am impressed with your Arduino tutorials. I cannot believe I had not found them before. Is it possible to transmit the GPS data gathered to a server to then display it in a website? Should I used Arduino or do you recommend a micro-controller with an operating system?

  25. Hi jeremy..
    am using GPS shield 1.1. this is the code am using but i cant receive any data. please help

    #include

    #include

    /* This sample code demonstrates the normal use of a TinyGPS object.
    It requires the use of SoftwareSerial, and assumes that you have a
    4800-baud serial GPS device hooked up on pins 3(rx) and 4(tx).
    */

    TinyGPS gps;
    SoftwareSerial ss(3, 4);

    void setup()
    {
    Serial.begin(4800);
    ss.begin(4800);

    Serial.print(“Simple TinyGPS library v. “); Serial.println(TinyGPS::library_version());
    Serial.println(“by Mikal Hart”);
    Serial.println();
    }

    void loop()
    {
    bool newData = false;
    unsigned long chars;
    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())
    {
    char c = ss.read();
    // Serial.write(c); // uncomment this line if you want to see the GPS data flowing
    if (gps.encode(c)) // Did a new valid sentence come in?
    newData = true;
    }
    }

    if (newData)
    {
    float flat, flon;
    unsigned long age;
    gps.f_get_position(&flat, &flon, &age);
    Serial.print("LAT=");
    Serial.print(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flat, 6);
    Serial.print(" LON=");
    Serial.print(flon == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flon, 6);
    Serial.print(" SAT=");
    Serial.print(gps.satellites() == TinyGPS::GPS_INVALID_SATELLITES ? 0 : gps.satellites());
    Serial.print(" PREC=");
    Serial.print(gps.hdop() == TinyGPS::GPS_INVALID_HDOP ? 0 : gps.hdop());
    }

    gps.stats(&chars, &sentences, &failed);
    Serial.print(" CHARS=");
    Serial.print(chars);
    Serial.print(" SENTENCES=");
    Serial.print(sentences);
    Serial.print(" CSUM ERR=");
    Serial.println(failed);
    }

  26. My GPS module is stuck at 9600 baud. Is there a way to change your examples to permit that? I tried changing ss.begin(4800) to 9600 but it didn’t work. Thanks, Eric

  27. hi jeremy.

    Am stuck here. Am using an arduino and want to interface lcd and sd card. i want to read data on the sd card then display the same on an lcd module. Here is my code.

    for the lcd:

    [quote]
    #include 

    [color=#7E7E7E]// initialize the library with the numbers of the interface pins[/color]
    [color=#CC6600]LiquidCrystal[/color] lcd(12, 11, 10, 9, 8, 7);

    [color=#CC6600]void[/color] [color=#CC6600][b]setup[/b][/color]() {
      [color=#7E7E7E]// set up the LCD’s number of columns and rows: [/color]
      lcd.[color=#CC6600]begin[/color](16, 2);
      [color=#7E7E7E]// Print a message to the LCD.[/color]
      lcd.[color=#CC6600]print[/color]([color=#006699]”hello, world!”[/color]);
    }

    [color=#CC6600]void[/color] [color=#CC6600][b]loop[/b][/color]() {
      [color=#7E7E7E]// Turn off the display:[/color]
      lcd.[color=#CC6600]noDisplay[/color]();
      [color=#CC6600]delay[/color](500);
       [color=#7E7E7E]// Turn on the display:[/color]
      lcd.[color=#CC6600]display[/color]();
      [color=#CC6600]delay[/color](500);
    }

    [/quote]

    To read from the sd card, i used the following code:

    [quote]
     
    #include 
    [color=#CC6600]int[/color] CS_pin = 10;
    [color=#CC6600]int[/color] pow_pin = 8;
    [color=#CC6600]File[/color] myFile;

    [color=#CC6600]void[/color] [color=#CC6600][b]setup[/b][/color]()
    {
     [color=#7E7E7E]// Open serial communications and wait for port to open:[/color]
      [color=#CC6600][b]Serial[/b][/color].[color=#CC6600]begin[/color](9600);
      [color=#CC6600][b]Serial[/b][/color].[color=#CC6600]print[/color]([color=#006699]”Initializing SD card…”[/color]);
      [color=#7E7E7E]// On the Ethernet Shield, CS is pin 4. It’s set as an output by default.[/color]
      [color=#7E7E7E]// Note that even if it’s not used as the CS pin, the hardware SS pin[/color]
      [color=#7E7E7E]// (10 on most Arduino boards, 53 on the Mega) must be left as an output[/color]
      [color=#7E7E7E]// or the SD library functions will not work.[/color]
       [color=#CC6600]pinMode[/color](10, [color=#006699]OUTPUT[/color]);
       [color=#CC6600]pinMode[/color](pow_pin, [color=#006699]OUTPUT[/color]);
       [color=#CC6600]digitalWrite[/color](pow_pin, [color=#006699]HIGH[/color]);
       
      [color=#CC6600]if[/color] (![color=#CC6600]SD[/color].[color=#CC6600]begin[/color](10)) {
        [color=#CC6600][b]Serial[/b][/color].[color=#CC6600]println[/color]([color=#006699]”initialization failed!”[/color]);
        [color=#CC6600]return[/color];
      }
      [color=#CC6600][b]Serial[/b][/color].[color=#CC6600]println[/color]([color=#006699]”initialization done.”[/color]);
    }
    [color=#CC6600]void[/color] [color=#CC6600][b]loop[/b][/color]()
    {
     myFile = [color=#CC6600]SD[/color].[color=#CC6600]open[/color]([color=#006699]”code.txt”[/color]);
      [color=#CC6600]if[/color] (myFile) {
        
       
        [color=#7E7E7E]// read from the file until there’s nothing else in it:[/color]
        [color=#CC6600]while[/color] (myFile.[color=#CC6600]available[/color]()) {
            [color=#CC6600][b]Serial[/b][/color].[color=#CC6600]write[/color](myFile.[color=#CC6600]read[/color]());
        }
        [color=#7E7E7E]// close the file:[/color]
        myFile.[color=#CC6600]close[/color]();
      } [color=#CC6600]else[/color] {
        [color=#7E7E7E]// if the file didn’t open, print an error:[/color]
        [color=#CC6600][b]Serial[/b][/color].[color=#CC6600]println[/color]([color=#006699]”error opening log.txt”[/color]);
      }
      [color=#CC6600]delay[/color](2000);
    }

    [/quote]

    please help me interface the two and come up with one..its my project and am stuck.

    kind regards,
    Peter.

  28. hi jeremy,
    i want to enhance the security of this thing, i want to know that how it is possible to get an interrupt when someone get the sd card from this sd card module??? where is the sd card detect pin in this module? i want to write to a log file each and every time when the sd card is removed and inserted into this module. please help me jeremy
    i think u could understand my problem??

  29. hi, im fhahad from Philippines.. Im newbies from arduino..

    I have a project entitled house security system with biometric and gps technology.. My concern is about the gps, on how can I track the house, does the gps work even without internet connection, how can i know that the house is being robed, do the gps sent sms even no gsm going to google map, and how can i enterface my gps to google map..
    Plz help.. Ur help will make my thesis project success.. Thank you

    1. Of you want you’re houce to be tracked without gsm / GPRS / 3G internet. Maybe spotconnect integration might be an option.

  30. Hi jeremy, can the code you used for your GPS Shield work with any GPS shield ? The GPS shield that I am using has an SD Card Shield attached to it (http://www.adafruit.com/products/98) and sample code that came with it is really difficult to understand. Any ideas on how to simplify the code ? Thanks

  31. Hey jeremy, I used the tinyGPS library along with my gpsShield and I also used the softwareserial (rx, tx) . Its seems to be working but for some reason the serial monitor is displaying symbols instead of actual words.. any ideas why this is so ?? Thanks

      1. Hey jeremy, thanks for the reply. Below is the code I have under void Setup(), what baudrate would you suggest..

        [CODE]

        void setup()
        {
        Serial.begin(115200);

        Serial.print(“Testing TinyGPS library v. “); Serial.println(TinyGPS::library_version());
        Serial.println(“by Mikal Hart”);
        Serial.println();
        Serial.println(“Sats HDOP Latitude Longitude Fix Date Time Date Alt Course Speed Card Distance Course Card Chars Sentences Checksum”);
        Serial.println(” (deg) (deg) Age Age (m) — from GPS —- —- to London —- RX RX Fail”);
        Serial.println(“————————————————————————————————————————————-“);

        nss.begin(4800);
        }

        [/CODE]

        1. Hi Lionel,
          I made exactly the same mistake, so I know the problem. The serial.begin statement is the baud rate for the monitor screen. When you are there, go to the bottom righthand corner and set the rate to the highest one, 115200. The odd thing about your code is that you have the statement nss.begin(4800). In the code I got (the same sketch) it is ss.begin. Are you sure an errant “n” didn’t get into your code?
          Good luck. Eric

          1. Thanks for helping out eric … Really Appreciate and you were right about the “n” , I fixed it already.

      2. Hey jeremey,

        Thanks for help so far, been really helpful. I have managed to fix the problem. But I still have one issue, my char Rx is showing 0 all through… that means based on what you said the gps is not transmitting data to the arduino.. How do I go about fixing this ??

  32. hai jeremy!
    Im student and im newbies for arduino and gps module and gsm.. Please can you give me a guide on how i can integrate the gsm to gps module and how can i get the longitude , tatitude altitude ant fix time and send it via sms.. I buy gsm shield sim900d and gps skg25a1.. Plz help to finish my thesis project.. Thankz for great tutorial it wil gve addition to my propose project

  33. hiii jeremy,what is model arduino can track location….android can comunicate or not to arduino gps tracker…???

  34. Hi,

    I need to collect the real GPS signal. The Arduino GPS Shield will allow to access the signal (raw or digitized)?

    Best,

    Becky

      1. I need to collect the gps signal before the device process it in order to extract the navigation data. Is there any way to access the received signal? I mean e.g. is it possible to connect the device to an oscillator and monitor the signal?

        1. I’m still not following what you want. It returns raw data about the number of satellites, etc. The signal is not “analog” – you can’t just monitor it.

  35. Hello, hi jeremy
    Firstly, i would say that congratulation on making tutorials video. I love to watch your video. and i want to ask for your help. can you make some tutorial on wifi module about APC 220. Please.. thank you,
    btw your video are some.

  36. Hey man,
    Is there any way i can make a tracking device using arduino ( or possibly without arduino ) where i dont need an internet connection, extracting live information from a satellite. I am thinking the smallest device possible, lean.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Advertisement