Tutorials / Sensors
GPS receiver (NEO-6M)
A module that talks on its own: NMEA sentences on a serial port, once a second, decoded with TinyGPS++.
- GPS NEO-6M
What it is
A GPS module is a computer of its own: it finds satellites and, once a second, sends its position as text lines in the NMEA format over a serial port at 9600 baud — nobody asks, it just talks. The firmware reads the port and decodes the sentences; TinyGPS++ does the decoding.
In the simulator
The block's sliders are what a moving receiver would report: Spd (km/h), Hdg (course) and Sat (satellites in view — fewer than 3 gives no fix, and the sentences go out empty, as the real module does). The position itself — latitude, longitude, altitude — is in Settings, Brasília by default, and so is the UART the bytes arrive on.
Pins
| Pin | What it is |
|---|---|
| TX | the module's transmit line — to the GPIO the sketch uses as Serial2's RX (16 in the example) |
| RX | the module's receive line — unused here; the simulated module ignores configuration |
| VCC | power — to a 3V3 symbol |
| GND | ground — to a GND symbol |
Wiring
The circuit below is the example GPS tracker from the lab — open it with Project → Open example… and it comes ready to run.
| GPS NEO-6M pin | Goes to |
|---|---|
| TX | RX2 on the board (GPIO 16) |
| RX | left unconnected |
| VCC | a 3V3 symbol |
| GND | a GND symbol |
Settings
Double-click the block's title bar to open its card, then the Settings tab. Changes apply to the running simulation right away.
| Setting | Accepts | Default | Notes |
|---|---|---|---|
| Latitude | -90 to 90 ° | -15.7939 ° | Decimal degrees; negative = southern hemisphere. The default is Brasilia. |
| Longitude | -180 to 180 ° | -47.8828 ° | Decimal degrees; negative = west of Greenwich. |
| Altitude | -100 to 9000 m | 1172 m | |
| ESP32 UART | Serial2 (the usual one for GPS) · Serial1 | Serial2 (the usual one for GPS) | The sketch picks the GPIOs in begin(); the simulation delivers the bytes on the UART chosen here. |
Code
#include <Arduino.h>
#include <TinyGPSPlus.h>
// The NEO-6M talks on its own: NMEA 0183 at 9600 baud, one packet per second.
// On the ESP32 Serial2 listens on any GPIOs — here RX=16 (the module's TX).
TinyGPSPlus gps;
// landmark to measure the distance to: Praca dos Tres Poderes, in Brasilia
const double MARCO_LAT = -15.8002, MARCO_LON = -47.8610;
void setup() {
Serial.begin(115200);
Serial2.begin(9600, SERIAL_8N1, 16, 17);
Serial.println("waiting for the first NMEA packet...");
}
void loop() {
while (Serial2.available()) gps.encode(Serial2.read());
static unsigned long antes = 0;
if (millis() - antes < 1000) return;
antes = millis();
// CLASSIC TinyGPS gotcha: isValid() latches on the last good value and
// never goes back to false. What tells you the fix DROPPED is the AGE of the
// data — with no satellites the module stops sending position and age() climbs.
if (!gps.location.isValid() || gps.location.age() > 3000) {
Serial.printf("no fix (%d satellites)\n", (int)gps.satellites.value());
return;
}
double dist = TinyGPSPlus::distanceBetween(
gps.location.lat(), gps.location.lng(), MARCO_LAT, MARCO_LON);
Serial.printf("%.4f, %.4f | %.0f km/h heading %.0f | %d sat | alt %.0f m | %.1f km to landmark\n",
gps.location.lat(), gps.location.lng(),
gps.speed.kmph(), gps.course.deg(),
(int)gps.satellites.value(), gps.altitude.meters(),
dist / 1000.0);
}
Serial2.begin(9600, SERIAL_8N1, 16, 17) opens the second serial port on the pins wired to the module; gps.encode() eats every byte. The example prints position, speed, heading, satellites, altitude and the distance to a landmark. Read its comment about isValid(): it never goes back to false — the age of the data is what tells you the fix was lost.
Run it
Press Build and run. The first build of a project takes a while; after that, only what changed is rebuilt.
Every second the serial monitor prints a line with the coordinates and the distance to the landmark. Drag Sat below 3: after three seconds the sketch reports “no fix”. Raise it again and the position returns.
How the simulation models it
- The simulation sends real NMEA: a RMC and a GGA sentence per second, with checksums, at the UART chosen in Settings, in two halves so the chip's serial buffer never overflows during a
delay(). - The position does not move. Speed and heading go into the sentences and TinyGPS++ reports them, but latitude and longitude stay where Settings put them. Change them in Settings to “teleport”.
- Time in the sentences is the real clock (UTC). Satellites below 3 empty the position fields and mark the fix invalid.
Try this
- Show the coordinates on the LCD, updated once a second.
- Log a line to the SD card on every fix: a track you could plot on a map.
See also
- The serial monitor — Reading what the firmware prints, typing to the board, and an example that takes commands from the monitor.
- SD card — A micro SD module on SPI that stores real files — they survive a restart, and you can eject the card to test your error handling.
- Character LCD with I²C backpack — The classic 16×2 text display cut down to two wires by a small I²C board — text, custom characters and a backlight.