TinyGPS++

A *NEW* Full-featured GPS/NMEA Parser for Arduino

TinyGPS++ is a new Arduino library for parsing NMEA data streams provided by GPS modules.

Like its predecessor, TinyGPS, this library provides compact and easy-to-use methods for extracting position, date, time, altitude, speed, and course from consumer GPS devices. 

However, TinyGPS++’s programmer interface is considerably simpler to use than TinyGPS, and the new library can extract arbitrary data from any of the myriad NMEA sentences out there, even proprietary ones.

Download and Installation

To install this library, download here, unzip the archive into the Arduino “libraries” folder, and restart Arduino. You should rename the folder “TinyGPSPlus”.
Download

History

TinyGPS++ is the immediate inheritor of TinyGPS, a popular compact parser that is used in Arduino installations around the world.  TinyGPS++ is not quite as ‘tiny’ as its older sibling, but its powerful and extremely easy-to-use new object model and useful new feature set make it an attractive alternative.

Usage

Let’s say you have an Arduino hooked to an off-the-shelf GPS device and you want to display your altitude.  You would simply create a TinyGPS++ instance like this:

#include "TinyGPS++.h"
TinyGPSPlus gps;

Repeatedly feed it characters from your GPS device:

while (ss.available() > 0)
  gps.encode(ss.read());

Then query it for the desired information:

if (gps.altitude.isUpdated())
  Serial.println(gps.altitude.meters());

Differences from TinyGPS

Although TinyGPS++ shares much the same compact parsing engine with TinyGPS, its programmer interface is somewhat more intuitive.  As a simple example, here’s how easy it is to print out the current latitude, longitude, and altitude in TinyGPS++:

Serial.print("LAT=");  Serial.println(gps.location.lat());
Serial.print("LONG="); Serial.println(gps.location.lng());
Serial.print("ALT=");  Serial.println(gps.altitude.meters());

Both libraries extract basic position, altitude, course, time, and date, etc. from two common NMEA sentences, $GPGGA and $GPRMC. But there are a number of other interesting sentences out there, both NMEA-defined and vendor-proprietary, just waiting to be harvested.

Consider the obscure $GPRMB, for example, which provides “recommended minimum navigation information” if you have a destination waypoint defined.

$GPRMB,A,4.08,L,EGLL,EGLM,5130.02,N,00046.34,W,004.6,213.9,122.9,A*3D

With TinyGPS++ it is now possible to extract just the “L” in the third field (it means “steer Left!”). It’s easy with the new TinyGPSCustom watcher object:

TinyGPSCustom steerDirection(gps, "GPRMB", 3);
...
Serial.print(steerDirection.value()); // prints "L" or "R"

Naturally, this extra functionality comes at some cost.  TinyGPS++ consumes somewhat more memory than TinyGPS, and it’s interface is incompatible.  So how to decide whether to update?  Here’s a guide:

Consider TinyGPS++ over TinyGPS if:

  • Compatibility with existing code (using TinyGPS) isn’t necessary.
  • Your sketch is not close to reaching RAM or flash resource limits.
  • You are running on Due or processor which can take advantage of the higher precision of 64-bit “double” floating-point.
  • You prefer the more intuitive object model.
  • You need to query for NMEA data beyond the basic location, date, time, altitude, course, speed, satellites or hdop.

Feeding the Hungry Object

To get TinyGPS++ to work, you have to repeatedly funnel the characters to it from the GPS module using the encode() method. For example, if your GPS module is attached to pins 4(RX) and 3(TX), you might write code like this:

SoftwareSerial ss(4, 3);
void loop()
{
  while (ss.available() > 0)
    gps.encode(ss.read);
  ...

After the object has been “fed” you can query it to see if any data fields have been updated:

  if (gps.location.isUpdated())
  {
    Serial.print("LAT="); Serial.print(gps.location.lat(), 6);
    Serial.print("LNG="); Serial.println(gps.location.lng(), 6);
  }
} // end loop()

The TinyGPS++ Object Model

The main TinyGPS++ object contains several core sub-objects:

  • location – the latest position fix
  • date – the latest date fix (UT)
  • time – the latest time fix (UT)
  • speed – current ground speed
  • course – current ground course
  • altitude – latest altitude fix
  • satellites – the number of visible, participating satellites
  • hdop – horizontal diminution of precision

Each provides methods to examine its current value, sometimes in multiple formats and units. Here’s a complete list:

Serial.println(gps.location.lat()); // Latitude in degrees (double)
Serial.println(gps.location.lng()); // Longitude in degrees (double)
Serial.print(gps.location.rawLat().negative ? "-" : "+");
Serial.println(gps.location.rawLat().deg); // Raw latitude in whole degrees
Serial.println(gps.location.rawLat().billionths);// ... and billionths (u16/u32)
Serial.print(gps.location.rawLng().negative ? "-" : "+");
Serial.println(gps.location.rawLng().deg); // Raw longitude in whole degrees
Serial.println(gps.location.rawLng().billionths);// ... and billionths (u16/u32)
Serial.println(gps.date.value()); // Raw date in DDMMYY format (u32)
Serial.println(gps.date.year()); // Year (2000+) (u16)
Serial.println(gps.date.month()); // Month (1-12) (u8)
Serial.println(gps.date.day()); // Day (1-31) (u8)
Serial.println(gps.time.value()); // Raw time in HHMMSSCC format (u32)
Serial.println(gps.time.hour()); // Hour (0-23) (u8)
Serial.println(gps.time.minute()); // Minute (0-59) (u8)
Serial.println(gps.time.second()); // Second (0-59) (u8)
Serial.println(gps.time.centisecond()); // 100ths of a second (0-99) (u8)
Serial.println(gps.speed.value()); // Raw speed in 100ths of a knot (i32)
Serial.println(gps.speed.knots()); // Speed in knots (double)
Serial.println(gps.speed.mph()); // Speed in miles per hour (double)
Serial.println(gps.speed.mps()); // Speed in meters per second (double)
Serial.println(gps.speed.kmph()); // Speed in kilometers per hour (double)
Serial.println(gps.course.value()); // Raw course in 100ths of a degree (i32)
Serial.println(gps.course.deg()); // Course in degrees (double)
Serial.println(gps.altitude.value()); // Raw altitude in centimeters (i32)
Serial.println(gps.altitude.meters()); // Altitude in meters (double)
Serial.println(gps.altitude.miles()); // Altitude in miles (double)
Serial.println(gps.altitude.kilometers()); // Altitude in kilometers (double)
Serial.println(gps.altitude.feet()); // Altitude in feet (double)
Serial.println(gps.satellites.value()); // Number of satellites in use (u32)
Serial.println(gps.hdop.value()); // Horizontal Dim. of Precision (100ths-i32)

Validity, Update status, and Age

You can examine an object’s value at any time, but unless TinyGPS++ has recently been fed from the GPS, it should not be considered valid and up-to-date. The isValid() method will tell you whether the object contains any valid data and is safe to query.

Similarly, isUpdated() indicates whether the object’s value has been updated (not necessarily changed) since the last time you queried it.

Lastly, if you want to know how stale an object’s data is, call its age() method, which returns the number of milliseconds since its last update. If this returns a value greater than 1500 or so, it may be a sign of a problem like a lost fix.

Debugging

When a TinyGPS++ sketch fails, it’s usually because the object received an incomplete NMEA stream, or perhaps none at all.

Fortunately, it’s pretty easy to determine what’s going wrong using some built-in diagnostic methods:

  • charsProcessed() – the total number of characters received by the object
  • sentencesWithFix() – the number of $GPRMC or $GPGGA sentences that had a fix
  • failedChecksum() – the number of sentences of all types that failed the checksum test
  • passedChecksum() – the number of sentences of all types that passed the checksum test

If your sketch has been running a while but charsProcessed() is returning 0, you likely have a problem with your wiring or serial connection. (If data never arrives from the GPS unit, it stands to reason it’s not getting to TinyGPS++.) I often insert a little debug clause into my GPS sketches detects this condition then prints out the incoming stream:

// Debug: if we haven't seen lots of data in 5 seconds, something's wrong.
if (millis() > 5000 && gps.charsProcessed() < 10) // uh oh
{
  Serial.println("ERROR: not getting any GPS data!");
  // dump the stream to Serial
  Serial.println("GPS stream dump:");
  while (true) // infinite loop
    if (ss.available() > 0) // any data coming in?
      Serial.write(ss.read());
}

Another common failure is when the sentences sent to TinyGPS++ are incomplete. This usually happens when you retrieve the characters from the GPS so slowly or infrequently that some are lost. The symptom is easy to spot: checksum failure.

Explanation: Every NMEA sentence ends with a numeric field that represents a mathematical summing of all the characters in the sentence. It’s there to ensure data integrity. If this number doesn’t match the actual sum (perhaps because some characters went awry), TinyGPS++ simply discards the entire sentence and increments an internal “checksum failed” counter. You can read this counter with:

Serial.print("Sentences that failed checksum=");
Serial.println(gps.failedChecksum());

// Testing overflow in SoftwareSerial is sometimes useful too.
Serial.print("Soft Serial device overflowed? ");
Serial.println(ss.overflow() ? "YES!" : "No");

If the checksum counter is continually incrementing, you have a problem. (Hint: don’t use delay() in your sketch.)

Custom NMEA Sentence Extraction

One of the great new features of TinyGPS++ is the ability to extract arbitrary data from any NMEA or NMEA-like sentence. Read up on some of the interesting sentences there are out there, then check to make sure that your GPS receiver can generate them.

The idea behind custom extraction is that you tell TinyGPS++ the sentence name and the field number you are interested in, like this:

TinyGPSCustom magneticVariation(gps, "GPRMC", 10)

This instructs TinyGPS++ to keep an eye out for $GPRMC sentences, and extract the 10th comma-separated field each time one flows by. At this point, magneticVariation is a new object just like the built-in ones. You can query it just like the others:

if (magneticVariation.isUpdated())
{
  Serial.print("Magnetic variation is ");
  Serial.println(magneticVariation.value());
}

Establishing a fix

TinyGPS++ objects depend on their host sketch to feed them valid and current NMEA GPS data. To ensure their world-view is continually up-to-date, three things must happen:

  1. You must continually feed the object serial NMEA data with encode().
  2. The NMEA sentences must pass the checksum test.
  3. For built-in (non-custom) objects, the NMEA sentences must self-report themselves as valid. That is, 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 the position and altitude information is discarded (though time and date are retained).

It may take several minutes for a device to establish a fix, especially it has traveled some distance or a long time has elapsed since its last use.

Distance and Course

If your application has some notion of a “waypoint” or destination, it is sometimes useful to be able to calculate the distance to that waypoint and the direction, or “course”, you must travel to get there. TinyGPS++ provides two methods to get this information, and a third (cardinal()) to display the course in friendly, human-readable compass directions.

const double EIFFEL_TOWER_LAT = 48.85826;
const double EIFFEL_TOWER_LNG = 2.294516;
double distanceKm =
  TinyGPSPlus.distanceBetween(
    gps.location.lat(),
    gps.location.lng(),
    EIFFEL_TOWER_LAT,
    EIFFEL_TOWER_LNG) / 1000.0;
double courseTo =
  TinyGPSPlus.courseTo(
    gps.location.lat(),
    gps.location.lng(),
    EIFFEL_TOWER_LAT,
    EIFFEL_TOWER_LNG);
Serial.print("Distance (km) to Eiffel Tower: ");
Serial.println(distanceKm);
Serial.print("Course to Eiffel Tower: ");
Serial.println(courseTo);
Serial.print("Human directions: ");
Serial.println(TinyGPSPlus.cardinal(courseTo));

Library Version

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

Serial.println(TinyGPSPlus::libraryVersion());

Sample Sketches

TinyGPS++ ships with several sample sketch which range from the simple to the more elaborate. Start with BasicExample, which demonstrates library basics without even requiring a GPS device, then move onto FullExample and KitchenSink. Later, see if you can understand how to do custom extractions with some of the other examples.

Acknowledgements

Thanks go out to the many Arduino forum users for outstanding help in testing and popularizing TinyGPS, this library’s predecessor. Thanks especially to Maarten Lamers, who wrote the wiring library that originally gave me the idea of how to organize TinyGPS++.

All input is appreciated.

Mikal Hart

Page last updated on July 5, 2014 at 4:16 pm
206 Responses → “TinyGPS++”

  1. pascalou

    3 months ago

    SOOOOOOOOOOOOOOOO GOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOD !
    THANK’S :-)


  2. Juan Pablo

    3 months ago

    Hello, I am using this library with the Copernicus I, and have not been able to get date or speed? Do you know why is that?


  3. Ed

    3 months ago

    Hi Mikal,
    I used your TinyGPS++ library for a school project last semester. Using an Arduino Uno R3 with the Firewing GPS Shield and a 1.8″ tft_lcd screen for real-time position info. I got it mostly working, I was able to display the gps data to the screen fine or I could log the data to SD card ok, but not both at the same time. However, this was just an issue with my code not handling the shared data lines properly, which I am currently working on. Anyway, I was really wondering how to send $PMTK commands to my GPS unit? When I try to send a command to change the datum so the date/time reflects current time zone, nothing happens? I’m pretty sure I am probably not implementing this in the code properly as I am still fairly new to C programming and Arduino IDE. From what I understand and read above, I should be able to just send the command via software serial, which is how my gps is connected to the arduino, by adding the following to the setup; ‘ss.write(“$PMTK330,124*2E”);’. However, as I said before this does not result in any change to the output data. Any help or suggestions would be appreciated! Thanks for the excellent and easy to use library as well!


  4. feby ferdian

    3 months ago

    sir, can you help me ? i get your video tutorial with pmb 648 at youtube http://www.youtube.com/watch?v=N69umIUiniI, and i tried with same code to my own pmb 648.. but no one data i get in serial monitor..

    why this happent ? can help sir ?


  5. owai

    3 months ago

    Hello,

    I had problem with your library and my mega 2560 until i saw this line in the “softwareserial” examples:


    Note:
    Not all pins on the Mega and Mega 2560 support change interrupts,
    so only the following can be used for RX:
    10, 11, 12, 13, 50, 51, 52, 53, 62, 63, 64, 65, 66, 67, 68, 69

    Not all pins on the Leonardo support change interrupts,
    so only the following can be used for RX:
    8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI).

    this may help others…

    thank you!


  6. Mikal

    3 months ago

    @pascalou–best comment ever. Thanks. :)


  7. Mikal

    3 months ago

    @Ed,

    My guess is that your device requires the string to be terminated with CR or CRLF. Try ss.write(“$PMTK330,124*2E*\r\n”) or possibly ss.println(“$PMTK330,124*2E*”).


  8. Mikal

    3 months ago

    @feby, sorry that’s not my video.


  9. Tom Baker

    3 months ago

    Love it thanks! Just one thing I think distanceTo in the course and direction example should be distanceBetween. Just in case anyone else is looking for it. Cheers!


  10. niq_ro

    2 months ago

    I try TinyGPS++ library and it works fine… first I try with serial monitor, now I put a LCD2004 (20×4) and work fine, see http://nicuflorica.blogspot.ro/2014/06/receptor-gps-conectat-la-un-arduino-2.html
    thx for library…


  11. niq_ro

    2 months ago

    I try GPS with TinyGPS++ in my car and… speed is always 0.00km/h :( my sketch is put at http://nicuflorica.blogspot.ro/2014/06/receptor-gps-conectat-la-un-arduino-2.html
    any solution?

    best regards, Nicu

    PS: my old GPR receiver not give data about years, mounth, days…


  12. NUGROHO

    2 months ago

    Mikal,
    Oke mikal thanks for ur sharing…, I see and understand now, but still confuse a little ^_^ thanks at all…


  13. Newbie_LED

    2 months ago

    I use TinyGPS++ for a long time, there was no issue until now. But, lately i’ve integrated TFT to Mega, there’s no problem with lat, lon, time, speed etc. internals but Custom part never works with UTFT :(


  14. Owen

    2 months ago

    Hello Mikal,

    Thank you for sharing your TinyGPS++ library. I’ve been testing with it for the past week and have found it very intuitive and useful.

    I’d like to get your advice with regards to a SoftwareSerial topic in combination with TinyGPS++.

    I have my GPS attached to a SoftwareSerial port, much like in your sketch.

    I also have a XBee breakout board attached to a second SoftwareSerial port on the Arduino for telemetry purposes.

    I’m also planning on adding a third device (on-board data logger) to record data from the tests that I’ll be running.

    From your NewSoftwareSerial library you advise to use the device.listen() to activate one particular software serial port at a time.

    With this in mind I spend most of the program time listening to the GPS device and only update the XBee communication once every 5 seconds (by comparing timers, no delay() used).

    However, I believe this makes it difficult to return data (new control loop gain values for example) to the Arduino via XBee as it is barely listening to this device.

    So my question is, how can/should I listen to the GPS while still being able to receive messages back via XBee on the Arudino. Should I use the native TX/RX pins for this? … the reason I don’t use them today is because I’m constantly having to disconnect the device that is attached to them when I reprogram the Arduino.

    Or is there such a thing as an interrupt driven SoftwareSerial port, since I don’t expect to send new setting very often, I rather have it listen to the the GPS and only discard the GPS data when I am sending new settings.

    Any advice is welcome, thanks again for your support with these libraries it saves us all a tremendous amount of time.

    Regards,
    Owen


  15. Stanley

    2 months ago

    Hi Mikal,

    Great work on the tinyGPS++, I was using your older lib and just upgraded to this libs..

    I’ve a question, for my APRS apps, I needed the GPS coordinates in degree, minute and seconds … 0310.13N 10138.99E format.

    Since your GPS coordinates is in lat / lon format, do you have a function to convert them to deg, min and sec format or any formula I can apply to make the coordinates conversion..

    Thanks

    Stanley


  16. olganet

    2 months ago

    This library is just a masterpiece, it’s written in a very intelligent way. Thank you very much Mikal for this great work.


  17. Mikal

    2 months ago

    Thanks, Tom. Fixed!


  18. Mikal

    2 months ago

    @niq_ro–

    Can you post the raw data?


  19. Mikal

    2 months ago

    @Owen–

    What I do in this kind of situation is use a device like the Teensy or Arduino Mega that has multiple serial ports. It’s very hard to design a working solution with more than one software serial port…


  20. Mikal

    2 months ago

    Hi Stanley–

    I don’t have such a function, but it can easily be written. See for example http://geography.about.com/library/howto/htdegrees.htm


  21. Grant

    2 months ago

    Hi. Love the lib.
    Just a couple of questions.
    Am I able to store the cardinal(courseTo_Plane) so that it can be used in calcs, etc. Whenever I try to do something as follows I get an error (error: invalid conversion from ‘const char*’ to ‘int’) is there any way to do this sort of thing?
    //Get the course to the plane from the camera unit.
    courseTo_Plane =
    TinyGPSPlus::courseTo(
    gps.location.lat(),
    gps.location.lng(),
    Plane_Lat,
    Plane_Lon);

    CourseTo_Plane = TinyGPSPlus::cardinal(courseTo_Plane);//


  22. Fredrick

    2 months ago

    Love the plugin. Having some issues but it might be my module?

    GPS: NEO-6M “gy-gps6mv2″ (http://arduino.ru/sites/default/files/u7441/261322446396.jpg)

    Can’t get number of satellites with gps.satellites.value(), always returns 0. Also it seems to be a lot of time between updated information.

    By running RAW data:
    while (Serial1.available() > 0)
    Serial.write(Serial1.read());
    Serial.println(“”);

    Log result:
    $GPRC,142539.00,A,4032.82750,N,00031.01260,E,0.017,,100714,,,D4
    3,39,37,144,44*40
    $GPGLL,4032.82750$GPRMC,142541.00,A,4032.82748,N,00031.01253,E,0.011,,100714,,,D0
    32.82748,N,00031.01253,E,142541.00,A,D*68

    $GPRMC,142542.00,A,4032.82745,N,00031.01250,E,0.024,,100714,,,D

    $GPRMC,142543.00,A,4032.82741,N,00031.01247,E,0.016,,100714,,,D

    $GPRMC,142544.00,A,4032.82740,N,00031.01246,E,0.025,,100714,,,D

    $GPRMC,142545.00,A,4032.82741,N,00031.01241,E,0.048,,100714,,,D
    $GPRMC,142546.00,A,4032.82742,N,00031.01241,E,0.014,,100714,,,D

    $GPVTG,,T,,M,0.014,N,0.025,K,D*24
    $GPGGA,142546.00,4032.82742
    $GPRMC,142547.00,A,4032.82743,N,00031.01238,E,0.021,,100714,,,D
    7,1.14,9.0,M,50.4,M,,0000*50
    $GPGSA,A,3,31,29,21,25,16,05,27,,
    $GPRMC,142548.00,A,4032.82744,N,00031.01236,E,0.014,,100714,,,D

    $GPGSV,3,1,11,05,07,052,32,16,19,301,44,18,00,150,28,21,56,160P
    VTG,,T,,M,0.012,N,0.022,K,D*25
    $GPGGA,142549.00,4032.82744,N,02
    3,04,313,33,25,31,107,39,27,06,250,32,29,52,046,50*7B
    $GPGSV,34
    ,9.1,M,50.4,M,,0000*5A
    $GPGSA,A,3,31,29,21,25,16,05,27,,,,,,1.
    40,203,43,39,37,144,43*46
    $GPGLL,4032.82743,N,00031.01235,E,14V
    ,3,1,11,05,07,052,32,16,19,301,45,18,00,150,30,21,56,160,43*7D

    $GPRMC,142552.00,A,4032.82745,N,00031.01235,E,0.009,,100714,,,D
    13,32,25,31,107,39,27,06,250,31,29,52,046,50*79
    $GPGSV,3,3,11,
    $GPRMC,142553.00,A,4032.82747,N,00031.01235,E,0.029,,100714,,,D
    3,43,39,37,144,44*41

    When trying some more pretty printing:

    Sats HDOP Latitude Longitude Fix Date Time Date Alt Speed Checksum Checksum
    (deg) (deg) Age Age (m) Fail Success
    0 0 40.55 0.52 7039 10/07/2014 14:16:56 7040 0.00 0.04 57 17
    0 0 40.55 0.52 7893 10/07/2014 14:16:56 7894 0.00 0.04 57 17
    0 0 40.55 0.52 8167 10/07/2014 14:16:56 8168 0.00 0.04 57 17
    0 0 40.55 0.52 3 10/07/2014 14:17:05 4 0.00 0.00 57 18
    0 0 40.55 0.52 273 10/07/2014 14:17:05 274 0.00 0.00 57 18
    0 0 40.55 0.52 1123 10/07/2014 14:17:05 1124 0.00 0.00 58 18
    0 0 40.55 0.52 1400 10/07/2014 14:17:05 1401 0.00 0.00 59 18
    0 0 40.55 0.52 2252 10/07/2014 14:17:05 2253 0.00 0.00 60 18
    0 0 40.55 0.52 2528 10/07/2014 14:17:05 2529 0.00 0.00 61 18
    0 0 40.55 0.52 3380 10/07/2014 14:17:05 3381 0.00 0.00 62 18
    0 0 40.55 0.52 3657 10/07/2014 14:17:05 3658 0.00 0.00 63 18
    0 0 40.55 0.52 4510 10/07/2014 14:17:05 4511 0.00 0.00 63 18

    As you can see the failed checksum increases a lot and example date age get quite high. Sitting outside when trying this.
    Any suggestions? Thanks.


  23. Stanley

    2 months ago

    Hi Mikal,
    Thanks, I’ve managed to do the conversion to deg, min & sec …

    I’ve another issue, the coordinates received seems to be wrong or way out when using the tinyGPS++
    I’ve confirm this using another APRS tracker to ensure the GPS receiver is working fine..

    I’m using Skylab SKM53 GPS module and I got the following coordinates :-
    0310.16N 10138.98E (3.1711 / 101.6605) but when using either tinyGPS or tinyGPS++ libs, I got the following coordinates… 0310.09N 10138.59E ( 3.169166 / 101.64972 ) with a distance of almost 500m away..

    Any idea why using different software gives a different readings ??

    I did the calc using the following website :-
    http://andrew.hedges.name/experiments/convert_lat_long/


  24. George

    2 months ago

    //Hi Mikal,
    //
    //Very good library and joy to use but I have a question regrading the Custom NMEA Sentence Extraction. I actually need to extract the info for magnetic variation and you show sample code for that. I am confused if more code is required to do that than what you show in the example and then where it needs to interested in the main loop. I tried playing with it but couldn’t get it ran even though it complied without error.
    //
    //Below is code that works for me and it correctly prints out lat and lon data and I would like to modify it so that it parses and outputs magnetic variation. I include the bare bones code that works fine and I have a reception on my GPS.
    //
    //Thanks for your help,
    //
    //George

    #include

    // The TinyGPS++ object
    TinyGPSPlus gps;

    void setup()
    {
    Serial.begin(115200);
    Serial1.begin(9600);
    Serial.println(F(“A simple demonstration of TinyGPS++ with an attached GPS module”));

    }

    void loop()
    {
    // This sketch displays information every time a new sentence is correctly encoded.
    while (Serial1.available() > 0)
    if (gps.encode(Serial1.read()))

    if (millis() > 5000 && gps.charsProcessed() < 10)
    {
    Serial.println(F("No GPS detected: check wiring."));
    while(true);
    }

    if (gps.location.isUpdated())
    {
    Serial.print("LAT="); Serial.print(gps.location.lat(), 6);
    Serial.println(" LON="); Serial.println(gps.location.lng(), 6);
    }


  25. fenjiro

    2 months ago

    hello,
    i am currently using tinygps++ with my GPS module.
    i would like tout save the full gprmc sentence on my sdcard ans print distance to a référence way point thanks to thé distance_to fonction in the lib.

    i was able to print the distance for each fix, but i can find a way to get thé full nmea sentence. i tried to mâke the GPS.term public, but i can only get the checksum.

    could you please help me how to do ?

    thanks you


  26. Stanley

    2 months ago

    Ignore my previous comment… the formula was wrong, the aprs.fi site needs deg mm.mm format whereas I converted everything to deg mm.ss ….


  27. Josh

    2 months ago

    Would it be possible for this library to also parse the ZDA sentance natively? I know I could use a custom watcher, but this way the built-in time handling would have 4 digits of year instead of two.

    My GPS chip from adafruit can be told to put out the ZDA sentance. I see this becomming more important as time goes on (didn’t we learn from Y2k?)


  28. Abdullah

    2 months ago

    Hi Mikal,

    I have a question, I am using your library and I wanted to calculate the distance traveled, like an odometer, there are two ways I have thought of doing this, one is to use the speed in meters and add it every second, the other would be to use the distance between function in your library and add the the distance travelled using the new gps position every second, which would be the better option, as I’m not sure how accurate would the distance calculated be in both the cases.

    Awesome work btw. Your library has helped a lot in my project.
    Regards,
    Abdullah


  29. harry

    2 months ago

    does tiny gpsplus work with a gps bee


  30. Michael

    1 month ago

    Hello. I am thinking of using this library. What license does it use and what are the terms of use? Thanks.


  31. Tim

    1 month ago

    Hello,
    is it possible to serial print the NMEA raw log ?


  32. harry

    1 month ago

    is it possible to read GPGGA say at the 6th comma to get if in std mode of DGPS mode


  33. harry

    1 month ago

    `how do you get the 6th position in GPGGA to Serial.print


  34. Mikal

    1 month ago

    @Grant,

    If you want to do numeric calculations, just use courseTo_Plane directly. The return from courseTo is a number from 0 to 360. At any time if you want to convert that to a string that represents direction, just call cardinal.

    If you really want to store the cardinal string, do it like this:

    char stored_cardinal[5];
    strcpy(stored_cardinal, TinyGPSPlus::cardinal(courseTo_Plane));


  35. Mikal

    1 month ago

    @fenjiro–

    Remember that TinyGPS++ is just a parser, parsing data that you provide it. If you want to print the full NMEA sentence, print it before you send it to TinyGPS++.

    At the end of each sentence (when you reach the \r\n end of line), call TinyGPS to get the fix. Wouldn’t that work?


  36. Mikal

    1 month ago

    @Josh, yes it could, but until it ZDA is proven to be widely used, I don’t want to consume resources to support it.


  37. Mikal

    1 month ago

    @Hi Abdullah, I think I would use the built-in distance function and add them together maybe every five seconds? If you do it too often I worry that small inaccuracies in the GPS might accumulate too rapidly. Thanks.


  38. Mikal

    1 month ago

    Hi Michael– It’s an LGPL license.


  39. Mikal

    1 month ago

    @Tim–
    Yes, print the characters before you send them to TinyGPS++.


  40. Mikal

    1 month ago

    @George,

    Can you tell us where you want to get magnetic variation from?


  41. Mikal

    1 month ago

    @Fredrick,

    TinyGPS++ gets satellite information from the $GPGGA sentence, 7th field. It looks like yours are truncated. I suspect that you’re losing/dropping some characters.


  42. Giancarlo

    1 month ago

    Hi sir, I bought this GPS module http://wiki.iteadstudio.com/Arduino_GPS_shield and with the TinyGPS I couldn’t decode the data, I just show in the serial the data format of the GPS ($GPRMC,A,7473838,N, ….). I tried to decode it because I only need latitude, longitude and altitude for my project. Then I downloaded this library, and I tried the second example( device example) and it didn’t work. I am using the 1.5.6 IDE version of the ARDUINO, and my GPS is fine, so what would you thing is the problem? Also the connections are good, I reviewed. Hope you can help me.


  43. Mikal

    4 weeks ago

    @Giancarlo, could you clarify what you mean “it shows problem” and “it didn’t work”?


  44. Stanley

    2 weeks ago

    Do you have any plans to support BeiDou / Glonass satellites NMEA sentences ??

    Thanks


  45. Robert

    2 weeks ago

    Thanks for writing this easy to use library!!

    If I use the FullExample, yoy wrote a smartDelay of 1 sec. This for feeding the GPS/encoder. But then the whole program is halted for that 1 sec. Is there an other way to do this, so the program continues without waiting?

    If i use the DeviceExample, the Serial.print shows 8x the same line.(Location & Date/Time) Any thoughts on that?

    Or is there a forum thread where i can ask these questions?
    Thanks!


  46. Vincenzo

    1 week ago

    I am having an issue in getting the right altitude, I have connected in parallel to the serial of my GPS module both a PC running ucenter v5.07 and an Arduino MEGA using TinyGPS++.

    I get wrong altitude from Arduino, the difference is always about 43 meter less than the correct value that is also correctly displayed by “ucenter”.

    I am just calling gps.altitude.meters() after checking that it is valid.

    Is this a known issue, or am I doing anything wrong?

    Thanks


  47. Henry Hung

    1 week ago

    Hi,
    I tried tinyGPS++ with MTK gps, in the fullexample, the check sum fail nr is increasing, as below, is it normal? and I can not get speed and course information..

    FullExample.ino
    An extensive example of many interesting TinyGPS++ features
    Testing TinyGPS++ library v. 0.92
    by Mikal Hart

    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
    —————————————————————————————————————————————
    **** **** ********** *********** **** ********** ******** **** ****** ****** ***** *** ******** ****** *** 63 0 0
    4 255 24.948257 121.509254 780 ********** 08:05:55 **** 128.20 ****** ***** *** 9792 327.98 NNW 269 1 1
    4 255 24.948257 121.509246 743 ********** 08:05:56 **** 128.20 ****** ***** *** 9792 327.98 NNW 573 2 3
    4 255 24.948257 121.509246 809 ********** 08:05:57 **** 128.20 ****** ***** *** 9792 327.98 NNW 779 3 4
    4 255 24.948257 121.509239 843 ********** 08:05:58 **** 128.20 ****** ***** *** 9792 327.98 NNW 1113 4 6
    4 255 24.948257 121.509231 133 ********** 08:06:00 **** 128.20 ****** ***** *** 9792 327.98 NNW 1319 5 6
    4 255 24.948257 121.509223 254 ********** 08:06:01 **** 128.20 ****** ***** *** 9792 327.98 NNW 1627 6 9
    4 255 24.948255 121.509223 262 ********** 08:06:02 **** 128.20 ****** ***** *** 9792 327.98 NNW 1835 7 11
    4 255 24.948253 121.509216 280 ********** 08:06:03 **** 128.20 ****** ***** *** 9792 327.98 NNW 2041 8 13
    4 255 24.948255 121.509216 311 ********** 08:06:04 **** 128.20 ****** ***** *** 9792 327.98 NNW 2247 9 13
    4 255 24.948251 121.509208 356 ********** 08:06:05 **** 128.30 ****** ***** *** 9792 327.98 NNW 2453 10 13


  48. Mikal

    1 week ago

    Thanks Robert. If you want to “do something” rather than just seemingly wait for 1 second, either add your own code to the sample SmartDelay function, or else reduce the amount of time waiting in SmartDelay. In that example, I chose a one second delay so that the updates would occur every second. But you could do with a smaller value.


  49. Mikal

    1 week ago

    Vincenzo– Hmm.. I don’t know why the values would differ like that. The only way to tell for sure is to print out and examine the NMEA data stream. Perhaps two different fields are being examined?


  50. Mikal

    1 week ago

    @Henry Hung,

    Does the checksum fail value continue to increase if you let the sketch continue to run?

    I think the problem here is that the sketch is not able to keep up with the data stream coming in from the GPS. This is likely because I think your GPS is updating 10 times per second and trying to Serial.print a line of text at each update. Serial.print is very slow. Possible solutions:

    1. Slow down the GPS update rate (MTK) to 1 per second.
    2. If possible increase the baud rate on the Serial console.
    3. Don’t print so much data at every update. Instead, print data every second or 5 seconds or something.

6 Trackbacks For This Post
  1. TinyGPS++ to the Rescue | Stainless Steelhead

    [...] to the brains behind Arduiniana, Mikal Hart, Poolbot has moved to the brand-new GPS library set, TinyGPS++.  This saved enormous time in developing custom code to process and check the validity of NMEA [...]

  2. Antenna tracker, first steps | kolin's

    [...] or none, I made simple arduino program for parsing NMEA crap and encoding it in LTM packets. I used TinyGPS++ library for parsing NMEA and few lines from TauLabs [...]

  3. GPS Ublox Neo-6M cu Arduino Uno | ArduHobby

    [...] Descarcati biblioteca tinyGPS sau tinyGPS++. [...]

  4. GPS-Logger | Pascal's Königreich

    [...] Card Breakout Board gibt’s bei Adafruit, um mit dem GPS Modul zu sprechen wurde die Library TinyGPS++ [...]

  5. GPS Distance Calculator (for golf) -Use Arduino for Projects

    [...] Tiny GPS++ [...]

  6. Arduino GPS with OLED Display | Home of Benty

    [...] OLED from Adafruit. It’s still a work in progress just squishing together code from the TinyGPS++ library and using the Adafruit GFX [...]

Leave a Reply