Connecting a GPS Module to Raspberry Pi
Interfacing a GPS module with a Raspberry Pi enables a wide range of mobile location tracking applications, from vehicle fleet monitoring to open-source asset management. By establishing a physical hardware serial connection and configuring Linux to read incoming NMEA 0183 standard data strings, you can accurately capture raw coordinates. This technical guide outlines how to configure the Pi’s GPIO pins, disable conflicting operating system services, and use Python to log coordinates for field deployments.
Required Hardware and Pin Connections
Most standard GPS modules, such as the NEO-6M, NEO-8M, or Adafruit Ultimate GPS, communicate via a standard Universal Asynchronous Receiver-Transmitter (UART) serial interface.
To connect the module to the Raspberry Pi GPIO header, you need four female-to-female jumper wires wired exactly as follows:
| GPS Module Pin | Raspberry Pi Pin | Description |
|---|---|---|
| VCC | Pin 1 or Pin 4 | 3.3V or 5V Power (Check module requirements) |
| GND | Pin 6 | Ground |
| TX (Transmit) | Pin 10 (GPIO 15 / RXD0) | Receives data from the GPS module |
| RX (Receive) | Pin 8 (GPIO 14 / TXD0) | Sends data to the GPS module (optional) |
Note: Always cross the communication lines: the TX pin of the GPS module must map directly to the RX pin on the Raspberry Pi.
System Configuration and Enabling UART
By default, the Raspberry Pi uses its hardware serial port for the Linux serial console. To use it for a hardware device instead, you must free up this port.
- Open a terminal session on the Raspberry Pi and run the system configuration utility:
sudo raspi-config- Navigate to Interface Options -> Serial Port.
- When prompted if you want a login shell accessible over the serial interface, select No.
- When prompted if you want the serial port hardware enabled, select Yes.
- Save your changes and reboot the system:
sudo rebootAlternatively, you can manually adjust this by opening
/boot/firmware/cmdline.txt (or
/boot/cmdline.txt on older operating systems) and removing
the phrase console=serial0,115200 to prevent system
messages from flooding the GPS data stream.
Reading Raw NMEA Data
Once the reboot is complete, the GPS module streams text data into
the system port, which is assigned as /dev/serial0 (a
symbolic link to either /dev/ttyAMA0 or
/dev/ttyS0 depending on your exact model).
Test if data is flowing correctly by outputting raw serial text to the console:
cat /dev/serial0If the physical connections are correct and the module has achieved a
line-of-sight satellite lock (indicated by a flashing status LED on the
GPS board), you will see constant output lines starting with standard
headers like $GPGGA or $GPRMC.
Processing Coordinates with Python
To make the data useful for a mobile tracking application, a Python script can parse the text strings to pull out clean latitude and longitude coordinates. First, ensure the Python serial helper library is installed:
sudo apt-get install python3-serialThe script opens the port at the default GPS baud rate (usually 9600) and extracts the coordinate values from the incoming data streams:
import serial
import time
# Initialize serial communication
serial_port = "/dev/serial0"
baud_rate = 9600
try:
gps = serial.Serial(serial_port, baud_rate, timeout=1)
print("Reading GPS data... Press Ctrl+C to stop.")
while True:
data = gps.readline().decode('utf-8', errors='ignore')
# Look for the Recommended Minimum Navigation Information string
if "$GPRMC" in data:
parts = data.split(',')
# Check if the GPS fix is valid ('A' = Active, 'V' = Void)
if parts[2] == 'A':
raw_lat = parts[3]
lat_dir = parts[4]
raw_lon = parts[5]
lon_dir = parts[6]
# Convert raw NMEA formatting into standard decimal degrees
lat_deg = float(raw_lat[:2]) + (float(raw_lat[2:]) / 60.0)
if lat_dir == 'S': lat_deg = -lat_deg
lon_deg = float(raw_lon[:3]) + (float(raw_lon[3:]) / 60.0)
if lon_dir == 'W': lon_deg = -lon_deg
print(f"Latitude: {lat_deg:.6f}, Longitude: {lon_deg:.6f}")
time.sleep(0.5)
except KeyboardInterrupt:
print("\nTracking stopped by user.")
except Exception as e:
print(f"Error: {e}")Implementing Mobile and Remote Tracking
For true mobile capabilities outside of a home local network, the device needs access to independent power and a method to upload or store telemetry.
- Power Delivery: A standard 5V portable power bank or a dedicated lithium-polymer (LiPo) battery pack shield connected to the Pi will keep the setup functional while moving.
- Local Storage: If network access isn’t available
during the journey, append the coordinates locally to a
.csvor.gpxfile stored on the micro SD card for retrieval later. - Cellular Uploads: For live tracking over long distances, mount a compatible 4G/LTE or GSM cellular HAT on the Raspberry Pi. Using a Python script, you can package the coordinates into an HTTP request or MQTT message to update a cloud tracking database or display live map pins on a remote dashboard in real time.