Prerequisites
- Raspberry Pi 3B with Raspberry Pi OS installed (Lite or Desktop version).
- GPS module (e.g., u-blox module or similar).
- 5 GPIO Jumper Cables
- Access to the Pi via SSH or a connected monitor, keyboard, and mouse.
Step 1: Hardware Setup
Connect the GPS module to the Raspberry Pi:
GPS to Raspberry Pi pin connections:
VCC (or VIN) → Pin 2 or 4 (5V) on the Raspberry Pi.
GND → Pin 6 (Ground) on the Raspberry Pi.
TX → Pin 10 (GPIO 15, UART RX) on the Raspberry Pi.
RX → Pin 8 (GPIO 14, UART TX) on the Raspberry Pi.
PPS → Pin 12 (GPIO 18) on the Raspberry Pi.
Step 2: Update the Raspberry Pi OS
Before proceeding, make sure your Raspberry Pi is fully up to date.
sudo apt update
sudo apt upgrade -y
Step 3: Disable Serial Console and Enable UART
The serial interface may be used by the system for console access, so we need to disable it.
Open the Raspberry Pi configuration tool:
sudo raspi-config
Navigate to Interface Options → Serial.
When asked if you want a login shell over the serial interface, select No.
When asked if you want to enable the serial hardware, select Yes.
Exit and reboot the Raspberry Pi:
sudo reboot
Step 4: Configure GPIO pin for PSS
Open /boot/firmware/config.txt
sudo nano /boot/firmware/config.txt
Add the following to the bottom under the [all]
section.
[all]
enable_uart=1
dtoverlay=pps-gpio,gpiopin=18
init_uart_baud=9600
Now add the PPS module
sudo bash -c "echo 'pps-gpio' >> /etc/modules"
Now reboot the device
sudo reboot
Step 5: Install and Configure GPSD
GPSD is a service that will handle communication between the GPS module and the system.
Install GPSD and its tools:
sudo apt install gpsd gpsd-clients python3-gps
Stop the GPSD service for manual configuration:
sudo systemctl stop gpsd
sudo systemctl disable gpsd
Edit the GPSD configuration file:
sudo nano /etc/default/gpsd
Set the GPSD config as below (you may need to change /dev/ttyS0
depending on your Pi)
START_DAEMON="true"
USBAUTO="true"
DEVICES="/dev/ttyS0 /dev/pps0"
GPSD_OPTIONS="-n"
Start GPSD manually:
sudo systemctl start gpsd
Verify GPS data with the following command:
cgps
You can also use gpsmon
or gpsmon -n
If everything is working, you should see satellite data and timing information from the GPS module.
Step 6: Enable PPS (Pulse Per Second) Support
PPS provides highly accurate timing data that will be used alongside the NMEA data from the GPS.
Install the necessary PPS tools:
sudo apt install pps-tools
Test the PPS signal: Check if the Raspberry Pi is receiving the PPS signal:
sudo ppstest /dev/pps0
You should see output indicating a pulse every second. If you don’t, check your wiring and ensure the correct GPIO pin is being used.
Step 7: Install and Configure Chrony
Chrony is a lightweight and efficient NTP implementation, perfect for use on systems like the Raspberry Pi.
Install Chrony:
sudo apt install chrony
Configure Chrony to use both the GPS and PPS signals as time sources: Edit the Chrony configuration file:
sudo nano /etc/chrony/chrony.conf
Add the following lines to configure the GPS and PPS sources:
# Use the GPS as a time source
refclock SHM 0 offset 0.5 delay 0.2 refid GPS precision 1e-1 noselect
# Use the PPS signal as a time source
refclock PPS /dev/pps0 refid PPS lock GPS precision 1e-9
refclock SHM 0
refers to GPSD’s shared memory segment where GPS data is available.refclock PPS
uses the Pulse Per Second signal from/dev/pps0
for precise timing.- The
lock GPS
option ensures that PPS is used in combination with the GPS time data.
Restart the Chrony service:
sudo systemctl restart chrony
Step 8: Verify the Chrony Setup
Check that Chrony is properly synchronizing with the GPS and PPS signals.
View the status of Chrony:
chronyc sources -v
You should see output indicating that both the GPS (SHM0) and PPS (PPS0) sources are being used for time synchronization.
Example output:
210 Number of sources = 2
MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
#* PPS0 0 4 377 1 -123ns[-131ns] +/- 127ns
#? SHM0 0 4 377 2 -0.01s[-0.01s] +/- 16.0ms
The PPS0 line should have a * next to it, indicating that Chrony is using the PPS signal for accurate time synchronization.
Monitor Chrony synchronization:
chronyc tracking
This will show information about the current system clock and the sources being used for synchronization.
Step 9: Allow clients to Use the Raspberry Pi as an NTP Server (Optional)
For clients to access the Raspberry Pi as an NTP server you need to add the allow line in your chrony config
sudo nano /etc/chrony/chrony.conf
To allow all clients from ANY source add the below line
allow 0.0.0.0/0
To allow clients from a specific subnet use the CIDR notation
allow 10.0.0.0/24
Troubleshooting
No GPS data in cgps:
- Check the wiring and ensure the serial interface
/dev/ttyS0
is correctly configured. - Ensure the GPS module has a clear view of the sky.
PPS not working:
- Verify that GPIO 18 is correctly configured for PPS in
/boot/firmware/config.txt
(Older Raspberry Pi OS version may use/boot/config.txt
) - Use ppstest to confirm PPS signals.
Chrony not using GPS or PPS:
- Check that Chrony is configured correctly and restart the service.
- Use
chronyc sources
to see which time sources Chrony is using.