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

  1. Mikal

    2 months ago

    @Gilles, the accuracy of the built-in data types float and double is a function of the processor. There’s nothing that SW can do to alleviate that I’m afraid. If you need higher precision, you might check out processors which use 64-bit doubles instead of 32, like the Due…?


  2. Mikal

    2 months ago

    @TommiP,

    Yes, you should copy the files to a new folder called TinyGPSPlus in the Arduino/libraries folder. Then make sure you exit and re-enter the Arduino IDE before running the examples.


  3. Mikal

    2 months ago

    @Pete B, thanks for the nice words. I believe the Adafruit library uses the fact that the Adafruit Ultimate GPS module (great module by the way!) has an asynchronous “FIX” output. You could simply watch that signal. I don’t want TinyGPS++ to depend on a feature that isn’t present in all GPS devices, but there’s no reason you can watch it asynchronously.


  4. Mikal

    2 months ago

    @flydr2, Thanks! Very cool.


  5. Mikal

    2 months ago

    @Costin, a trick to reset the GPS object is:

    TinyGPSPlus gps;
    
    ...
    
    {
    ...
       gps = TinyGPSPlus(); // reset with new object.
    ...
    }
    

  6. Mikal

    2 months ago

    @Jay Be, are you running the examples? What is the refresh rate of the GPS? 10Hz?


  7. Jay Be

    2 months ago

    yes, i’m running the “FullExample” and just changed this two lines:

    static const int RXPin = 10, TXPin = 9;
    static const uint32_t GPSBaud = 9600;

    refresh rate is 1hz.
    i also get checksum errors between 1 and 6…
    thanks!


  8. Makis

    2 months ago

    Hi is it posible to use the GPS++ To Serial.println only the $GPRMC sentence? in raw format as it came from GPS.

    Thanks in advance!


  9. Diego

    2 months ago

    How can I can do to get into a string frame the entire $ GPRMC frame , ie complete. I do not want to get only one field , I want to get the full frame and store it in a string variable . Thank you very much .


  10. Mikal

    2 months ago

    @Makis, no the library (purposefully) does not store complete sentences. But you know, you are completely in control of the byte stream before you send it to TinyGPS++’s encode() method. Why not simply look for that yourself?


  11. Mikal

    2 months ago

    @Diego, since you control the stream of data before it gets sent to TinyGPS++, just capture all the characters up until the newline terminator, beginning each time you see the characters “$GPRMC”.


  12. Brian

    2 months ago

    Hi!

    The isValid() test seems a little odd if all the NMEA strings are checksum-verified. Does isValid() check for usable data versus empty fields?

    Also, I need to save some of the NMEA data to an SD card, are the currently validated NMEA strings stored anywhere so I don’t need to recreate them from the object data?


  13. Ron Koval

    2 months ago

    I have run your example program which extracts R and L from the $GPRMB sentence and it works just fine. I have tried to work with conditional statements with steerDirection.value() without any success. I have added a few lines to your example and tried to assign steerDirection.value() to an integer variable, it compiles fine, but all I get is R575 or L575 for the program below. Can you direct me as how to get the steerDirection.value to work with other functions than Serial.print ? Thanks.

    Here is the section of code with // added for the 3 lines I have added

    void loop()
    {
    int dir; // added declaration of integer called dir
    {
    Serial.print(steerDirection.value());
    dir = int(steerDirection.value()); // added
    Serial.print(dir); // added, prints 575 no matter if L or R
    Serial.println();
    }

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


  14. Mikal

    2 months ago

    @Brian, it possibly could have been better named, but isValid simply means that at least one sentence has set the value correctly. Initially all values are NOT valid, but as soon as the first legal sentence sets it, that value is valid forever. It does not currently sense empty fields.

    It’s one of TinyGPS++’s design goals to be very stingy with memory consumption, and accordingly, complete NMEA sentences are never stored. If you want to store complete sentences you will have to do it yourself.


  15. Mikal

    2 months ago

    @Ron, the line beginning “dir = …” converts a character pointer into an int. That’s not what you want for dir. Either directly use the string

    Serial.println(steerDirection.value());
    

    or calculate dir correctly

    dir = strcmp(steerDirection.value(), "L") == 0 ? -1 : 1; // -1 for L, 1 for R
    

  16. Brian

    2 months ago

    Good to know that the “validated” NMEA strings are not available, but for others to note, it is quite easy to simply re-create the strings by using custom objects.

    You probably would not want to re-create a lot of them, but the basic GPRMC and GPGGA (Google Earth basics) share a lot of the same data, and could be easily re-assembled from custom strings, then have a valid checksum calculated and appended to the end.

    I’m in the midst of testing, but I have my doubts that the isUpdated() function works properly on custom objects. It seems to be firing about 10x as often as possible (1Hz uBlox update rate). More to follow…


  17. Brian

    2 months ago

    FYI, HDOP is Horizontal -Dilution- of Position, you use “diminution” which is the French equivalent, and not really correct.


  18. Brian

    2 months ago

    Solved the “issue” of rapid updates, my fault! ;)

    I’ve got the “re-assembly” of a GPRMC string going fine, with a recalculated checksum added to the end (some unused parameters are dummy data, so it will be different), but I’ve run into an issue in GPGGA where a custom object can be a variable length, like altitude.

    I use this technique to utilize the custom object (display on LCD, write to SD, etc): (Not in the order below. just the concept, which works fine…)

    - TinyGPSCustom GGAalt(gps, “GPGGA”, 9);
    - strncpy(GPSaltArrayText,GGAalt.value(),4);

    The issue is with altitude, I can’t predict how many bytes the custom object will contain, and something like: arraySize = sizeof(GGAalt); seems to crash the AVR

    1) Is there a better way to move the contents of a custom object into a char array?

    2) Is there some way to determine how many bytes a custom object contains?

    Thanks!


  19. Mikal

    2 months ago

    @Brian, are you familiar with the strcpy() function? The value() method of TinyGPSCustom returns a true C-style string, so you should be able to simply:

    strcpy(GPSaltArrayText, GGAalt.value());
    

    Alternatively, if you want to make sure it fits before you copy:

    int len = strlen(GGAalt.value());
    if (len < sizeof(GPSaltArrayText))
       strcpy(GPSaltArrayText, GGAalt.value());
    

  20. Brian

    2 months ago

    Still a little fuzzy on “isValid()”…

    This is a completely “valid” NMEA string:

    $GPGGA,033219.00,,,,,0,00,99.99,,,,,,*6C

    It’s essentially what you get before the GPS has a fix, but is tracking satellites (thus the time is correct, valid, and incrementing; therefore “updating”).

    Would TinyGPS++ consider the above sentence “valid” and “updating”? If so, I need to do a lot more field validations!

    Thanks.


  21. Daniel C

    1 month ago

    Mikal,

    Great Library, thanks for the great work. I have been using it with Hardware Serial and a Mega, but I have found that the hardware serial only works with the older versions of the Arduino IDE, and now I need to be able to use the later version. I have the GPS chip (Adafruit) hooked up properly and I launch the 1.0.5 IDE and use your DeviceExample script, replacing the software serial with hardware serial, change BAUS to 9600 and it works great. I then close that and open the 1.6.0 IDE and and do the same thing and get “No GPS data received: check wiring”. Any thoughts on why I might be seeing this?

    Thanks.


  22. Ronaldo

    1 month ago

    Dear Mikal,
    How do I record only $GPRMC on the memory card?


  23. Shelley

    1 month ago

    I have gps and openlog attached to the hardware serial pins and 16×2 lcd on other pins. Everything is running at baud rate of 57600 (I need a 5 Hz updated speed readings). Data is coming through ok but there is duplicate data showing up…for every 1/5 sec I get the same reading 20x’s. Is this a baud rate issue?


  24. W1BMW

    1 month ago

    Thanks for all your hard work on the libraries offered here! I’m using TinyGPS++ and an Argent Data radio shield for an APRS tracker. Your library made coding a snap!

    I had some problems initially that turned out to be a baud rate issue. The default value of 4800 baud must be changed to 9600 for the Adafruit Ultimate GPS Breakout Board, but the code worked right out of the box!

    73 de W1BMW


  25. Georges Payne

    4 weeks ago

    Hello Mikal,

    Noob here, in dire need of help!

    I have a Arduino Uno rev.3 and a Garmin 72 GPS unit. I familiarized myself with the Arduino environment by playing around with a few examples and by writing my own (simple) code also. Now I am trying to run the TinyGPSPlus DeviceExample code in order to grab data from the GPS. I have connected the Tx line from the GPS to pin #3 on the Arduino and the ground wire from the GPS to the GND pin next to pin 13. The GPS is correctly setup and using a terminal program on my PC, I can read the sentences just fine at 4800 baud.

    With the GPS unit connected to the Arduino, and without any modifications in the code, The program seems to hang after the credits in the beginning, right after “By Mikal Hart”. It does not say “No GPS, check wiring…” but it doesn’t proceed to the DisplayInfo loop either, because it doesn’t print “Location: “.

    The while loop doesn’t seem to be working, because if I disconnect the GPS it doesn’t go to “No GPS”.

    If I reset the Arduino with the GPS disconnected, it says “No GPS…” but if I reconnect the GPS without resetting the Arduino, nothing happens.

    I tried the debugging lines of code you provided in this page and I can see waves after waves of gibberish characters on the serial monitor.

    I also tried the checksum line, but wasn’t able to get any results with it.

    I have banged my head against this four nights in a row, but I am stuck. I live in a somewhat remote location, and I tried to see if there are any robotics clubs around, but couldn’t find anything.

    So I’m desperate. Any help, any help at all, would be greatly appreciated.

    Cheers!
    Georges


  26. Georges Payne

    3 weeks ago

    Hello Mikal,

    Never mind. A noob mistake, the Garmin GPS 72 output is Serial RS232, and the Arduino serial is TTL. I bought a 7$ RS232-TTL converter, and now I can read the phrases all right.

    Thanks anyway, your page was a tremendous help.

    Cheers!
    Georges


  27. Mikal

    3 weeks ago

    @Daniel C, are you sure the program you’re compiling is identical when you make the transition to 1.6.0? And all the libraries?


  28. Mikal

    3 weeks ago

    @Ronaldo, I think I would do that outside of TinyGPS. You are capturing the raw stream: just write what you need to SD.


  29. Mikal

    3 weeks ago

    @Shelley, depending on which sample app you’re running, it may print data every time a new sentence is parsed. But not every sentence brings fresh instances of the data you’re looking for. It’s not an error really, just a quirk. You could modify the sample to print only when the datum you seek actually changes.


  30. Mikal

    3 weeks ago

    @W1BMW, hey, thanks!


  31. Lespaul

    3 weeks ago

    Hello Mikal (Sorry, not good at English)
    I have used gr83 mudule gps with mega1280.
    I have taken from gr83 NEMA codes to enter the gps stream.

    const char * gpsStream =
      “$ GPRMC, 000118.050, V, 1335.5938, N, 10044.9498, E ,,, 160406 ,,, N * 70 \ r \ n”.
      “$ GPGGA, 000118.050,1335.5938, N, 10044.9498, E, 0,00 ,, – 25.9, M, -27.0, M ,, 0000 * 4B \ r \ n”;

    But the result is

    BasicExample.ino
    Basic demonstration of TinyGPS ++ (no device needed).
    Testing TinyGPS ++ library v. 0.92.
    by Mikal Hart

    Location: INVALID Date / Time: 4/16/2006 00: 01: 18.05.
    Location: INVALID Date / Time: 4/16/2006 00: 01: 18.05.

    Done.

    Help me please.


  32. KP

    3 weeks ago

    I want to just take some time to thank you for the great library! I’ve been using this library to parse non standard (custom) NMEA data from a weather station sensor (also includes a GPS in it).


  33. kostas stefani

    3 weeks ago

    Hello, i want to build a project that will have an arduino gps module on it, propably a shield that would also log the gps data. I would like to ask about the accuracy of the gps,is it a matter of hardware or software?? I mean if i use this library with a gps module that says it has an accuracy of 3m or an accuracy of 10m, will i get a much better accuracy with this library and a help of a magnetometer?


  34. Mikal

    3 weeks ago

    @KP, hey, thanks for that! So glad it’s useful for you.


  35. Mikal

    3 weeks ago

    Hi @Lespaul,

    The problem is that your two NMEA sentences indicate that you don’t have a good fix.

    The ‘V’ in field 3 of $GPRMC means “invalid”.
    The ’0′ in field 7 of $GPGGA means “no fix”.

    In this case TinyGPS++ discards all position, speed, course, or altitude data.


  36. Mikal

    3 weeks ago

    @kostas stefani,

    The software neither adds or subtracts accuracy. It reports exactly what the GPS module is reporting, only in a more convenient form.


  37. KP

    3 weeks ago

    Mikal,

    Is there already a built in function to get gps data (lat and lng) with 6 decimal as unsigned number? such as 90.123111 to 90123111?

    Thanks.


  38. Mikal

    3 weeks ago

    @KP, no, but you could synthesize it pretty closely with

    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)

    This won’t be exactly correct, because small billionths” values won’t be left padded with zeros, but you could create this pretty easily.


  39. KP

    2 weeks ago

    Hey Mikal,

    Thanks for the information.

    This is what I ended up doing.

    latitudeUINT = (gps.location.rawLat().deg * pow(10, 6)) + (round((gps.location.rawLat().billionths) / 1000.000)) ; // combine degree and decimal
    longitudeUINT = (gps.location.rawLng().deg * pow(10, 6)) + (round((gps.location.rawLng().billionths) / 1000.000));


  40. artem

    1 week ago

    Hi.
    Try to use your library.
    I receive from GPS:
    5245.94146 —- 05548.84800
    but your library converts it to:
    52.765663 —- 55.814132

    I need original GPS strings. How to get it? Make example please.


  41. Mikal

    1 week ago

    @artem,

    The original strings contain the latitude and longitude in degrees/minutes form, or more precisely, DDMM.MMMMM. The library converts the values to decimal degrees.

    Always remember that you control the GPS strings before you send them to TinyGPS++. If you want the raw GPS string, just save it yourself before you send it on to TinyGPS.


  42. Mikal

    1 week ago

    @KP. Perfect. Although I would use the integral constant 1000000UL instead of the function pow(10, 6), which is a floating point number.


  43. Ron Koval

    1 week ago

    Mikal,

    I have been trying to use TinyGPSCustom steerDirection(gps, “GPRMB, 3); to get the R and L from my Garmin GPS. Indeed R and L are read, but the GPS seems extremely slow to update, indicate a necessary change from R to L or L to R.

    I see I can extract “course” (which I assume is the equivalent to “Track” on the Garmin display, but is there a way to extract “Bearing” which is the goto heading? I would hope that these would update very quickly as I notice on the Garmin display.

    Thanks in advance to your reply.


  44. Ron Koval

    1 week ago

    Mikal,

    I asked too quickly. Bearing is the 11th field of the $GPRMB sentence. So using Bearing and Course, I can determine R and L and hopefully much quicker than my Garmin analyzes and updates it.


  45. KP

    1 week ago

    Mikal,

    Is there any specific reason I should avoid using the pow other than it is a floating point? What does 1000000UL do and why declare as such?

    Also if it is better or more effective, could I replace all my pow usage to XXXUL?

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

Leave a Reply