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(), 6);
Serial.print("LONG="); Serial.println(gps.location.lng(), 6);
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(), 6); // Latitude in degrees (double)
Serial.println(gps.location.lng(), 6); // 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 September 28, 2014 at 11:35 am
429 Responses → “TinyGPS++”

  1. Mikal

    6 years ago

    @Gustavo,

    The problem here is your terminations are spelled incorrectly. They should be \r\n instead of /r/n. Once I made the change I got this output:

    Location: 6.265981,-75.599311 Date/Time: 1/31/2018 17:32:06.00
    Location: 6.265981,-75.599311 Date/Time: 1/31/2018 17:32:06.00
    Location: 6.265981,-75.599311 Date/Time: 1/31/2018 17:32:07.00
    Location: 6.265981,-75.599311 Date/Time: 1/31/2018 17:32:07.00

    M


  2. Golpesar

    6 years ago

    HI Please Tell me How To Get Number of avalable satelliteand their SNR values
    thank you


  3. Mikal

    6 years ago

    @Golpesar, there are two satellite inspection examples. Try them out.


  4. Matt

    6 years ago

    I love the library but does this work with a BN-880? It seems to be UbloxM8N clone.
    I am using your library and love the features but the ‘parsing’ is not working correctly. Everything looks ok when I run the tests code but when I try it out updating the position is really slow and I am guessing some sort of parsing issue. Then I read on the Arduino forum that this library is not compatibale with the M8N. Is that true? Any workaround?

    No matter what. Really like your library so thanks for your effort.


  5. Henrique

    6 years ago

    When I lost conection to/restart GPS, and lose the FIX, the funcions isValid and isUpdate still returning true even if the GPS are putting out GPRMC with no data other then date and time ? How culd I know if I really have a valid data ?


  6. Henrique

    6 years ago

    @Mikal

    “Yes, it’s a little confusing, but the “isValid()” method on date and time is simply the library reporting that at least one NMEA stream that could contain a date or time has been parsed. Would you suggest a different algorithm? I’ll think about this.”

    This should be based on FIX, “GPRMC”, filed 2, A or V! So we could know if data is valid


  7. sheryl

    6 years ago

    I am always getting no gps data .check wiring why??????????


  8. Vinicius Senna

    6 years ago

    Hello

    Can you tell me if this code work in ESP8266 or ESP32 ?
    Thank you


  9. Jana

    6 years ago

    Whether i can use this library with nodemcu


  10. Mikal

    6 years ago

    @Matt, it looks like it can be configured to be GPS/NMEA compatible but may not be so natively.

    https://forum.u-blox.com/index.php/4637/neo-m8-to-nmea


  11. Konstantinos

    6 years ago

    Hello Mikal,

    Thanks for the so nice library.
    I have an issue with date.
    I ran your Device example as is and works fine.
    If I add a delay at the end of the loop, so I can receive data at a slower rate, I get all the information again but not the Date which is Invalid all the time. If I remove the delay, everything comes back to normal.
    I thought of the delay as an idea to slow down the display on an LCD.

    Any hint?
    Thanks in advance,

    Konstantinos


  12. Mikal

    5 years ago

    @Konstantinos, it’s important that you don’t use delay() in any sketch which processes streaming serial input. If you wish the slow down a display, try a different technique, like keeping track of the last time the display was updated. You can add logic to avoid updating the display except, say, after 1000 milliseconds have elapsed.


  13. Thomas Michalak

    5 years ago

    Hi,

    I’ve been trying to use the sub-object speed but without success. While driving around the recorded speed is quite inconsistent with the speed of the car. Feels even random sometimes.

    Is there anything special I’m missing when using the speed object? Should the values match the car speed? Is the speed not representing my speed?

    I understand that there is a refresh rate on the GPS but I drove at a steady speed for at least 10mins and there was still lots of high variations in the speed value.

    Thanks again for the fantastic library.


  14. Thomas Michalak

    5 years ago

    Hi again,

    Forget what I said! I must not have been thinking straight when I did my first tests!

    Using isValid() and isUpdated() might have made the difference but the outcome is that speed reading from the library matches the car’s speedometer and it’s actually very precise.

    Thanks again for this great library!


  15. Mostafa

    5 years ago

    Hi
    I am using the tinygpsplus library to run ublox neo-6m GPS module, I used the fullexample code in the tinygpsplus package but the only result that I could take is just some stars in all lines, What should I do to achieve accurate data?

    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
    **** ***** ********** *********** **** ********** ******** **** ****** ****** ***** *** ******** ****** *** 270 0 0

    thanks


  16. Andy Basacchi

    5 years ago

    Hi Mikal: I have been using your code quite successfully (thank you!), but now have some questions. When my GPS device goes from a stopped to a moving position, or from moving to stopped position – it takes some 8-10 seconds for the speed to catch-up. Also when completely stopped (no movement at all) the GPS displays a drifting velocity (usually 0 to as much as 2 kph). Do you know what is causing this and if there is a way to improve this? I need this more accurate as I am planning to use this in a cycling application. Thank you


  17. Brian

    5 years ago

    This is probably obvious, but if you have a loop that uses isUpdated() to ensure that your GPS signal is being received, then subsequent use of age() is pointless since age() is refreshed when is isupdated() fires, correct?

    I’m assuming that any valid isupdated() parameter is true for all possible data in that particular NMEA string, regardless if it changed or not? Ergo, there’s no need/purpose to further test any parts of that string.

    With respect to age(), I guess it is really only useful as a debugging test to see if you’ve had -any- valid data.

    The one caveat might be that one NMEA string is valid and the other is invalid due to corrupted data.


  18. Railroader

    5 years ago

    Thank You for a fantastic library, TinyGPS++.
    It just made a portable speed indicator work.


  19. varsha

    5 years ago

    Is there any way to come out after getting few gps values
    Like , exiting the loop after getting say, 5 continuous GPS readings.

    I have used the device library program to get the Readings and I’m perfectly getting it.


  20. Mr.Sensor

    5 years ago

    Hey Mikal,

    first of all thanks for sharing your library.
    I just tested your gps.time.centisecond() function but it only returned zeros instead of values between 0 an 99. Could you tell me what I did wrong, since the other time functions are running perfectly?

    Regards,

    Mr. Sensor


  21. Mikal

    5 years ago

    @Mr. Sensor– if centisecond is always 00, that *probably* means your GPS doesn’t report hundredths of a second, or perhaps reports them every time as 00. I’ve encountered both types. If you could provide a sample of your NMEA output I could easily see.


  22. Mikal

    5 years ago

    @Andy Basacchi, GPS drift is unfortunately a normal behavior in every commercial GPS device. I don’t know of any easy way to solve that problem cheaply.


  23. Mikal

    5 years ago

    @Mostafa, I would guess that you have selected the wrong baud rate?


  24. Mr.Sensor

    5 years ago

    @Mikal, thanks a lot for your reply. My fault was that the module i used updated the time every second, as a result centiseconds were always 00. Is there any chance, that your library could also report milliseconds even though my gps updates only with a frequency of 10Hz? For example using centiseconds or better said the time between two centiseconds and splitting them up to be more accurate…

    Regards,

    Mr. Sensor


  25. Mikal

    5 years ago

    @Mr.Sensor, I think it’s pretty reasonable to say that TinyGPS++’s job is to simply report the data provided by the GPS module in human-readable form. I’m very reluctant to modify that basic premise.


  26. Filippo

    5 years ago

    Hi Mikal,

    first of all thanks for sharing your library. I have a problem, I have a problem, I want to put the latitude value in a variable but i don’t work.
    Here my program:

    Serial.println(“Latitude= “); // It works
    Serial.println(gps.location.lat(), 6); //It works

    double temp_lat = (gps.location.lat(), 6);

    Serial.println(temp_lat); // It doesen’t work.

    Please, could you tell me what there is of wrong?
    Thanks
    Filippo


  27. Mikal

    5 years ago

    @Filippo

    double temp_lat = gps.location.lat();
    Serial.println(temp_lat, 6);


  28. Mike Morrow

    5 years ago

    Using this: TinyGPSCustom GSATest(gps, “GNGSA”, 1); // $GNGSA sentence, first element

    then this: if (GSATest.isUpdated()) {

    It is always on. After every single character from the GPS, it fires again. It is never off. I want to catch GNGSA statements and pick up the number of sats used in the solution. There are two of these in each block (one for GPS, one for GLONASS). I need to get control on each of them but it is not working that way. It is always firing!

    Is there something else I need to do?


  29. Mike Morrow

    5 years ago

    Having a problem trying to get numbers from GNGSA statements. I need to get all 12 of the in-use slots from 2 of these statements that come one after the other. Trouble is, with the Custom statements coded:

    TinyGPSCustom GSATest(gps, “GNGSA”, 1); // $GNGSA sentence, first element

    the

    if (GSATest.isUpdated()) {

    statement fires EVERY character coming from the GPS. The others seem to be performing properly.

    TinyGPSCustom satsInViewP(gps, “GPGSV”, 3);

    and

    TinyGPSCustom satsInViewL(gps, “GLGSV”, 3);

    I only want it to fire once per GNGSA statement, obviously. Is there something else I should be doing to read the GNGSA statements? The GPS I am using does not emit GPGSA at all, but two GNGSA statements. I need to get access to both and total up the in-use sats since this is not available anywhere I can find. In view is available from the GPGSV and GLGSV statements. I add these together for the total in vies sats. Just need GNGSA to operate properly.

    Thanks for a nice library.

    Mike


  30. Mikal

    5 years ago

    @Mike Morrow,

    When you retrieve the value of your GSATest custom object, are you using value() every time? The “updated” flag is cleared every time you retrieve the value using this technique.

    (code)
    const char *value() { updated = false; return buffer; }

    Mikal


  31. Mike Morrow

    5 years ago

    TinyGPSCustom GSATest(gps, “GNGSA”, 15);

    if (GSATest.isUpdated()) {
    Serial.print(millis());
    Serial.println(” – pdop updated.”);
    }

    From one of your examples. This pops every 2 ms. That is not possible. Yes, GNGSA. When it is set to GPGSA it does not pop at all. And, at least, that part is correct since I don’t get GPGSA. I get GNGSA and I want to read the details of them. Can’t I get an answer from someone? I have written in 2 places and get no answers.


  32. Mikal

    5 years ago

    @Mike Morrow,

    Per my answer from 4 days ago, the “updated” flag is only cleared when you actually retrieve the value with the “value()” method. The code you quote, which incidentally is not from one of my examples, simply reports on the state of the updated flag.


  33. Mike Morrow

    5 years ago

    I have figured out how to cause and (sorta) solve the problem (for me, at least, but not solving it in the general case).

    Higher on this page, the documentation says “isUpdated() indicates whether the object’s value has been updated (not necessarily changed) since the last time you queried it”. Pretty straightforward.

    That implies that the is-updated flag will be reset when it is checked and stay reset until the firing action occurs once again. Seems like correct operation to me. But that is not how it is working.

    Coded:
    TinyGPSCustom pdop(gps, “GNGSA”, 15); // $GPGSA sentence, 15th element
    TinyGPSCustom hdop(gps, “GNGSA”, 16); // $GPGSA sentence, 16th element
    TinyGPSCustom vdop(gps, “GNGSA”, 17); // $GPGSA sentence, 17th element

    So, when I do this:

    void loop() {
    if (pdop.isUpdated())
    {
    Serial.print(millis());
    Serial.println(” – pdop updated.”);
    // Serial.print(F(“, PDOP=”)); Serial.print(pdop.value()); // line 1
    // Serial.print(F(“, HDOP=”)); Serial.print(hdop.value()); // line 2
    // int i = int(pdop.value()); // line 3
    }
    while (NMEA.available() > 0)
    gps.encode(NMEA.read());
    } // The entire loop() routine.

    so then pdop.isUpdated() fires every input character (every 2 ms.) and I print like crazy to the Serial monitor.

    When I uncomment only “line 1″, it fires properly. Unclear why the change.

    When I uncomment only “line 2″, it starts firing every input character again.

    Also, uncommenting only line 3 makes it fire twice per second as it should.

    Uncommenting 1 or 3 cause the data element associated with the firing to be referenced and that, magically, resets the isUpdated() flag. It takes both actions. That is not mentioned, above.

    But with all 3 commented, the thing pops on every input character — essentially every time it can.

    Is this the intended operation of the library? I would think not. It seems like isUpdated() is somehow linked with the specific .value retrieval it fired for and never gets unset just by checking it as mentioned, above. Am I completely missing the point here?

    The sample code I referred to, previously, is here:

    https://github.com/mikalhart/TinyGPSPlus/blob/master/examples/UsingCustomFields/UsingCustomFields.ino

    I used it as my guide. And it finally led me to finding out that I had to reference the data element associated with the firing as well as calling isUpdated() to have it function properly. Since I will reference the firing data element, it will work properly and I can proceed to finishing my project but I would hope that you check further into this and make it work as documented. At least, as I read the documentation. I hope I did not miss something…

    Your library has saved me a bunch of time but has cost me many days of intermittently trying to troubleshoot this troublesome operation. I guess it is still a win. Thanks.

    I have written this code before (in VB6) with far more detailed data parsing and did not want to have to write it, again, in a different language (C).


  34. Mikal

    5 years ago

    I don’t know what to tell you, Mike. What you describe is exactly how I would expect it to behave, and how it’s documented to behave. If you “uncomment only line 2″ and leave the other 2 commented out, you are no longer checking pdop.value(), therefore, isUpdated() will return “true” every time. Here’s the summary:

    1. If you don’t ever call pdop.value() (i.e. if you have lines 1 and 3 commented out) then pdop.isUpdated() will always be true, as documented.
    2. Line 2 references hdop a different object, so it has no bearing on pdop.isUpdated().

    It’s not “magic”: it’s exactly what’s in the documentation:

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


  35. Ricardo

    5 years ago

    Hi Mika, thankyou for library very nice!!
    I have a problem in the recovered values of gps.time.isValid ()
    my code:
      if (gps.time.isValid ())
       {
         Serial.print (gps.time.value ()); // Raw time in HHMMSSCC format (u32)
         hour = gps.time.hour ();
         minute = gps.time.minute ();
         second = gps.time.second ();
       }

    Everything works fine, as long as there are no zeros.
    for example for
    23:59:59
    time.value = 23595900
    time.hour = 23
    time.minute = 59
    time.second = 59

    but if time is 00:01:00
    time.value = 010000 (2 digits missing)
    time.hour = 0
    time.minute = 01
    time.second = 0

    The worst is the case of:
    time now 23:00:00
    time.value = 2300
    and
    time.hour = NULL
    time.minute = 23 (this is the time not the minutes)
    time.second = 0

    Explain well?
    Thanks for a solution, your library is very practical.


  36. Alexander Rubli

    5 years ago

    HI
    I would like to know if it is possible to disable the checksum verification. I would like to send some test sentences to see if my project handles correctly some error conditions and if my DST subroutine is working.

    I am not a seasoned programmer… just sort of an advanced beginner.

    thank you


  37. Mikal

    5 years ago

    @Alexander… see my github comment.


  38. Mikal

    5 years ago

    @Ricardo,

    What GPS device are you using? I admit I don’t see how this can happen. It might help if you could supply some of the raw NMEA or your code.


  39. Michael Strnad

    5 years ago

    Hello Mikal!
    First of all, that library is really great, I like it and used it already in some projects. Now I try to get the exact time from GPS to correct my clock: I have a Citroen 2CV that was electrified by the local technical school in 2007. 2011 I was able to buy it and now I try to have a look to the electrical interior with several sensors and an Arduino Mega. To have an overview I use a SmartGPU2 from Vizic Tec. But now with the GPS there must be a conflict at the serial. Vizic told me:
    From the examples I learned that Pin 10, 11 is used for data for the Mega. To define par example Pin 14, 15 and Serial1 for the communication with the GPS did not work and I have no experience how to do it. I would be glad for a hint how to do it. Thanks a lot!


  40. Rushi

    5 years ago

    I did not get Location in indoor. Can this module support indoor location? I am use TinyGPS library. Please tell me what to do for indoor location?


  41. Yannis Xidianakis

    5 years ago

    Hi and thanks for this amazing library.
    I want to use a function to show me in an OLED display the fix 2D or 3D or none and also to get the sat elevation.
    How can i do taht?
    Thank you.


  42. Heikki

    5 years ago

    Hi and thank you for sharing this. Would it be possible to have two receivers on Arduino Due with TinyGPSPlus? I tried first reading one on serial2 and then another on serial3 on same loop. This returns invalid position. While reading just one or the other data is valid. I would like to see how position drifts between two receivers that are close to each other. I could try making a compass by placing two receivers at distance of about 7 meters from each others. Heading signal could be filtered as I have gyro data to enhance heading. As I have CAN bus and several arduinos on the bus I could send the position of the other receiver over the bus and see how that works.

    Is position available in radians on TinyGPSPlus? Not of course a big thing.


  43. Mikal

    5 years ago

    Hi @Heikki,

    Yes, you can use two receivers at once. Just make sure you declare two TinyGPS++ objects… one for each stream:

    TinyGPSPlus gps1, gps2;
    while (true)
    {
    if (Serial2.available())
    gps1.encode(Serial2.read());
    if (Serial3.available())
    gps2.encode(Serial3.read());

    … do stuff here with gps1 and gps2 …
    }


  44. Chris

    5 years ago

    Thank you so much, I’ve been working with a GPS unit from Adafruit for the last three days and I could not understand what to do until I dl’d/installed your lib and read your documentation. The explanation was key, and thank you for publishing the methods. All of the other libraries I found we very dense and poorly documented. Your examples are clearly superior as well.

    Thanks again.


  45. Christiaan

    5 years ago

    I get this error, while using the “courseTo” function. I just copied the code from the code box.

    GPS_plaatsdetectie:38: error: expected primary-expression before ‘.’ token

    TinyGPSPlus.courseTo(

    ^

    exit status 1
    expected primary-expression before ‘.’ token


  46. Mikal

    5 years ago

    @Chris, thanks for the nice message.


  47. Mikal

    5 years ago

    @Christiaan, in C++ the syntax for static functions is

    TinyGPSPlus::courseTo(…)

    (Note double semicolon.)


  48. Bengt

    3 years ago

    Hi, thanks for excelent code. I have a problem trying to asign the value when I have used a ustom NMEA Sentence Extraction like this:

    TinyGPSPlus NEXUS;
    TinyGPSCustom hdmNow(NEXUS, “IIHDM”, 1); // $IIHDM sentence, 1st element

    SerialMonitor.println(hdmNow.value()); // Works
    double oldDir = *hdmNow.value(); // Does not work, value of oldDir is not set


  49. Pit Hermann

    6 months ago

    @Mikal

    Hello,
    I’m missing the values for W (West) and E (East) on longitude and even
    the values for N (North) and S (South) on latitude
    Did you implement them with location.rawLat().negative and gps.location.rawLng().negative ?

    Pit


  50. Martin Brightmore

    5 months ago

    Hi Mikal

    Great piece of software, thank you.

    Could you explain why LONDON_LON is divided by 1000 in the following statement?

    unsigned long distanceKmToLondon =
    (unsigned long)TinyGPSPlus::distanceBetween(
    gps.location.lat(),
    gps.location.lng(),
    LONDON_LAT,
    LONDON_LON) / 1000;
    printInt(distanceKmToLondon, gps.location.isValid(), 9);

    Thank you
    Martin

29 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 [...]

  7. SpainLabs - Mantener tus proyectos en hora

    [...] Con Arduino puedes usar la librería tyniGPS++. [...]

  8. Prototype 1 – GPS Module | A Mean Center

    [...] something useful with it. This isn’t due to any competence on my part, but because of  the TinyGPS++ library by Mikal Hart which is just amazing. There are many examples included with the library, so it is [...]

  9. Unexpected behavior of sprintf with i32/u32 | CL-UAT

    [...] trying to build a string of characters from several elements given by the TinyGPS++ library with the use of [...]

  10. Connecting u-blox NEO-6M GPS to Arduino | Big Dan the Blogging Man

    [...] http://arduiniana.org/libraries/tinygpsplus/ [...]

  11. LatLong to XY | Rocket Project

    [...] the same. latlon2xy is the doc with the Arduino code. Since I last looked at GPS, Mikal Hart has an updated GPS library that computes distanceBetween() and courseTo(). It might be worth pursuing. Share [...]

  12. با برد آردوینو و شیلد GPRS دستگاه ردیاب کوچک و کارآمد بسازید | رایانش نیوز

    [...] این کتابخانه را برای استفاده از برد GPS دانلود کنید. سپس کدهای [...]

  13. Shield GPS Ublox NEO-6M – Programación con Arduino MEGA 2560 – Tecno-fly C.A

    [...] http://arduiniana.org/libraries/tinygpsplus/ [...]

  14. Leyendo datos del GPS – OCEANO ABIERTO

    [...] Arduino que nos permite convertir esas cadenas de caracteres en valores fácilmente interpretables: TinyGPSplus. Tendremos que descargar el archivo .zip de la última versión e instalarlo manualmente en nuestro [...]

  15. Lightweight Module for Collecting Stratospheric Microbes | HENRY-1 HAB MISSION

    [...] RBBB was programmed with Arduino’s IDE and includes both the TinyGPS++ and Arduino Servo libraries. The TinyGPS library is very effective at parsing NMEA GPS data [...]

  16. How to make a GPS Speedometer? – DFRobot

    [...] following library ‘s in your Arduino Library Folder. U8glib – For the oled display. TinyGps++ – For the GPS. The code is “printing” the speed, course, number of satellites, [...]

  17. IoT WiFi Boat Monitor | Mechinations

    [...] Next, grab the starting source code. You will also need to install the TinyGPS++ library. [...]

  18. Adding Location to Microcontroller Projects: GPS Tutorial | Teach Me Micro

    [...] levels hence a voltage divider is needed to step down the voltage from the Arduino.You can use the TinyGPS++ library for easier Arduino GPS interfacing. Here's an example sketch from the library (modified to fit [...]

  19. Using Seeeduino LoRaWAN with GPS and Loriot.io – Squix – TechBlog

    [...] temperature and humidity we have to install two libraries. Download the TinyGpsPlus library from http://arduiniana.org/libraries/tinygpsplus/ Then install also the DHT library from Adafruit from the library manager in the Sketch > [...]

  20. GPS CLOCK with M5STACK | macsbug

    [...]  TinyGPS++ [...]

  21. Guide to NEO-6M GPS Module Arduino | Random Nerd Tutorials

    [...] to get information on location in a format that is useful and easy to understand. You can click here for more information about the TinyGPS++ [...]

  22. GPS With Arduino Tutorial | How To Interface GPS With Arduino using tiny gps++

    [...] Tiny GPS Library Download Table of Contents1 How to Interface GPS with Arduino Uno2 GPS  Arduino Code Display on Serial Monitor3 How to Display Longitude and Latitude on LCD3.1 16×2 LCD and Arduino Connection4 Arduino GPS LCD Code5 GPS Arduino Projects [...]

  23. GPS Tutorial–Sending GPS Coordinates over GSM | alselectro

    [...] http://arduiniana.org/libraries/tinygpsplus/ [...]

  24. GY-NEO6MV2 GPS Module – Mr. Robotrick

    [...] tiny GPS Module can connect to 4 Sattelite and it is pretty accurate. The library I use to interact with this module makes getting coordinates very easy., just add it to your [...]

  25. GPS Neo-6M com Arduino - Aprenda a usar - Blog Eletrogate

    [...] Biblioteca TinyGPS++ Avaliações: 5.0. de 1 voto. Por favor, aguarde…{"item":{"entity":"posts","name":"post","id":3185,"item_id":74,"nonce":"60e8e7599d"},"render":{"args":{"echo":false,"entity":"posts","name":"post","item_id":null,"id":3185,"method":"stars-rating","series":null},"method":{"disable_rating":false,"allow_super_admin":true,"allow_user_roles":["administrator","editor","author","contributor","subscriber"],"allow_visitor":true,"allow_author":false,"template":"default","alignment":"center","responsive":true,"distribution":"normalized","rating":"average","style_type":"font","style_name":"star","style_size":30,"font_color_empty":"#cccccc","font_color_current":"#ffcb05","font_color_active":"#ffd016","style_class":"","labels":["Pu00e9ssimo","Ruim","Bom","u00d3timo","Excelente"]}},"stars":{"max":5,"resolution":100,"responsive":true,"current":100,"char":"s","name":"star","size":30,"type":"font"},"labels":["Pu00e9ssimo","Ruim","Bom","u00d3timo","Excelente"]} [...]

  26. Wio LTEで遊んでみる(その5:3軸デジタル加速度センサーとGPS) | IT技術情報局

    [...] が、これだけだと読みにくい。 なので、上記のサイトをそのまま参考にTinyGPS++」を使用して読みやすくする。 [...]

  27. Cara Menggunakan GPS Ublox Neo 6M + Arduino – Coretan Aja

    [...] http://arduiniana.org/libraries/tinygpsplus/ http://geekistuff.blogspot.com/2014/06/advance-u-blox-neo-6m-gps-module.html Bagikan ini:TwitterFacebookGoogleSukai ini:Suka Memuat… [...]

  28. Using the GT-U7 GPS module based on u-blox 7th generation GPS chip – Pseudo Random

    [...] http://arduiniana.org/libraries/tinygpsplus/ [...]

  29. In-Depth: Interface ublox NEO-6M GPS Module with Arduino

    [...] to Mikal Hart for his great contribution. His website Arduiniana.org has a full overview of all of the capabilities of the TinyGPS++ [...]

Leave a Reply