TinyGPS

A Compact Arduino GPS/NMEA Parser

TinyGPS is designed to provide most of the NMEA GPS functionality I imagine an Arduino user would want – position, date, time, altitude, speed and course – without the large size that seems to accompany similar bodies of code.  To keep resource consumption low, the library avoids any mandatory floating point dependency and ignores all but a few key GPS fields.

Usage

To use, simply create an instance of an object like this:

#include "TinyGPS.h"
TinyGPS gps;

Feed the object serial NMEA data one character at a time using the encode() method. (TinyGPS does not handle retrieving serial data from a GPS unit.) When encode() returns “true”, a valid sentence has just changed the TinyGPS object’s internal state. For example:

#define RXPIN 3
#define TXPIN 2
SoftwareSerial nss(RXPIN, TXPIN);
void loop()
{
  while (nss.available())
  {
    int c = nss.read();
    if (gps.encode(c))
    {
      // process new gps info here
    }
  }
}

You can then query the object to get various tidbits of data. To test whether the data returned is stale, examine the (optional) parameter “fix_age” which returns the number of milliseconds since the data was encoded.

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);

// time in hhmmsscc, date in ddmmyy
gps.get_datetime(&date, &time, &fix_age);

// returns speed in 100ths of a knot
speed = gps.speed();

// course in 100ths of a degree
course = gps.course();

Statistics

The stats method provides a clue whether you are getting good data or not. It provides statistics that help with troubleshooting.

// statistics
gps.stats(&chars, &sentences, &failed_checksum);
  • chars – the number of characters fed to the object
  • sentences – the number of valid $GPGGA and $GPRMC sentences processed
  • failed_checksum – the number of sentences that failed the checksum test

Integral values

Values returned by the core TinyGPS methods are integral. Angular latitude and longitude measurements, for example, are provided in units of millionths of a degree, so instead of 90°30’00”, get_position() returns a longitude value of 90,500,000, or 90.5 degrees. But…

Using Floating Point

…for applications which are not resource constrained, it may be more convenient to use floating-point numbers. For these, TinyGPS offers several inline functions that return more easily-managed data. Don’t use these unless you can afford to link the floating-point libraries. Doing so may add 2000 or more bytes to the size of your application.

float flat, flon;

// returns +/- latitude/longitude in degrees
gps.f_get_position(&flat, &flon, &fix_age);
float falt = gps.f_altitude(); // +/- altitude in meters
float fc = gps.f_course(); // course in degrees
float fk = gps.f_speed_knots(); // speed in knots
float fmph = gps.f_speed_mph(); // speed in miles/hr
float fmps = gps.f_speed_mps(); // speed in m/sec
float fkmph = gps.f_speed_kmph(); // speed in km/hr

Date/time cracking

For more convenient access to date/time use this:

int year;
byte month, day, hour, minutes, second, hundredths;
unsigned long fix_age;

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

Establishing a fix

TinyGPS objects depend on an external source, i.e. its host program, to feed valid and up-to-date NMEA GPS data. This is the only way to make sure that TinyGPS’s notion of the “fix” is current. Three things must happen to get valid position and time/date:

  1. You must feed the object serial NMEA data.
  2. The NMEA sentences must pass the checksum test.
  3. The NMEA sentences must report valid data. If the $GPRMC sentence reports a validity of “V” (void) instead of “A” (active), or if the $GPGGA sentence reports fix type “0” (no fix) then those sentences are discarded.

To test whether the TinyGPS object contains valid fix data, pass the address of an unsigned long variable for the “fix_age” parameter in the methods that support it. If the returned value is TinyGPS::GPS_INVALID_AGE, then you know the object has never received a valid fix. If not, then fix_age is the number of milliseconds since the last valid fix. If you are “feeding” the object regularly, fix_age should probably never get much over 1000. If fix_age starts getting large, that may be a sign that you once had a fix, but have lost it.

float flat, flon;
unsigned long fix_age; // returns +- latitude/longitude in degrees
gps.f_get_position(&flat, &flon, &fix_age);
if (fix_age == TinyGPS::GPS_INVALID_AGE)
  Serial.println("No fix detected");
else if (fix_age > 5000)
  Serial.println("Warning: possible stale data!");
else
  Serial.println("Data is current.");

Interfacing with Serial GPS

To get valid and timely GPS fixes, you must provide a reliable NMEA sentence feed. If your NMEA data is coming from a serial GPS unit, connect it to Arduino’s hardware serial port, or, if using a “soft” serial port, make sure that you are using a reliable SoftSerial library. As of this writing (Arduino 0013), the SoftwareSerial library provided with the IDE is inadequate. It’s best to use my NewSoftSerial library, which builds upon the fine work ladyada did with the AFSoftSerial library.

Library Version

You can retrieve the version of the TinyGPS library by calling the static member library_version().

int ver = TinyGPS::library_version();

Resource Consumption

Linking the TinyGPS library to your application adds approximately 2500 bytes to its size, unless you are invoking any of the f_* methods. These require the floating point libraries, which might add another 600+ bytes.

Download

The latest version of TinyGPS is available here: TinyGPS13.zip

Change Log

  1. initial version
  2. << streaming, supports $GPGGA for altitude, floating point inline functions
  3. also extract lat/long/time from $GPGGA for compatibility with devices with no $GPRMC
  4. bug fixes
  5. API re-org, attach separate fix_age’s to date/time and position.
  6. Prefer encode() over operator<<. Encode() returns boolean indicating whether TinyGPS object has changed state.
  7. Changed examples to use NewSoftSerial in lieu of AFSoftSerial; rearranged the distribution package.
  8. Greater precision in latitude and longitude.  Angles measured in 10-5 degrees instead of 10-4 as previously.  Some constants redefined.
  9. Minor bug fix release: the fix_age parameter of get_datetime() was not being set correctly.
  10. Added Maarten Lamers’ distance_to() as a static function.
  11. Arduino 1.0 compatibility
  12. Added satellites(), hdop(), course_to(), and cardinal()
  13. Improved precision in latitude and longitude rendering. get_position() now returns angles in millionths of a degree.

Acknowledgements

Many thanks to Arduino forum users mem and Brad Burleson for outstanding help in alpha testing this code. Thanks also to Maarten Lamers, who wrote the wiring library that originally gave me the idea of how to organize TinyGPS.  Thanks also to Dan P. for suggesting that I increase the lat/long precision in version 8.  Thanks to many people who suggested new useful features for TinyGPS, especially Matt Monson, who wrote some nice sample code to do so.

All input is appreciated.

Mikal Hart

Page last updated on August 31, 2013 at 7:00 pm
702 Responses → “TinyGPS”

  1. Albert

    14 years ago

    Hi, I got my LS20031 GPS working with the Arduino Mega 2560. But now I would like to change the settings of the GPS. Do you know whether this is possible via the Arduino? Or do I need a FTDI cable? Thank you for your reply. Albert


  2. F4FWH

    14 years ago

    Hi Mikal,

    I’m working on a Hamradio project that is using your TinyGPS library.
    All the info that I need is in your library, but I need just one more things, is there a way to take the lat and lon as the NMEA sentences give it?

    For exemple on this sentence :
    “$GPRMC,201547.000,A,3014.5527,N,09749.5808,W,0.24,163.05,040109,,*1A”

    I need to had :
    3014.5527
    N
    09749.5808
    W

    Can you tell me how to modify the library to take this info?

    Thanks a lot for your works ;)

    73 Vivien


  3. Matt

    14 years ago

    Hey, I’d like to contribute some changes, namely storing off the # of satellites in view, and a bearing_to function to go along with the distance_to function.

    How would I go about getting you the changes?


  4. scompo

    14 years ago

    Hi, great stuff here, I just noticed that with the 1.0 release of the ide there is a problem compiling it.. The reference to wprogram.h it’s not working due to the new version of it..

    changing the include with this piece here (found on the release notes) works flawlessly for both new and old IDE..

    #if defined(ARDUINO) && ARDUINO >= 100
    #include “Arduino.h”
    #else
    #include “WProgram.h”
    #endif

    Thanks so much for the great stuff by the way!


  5. Joe

    14 years ago

    Hi Mikal!

    I couldn’t change the baudrate of my GPS (I dont know how) to 4800 so i changed the nss.begin(4800) to nss.begin(9600).

    either way however, im stuck at
    “Testing TinyGPS library v. 10
    by Mikal Hart
    Sizeof(gpsobject) = 103″

    i have checked that the RX goes to TX and vice versa.
    please enlighten me..


  6. Tomás

    14 years ago

    Tengo un GPS Parallax http://www.parallax.com/StoreSearchResults/tabid/768/txtSearch/gps/List/0/SortField/4/ProductID/396/Default.aspx, un Arduino Mega 2560 y el software arduino 1.0 y por más que trato leer los datos del gps no puedo U.U, incluí la carpeta GPS_Arduino_10 en donde esta el .h TinyGPS, he hecho muchas pruebas y nada :( , Somebody can help me? *.*


  7. UrSuS

    14 years ago

    Hi! Is there a way to check current GPS accuracy? (I want to log coordinates only if accuracy is +-3m)
    Thanks!


  8. Mikal

    14 years ago

    @F4FWH,

    Hmm… TinyGPS doesn’t provide access to the raw data. I should consider this. Thanks.


  9. Mikal

    14 years ago

    @Matt,

    Thanks for the offer. Email is probably the best way…


  10. Mikal

    14 years ago

    @scompo,

    TinyGPS now works with Arduino 1.0. Thanks!

    M


  11. Mikal

    14 years ago

    @Joe, I think I would examine the stats in TinyGPS. Are you actually getting any data?


  12. Van Taiariol

    14 years ago

    Hi Mikal,

    TinyGPS, Great program!. Have one question. Using a Polstar PMB-688
    (parallax purchase) I get 0.00 knt when actual is below 2Knts. Above
    3 knts read out is OK. Don’t know if this is a hardware issue (gps module)
    or software. Has anyone else experienced this??

    Regards,

    Van


  13. scompo

    14 years ago

    @Mikal You’re welcome. Glad I’ve helped.


  14. UrSuS

    14 years ago

    Could you please answer my question about position accuracy?


  15. Mikal

    14 years ago

    @UrSuS,

    I didn’t answer directly because I don’t know exactly, but I know of two strategies that people have used to increase accuracy:

    1. Examine the “number of satellites seen” field on the theory that the more satellites seen, the greater the accuracy. Note that the current version of TinyGPS does not support number of satellites in view, but I expect that the next version will, and it’s an easy patch.
    2. On the theory that the initial fixes reported by a GPS are the least accurate (and I confirm this experimentally with my EM-406A), simply wait until you’ve seen, say, 10 different fixes.

    That said, I don’t how to prove that the accuracy is within a given radius.


  16. Mikal

    14 years ago

    @Van Taiariol,

    It’s hard to imagine that being a software issue, but I can’t say for sure. Is there any chance you could capture the NMEA stream when the speed is below 2 knots?


  17. UrSuS

    14 years ago

    @Mikal,
    2. Do you mean $GPGGA sentence? The 7th value of the sting “Horizontal Dilution of Precision (HDOP)” (After fix quality and number of satellites)
    You say it’s unreliable?


  18. bklw

    14 years ago

    Great work dude, but can I also read the current time if the fix status is void? Could this be implemented or is it already?


  19. Kyle

    14 years ago

    @UrSuS – HDOP is only a measure of the standard deviation of the horizontal accuracy. While it can give you an idea of the possible radius, it’s extremely difficult to pin down what the position error actually is with any given fix.

    That being said, it would be nice to have access to the parameter. Willem posted a modified version 10 in these comments about a year ago with a hor_acc() function. Mikal, any way you could incorporate this into the main version? Not hard to add on our own but it’s always good to keep things centralized if possible.

    Thanks for your amazing work on the library, it’s been invaluable.


  20. Gatech

    14 years ago

    Hey mikal: I have tried some example codes for using my new Skylab SKM53 GPS Module with my Arduino Board.

    I connected it well, but codes aren’t working.

    I got that gps.encode(GPS.read()) returns FALSE, and I never get and print a position.

    I think my GPS Module is bad Sad, but I added a Serial.print(GPS.read()); before gps.encode(…) and get responses from the GPS like this (on Processing’s Serial Monitor):

    36807144495753535356544648487848484848484444444449554877494644444252107171657749
    444444444444508342576748534848486946484913

    36807144495756535356544648487848484848484444444449554877494644444257107171657749
    444444444444508342574448444848486948554910

    All the same length…

    Is it broken?. What am I doing bad?.

    Regards :)


  21. Mikal

    14 years ago

    @bklw,

    Not sure I understand the question, but if the time fix status is GPS_INVALID_FIX_TIME, then TinyGPS hasn’t seen any valid time.


  22. Mikal

    14 years ago

    @Kyle,

    Congratulations–you finally pushed me over the edge and I’m soon posting TinyGPS 12, which supports satellites and HDOP as well as a couple of other goodies. :) Yay! I’m actually really happy to have those in there, and I intend to use them in my own projects. Thanks for the prod and for everyone who has asked for those.


  23. Mikal

    14 years ago

    @Gatech,

    Hmm… Instead of Serial.print(), can you Serial.write() those values? I think you’re getting real data, although not quite the type TinyGPS expects. Here’s a partial decode using http://www.asciitable.com:
    36 80 71 44 49 57 53 53 53 56 54 46 48 48 78 48 48 48 48 48 44 44 44 44 49 55 48 77 49 46 44 44 42 52 10 71 71 65 77 49
    $PG,1955586.00N00000,,,,

    It looks a lot like NMEA data. Sort of.

    Also, make sure you aren’t losing characters. Make sure you are talking to the Serial port at 115200K Baud, so that you write as quickly as possible.


  24. UrSuS

    14 years ago

    @Mikal, @Kyle,
    Thanks for reply guys!
    Will wait for the new version 12 with goodies! Hooray! :)


  25. Gatech

    14 years ago

    Thanks. I’m getting:

    $PMTK011,MTKGPS*08
    $PMTK010,001*2E
    $GPGGA,015540.220,8960.0000,N,00000.0000,E,0,0,,137.0,M,13.0,M,,*46
    $GPGSA,M,1,,,,,,,,,,,,,,,*12
    $GPGSV,1,1,00*79
    $GPRMC,015540.220,9.00,N,0000E,0.0000212,,7

    Is good? :S


  26. Mikal

    14 years ago

    @Gatech,

    The sentences TinyGPS is interested in are $GPGGA and $GPRMC. In your short example, the $GPRMC sentence is truncated–they all should end with a *XX checksum–and the $GPGGA sentence seems slightly bogus. The sixth term is 0, meaning that the data should be considered suspect, and the data itself is a little screwy: Lat = 89 degrees 60 minutes N by 0 degrees 0 minutes E. That’s the north pole! I think your GPS hasn’t detected a fix yet, but TinyGPS is probably processing this data correctly.


  27. Gatech

    14 years ago

    Thanks. You know how to make it detect a fix?. Or to know its status?.

    Regards.


  28. Gatech

    14 years ago

    THANKS. I FIXED THIS.

    The cables I were using, didn’t make a correct connection, and it was in short. :S I checked all with testers, and it was… now is working. Thanks to god it didn’t break my GPS.

    2. The new Script for v12 is too long and I can’t install on my Arduino :(


  29. Gatech

    14 years ago

    Now, I can’t understand what’s happening.
    Program tells me some LAT/LONG, and they are really near between them, but looking in Google Maps they are like 1KM far of my real location. :S

    Its not supossed to be max some METTERS exactly?.


  30. Mikal

    14 years ago

    @Gatech,

    Hmmm, my EM-406A is always very close to where Google Maps places it, especially when there are lots of satellites in the equation. The EM-406A I believe advertises +/- 10m accuracy?


  31. Gatech

    14 years ago

    Thanks. After someeeeeeeeeee… tests, now it’s working well!!!.

    A question. Is there a method for importing a version of TinyGPS more ‘light’?. In version v12 test_with_gps_device can’t upload on my Arduino due of its size. V11 is ligther, but I don’t know if are functionalities on 12 that are important. On my final work I think I only need LAT, LONG and “Precision”. Which version of TinyGPS should I use?. My sketch will also have GPRS, and sooome code, so I need to use well my 13Kb :(

    Thanks for all your support!.
    Gatech. From Colombia.


  32. Mitch

    14 years ago

    Hi, I’m getting this error when I compile simple_test – “TinyGPS does not name a type”, and when I compile test_with_gps_device, a compile error, “variable or field ‘gpsdump’ declared void” The version 11 examples compiled with no errors. I’m using the latest 1.0 version. Any ideas? Thanks in advance.


  33. David (D9W)

    14 years ago

    May I make a suggestion?
    Background: I am using the new Arduino 1.0 IDE.
    I know this is all nuances but I the way you have the code here on your web page>>

    #define RXPIN 3
    #define TXPIN 2 // From the GPS to the Arduino
    SoftwareSerial nss(RXPIN, TXPIN);

    VS the code in the example that comes with TinyGPU (test_with_gps_device )>>

    /* 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 2(rx) and 3(tx). (I changed the pin numbers for this example- but not having them name can lead to mistakes).
    */

    TinyGPS gps;
    SoftwareSerial nss(2, 3);

    I think the first example would lead to fewer mistakes of which Pin is the RX and which Pin is the TX, then your second example. I had been fighting with why I could not the TinyGPS to work at all, and it had to do with the fact I had them switch and did not know it. I know this is all code/nuances and the #define statements really don’t mean anything but having those named like in your first example made me stop and look how I had things wired up. (Thanks!). Too bad the example can’t be updated to reflect the first example. That still does not explain why SoftwareSerial is spitting out so much junk for 1.0 IDE. And I hope you can help me figure out why SoftwareSerial is giving me so many problems (over on the SoftwareSerial web page.)


  34. Ratheesh

    14 years ago

    Where can I download the library?


  35. Seriogal

    14 years ago

    Hello,

    just tried to move from Arduino v0.23 to v1.0 by changing TinyGPS library (tried v11 and v12). Several remarks:

    – print_date(gps) function always return 0/0/2000 and time returns HOUR:MINUTES:SECONDSHUNDREDS (why not seconds only?)
    – gps.f_speed_kmph() never return speed
    – gps.f_course() never return course

    rest functions seems to be working Ok.

    P.S. With v10 all these functions worked correctly.


  36. Mikal

    14 years ago

    Mitch–

    My guess is that there’s some kind of an installation problem. Have you figured it out?


  37. Mikal

    14 years ago

    @David,

    Good suggestion. Thanks!


  38. Mikal

    14 years ago

    @Ratheesh,

    It’s right on this page–though a little hard to see. Sorry!


  39. Mikal

    14 years ago

    @Seriogal,

    Hmm. These all work for me. Can you try the new “test_with_gps_device” sample?


  40. Graphene

    14 years ago

    Have you ever considered publishing your project on github.com?


  41. Seriogal

    14 years ago

    @Mikal,

    my output:

    Testing TinyGPS library v. 12
    by Mikal Hart

    Sizeof(gpsobject) = 115

    Sats HDOP Latitude Longitude Fix Date Time Date Alt Course Speed Card Distance Course Card Chars Sentences Checksum
    (deg) (deg) Age Age (m) — from GPS —- —- to London —- RX RX Fail
    ————————————————————————————————————————————–
    6 350 54.68775 25.42464 753 00/00/2000 20:16:21 766 203.90 ****** ***** *** 1732 268.76 W 185 1 3
    6 350 54.68775 25.42465 765 00/00/2000 20:16:22 780 203.80 ****** ***** *** 1732 268.76 W 370 2 6
    6 350 54.68775 25.42464 778 00/00/2000 20:16:23 791 204.50 ****** ***** *** 1732 268.76 W 555 3 8
    6 350 54.68775 25.42462 792 00/00/2000 20:16:24 804 205.90 ****** ***** *** 1732 268.76 W 739 4 11
    5 430 54.68775 25.42462 801 00/00/2000 20:16:25 814 206.10 ****** ***** *** 1732 268.76 W 1046 5 15
    6 350 54.68775 25.42461 816 00/00/2000 20:16:26 829 206.60 ****** ***** *** 1732 268.76 W 1231 6 17
    5 430 54.68775 25.42462 829 00/00/2000 20:16:27 842 206.50 ****** ***** *** 1732 268.76 W 1415 7 19
    5 430 54.68775 25.42462 1841 00/00/2000 20:16:27 1854 206.50 ****** ***** *** 1732 268.76 W 1600 7 21

    CoPilot BTGPS. Revorked to Serial transmit (I use only RX pin… haven’t found TX pin location on the board) :). Strange thing – if I run old library… It also doesn’t show date :(… Previously it was Ok. Maybe problem is inside mine device.


  42. James

    14 years ago

    Maybe a random question. I’ve started with your “test_with_gps_device” file – Works mint, love it. Can’t believe I spent a week messing around trying to get stuff to work before I found TinyGPS…

    Anyhow – I’ve made some modifications in order to be able to post data to a website (ie, dump.php?var=val&var2=val2). It’s all working well, except I can’t get both alt and speed to post this way at the same time when they have values (They work in error state). Output to serial is fine.

    I just changed your print_float to print to ethernet instead:

    ethClient.print(” “);

    And have this code:

    ethClient.print(“GET /ard/dump.php?id=” + deviceID);
    ethClient.print(“&sats=”); ethClient.print(gps.satellites());
    ethClient.print(“&hdop=”); ethClient.print(gps.hdop());
    gps.f_get_position(&flat, &flon, &age);
    ethClient.print(“&lat=”); print_float_eth(flat, TinyGPS::GPS_INVALID_F_ANGLE, 9, 6);
    ethClient.print(“&long=”); print_float_eth(flon, TinyGPS::GPS_INVALID_F_ANGLE, 10, 6);
    ethClient.print(“&fixage=”); ethClient.print(age);
    ethClient.print(“&alt=”); print_float_eth(gps.f_altitude(), TinyGPS::GPS_INVALID_F_ALTITUDE, 8, 2);
    ethClient.print(“&speed=”); print_float_eth(gps.f_speed_kmph(), TinyGPS::GPS_INVALID_F_SPEED, 6, 2);
    ethClient.println(” HTTP/1.0″);
    ethClient.println();

    etc. etc. All works mint – except no matter what I’ll only get alt, not speed. If I swap them around, I’ll get speed, not alt. It’s very odd.. Have tried moving the whole order around and get the same sort of results.

    Is there a specific order they have to be in?


  43. Oleg Mazurov

    14 years ago

    I was successfully using TinyGPS with USB GPS receivers -> https://www.circuitsathome.com/mcu/communicating-to-gps-receiver-using-usb-host-shield

    Just checked v.12 – everything works!


  44. Mikal

    14 years ago

    Thanks Oleg.


  45. Dave

    14 years ago

    As with a previous posting, I am having trouble getting satellites() and hdop() to give me anything other than ****. I migrated from v11 to 12. When I run my sketch as well as the sample, these two always show **** even though I am getting a position etc. Here is a sample output:

    Lat/Long(float): 43.40070, -79.79082 Fix age: 600ms. (kmph): 0.1667
    Sats: **** HDOP: **** Course: 18.96 Cardinal: NNE Delta = 2686.52 Meters

    and here are the serial statements:

    Serial.print(“Lat/Long(float): “); Serial.print(flat, 5); Serial.print(“, “); Serial.print(flon, 5);
    Serial.print(” Fix age: “); Serial.print(age); Serial.print(“ms.”);
    Serial.print(” (kmph): “); Serial.print(gps.f_speed_kmph(),4); Serial.println();
    //Serial.print(” Sats: “); Serial.print(gps.satellites()); Serial.println();
    feedgps(); // If we don’t feed the gps during this long routine, we may drop characters and get checksum errors
    Serial.print(” Sats: “); print_int(gps.satellites(), TinyGPS::GPS_INVALID_SATELLITES, 5);
    Serial.print(” HDOP: “); print_int(gps.hdop(), TinyGPS::GPS_INVALID_HDOP, 5);
    Serial.print(” Course: “); print_float(gps.f_course(), TinyGPS::GPS_INVALID_F_ANGLE, 7, 2);
    Serial.print(” Cardinal: “); print_str(gps.f_course() == TinyGPS::GPS_INVALID_F_ANGLE ? “*** ” : TinyGPS::cardinal(gps.f_course()), 6);


  46. Mikal

    14 years ago

    @Dave and anyone else with the general question “Why do I get XXX data just fine but YYY is invalid or not there?”, it’s hard to answer the question without seeing the data stream that TinyGPS is given. Remember that TinyGPS just parses the data you give it. If HDOP doesn’t show up it probably means that it either isn’t provided in the NMEA sentences that you unit is sending you, or possibly that those sentences have become corrupt somehow.

    Either way, the easiest way to debug is to display the raw NMEA sentences. In the test_with_gps_device sample, this means changing feedgps from

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

    to

      while (nss.available())
      {
        char c = nss.read();
        Serial.write(c);
        if (gps.encode(c))
          return true;
      }
    

    Post your output and we’ll take a look.

    Mikal


  47. David (D9W)

    14 years ago

    Or Mikal,
    you could use this one to spit out the NMEA sentences >>

    #include
    #define RXPIN 3 // From the GPS to the Arduino
    #define TXPIN 4
    SoftwareSerial mySerial(RXPIN, TXPIN);

    /*
    The Circuit:
    Pin assignments for the LS20031 GPS:
    • GPS Pin 5 (left-most when viewed from above) : No connection (or ground)
    • GPS Pin 4 : to Arduino ground (GND) pin
    • GPS Pin 3 : to Arduino pin 3
    • GPS Pin 2 : No connection
    • GPS Pin 1 (right-most when viewed from above) : to Arduino 3.3V pin
    */

    void setup()
    {
    Serial.begin(115200);// old 57600 New 115200
    Serial.println(“Goodnight moon!”);

    // set the data rate for the SoftwareSerial port
    mySerial.begin(57600); // old 4800 new 57600
    mySerial.println(“Hello, world?”);
    }

    void loop() // run over and over
    {
    if (mySerial.available()){
    Serial.write(mySerial.read());
    }
    }


  48. David (D9W)

    14 years ago

    Mikal,
    I don’t want to take up the total page, but I noticed that someone else was having the same problem I have been having with the date showing up as 00/00/2000. Time is great and on time. Just the date is off. I know you have said my GPS baud rate is too high, but the only part is missing from the output is the date and course speed card from GPS. This is the tinyGPS output >>

    Testing TinyGPS library v. 12
    by Mikal Hart

    Sizeof(gpsobject) = 115
    Serial Buffer size =128

    Sats HDOP Latitude Longitude Fix Date Time Date Alt Course Speed Card Distance Course Card Chars Sentences Checksum
    (deg) (deg) Age Age (m) — from GPS —- —- to London —- RX RX Fail
    ————————————————————————————————————————————–
    8 103 47.86107 -121.7066637 00/00/2000 22:43:54 41 48.00 ****** ***** *** 7651 34.66 NE 1065 7 0
    8 103 47.86107 -121.7066650 00/00/2000 22:43:56 54 48.00 ****** ***** *** 7651 34.66 NE 2003 14 0
    8 103 47.86107 -121.7066669 00/00/2000 22:43:57 72 48.00 ****** ***** *** 7651 34.66 NE 2941 21 0
    8 103 47.86107 -121.7066676 00/00/2000 22:43:58 80 48.00 ****** ***** *** 7651 34.66 NE 3878 28 0
    8 103 47.86107 -121.7066694 00/00/2000 22:44:00 98 48.00 ****** ***** *** 7651 34.66 NE 4816 35 0
    8 103 47.86107 -121.7066692 00/00/2000 22:44:01 95 48.00 ****** ***** *** 7651 34.66 NE 5756 41 1
    8 103 47.86107 -121.70666108 00/00/2000 22:44:03 5 48.00 ****** ***** *** 7651 34.66 NE 6820 48 3
    8 103 47.86107 -121.7066620 00/00/2000 22:44:04 24 48.00 ****** ***** *** 7651 34.66 NE 7758 55 3

    and here’s the SoftwareSerial out put >>

    Goodnight moon!
    1±£ºªŠr²ªÊšbr±ÅÉÅђršÊʲbºb’’¢ºª’r†ÁÁ±±©Ñá5R”:A›±5±Í±š‚b’ªb’‚b6űÁűŠšb’šb‚¢bbƉ)r²ºb‚rÊ¢bŠrš†©Á 5)‘AMY±Ñ±ŠÆŠšb’‚bºšb’ºŠb$GPGGA,224753.000,4751.6593,N,12142.3996,W,1,8,1.05,46.2,M,-16.9,M,,*5B
    $GPGLL,4751.6593,N,12142.3996,W,224753.000,A,A*41
    $GPG&AAr$GPGGA,224753.200,4751.6593,N,12142.3996,W,1,8,1.05,46.2,M,-16.9,M,,*59
    $GPGLL,4751.6593,N,12142.3996,W,224753.200,A,A*43
    $GPG&¢ªª$GPGGA,224753.400,4751.6593,N,12142.3996,W,1,8,1.05,46.2,M,-16.9,M,,*5F
    $GPGLL,4751.6593,N,12142.3996,W,224753.400,A,A*45
    $GPG&Êbr$GPGGA,224753.600,4751.6593,N,12142.3996,W,1,8,1.05,46.2,M,-16.9,M,,*5D
    $GPGLL,4751.6593,N,12142.3996,W,224753.600,A,A*47
    $GPGLA²º$GPGGA,224753.800,4751.6593,N,12142.3996,W,1,8,0.94,46.2,M,-16.9,M,,*5A
    $GPGLL,4751.6593,N,12142.3996,W,224753.800,A,A*49
    $GPGšš,3$GPGGA,224754.000,4751.6593,N,12142.3996,W,1,8,0.94,46.2,M,-16.9,M,,*55
    $GPGLL,4751.6593,N,1214™—¦§’é±ÉÉÑݪ¢r‚‚b
    ±©ÑÙ5R”:A›b,‚$GPGGA,224754.200,4751.6593,N,12142.3996,W,1,8,0.94,46.2,M,-16.9,M,,*57
    $GPGLL,4751.6593,N,12142.3996,W,224754.200,A,A*44
    $GPG&Aª$GPGGA,224754.400,4751.6593,N,12142.3996,W,1,8,0.94,46.2,M,-16.9,M,,*51
    $GPGLL,4751.6593,N,12142.3996,W,224754.400,A,A*42
    $GPG&šbr$GPGGA,224754.600,4751.6593,N,12142.3996,W,1,8,0.94,46.2,M,-16.9,M,,*53
    $GPGLL,4751.6593,N,12142.3996,W,224754.600,A,A*40
    $GPGKº63‰r$GPGGA,224754.800,4751.6593,N,12142.3996,W,1,8,0.94,46.2,M,-16.9,M,,*5D
    $GPGLL,4751.6593,N,12142.3996,W,224754.800,A,A*4E
    $GPGšR²Ê$GPGGA,224755.000,4751.6593,N,12142.3996,W,1,9,0.94,46.2,M,-16.9,M,,*55
    $GPGLL,4751.6593,N,12142.3996,W,224755.000,A,A*47
    $GPG4Iº2)$GPGGA,224755.200,4751.6593,N,12142.3996,W,1,8,0.94,46.2,M,-16.9,M,,*56
    $GPGLL,4751.6593,N,12142.3996,W,224755.200,A,A*45
    $GPGiŠb0$GPGGA,224755.400,4751.6593,N,12142.3996,W,1,8,0.94,46.2,M,-16.9,M,,*50
    $GPGLL,4751.6593,N,12142.3996,W,224755.400,A,A*43


  49. David (D9W)

    14 years ago

    Mikal, could you give us come clarification please?

    In your example on your web page up top you state >>

    while (nss.available())
    {
    int c = nss.read();
    if (gps.encode(c))
    {
    // process new gps info here
    }

    In the example to Dave you give us >>

    while (nss.available())
    {
    char c = nss.read();
    Serial.write(c);
    if (gps.encode(c))
    return true;
    }

    Is ‘c’ supposed to be an int or a char and does it matter? There are some purest out there that where happy to let me know I had the wrong type for the read() function. So I am a little confused as to which is correct. For the person who had nothing but numbers for their sentences, I found that type casting it as an int will give you that. Meaning int c = nss.read(); . Makes me wonder what happening here >>

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

    Also I tried to hunt down why I was not getting any DATE with my output from SoftwareSerial (besides the speed)(with my Locosys LS20031- it took some doing but I found a great resource in their version 1.3 manual {they had the $PMTK251 configuration codes } – http://www.locosystech.com/product.php?zln=en&id=20
    On that web page, they have two tabs – one for information and one for Download. Select the download and Datasheet_v 1.3, and that has all those codes that are hard to find to talk to the LS20031 GPS’s.

    – After reading that data sheet, I Now understand that not getting the DATE has to do with not getting the $GPRMC sentences. Now here’s the weird part coming from SoftwareSerial, 300 lines and not once did I see a RM or MC next to each other. You have to have both to get $GPRMC. It makes me wonder why or what SoftwareSerial is doing to prevent $GPRMC from showing up. But it’s not just not showing up with the beginning of $GPRMC, the whole sentence is missing. These sentences come in a order, and from what I can tell SoftwareSerial loves $GPGLL and tries to merge $GPGGA with something else. That kind of explains why I am seeing so many other people not getting the DATE too.

    Once I figure out how to use a voltage Level Translator (so I don’t fry the GPS while talking to the GPS), I will try cutting out all the clutter (everything else but $GPGGA and $GPRMC) and see how if SoftwareSerial will warm up to me. Not frying the 3volt GPS while talking to the GPS is a totally another type of issue.

    -Thanks for your patient Mikal, with all us newbie’s to TinyGPS, while we banging our heads against the wall a few hundred times.

1 Trackbacks For This Post
  1. Moving Forward with Arduino – Chapter 19 – GPS part II « t r o n i x s t u f f

    […] forget the 10k ohm pull-down resistor). You will need to install NewSoftSerial library, TinyGPS library and the SdFat library if not already […]

Leave a Reply