TinyGPSPlus: GPS location, speed and time
TinyGPSPlus (included as TinyGPS++.h) is Mikal Hart鈥檚 second GPS parser and the one most current tutorials use. You feed it the characters your GPS module sends, and it keeps a set of objects up to date: gps.location, gps.date, gps.time, gps.speed, gps.course, gps.altitude, gps.satellites and gps.hdop.
Built in on Mokxi: #include <TinyGPS++.h> and it builds, with nothing to install. Free, and no account needed.
What TinyGPSPlus does
Each object can tell you two things before you read it. isValid() says whether the module has ever reported that value, and isUpdated() says whether it changed since you last read it. That makes a sketch simple: feed encode() everything that arrives, then print the location only when gps.location.isUpdated() is true.
For a field the library does not parse, TinyGPSCustom watches any term of any sentence, for example the PDOP in a GPGSA sentence. And TinyGPSPlus::distanceBetween() and courseTo() work out the distance and bearing between two points, which is most of a geocaching or return-to-home sketch.
| Library Manager name | TinyGPSPlus |
|---|---|
| Author | Mikal Hart |
| Include | #include <TinyGPS++.h>#include <TinyGPSPlus.h> |
| Boards | every board Mokxi compiles for but ATtiny85 |
| In the simulator | Simulated: it runs against the part the way it does on the bench. |
| Parts it drives | GPS module, NEO-6M |
Install it
It builds on every board Mokxi compiles for but ATtiny85.
In Mokxi it is built in: #include <TinyGPS++.h> and the sketch compiles, with no download, no zip and no Library Manager.
On a real board, install "TinyGPSPlus" by Mikal Hart from the Arduino IDE鈥檚 Library Manager (Sketch, Include Library, Manage Libraries), or add TinyGPSPlus to lib_deps in PlatformIO. Mokxi follows the calls of release 1.0.3, so a sketch written here builds there too.
ESP32-C3 路 Arduino Uno 路 Arduino Nano 路 Arduino Mega 2560 路 Arduino Leonardo 路 SparkFun Pro Micro 路 Arduino Micro 路 ESP32-C6 路 Raspberry Pi Pico 路 Raspberry Pi Pico W 路 Seeed XIAO SAMD21 路 STM32 路 STM32 Nucleo-F411RE 路 STM32 Blue Pill 路 micro:bit V2 路 Arduino Uno R4 路 ESP32 DevKit 路 ESP32-S3-DevKitC-1 路 ESP8266 NodeMCU 路 Arduino Pro Mini 3.3 V 路 Seeed XIAO ESP32-C3 路 ESP32-C3 SuperMini 路 Seeed XIAO ESP32-C6 路 ESP32-DevKitC V4 路 LOLIN32 Lite 路 Wemos D1 R32 路 Cheap Yellow Display 路 TTGO T-Display 路 Seeed XIAO ESP32-S3 路 Arduino Nano ESP32 路 Arduino Nano RP2040 Connect 路 Seeed XIAO RP2040 路 Waveshare RP2040-Zero 路 Arduino Uno R4 WiFi
The calls you will use
In the order a sketch meets them.
TinyGPSPlus gps
Creates the parser.
gps.encode(c)
Feeds one character. Call it for every byte the module sends.
gps.location.isValid()
True once the module has reported a position fix.
gps.location.lat()
Latitude in degrees as a double; gps.location.lng() is longitude.
if (gps.location.isUpdated()) {
Serial.print(gps.location.lat(), 6);
Serial.print(",");
Serial.println(gps.location.lng(), 6);
}gps.time.hour()
The UTC hour, with minute() and second(); gps.date.year(), month() and day() give the date.
gps.speed.kmph()
Ground speed in kilometers per hour, or mph(), knots() and mps().
gps.satellites.value()
How many satellites are in use.
gps.charsProcessed()
How many characters encode() has seen. Under 10 after a few seconds means nothing is reaching the board.
TinyGPSPlus::distanceBetween(lat1, lng1, lat2, lng2)
The distance in meters between two points.
TinyGPSCustom pdop(gps, "GPGSA", 15)
Watches the 15th term of GPGSA sentences; pdop.value() is its text.
Example: GPS position
On the Arduino Uno R3. It runs in the browser exactly as printed.
// GPS position: a NEO-6M on an Uno, the way the tutorials wire it.
//
// NEO-6M TX -> pin 4 (the sketch's RX)
// NEO-6M RX <- pin 3 (the sketch's TX; the module ignores it here)
// NEO-6M VCC -> 5V, GND -> GND
//
// The module sends NMEA sentences at 9600 baud, once a second. TinyGPS++
// reads them one character at a time, and the sketch prints the position
// each time a new one arrives.
//
// The serial monitor runs at 115200, as in the TinyGPS++ examples. Mokxi's
// Serial has no send buffer: it waits for each byte to leave. At 9600 a
// printed line takes about 70 ms, the GPS keeps talking meanwhile, and
// SoftwareSerial's 64-byte buffer overflows: the sentence with the satellite
// count and the altitude is the one that gets lost. A real Uno buffers its
// Serial output, so a short line costs far less there; a long print or a long
// delay() can still make it miss bytes.
//
// There is no sky here. Mokxi does not model satellites or a radio. The
// position is a property of the module: click it and change lat and lon in
// the properties panel to move it. Click the module on the canvas to lose the
// fix, and click again to get it back.
#include <SoftwareSerial.h>
#include <TinyGPS++.h>
static const int RXPin = 4, TXPin = 3;
static const uint32_t GPSBaud = 9600;
TinyGPSPlus gps;
SoftwareSerial gpsSerial(RXPin, TXPin);
void setup() {
Serial.begin(115200);
gpsSerial.begin(GPSBaud);
Serial.println("Waiting for the GPS...");
}
void twoDigits(int value) {
if (value < 10) Serial.print('0');
Serial.print(value);
}
void showPosition() {
Serial.print("Lat: ");
Serial.print(gps.location.lat(), 6);
Serial.print(" Lng: ");
Serial.print(gps.location.lng(), 6);
Serial.print(" Sats: ");
Serial.print(gps.satellites.value());
Serial.print(" Alt: ");
Serial.print(gps.altitude.meters(), 1);
Serial.print(" m UTC ");
twoDigits(gps.time.hour());
Serial.print(':');
twoDigits(gps.time.minute());
Serial.print(':');
twoDigits(gps.time.second());
Serial.println();
}
// Every character the module sent since last time, into the parser.
void readGps() {
while (gpsSerial.available() > 0) {
gps.encode(gpsSerial.read());
}
}
unsigned long lastLine = 0;
bool warned = false;
void loop() {
readGps();
// The GGA sentence brings the position, the satellites and the altitude
// together, once a second. (RMC updates the position too, a moment
// earlier, but carries no altitude.)
if (gps.location.isUpdated() && gps.altitude.isUpdated()) {
showPosition();
lastLine = millis();
}
// Sentences but no position: the module has no fix.
if (gps.charsProcessed() > 10 && millis() - lastLine > 3000) {
Serial.println("No fix yet: waiting for satellites.");
lastLine = millis();
}
// Nothing at all after five seconds is a wiring fault, not a sky fault.
if (!warned && millis() > 5000 && gps.charsProcessed() < 10) {
Serial.println("No data from the GPS: check TX goes to pin 4.");
warned = true;
}
}Open it in the editor, wired and ready to run 路 GPS position: the project page
Common errors and how to fix them
No GPS detected: check wiring.
This is the example鈥檚 message when charsProcessed() stays under 10. The module鈥檚 TX goes to the board鈥檚 RX pin; check the baud rate (9600 for a NEO-6M) and that the module has power.
Characters arrive but location is never valid
The module has no fix yet. Its LED blinks once a second when it has one. Move outdoors, give a cold start a few minutes, and check isValid() before printing.
Location updates only every few seconds
The loop spends too long in delay() and the serial buffer overflows. Remove long delays and call encode() on every byte as it arrives, then do the slow work less often with millis().
Projects that use TinyGPSPlus
Built-in projects that include it. Each page has the full sketch and opens in the editor, already wired.
Keep going
Parts
More communication libraries
Try TinyGPSPlus without installing anything
Open the example, change the sketch, and keep your version in a free account.