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
417 Responses → “TinyGPS++”

  1. Mike

    4 years ago

    Love this, thank you so much!


  2. exemusBeta

    4 years ago

    Noticed that here uses the millis() function in the library. So is there a problem that can happen with overflow. I want to run the program for a long time(like a year). How should I avoid overflow?
    Thanks in advance !!!


  3. Mark

    4 years ago

    Mikal,

    Forgive my lack of programming knowledge… What changes do i need to make to get a distance value to cm level? Units are currently in Km and I guess use of unsigned long means no decimal places. If it helps, the distances I play with are less than 100Km so a value in the form 00.00001 would allow me to get down to 1cm and up to 99.99999Km

    Thanks for creating such great code. It helps me to learn by doing.

    Mark


  4. Mark

    4 years ago

    Mikal,

    Please disregard my earlier question. I did some reading and worked out that I should change the unsigned long to a float and the PrintInt to PrintFloat.

    Thanks again for a great routine.

    Mark


  5. Mikal

    4 years ago

    @Mike, :)


  6. Mikal

    4 years ago

    @exemus,

    Good news for you: as long as you are regularly sending the TinyGPS++ object data (i.e. at least once every 47 days), you won’t have any risk of overflow. The library only uses millis() to calculate how much time has elapsed between valid sentences, which is normally just a second at most.


  7. Mark

    4 years ago

    Mikal,

    Now that I have distance in a xx.xxxxxx format, I find that I no longer have a space between the distance and course values when viewed on the Serial Monitor. I suspect this is due to the section…

    static void printFloat(float val, bool valid, int len, int prec)
    {
    if (!valid)
    {
    while (len– > 1)
    Serial.print(‘*’);
    Serial.print(‘ ‘);
    }
    else
    {
    Serial.print(val, prec);
    int vi = abs((int)val);
    int flen = prec + (val = 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
    for (int i=flen; i<len; ++i)
    Serial.print(' ');
    }
    smartDelay(0);
    }

    which I guess is working out the field length and adding spaces but I can't work out how. Any clues would be welcome.

    Thanks,

    Mark


  8. Doug

    4 years ago

    I just used for the frist time with a salvaged GPS module and setup worked on first attempt. Excellent library with really intuitive commands. Thanks very much for providing this to the community!
    (Sorry about the masked email address.)


  9. Mikal

    4 years ago

    Mark, is this one of the example sketches you’re running?


  10. Mikal

    4 years ago

    Thanks Doug. Glad you are finding the library useful.


  11. Larry

    4 years ago

    Mikal,

    I have a GY-GPS6MV2 with a UBLOX NEO-6M and tried the full example with a UNO R3. I get a HDOP between 70 and a little over 100. I have also run this GPS on a UBLOX program (u-center)and get an HDOP of 0.6 to 1.1. It appears to me that TinyGPS++ has increased the HDOP value. Why do the values differ by two orders of magnitude in TinyGPS++?

    This is an example of a string I captured using “RS232 data logger” and the HDOP value is 0.87 $GPGGA,021542.00,3756.24947,N,10452.17668,W,1,10,0.87,1900.2,M,-22.6,M,,*56


  12. Mikal

    4 years ago

    Hi Larry,

    HDOP is one of a handful of TinyGPS++ objects–others include speed, course, and altitude–that return integral values in 100th of units. The reason for this is to avoid having to work with floating point numbers if the user wants to avoid them, because floating point support uses lots of precious memory.

    For example, if you examine tinygps.speed.value(), you’ll get the speed in 100ths of a knot.

    However, for those other object types I give you the option of using float if you value the convenience. For example, if you look at tinygps.speed.knots() you’ll get a floating point number. I don’t offer this for HDOP though. Would you like to see something like tinygps.HDOP.units()?


  13. Tim

    4 years ago

    I have an iTead GPS receiver working with an UNO. I compared the time on the serial monitor with a GPS app on my Android phone and an internet time source, the time shown from the iTead is 9 seconds behind the other two sources. Can someone else compare times and see if it is just me seeing this?
    Thanks,
    Tim in Toccoa, GA


  14. Larry

    4 years ago

    Mikal,

    After digging through the .h and .cpp files I found where it said that HDOP was in 100ths though it took me a while to figure it out. I’m mainly interested in whether the value is 2 or less so it doesn’t make a difference if its in 100ths as then I can use values >= to 200.

    I notice that the “deviceExample” uses almost a third of the available memory and the “fullExample” uses almost half. Is that in part due to the size of the the tinygpsplus header and cpp files? I haven’t done any C programming for more than 10 years and am now brushing up on it by reading “New C Primer Plus” (old copy) and running some of the examples.

    I’m thinking that I would like to use the GPS and maybe an IMU, altimeter, and compass to design a autopilot for an UAV. I’m concerned that I may need every bit of computing power of the ATmega328p to do this and the TinyGPS++ header and cpp files may need to be more compact.

    Thanks for your reply to HDOP


  15. Another Tim

    4 years ago

    Mikal,

    just wanted to extend gratitude from this rather inexperienced Arduino user and/or programmer. Your library worked out of the box with my UNO R3 and a u-blox NEO-6M.

    I haven’t delved into the advanced examples yet. Baby steps!

    Regards,

    Tim


  16. Viegas

    4 years ago

    Hi, so I’m switching from TinyGPS to TinyGPS++ for a Cansat and I can’t find any examples of complete code. Can you provide me with a example of the full code for a GPS?


  17. Mikal

    4 years ago

    @Another Tim, thanks!


  18. Mikal

    4 years ago

    @Viegas, try the examples that ship with the library at File/Examples/TinyGPSPlus.


  19. Electrophile

    4 years ago

    Hi, Sorry for the delayed reply. Yes I’m trying DeviceExample.ino from the examples folder. I tried various baud rates, all the way from 1200 to 115200 but nothing worked. The Adafruit library worked right away though. I even tried the TinyGPS library (without the ++) and that did not work too. I’ll also try an AVR C library and see if that works.


  20. Mikal

    4 years ago

    @Electrophile, I haven’t seen your code, but my best guess is that you have your RX and TX lines reversed.


  21. Jeroen

    4 years ago

    This is sooooo good!
    Very very nice and intuitive library. Absolutely fantastic!


  22. Alf

    4 years ago

    Hello Mikal,
    First of all: I love your TinyGPSPlus library.
    In your documentation there seems to be a bug:
    Serial.println(gps.location.rawLatDegrees()); // Raw latitude in whole degrees
    Serial.println(gps.location.rawLatBillionths()); // … and billionths (i16/u32)
    Serial.println(gps.location.rawLngDegrees()); // Raw longitude in whole degrees
    Serial.println(gps.location.rawLngBillionths()); // … and billionths (i16/u32)

    I think in your kitchen sink demo there are the correct expressions.
    Hope that helps.

    Best regards,
    Alf


  23. Mikal

    4 years ago

    @Alf,

    It does help indeed! Thank you very much…!


  24. David Ball

    4 years ago

    Fantastic, so much faster to code than the tinyGPS library. It’s got pretty much all that’s needed brought to an easy to use set of variables.

    The temptation to use GPS in many more projects might be harder to control!

    Keep up the great work!


  25. David GM4JJJ

    4 years ago

    Many thanks, I used the TinyGPS++ library for my clock project with a UBLOX NEO-6M which has a built in RTC:

    A 4 digit LED clock built with an Arduino Uno and an inexpensive ublox NEO-6M GPS module GY-GPS6MV1 to set the time automatically and keep it in sync.

    The GPS module has a battery to keep its Realtime clock running even if the GPS signal is lost.

    The 4 digit, 7 segment LED display is common cathode, type number 5461AS.

    The clock will automatically change to and from Daylight Saving Time for the timezone chosen.

    The time can also be toggled to and from UTC and local time, by using an infrared remote controller.

    Most components needed are in the Sainsmart UNO R3 Starter Kit: http://www.sainsmart.com/starter-kits/uno-r3-smartkits/sainsmart-uno-r3-starter-kit-with-16-basic-arduino-projects.html

    Full details at:

    http://sourceforge.net/projects/arduinoledgpsclock/


  26. Brian

    4 years ago

    Might be a dumb question, but is there a way to use a function similar to the CustomFields to simply extract an entire valid NMEA sentence, like GPGGA?

    I made my own parser using CustomFields to display lat/long as HH MM.MMMM, but it would be easier to record the NMEA data if I could just grab the entire sentence and send it EEPROM or SD.

    Thanks!


  27. Brian

    4 years ago

    Sorry, the above should read: DD MM.MMMMM ;)


  28. Pedro Cruz

    4 years ago

    Hello

    Mikal

    How can i send tinygps to print out N S E W, to replace the – and +.

    best regards

    Pedro Cruz


  29. Mikal

    4 years ago

    Love it! Thanks for sharing @David GM4JJJ.


  30. Mikal

    4 years ago

    Hi @Pedro Cruz,

    I think I would just write a little code like this:

    if (gps.location.lat() < 0)
    {
      Serial.print(-gps.location.lat(), 6);
      Serial.println("S");
    }
    else
    {
      Serial.print(gps.location.lat(), 6);
      Serial.println("N");
    }
    

  31. Mikal

    4 years ago

    @Brian,

    For the sake of tininess, TinyGPS[++] purposely never stores entire NMEA sentences. However, keep in mind that TinyGPS[++] gets it data from your sketch. You have custody of the data before it is ever processed by the library. This is a frequently asked question, and my answer is the same: If you want to store and record sentences, simply create a ~100-character buffer and store the data into that as it arrives. Then when you get to the carriage return (\r) character, write it to the log and start again.


  32. Seth

    4 years ago

    I have two GPS modules. One is the Venus 6 Breakout from Sparkfun and the other is the UBlox 6M. They both work great when I use an Arduino Uno or Nano, but when I attempt to use it with a Teensy++ 2.0, I get nothing. I have multiples of each microprocessors and tested each one to verify the Teensy board wasn’t bad. I also attempted to use different pins and serial libraries on the Teensy, but that was also a dead end. Does anybody have any tips or ideas to why this is happening? I have to use the Teensy for the amount of memory and pins they have. The GPS modules have been connecting to satellites.


  33. Mikal

    4 years ago

    @Seth,

    Yep. Probably. Unlike Uno and Nano, not all pins on Teensy are compatible with SoftwareSerial. See http://www.pjrc.com/teensy/td_libs_NewSoftSerial.html for details. Otherwise, it might be that you have swapped RX and TX? I can vouch that TinyGPS[++] plus SoftwareSerial works fine on Teensy: I’ve done it many times.


  34. Seth

    4 years ago

    Thanks Mikal! I guess I overlooked that page because it had the old name for the softserial library name. Using the wrong pins turned out to be the case with the Teensy.


  35. Gijs

    4 years ago

    Hi Mikal,

    First off, many thanks for a great library!

    I have programmed a little gps datalogger but have run into something my limited programming knowledge can’t solve… I want my program to see if I have a gps-fix using a custom field:

    void setup(void) {
      ....
      TinyGPSCustom customDataFixed (gps, "GPGGA", 6);
    }
    void loop(void) {
      ....
      String fixedChar = customDataFixed.value();
      if (fixedSymbol == "1" &amp;&amp; gps.sentencesWithFix() &gt; lastSentencesWithFix) {
        fix = true; // we have a fix!
      }
      ...
    }
    

    Is there another way to check if I have a fix without having to convert my TinyGPSCustom field to a string? It adds about 2000 bytes to my sketch…


  36. Mikal

    4 years ago

    Hi Gijs–

    Thank you. Yep, try using either this arcane syntax:

    if (customDataFixed.value()[0] == '1' && gps.sentencesWithFix() > lastSentencesWithFix) {
    ...
    

    or if that seems too crazy, this:

    char *fixedChar = customDataFixed.value();
    if (fixedChar[0] == '1' && gps.sentencesWithFix() > lastSentencesWithFix) {
    ...
    

    Note the single ‘ quotes.


  37. Alan

    4 years ago

    Mikal,

    I’ve found a fairly limiting bug in your library. When a GPS is first powered up, if doesn’t have a fix, it will return NMEA strings with valid sentence makeup, but the values will be NULL.

    E.g.
    $GPGGA,,,,,,, …

    This is a problem is you want to wait until a valid time/date and here’s why.

    the code will watch for the ‘,,’ and doesn’t call the setTime(term) function because with a “,,” string, the term[0] will indeed be null… However, because the checksum at the end of this string full of commas will be valid, when it gets to the end of the string, it will go through the switch statement as if the string were valid and it will call the time and date commit…. which updates all the internals as if an actual date/time were set, which is wasn’t

    So there is no way to wait for a valid date/time as currently implemented. The valid, isupdated, all get updated even tho nothing was set.


  38. Alan

    4 years ago

    BTW, for millis()… I actually use the same as do most STM guys so I didn’t have to change a thing there :)


  39. Alan

    4 years ago

    a little more on the time/date topic above… this might be fixable if you check the value in parsedecimal for a valid string *before the call to atol*, and set valid based upon that instead of the commit

    Alan


  40. Mikal

    4 years ago

    Thanks for that Alan. I’ll enter an an issue on github. I don’t see this problem in my own installations, because the modules I mostly use don’t seem to send empty strings like that. What model GPS are you using?


  41. Alan

    4 years ago

    all of the UBLOX modules send like that when they have no information..

    e.g.$GPGSV,1,1,02,08,,,26,17,,,33*71
    $GPGLL,,,,,022553.00,V,N*49
    $GPRMC,022554.00,V,,,,,,,210414,,,N*7B
    $GPVTG,,,,,,,,,N*30
    $GPGGA,022554.00,,,,,0,00,99.99,,,,,,*62
    $GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30
    $GPGSV,1,1,02,08,,,27,17,,,32*71
    $GPGLL,,,,,022554.00,V,N*4E
    $GPRMC,022555.00,V,,,,,,,210414,,,N*7A
    $GPVTG,,,,,,,,,N*30
    $GPGGA,022555.00,,,,,0,00,99.99,,,,,,*63
    $GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30
    $GPGSV,1,1,02,08,,,26,17,,,32*70
    $GPGLL,,,,,022555.00,V,N*4F
    $GPRMC,022556.00,V,,,,,,,210414,,,N*79
    $GPVTG,,,,,,,,,N*30


  42. Kyniu

    4 years ago

    I have a problem with UBLOX NEO-6M. Using simple code from http://www.elecrow.com/wiki/index.php?title=GPS_shield I get correct data:

    $GPGGA,160133.00,5054.19463,N,02038.58806,E,2,05,1.80,291.6,M,37.3,M,,0000*59
    $GPGSA,A,3,25,04,29,12,14,,,,,,,,3.02,1.80,2.42*00
    $GPGSV,3,1,12,02,24,130,,04,30,084,19,12,76,294,45,14,34,295,41*78
    $GPGSV,32,1,15,0,$GPRMC,160134.00,A,5054.19478,N,02038.58832,E,0.089,,230414,,,D*7F
    $GPVTG,,T,,M,0.089,N,0.165,K,D*25
    $GPGGA,160134.00,5054.19478,N,02038.58832,E,2,06,1.80,291.1,M,37.3,M,,0000*57
    $GPGSA,A,3,25,24,04,29,12,14,,,,,,,3.02,1.80,2.42*06
    $GPGSV,3,1,12,02,24,130,,04,30,084,19,12,76,294,45,14,34,295,41*78
    $GPGSV,,2,1215,$GPRMC,160135.00,A,5054.19492,N,02038.58848,E,0.646,,230414,,,D*72
    $GPVTG,,T,,M,0.646,N,1.196,K,D*2D

    But with TinyGPS (debug code from above) I have a mess like this:

    $GPGGA,16032.054132N03.83,,,816256M3.M,005
    $GAA32,400,72,21,,17,.6.80
    $PS,,,202,21,43,8,027,9,41,42447
    $PS,,1,71,4,900,1,2,8152,,8234*0
    GGV3322,7233,,3300,32,2,533,7,7
    $PL,0.97,,23.83E102.0AD6
    $GPRMC,160327.00,A,5054.19357,N,02038.58298,E,0.123,,230414,,,D*7E
    $GPVTG,,T,,M,0.123,N,0.228,K,D*2E
    $GPGGA,160327.055.97N008528E2010,9.,,73M,000
    GGAA352,20,72,21,,17,.613*1
    GGV,,20,51960,0032,27,9,,43,9,07
    $PS321,71,41,00,1,2,81522,8234*3
    GGV,,22,72333,3300,32,2,593,7,7
    $GL55.95,,23.88E102.0AD6
    $GPRMC,160328.00,A,5054.19343,N,02038.58272,E,0.271,,230414,,,D*74
    $GPVTG,,T,,M,0.271,N,0.501,K,D*26
    $GPGGA,160328.055.33N008522,,810,9.,,73M00*9
    GGAA322,20,72,24,,17,.613*1
    PS,,,20,52,80,0031,26274,43,9,07
    GGV321,75061,00,1,2,85,22,8234*1
    GS,,,22,71,23,3301,32,33,93,7,7
    $PL55.94,,28522E102.0AD9

    Please help !!! What am I doing wrong?


  43. Mikal

    4 years ago

    @Kyniu,

    It looks like you are dropping characters. If you are using soft serial, check the overflow() flag to verify. If you are dropping, it’s because your processing loop is taking too long. Often this is simply because you are writing data to the serial console at too low a baud rate.


  44. Nancy

    4 years ago

    Is there any capability, or are you planning to add, the ability to upload a custom control string to the GPS? I’m using a SparkFun GPS Shield with an EM-406 engine and I’d like to change its baud rate to 9600 instead of the default 4800.
    A mirror to the “Custom NMEA Sentence Extraction” would be REALLY nice.


  45. Mikal

    4 years ago

    @Nancy,

    I doubt if I will be adding this feature any time soon. TinyGPS++ tries to be a device-agnostic parser. Remember, TinyGPS++ never takes control of the serial stream. At any time you can simply

    ss.print("<some device-specific string>");
    

    to the device.


  46. Kyniu

    4 years ago

    I know this is not a problem with TinyGPS library but have no idea where to ask for help. I have ublox NEO-6M receiver connected to Arduino Leonardo. And it looks that I overflow the buffer all the time. I wrote simple test code:

    #include
    #include

    SoftwareSerial SoftSerial(10, 11);

    TinyGPSPlus gps;

    void setup()
    {
    SoftSerial.begin(9600); // the SoftSerial baud rate
    Serial.begin(115200); // the Serial port of Arduino baud rate.
    }

    void loop()
    {
    if (SoftSerial.available() > 0)
    {
    gps.encode(SoftSerial.read());
    Serial.println(SoftSerial.overflow() ? “YES!” : “No”);
    }
    }

    And the result looks like this:

    (…)
    No
    No
    No
    No
    No
    YES!
    YES!
    YES!
    YES!
    YES!
    YES!
    YES!
    YES!
    (…)
    No
    No
    No
    No
    No
    YES!
    YES!
    YES!
    YES!
    YES!
    YES!
    YES!
    YES!
    (…)

    What is happening? Is NEO-6M realy sending too much data for Leonardo to handle it? According to NEO-6M datasheet I can not slow it down more then 9600. Would be very gratefull for any help.


  47. Alan

    4 years ago

    SoftSerial is really a poor implementation to deal with most anything serial related. All the logic handling serial timing, bit sending/receiving etc are all done in software and if *anything* is happening during that (other interrupts from timer, pwm, etc) it’s going to cause issues even at 9600 baud. If it were me, I’d look at some other way to connect to the gps such that you are using hardware based serial. You’ll just continue to have problems trying to use softserial.


  48. Alan

    4 years ago

    Ya know, I’ll try and pull you together a pull request. If interested I’ve added support for the polled PUBX protocol, it’s a one line protocol similar to NMEA that UBlox uses, you poll it with a command and it responds with ascii. Biggest problem is that I’ve modified the library to also support the UBX binary protocol as well… it’s inline so that either can work somewhat at the same time.

    Alan


  49. Edwin Noorlander

    4 years ago

    Hi, I use this library with a MEGA2560 and a LCD12864-ST via SPI and a SD card reader.

    If I want to use the following function (TinyGPSCustom) then running the Arduino MEGA2560.

    Who knows what’s going wrong.

    <snip>
    void loop(){
    <snip>
    //
    Serial.println();
    //TinyGPSCustom NZ(gps, &quot;GPRMB&quot;, 7);
    //Serial.println(NZ.value()); // Greb from GPRMB the 8th position ($GPRMB,A,4.08,L,EGLL,EGLM,5130.02,((N)),00046.34,W,004.6,213.9,122.9,A*3D)
    //TinyGPSCustom EW(gps, &quot;GPRMB&quot;, 9);
    <snip>
    }


  50. Mikal

    4 years ago

    @Edwin Noorlander,

    You need to make the TinyGPSCustom objects global. As it is right now, if you uncomment them they are created and destroyed each time through the loop.

28 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/ [...]

Leave a Reply