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. Mikal

    14 years ago

    @dan z,

    Make sure you print out the raw NMEA data being retrieved from the device.


  2. Mikal

    14 years ago

    @andrew m,

    Someday… someday.


  3. dan z

    14 years ago

    @Mikal

    I get something like this:
    2031938230179785810399154166230100133155785426147423021116620415438230211166230243230204230211381021315524913720115357147230147230211166230211166204154230204154381025614738230230179102230243166204154382301791022302041541021022051531662141102262302115711510223010210211523010238381021021471662041532308357243102243230230179…

    nothing like :

    $GPRMC,212352.000,A,4646.9834,N,02338.3160,E,0.00,297.18,080612,,,A*6B
    $GPGGA,212353.000,4646.9834,N,02338.3160,E,1,11,0.9,330.4,M,37.5,M,798.8,0000*7C

    how can i make sure this is good data?

    could it be the faulty gps receiver?

    any thoughts?


  4. dan z

    14 years ago

    And for some reason

    SoftwareSerial nss(RXPIN, TXPIN);
    void loop()
    {
    while (nss.available())
    {
    int c = nss.read();

    wont work for me.
    i Have to use Serial.read() instead and use the default Rx Tx pins (0 & 1) to get some data that looks like one written above (I’m not sure but i think i get different sets of numbers for different baud rates).

    PS: I’m using an Arduino Duemilanove ATmega328P


  5. thisoldgee

    14 years ago

    Mikal-

    I’m puzzled on my output. On arduino 1.0.1, an Uno and an EM-406A GPS under Ubuntu 10.04, I get the following output in the serial monitor, good at first then garbage characters:

    Simple TinyGPS library v. 12
    by Mikal Hart

    CHARS=264 SENTENCES=0 CSUM ERR=0
    CHARS=303 SENTENCES=0 CSUM ERR=0
    CHARS=342 SENTENCES=0 CSUM ERR=0
    LAT=37.961231 LON=-122.088027 SAT=0 PREC=0 CHARS=1530 SENTENCES=17 CSUM ERR=0
    LAT=37.961231 LON=-122.088027 SAT=0 PREC=0 CHARS=1600 SENTENCES=18 CSUM ERR=0
    LAT=37.961231 LON=-122.088027 SAT=0 PREC=0 CHARS=1670 SENTENCES=19 CSUM ERR=0
    LAT=37.961231 LON=-122.088027 SAT=0 PREC=0 CHARS=1740 SENTENCES=20 CSUM ERR=0
    ÿÿÿýþüþýÿøþûÿÿýøü7

    (Note: some good response lines were deleted to save space here).

    Any ideas as to what might be happening?

    Thanks…


  6. Syzygy

    14 years ago

    @dan z
    A common mistake (and one I make myself from time to time). You’re printing out the integer value of the characters instead of the characters themselves. It’s easy to do because the read() function returns an int, not a char.

    So instead of this:
    while (gps.available()) Serial.print(gps.read());

    Do this instead:
    while (gps.available()) Serial.print((char)gps.read());

    That said, was your example string intentionally gibberish? Because I can’t seem to decode it to anything interesting. You should at the least be seeing strings of 367180, which decodes to $GP.


  7. Mikal

    14 years ago

    @thisoldgee,

    Hmmm, no I can’t begin to guess. The umlauted y (ÿ) is ASCII code 0xFF, but that doesn’t explain why it’s being printed.


  8. Gustav

    14 years ago

    Dear Mikal,

    I get these compiling errors,when compiling GPS Toy
    what is wrong?
    I use Arduino IDE 1.0.1

    TinyGPS\TinyGPS.cpp.o: In function `TinyGPS’:
    C:\Users\Gustav\Documents\Arduino\libraries\TinyGPS/TinyGPS.cpp:28: multiple definition of `TinyGPS::TinyGPS()’
    TinyGPS.cpp.o:C:\Users\Gustav\AppData\Local\Temp\build5547417453074466164.tmp/TinyGPS.cpp:28: first defined here
    TinyGPS\TinyGPS.cpp.o: In function `TinyGPS’:
    C:\Users\Gustav\Documents\Arduino\libraries\TinyGPS/TinyGPS.cpp:28: multiple definition of `TinyGPS::TinyGPS()’
    TinyGPS.cpp.o:C:\Users\Gustav\AppData\Local\Temp\build5547417453074466164.tmp/TinyGPS.cpp:28: first defined here

    Best regards,

    Gustav


  9. Dan

    14 years ago

    Mikal,
    Is there a way to change km to feet?


  10. Jan-Albert van Ree

    14 years ago

    Have you considered adding decoding for other sentences? My Rockwell Jupiter module doesn’t output $GPRMC but $GPVTG, which basically contains the same info…

    Or would you accept patches to the code to add decoding the GPVTG string?


  11. Kyron

    14 years ago

    I’m using the library to try and receive signal from my parallax RXM-SG GPS Module, but I receive no signal. When using the USB method of getting GPS data I receive data after at most 2-3 mins and I can tell when the 2nd LED is blinking red having satellites in range. When cod to the Arduino Mega AT Mega 1280 I ONLY see the green LED flashing indicating that it is on.


  12. dr john smith

    14 years ago

    the data ,umlart question,

    can you check your serial data with a scope ?
    I think it might be up side down,

    I have been experimenting with a few different manufacturers NMEA equipment over the past month,

    And they can not seem to decide on the polarity.
    so if data is once per second, the level in between the data in some systems is high, and in others is low,

    seems the NMEA spec was ambiguous in the use of differential signals, which most companies only receive one side off,

    that’s excusable, but the company that sends its NMEA data back to front should be shot………

    now if only the hardware uarts on the pic could be turned to accept active high or low serial data…

    luckily, the soft serial implementation does allow this,

  13. Hello, It can return the raw nmea?
    Just sentences GPRMC and GPGGA…


  14. Tom

    14 years ago

    Hi Mikal,

    Thank you for writing this library.

    I am having a bit of a problem that I hope you can help with. I am using an arduino uno and a venus gps module. I seem to get valid NMEA sentences and I get good readouts for Lat, Long, altitude, time, and (sometimes) date (they change as I walk around with the gps and the lat/long resolves to my current location). I cannot get readouts for course or speed no matter what I do. If I send the value to the serial monitor it shows 1000.0 for course and -1 for speed.

    Could you offer some advice as to what might be the problem? Thanks.


  15. Mikal

    14 years ago

    @Gustav, it looks like the library is being linked twice. Do you have multiple files or multiple #include’s or something?


  16. Mikal

    14 years ago

    @Dan,

    Yep.

    float feet = 3280.84 * km;


  17. Mikal

    14 years ago

    @Jan-Albert,

    Yes, I’m working on a new TinyGPS design that would support arbitrary sentences. (When I get time!)


  18. Mikal

    14 years ago

    @Luiz,

    Since the library accepts raw NMEA as input, just print that out (or do whatever you want with it) before you send it to gps.encode().


  19. Mikal

    14 years ago

    @Tom,

    I’m guessing that your Venus GPS doesn’t support certain values. Can you capture 10 seconds worth of NMEA data and post it?


  20. Keve

    14 years ago

    Hi!

    I just want to let you know about a possible precision issue.
    I read it here: https://sites.google.com/site/wayneholder/self-driving-rc-car/getting-the-most-from-gps
    The last part “Precison loss in Tinygps”
    What do you think?


  21. Tom

    14 years ago

    Hi Mikal,

    The gps module does provide the values. If I test it with your test_with_gps_device example I get the correct information so it is working. I have done some experiments and think I know where the problem is coming from but not why. I am using a Nokia 6100 color lcd from sparkfun and the gLCD library created by Tom Carpenter. If I don’t use gLCD and just display the data via serial (to the computer) it seems to work, but if I include the gLCD library I get the invalid data.

    Do you know of or suspect some kind of conflict between the two libraries? Or could it be a timing issue of some kind (i.e. writing to the lcd takes to much time)?

    I can get the gps and gLCD to work together if I parse the data by hand (write my own parsing code) and that may be the way I have to go. But your library provides some data that I would rather not have to code myself.

    So, if you are familiar with the gLCD library by Tom Carpenter (https://github.com/TCWORLD/gLCD-Library) could there be a conflict between it and TinyGPS? Or would the problem lie elsewhere?

    I realize without the code it is hard to tell and I can post it if necessary.

    Thanks


  22. Tom

    14 years ago

    Here is 10 seconds of output from your example sketch:

    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
    ————————————————————————————————————————————–
    8 120 46.74856 -116.99318173 07/25/2012 14:52:43 209 808.50 342.10 0.00 NNW 7544 36.84 NE 595 2 1
    8 120 46.74856 -116.99318270 07/25/2012 14:52:44 306 808.50 342.10 0.00 NNW 7544 36.84 NE 1132 4 1
    8 120 46.74856 -116.99318373 07/25/2012 14:52:45 415 808.50 342.10 0.00 NNW 7544 36.84 NE 1682 7 1
    8 120 46.74856 -116.99318104 07/25/2012 14:52:46 123 808.50 342.10 0.00 NNW 7544 36.84 NE 2133 9 1
    8 120 46.74856 -116.99318174 07/25/2012 14:52:47 191 808.50 342.10 0.00 NNW 7544 36.84 NE 2584 11 1
    8 120 46.74856 -116.99318245 07/25/2012 14:52:48 264 808.50 342.10 0.00 NNW 7544 36.84 NE 3035 13 1
    8 120 46.74856 -116.99318318 07/25/2012 14:52:49 335 808.50 342.10 0.00 NNW 7544 36.84 NE 3486 15 1
    8 120 46.74856 -116.99318394 07/25/2012 14:52:50 412 808.50 342.10 0.00 NNW 7544 36.84 NE 3935 17 1
    8 120 46.74856 -116.99318457 07/25/2012 14:52:51 474 808.50 342.10 0.00 NNW 7544 36.84 NE 4386 19 1
    8 120 46.74856 -116.99318536 07/25/2012 14:52:52 554 808.50 342.10 0.00 NNW 7544 36.84 NE 4851 21 1
    8 120 46.74856 -116.99318623 07/25/2012 14:52:53 664 808.50 342.10 0.00 NNW 7544 36.84 NE 5411 24 1


  23. Dorothee

    14 years ago

    Hi Mikal,

    Although the test program seems to work for anyone else, I am running into problems, and I would greatly appreciate your help or advice!

    I am using Arduino Rev 3 board with the sparkfun gps shield and the EM406A gps module.
    I downloaded the libraries, TinyGPS, and I started with the “simple test” example, and I also tried “test with gps device”
    When mounted together and plugged into the computer (mac), aA red LED light is shining on the shield as well as on the module)

    The first test:
    (just to make sure, you know which code I am using)

    What I receive is:

    by Mikal Hart

    CHARS=0 SENTENCES=0 CSUM ERR=0
    CHARS=0 SENTENCES=0 CSUM ERR=0
    CHARS=0 SENTENCES=0 CSUM ERR=0
    which is ongoing.

    Trying the other example: "test with gps device"
    I obtain:

    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
    ————————————————————————————————————————————–
    **** **** ******* ******* **** ******* ******* **** ******* ****** ***** *** 0 0.00 *** 0 0 0
    **** **** ******* ******* **** ******* ******* **** ******* ****** ***** *** 0 0.00 *** 0 0 0
    **** **** ******* ******* **** ******* ******* **** ******* ****** ***** *** 0 0.00 *** 0 0 0
    **** **** ******* ******* **** ******* ******* **** ******* ****** ***** *** 0 0.00 *** 0 0 0
    **** **** ******* ******* **** ******* ******* **** ******* ****** ***** *** 0 0.00 *** 0 0 0
    **** **** ******* ******* **** ******* ******* **** ******* ****** ***** *** 0 0.00 *** 0 0 0
    **** **** ******* ******* **** ******* ******* **** ******* ****** ***** *** 0 0.00 *** 0 0 0


  24. Tom

    14 years ago

    Hi Mikal,

    As a followup here is some raw data from the Venus GPS unit:

    $GPGGA,044912.327,4644.8437,N,11659.5572,W,1,10,0.8,506.1,M,-14.1,M,,0000*65
    $GPGSA,A,3,30,05,21,29,26,15,25,18,16,06,,,1.6,0.8,1.4*39
    $GPGSV,3,1,10,21,64,287,33,29,58,145,42,18,37,212,26,30,30,281,26*71
    $GPGSV,3,2,10,26,30,086,21,15,29,129,27,05,25,051,27,16,23,313,39*7D
    $GPGSV,3,3,10,25,08,194,23,06,08,312,26*70
    $GPRMC,044912.327,A,4644.8437,N,11659.5572,W,000.0,183.4,270712,,,A*7A
    $GPVTG,183.4,T,,M,000.0,N,000.0,K,A*03
    $GPGGA,044913.327,4644.8437,N,11659.5572,W,1,10,0.8,506.1,M,-14.1,M,,0000*64
    $GPGSA,A,3,30,05,21,29,26,15,25,18,16,06,,,1.6,0.8,1.4*39
    $GPGSV,3,1,10,21,64,287,34,29,58,145,43,18,37,212,25,30,30,281,27*75
    $GPGSV,3,2,10,26,30,086,20,15,29,129,25,05,25,051,26,16,23,313,39*7F
    $GPGSV,3,3,10,25,08,194,23,06,08,312,29*7F
    $GPRMC,044913.327,A,4644.8437,N,11659.5572,W,000.0,183.4,270712,,,A*7B
    $GPVTG,183.4,T,,M,000.0,N,000.0,K,A*03
    $GPGGA,044914.327,4644.8437,N,11659.5572,W,1,10,0.8,506.1,M,-14.1,M,,0000*63
    $GPGSA,A,3,30,05,21,29,26,15,25,18,16,06,,,1.6,0.8,1.4*39
    $GPGSV,3,1,10,21,64,287,32,29,58,145,42,18,37,213,25,30,30,281,27*73
    $GPGSV,3,2,10,26,30,086,20,15,29,129,25,05,25,051,25,16,23,313,38*7D
    $GPGSV,3,3,10,25,08,194,23,06,08,312,28*7E
    $GPRMC,044914.327,A,4644.8437,N,11659.5572,W,000.0,183.4,270712,,,A*7C
    $GPVTG,183.4,T,,M,000.0,N,000.0,K,A*03
    $GPGGA,044915.327,4644.8437,N,11659.5572,W,1,10,0.8,506.1,M,-14.1,M,,0000*62
    $GPGSA,A,3,30,05,21,29,26,15,25,18,16,06,,,1.6,0.8,1.4*39
    $GPGSV,3,1,10,21,64,287,32,29,58,145,43,18,37,213,26,30,30,281,28*7E
    $GPGSV,3,2,10,26,30,086,20,15,29,129,25,05,25,051,26,16,23,313,38*7E
    $GPGSV,3,3,10,25,08,194,23,06,08,312,29*7F
    $GPRMC,044915.327,A,4644.8437,N,11659.5572,W,000.0,183.4,270712,,,A*7D
    $GPVTG,183.4,T,,M,000.0,N,000.0,K,A*03
    $GPGGA,044916.327,4644.8437,N,11659.5572,W,1,10,0.8,506.1,M,-14.1,M,,0000*61
    $GPGSA,A,3,30,05,21,29,26,15,25,18,16,06,,,1.6,0.8,1.4*39
    $GPGSV,3,1,10,21,64,287,32,29,58,145,43,18,37,213,26,30,30,281,28*7E
    $GPGSV,3,2,10,26,30,086,20,15,29,129,25,05,25,051,26,16,23,313,38*7E
    $GPGSV,3,3,10,25,08,194,23,06,08,312,29*7F
    $GPRMC,044916.327,A,4644.8437,N,11659.5572,W,000.0,183.4,270712,,,A*7E
    $GPVTG,183.4,T,,M,000.0,N,000.0,K,A*03


  25. Dorothee

    14 years ago

    Hi Mikal,

    in Addition to what I posted yesterday I should say that I placed the module outside, and it is blinking.
    But still, I obtain the same result of zero and stars.


  26. Mikal

    13 years ago

    @Keve,

    Yes, Wayne informed me about that. It won’t matter for most applications, but I intend to fix it in the next iteration of TinyGPS. Thanks!


  27. Mikal

    13 years ago

    Tom, the best way to debug this is to examine the internal statistics counters of TinyGPS and [New]SoftSerial. In particular, does software serial report any “overflow” error? That would indicate that you are not processing the incoming data stream fast enough. Alternately, if TinyGPS reports checksum error, then you may be experiencing some corruption caused by interference with the other device.


  28. Mikal

    13 years ago

    @Dorothee,

    Does the SparkFun shield deliver the serial data on pins 3 (RX) and 4 (TX)?


  29. j ferguson

    13 years ago

    I have just upgraded to rev 12. It supports my application, but I would like to use some of the built-in functions which i had to code myself for previous versions.

    But:

    I cannot compile simple_test.pde with Arduino 1.0.1 IDE running on Linux 12.04

    I get these errors:
    simple_test.cpp: In function ‘void loop()’:
    simple_test.cpp:50:26: error: ‘GPS_INVALID_F_ANGLE’ is not a member of ‘TinyGPS’
    simple_test.cpp:52:26: error: ‘GPS_INVALID_F_ANGLE’ is not a member of ‘TinyGPS’
    simple_test.cpp:54:22: error: ‘class TinyGPS’ has no member named ‘satellites’
    simple_test.cpp:54:38: error: ‘GPS_INVALID_SATELLITES’ is not a member of ‘TinyGPS’
    simple_test.cpp:54:80: error: ‘class TinyGPS’ has no member named ‘satellites’
    simple_test.cpp:56:22: error: ‘class TinyGPS’ has no member named ‘hdop’
    simple_test.cpp:56:32: error: ‘GPS_INVALID_HDOP’ is not a member of ‘TinyGPS’
    simple_test.cpp:56:68: error: ‘class TinyGPS’ has no member named ‘hdop’

    I’d be happy to try any experiments you might recommend. i did try taking the if/else code out of TinyGPS.h and having #include “Arduino.h” as a separate line – but no joy.

    Are the examples known to work with rev 12?

    best regards,

    John ferguson


  30. Commuted

    13 years ago

    Is this the sirf3 chip? I have one and it outputs NMEA strings continuously. I’m not sure if it’s working. I thought I would need to poll it with strings like “GGA”. The PC software does not work either, but the time and location is correct.


  31. j ferguson

    13 years ago

    Hi Mikal,

    I was able to use distance_between function from my application perfectly,
    gps.distance_between(flat, flon, x2lat, x2lon) works great.

    but not gps.course_to(flat, flon, x2lat, x2lon).
    It gives this error:
    “_1gps_with_heading_serial_LCD_1d_1.cpp381:30: error: ‘class TinyGPS’ has no member named ‘course_to”

    I thought problem might be that somehow “course_to” was a protected name and changed the names in the library (both .cpp and .h files) to ‘bearingto’ but get same error. It is certainly in there and there is no spelling error, why can’t my sketch see it?

    As an aside. Yesterday, after interminable fussing with my code which reads a skylab SKM 53 (Mediatek 3329), which seemed to die after a few seconds and although emitting clock signals, and nmea sentences, quits indicating position changes if there isn’t much movement. It turns out that there is a speed threshold function built into the firmware which turns-off new position indications if the chip hasn’t moved faster than some threshold speed – default appears to be 2 M/sec. This is for use in cars and is intended to restrict display of position “hunting” when the car is parked. No good for use on anchored boat where movement is less than 2 M/sec. There is a command to reset threshold to lower speed or nothing.
    examples:
    $PMTK397,0.2*3F
    $PMTK397,2.0*3F
    first reset threshold to 0.2 m/sec, second to 2.0 m/sec.

    These cannot be written to flash so need to be added to startup.

    but then maybe you already knew about this.

    best regards, john ferguson


  32. Mikal

    13 years ago

    @j ferguson,

    The error messages you mention would suggest to me that you haven’t successfully put the new TinyGPS library in the right place. If your compiler knows you have a TinyGPS class, but you have “no member named ‘course_to'”, that means you’re using the older .h header file.


  33. Mikal

    13 years ago

    @Commuted,

    This software tries to be chip agnostic. If the chip generates $GPGGA and $GPGLL it should work. (But yes, I test with SIRF3.)


  34. j ferguson

    13 years ago

    Hi Mikal,
    my stupid mistake re: missing TinyGPS members was assuming that I could leave earlier TinyGPS library in place and just change folder name to TinyGPSorig without also changing the cpp and h names. I took it out altogether and now everything works fine.

    thanks for your very useful library. I especially appreciate having course_to and distance_between in the library so i can clean my application up a bit.

    now on to the challenge of controlling the minimum speed threshold on the mediatek 3329.

    very best regards, john


  35. j ferguson

    13 years ago

    Hi Mikal,
    I added two words to TinyGPS to make it possible to retrieve content of field 6 in GPGGA, which if non-zero shows data is good, but also shows whether it has DGPS or other correction – thus it is good to know if number was 1 or 2.

    I also added word for GPRMC field 12, which can show a bit more about how the GPS is getting data, in this case “A” for autonomous – good data but no correction, or “D” for DGPS correction which depending on chip, could be WAAS or one of European correction systems, or RTCM if that signal can be input into the chip. I think my Garmin 152H sends “W” if it is WAAS and “D” if it is RTCM from connected DGPS receiver.

    I don’t think it would be good to add these to your code, because i don’t think many other people would want this, but my question is:

    Doesn’t the size of Arduino compiled code depend on which things you’ve called from a library? In other words, if there are things in the library which you do not reference, your code will be no bigger because they are there.

    I know featuritis is a disease, but???


  36. chicodog530

    13 years ago

    Hi, I am trying to make a gps log data to an sd card.
    I have a duemilanove , pharos-gps500 sirf3 and a seeedstudio sd shield. I fly rc planes and want to log the speed and possibly altitude. I have been able to get the gps working with tinygps no problem. But I am lost on how to log the info it displays to my serial monitor on the sdshield. I have been searching online for several days with no luck. I have no prior programming experience. Is there any code out there that you know of that would help me along. Thanks


  37. Ph Dal

    13 years ago

    Hi,

    I’m testing the lib with the example on a ATMEL 2560, and a GP-2106 SiRF IV receiver, connected on Serial2. Compilation is fine, but the GPS seems to be dead, no valid printing is produced on Serial port. I checked with another test of mine, and the GPS does reply, so it is fine. Any hint?
    Thanks.
    Ph


  38. Mikal

    13 years ago

    j ferguson,

    I am eager to make some improvements to TinyGPS. You are correct that a function that is not called by any code is typically optimized away, but it’s hard to make completely independent (and therefore excisable) functions in a library like this.

    M


  39. Mikal

    13 years ago

    @Ph Dal,

    You might try looking at the TinyGPS::stats to see what clues it gives you to start with.


  40. Armand Aanekre

    13 years ago

    Hi Mikal
    I have problems retrieving data on my Arduino uno from my Eagle tree V4 GPS. It sends data at 38400 baud (verfied with oscilloscope, 5 Volts). Three strings: GPGGA @ 10Hz, GPRMC @ 10Hz and GPGSA @ 1 Hz.
    With a simple code using the RX pin (Pin 0) @ 38400 I get correct data as shown below:
    $GPGGA,213841.600,5938.6597,N,00938.6553,E,1,8,1.40,181.3,M,41.0,M,,*59
    $GPRMC,213841.600,A,5938.6597,N,00938.6553,E,0.01,171.12,220912,,,A*67
    $GPGGA,213841.700,5938.6597,N,00938.6553,E,1,8,1.40,181.3,M,41.0,M,,*58
    $GPRMC,213841.700,A,5938.6597,N,00938.6553,E,0.01,171.12,220912,,,A*66
    $GPGGA,213841.800,5938.6597,N,00938.6553,E,1,8,1.40,181.3,M,41.0,M,,*57
    $GPGSA,A,3,13,04,32,23,20,02,31,30,,,,,2.53,1.40,2.11*06
    $GPRMC,213841.800,A,5938.6597,N,00938.6553,E,0.01,171.12,220912,,,A*69

    I have changed the baudrate to this: nss.begin(38400)

    When running your example code, this is what I get.

    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
    ————————————————————————————————————————————–
    **** **** ******* ******* **** ******* ******* **** ******* ****** ***** *** 0 0.00 *** 955 0 0
    **** **** ******* ******* **** ******* ******* **** ******* ****** ***** *** 0 0.00 *** 1911 0 0
    **** **** ******* ******* **** ******* ******* **** ******* ****** ***** *** 0 0.00 *** 2803 0 0
    **** **** ******* ******* **** ******* ******* **** ******* ****** ***** *** 0 0.00 *** 3696 0 0

    Any ideas about what is going on?


  41. Armand Aanekre

    13 years ago

    I removed the SoftSerial and used the “real” RX port to receive data and now it works. I also tried this simple code that should really only repeat the input and it seems that it works somehow, but there seems to be missing/erroneous data at the end of the GGA telegram sometimes.
    I guess Softserial is no good at 38400.. (Running arduino 1.0.1 on original Arduino UNO)

    This is the code I tested softserial with:

    #include
    SoftwareSerial mySerial(3, 4);
    void setup()
    {
    Serial.begin(57600);
    mySerial.begin(38400);
    }
    void loop()
    {
    if (mySerial.available())
    {
    Serial.write(mySerial.read());
    }
    }

    This is the result: (no lineshift either)

    $GPGGA,010034.600,5938.6576,N,00938.6540,E,1,9,0.90,175.8,M,41.E
    $GPGGA,010034.700,5938.6576,N,00938.6540,E,1,9,0.90,175.9,M,41.6
    $GPGGA,010034.800,5938.6576,N,00938.6540,E,1,9,0.90,175.9,M,41.,9
    $GPGGA,010034.900,5938.6576,N,00938.6540,E,1,9,0.90,175.9,M,41.5
    $GPGGA,010035.000,5938.6576,N,00


  42. Ivan Gustavo

    13 years ago

    To get more accurate precision of latitude and longitude, change the code of the function parse_degrees() to this:

    unsigned long TinyGPS::parse_degrees()
    {
    char *p;
    unsigned long left = gpsatol(_term);
    unsigned long tenk_minutes = (left % 100) * 100000;
    unsigned long grad = (left / 100) * 1000000;
    for (p=_term; gpsisdigit(*p); ++p);
    if (*p == ‘.’)
    tenk_minutes += gpsatol(++p);
    return grad + (tenk_minutes / 60);
    }

8 Trackbacks For This Post
  1. Arduino GPS module test sketch - Develop with Arduino

    […] Working with Arduino and TinyGPS […]

  2. Distance measuring with Arduino - Develop with Arduino

    […] Working with Arduino and TinyGPS […]

  3. Tutorial 15 for Arduino: GPS Tracking | JeremyBlum.com

    […] used the tinyGPS library to decode the NMEA GPS Data. Cooking-Hacks generously supplied both the GPS shield and SD Card […]

  4. Early Sailing Sensor designs | Andrew Hodel

    […] the TinyGPS library: http://arduiniana.org/libraries/tinygps/ Share this: Written by andrewhodel Posted in Engineering, […]

  5. When thinking o… | pa2dy

    […] “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 floating point dependency and ignores all but a few key GPS fields.” – TinyGPS website […]

  6. GPS Box | pa2dy

    […] “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 floating point dependency and ignores all but a few key GPS fields.” – TinyGPS website […]

  7. GPS Box « Sketching with Hardware

    […] “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 floating point dependency and ignores all but a few key GPS fields.” – TinyGPS website […]

  8. Telemetría y data logger with Arduino Part IIÁlvaro López | Álvaro López

    […] a Base y testear el alcance de las antenas, el proceso lo he ejecutado en el Base. He utilizado la librería TinyGPS que aparentemente funciona bastante bien, y los programas usados han sido los […]

Leave a Reply