I made my own PI-based GPS time server that's accurate to the nanosecond level
Spent the last few weekends building out a hardware time reference using a Pi 4 (could use any Pi really as it uses almost no cpu power and memory) and it's been a fun rabbit hole.
Hardware:
- Pi 4 Model B 4GB
- GT-U7 GPS module (~$10 on Amazon) wired to GPIO. VCC/GND to pins 4/6, RX/TX swapped onto the UART pins 8 and 10, and PPS on pin 12
- Antenna sitting in a window
The PPS pin is where the accuracy comes from. NMEA serial data alone is good for ~50ms accuracy because of the variable lag between satellite reading and serial transmission. The PPS pulse is hardware-aligned to the actual GPS second within tens of nanoseconds, so chrony uses NMEA to figure out what time it is and PPS to figure out exactly when each second starts. Together you get sub-microsecond accuracy.
A few config things that helped:
- Disabled bluetooth in /boot/firmware/config.txt to free up the primary UART (the Pi 4 has the bluetooth chip wired to the good UART by default)
- Used isolcpus=3 nohz_full=3 rcu_nocbs=3 to dedicate one core to time-critical work and keep scheduler noise off it. (This is very much overkill but it will keep the core free if I want to run other services)
- gpsd reads NMEA and pushes to chrony via shared memory, chrony grabs the PPS directly from /dev/pps0
Current state per chronyc tracking:
- Stratum 1 (This is how many steps away you are from the gps source, NTP servers are usually 3 or 4)
- Last offset typically in the 50-500 nanosecond range
- RMS offset around 450ns
- System time within 0-45ns of NTP time
- Frequency stable around 9.7ppm fast (the Pi's crystal is consistently off but predictable)
I admittedly am more of a Pi programmer and not much of a web developer so I had help from Claude for the web portion. It looks way better and took way less time than what I couldn't came up on my own.
Disclaimer: This is a $10 GPS unit with an antenna sitting inside in a non-ideal window in my home. If you visit my site and it says it's not syncing to GPS and it's fallen back to NTP it happens sometimes but it recovers. This is for fun on my LAN and for nothing mission critical, just wanted to share.
The main lesson though: antenna placement matters way more than the GPS module quality. Spent more time moving the antenna around than doing anything else. Got from 1-2 satellites in a fix to consistently 8-11 just by finding a window with a clearer southern view.
Here is my repo for the project
https://github.com/BenLeikin/PiTime/