u/pilg0re

▲ 120 r/raspberryDIY+1 crossposts

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/

reddit.com
u/pilg0re — 1 day ago

I built a GPS-disciplined NTP server on a Pi 4

Spent the last couple weekends building out a ntp server for my LAN and a silly webpage using a Pi 4 and it's been a fun rabbit hole.

Hardware:

  • Pi 4
  • GT-U7 GPS module. VCC/GND to pins 4/6, RX/TX swapped onto the UART pins 8 and 10, and PPS on pin 12
  • GPS antenna sitting in a window

The PPS pin is the part that matters. NMEA serial data alone is good for maybe 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 which weren't necessary but fun tweaks to try to squeeze every but of accuracy out of this hardware I could:

  • 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, which is dumb)
  • Used isolcpus=3 nohz_full=3 rcu_nocbs=3 to dedicate one core to time-critical work and keep scheduler noise off it (really really not necessary but it will allow me to add other services to this pi later without hurting the speed)
  • 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
  • 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)

Total cost was about $90? I had the pi laying around and the GPS was about $20 I think.

The main lesson: 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.

Disclaimer: AI was used to write the "fun facts" section on my webpage

ntp.pilg0re.net
u/pilg0re — 3 days ago