GPS module
The NEO-6M GPS module (GY-NEO6MV2) costs $15 and reports position, time, speed and course as NMEA sentences once a second on a plain serial line. It is the simplest "sensor" interface on the Pi: no I²C registers, no timing-critical GPIO — just text. Two wires carry the data (TX → the Pi's RXD, RX → the Pi's TXD), plus power and ground. After power-up it needs about half a minute to find satellites; the module's blue LED blinks once a second only once it has a fix. The GPS over serial page covers the parsing side in depth.
Pins
| Pin | What it is | Type |
|---|---|---|
| VCC | Supply 3.3–5 V | power |
| RX | UART in (from the Pi's TXD) | io |
| TX | UART out (to the Pi's RXD) | io |
| GND | Ground | ground |
| Setting | Type | Range | Default |
|---|---|---|---|
baud | enum | 4800, 9600, 19200, 38400, 57600, 115200 | 9600 |
In circuit.py:
GPS()— GPS module — $15- Pins: 4
The baud setting matches the port's speed — leave it at 9600 unless you know the module was reconfigured. The module's TX is an output, so it goes to the Pi's receive pin; RX goes to the Pi's transmit pin.
Wiring it in circuit.py
from wiring import *
pi = Pi()
gps = GPS()
pi.V3_3 >> gps.vcc # 2.7–5.5 V: 3.3 V is plenty
gps.gnd >> pi.GND
gps.tx >> pi.RXD # module talks, Pi listens
gps.rx >> pi.TXD # Pi talks, module listensOn a real Pi you must first disable the serial console (raspi-config → Interface → Serial) so the kernel does not fight your program for /dev/serial0; the simulator opens the port directly. RXD/TXD are GPIO15 and GPIO14, the header's dedicated UART pins.
Driving it in main.py
import serial
import pynmea2
port = serial.Serial("/dev/serial0", baudrate=9600, timeout=2)
while True:
line = port.readline()
if not line.startswith(b"$GPRMC"):
continue
fix = pynmea2.parse(line.decode("ascii", "ignore"))
if fix.status == "A":
print(f"{fix.latitude:.5f}, {fix.longitude:.5f}")
else:
print("waiting for a fix")readline() returns bytes, so decode before parsing. The RMC sentence carries the status (A fixed, V not) and the decimal-degree latitude/longitude; GGA adds satellites and altitude, VTG speed and course. With the default 27-second cold start, the example spends its first seconds printing "waiting for a fix" — which is exactly what real code must tolerate.
Electrical notes
- Supply is 2.7–5.5 V; current is about 45 mA, so use the 5 V rail if the 3V3 budget is tight elsewhere.
- Default baud is 9600; update rate is 1 Hz; horizontal accuracy is about 2.5 m.
- Cold and warm start take about 27 s, a hot start about 1 s. The first fixes after power-on are marked
V(invalid) until enough satellites are tracked — four is the minimum for a 3D fix. - The UART is 3.3 V logic, which is what the Pi's header uses; no level shifting is needed at 3.3 V supply.
- Serial console,
dtoverlay=disable-btor raspi-config: on a real Pi the header UART is shared with Bluetooth on some models, so/dev/serial0is the alias that keeps working.
Simulator vs real hardware
- The position is the World's location, plus metre-scale wander that drifts like a real fix (a
jitterMknob, 2.5 m by default) and a circular path when the feed is set to walking or driving. The timestamp inside the sentences is the simulated world clock. - Checksums are computed with the real NMEA XOR, so parsing and validation code behave identically. There is no UBX binary protocol, no USB serial adapters and no PPS output pin —
PPSis internal only. - The
coldStartSknob (27 s by default) governs time-to-first-fix; with no fix the position fields are empty and the status isV, matching a real cold start. - Two modules can share the UART, and bytes sent at the wrong baud rate arrive garbled with framing errors, exactly as on hardware.
Going deeper
- The full parsing guide: GPS over serial.
- Primer: I²C, SPI, UART and 1-Wire — how a UART differs from the other buses.
- Other digital sensors: PIR, DHT22, HC-SR04.
Further reading
- u-blox NEO-6 data sheet (GPS.G6-HW-09005) — pinout, start-up times and electrical data.
- pySerial documentation —
Serial, timeouts and line reading. - pynmea2 on GitHub — the sentence parser used above.