A Raspberry Pi stratum 1 time server.
Takes in GPS (or potentially other stratum 0 time sources), spits out NTP, PTP, etc.
To run a decent time server (with high accuracy), you need a few things:
- A computer running Linux (all the nice tooling for network time is availabe here)
- A high quality time source (GPS is most commonly used these days)
- A network adapter capable of hardware timestamping (Intel and ASIX make some good NICs for time-related applications)
There are many options for each of the above items—for example, many use Adafruit's Ultimate GPS HAT or its USB equivalent for GPS acquisition, and for PTP, you can use a Compute Module 4 or 5's built-in NIC (with PPS in or out), or add on a compatible NIC on the Pi 5 with something like the uPCIty Lite.
My own hardware configuration—which is the basis for the code in this repository, consists of:
- Computer: Raspberry Pi 5 model B
- Time source: u-blox ZED-F9T-00B-01 (installed on TimeHAT V2)
- NIC: Intel i226-LM (installed on TimeHAT V2)
A precise GPS signal for nanosecond-accurate time requires a decent antenna with as clear a view of the sky as possible. Some GPS receivers are better than others, but even USB receivers will do better than NTP!
I use a small active GPS antenna for testing, but for permanent installation it is best to mount a higher-quality GPS antenna outside, clear of obstructions.
Make sure you have Ansible installed. Copy the example.hosts.ini
file to hosts.ini
and customize it so Ansible can connect to your Pi.
Because I can't quite get cmdline.txt
changes automated the way I like, manually edit /boot/firmware/cmdline.txt
and remove the portion console=serial0,115200
, so GPS can use the serial port.
Now run the Ansible playbook:
ansible-playbook main.yml
This playbook will configure:
- GPSd: interface with the u-blox GPS and provide GPS data to other applications
- Chrony: NTP server, which also sync GPS time (with Internet NTP server backup) to the system clock
- Linux PTP: synchronize the system clock to the NIC PHC (Physical Hardware Clock), and set up the Pi as a PTP grandmaster clock
Intel i226 Notes: Currently I can't get the i226 to work with DHCP at all, so I have to manually set an IP address using
nmtui
. It also doesn't work at 2.5 Gbps currently, and it can't be overridden via Linux, so I make sure to plug it into a 1 Gbps port on my network.
Some handy commands:
# GPS-related debugging
sudo systemctl status gpsd # check gpsd status
gpsmon -n # monitors gpsd output
cgps -s # also monitors gps output
# PTP timestamping debugging
ethtool -T eth0 # or eth1, lists hardware clock info
# Chrony debugging
chronyc sources -v # shows sources with documentation of fields
chronyc -n tracking # shows detailed timing data
# Checking on NTP service from another computer
ntpdate -q [ip of grandmaster]
Much of the work that went into this project was documented in this thread on the TimeHat v2.
GPLv3 or Later
Jeff Geerling, with assistance from Ahmad Byagowi and Oleg Obleukhov from Meta.