A Raspberry Pi makes an excellent GNSS-disciplined network time server and is much easier to set up than you might imagine. All you need is a Pi and GNSS receiver that outputs PPS.
There are a few things to keep in mind when using a Pi as a network time server. Most of these relate to maintaining the best performance and accuracy as possible.
dietpi-config
or raspi-config
utilities. Here's an example config.txt that I have found works well. This has been tested to work on the Pi2, 3, and 4.
# cut down GPU-allocated RAM gpu_mem_256=16 gpu_mem_512=16 gpu_mem_1024=16 # disable splash screen disable_splash=1 # disable audio dtparam=audio=off # enable I2C dtparam=i2c_arm=on dtparam=i2c1=on # configure DS3231 as hardware RTC dtoverlay=i2c-rtc,ds3231 # disable SPI dtparam=spi=off # enable UART (/dev/ttyAMA0) enable_uart=1 # disable speedstep and lock CPU freq force_turbo=1 arm_freq=800 # disable video core dtoverlay=dietpi-disable_vcsm # disable wifi and bt dtoverlay=disable-wifi dtoverlay=disable-bt # configure GPIO4 as the input for /dev/pps0 dtoverlay=pps-gpio,gpiopin=4 # set the activity LED to blink in a heartbeat pattern. # This provides a quick visual indicator of the system status. dtparam=act_led_trigger=heartbeat
These links include sample configurations.
There are a number of different tests you can perform to verify system operation if you're running into trouble. You will need to have minicom
and pps-tools
installed on the server to perform some of these tests.
Put a jumper across pins 8 and 10, creating a UART loopback. Run sudo minicom -b 9600 -D /dev/ttyAMA0
and type into the console. Everything you type should appear in the terminal. If it does not, make sure your configuration options in config.txt are correct.
First, make sure GPSD is stopped. Run sudo minicom -b 9600 -D /dev/ttyAMA0
(assuming your GNSS is running at 9600 baud, adjust as appropriate). If you do not see a constant flow of data from your GNSS receiver, make sure that you have properly connected the receiver and set the baud rate. Remember, Tx on the GNSS goes to Rx on the Pi, and vice versa!
Use cgps
to verify that your GNSS receiver has a lock and that gpsd is receiving and parsing its output correctly. . Here's example output indicating that gpsd is working and that the GNSS receiver has a good lock:
Verify that your system is picking up the PPS signal from your GNSS receiver with sudo ppstest /dev/pps0
. Output should look like this:
trying PPS source "/dev/pps0" found PPS source "/dev/pps0" ok, found 1 source(s), now start fetching data... source 0 - assert 1614093326.000000138, sequence: 1231 - clear 0.000000000, sequence: 0 source 0 - assert 1614093326.999999940, sequence: 1232 - clear 0.000000000, sequence: 0 source 0 - assert 1614093327.999999325, sequence: 1233 - clear 0.000000000, sequence: 0 source 0 - assert 1614093328.999999075, sequence: 1234 - clear 0.000000000, sequence: 0 source 0 - assert 1614093329.999999085, sequence: 1235 - clear 0.000000000, sequence: 0
If you do not see a result like this, verify that you have properly connected the PPS output from your GNSS receiver to the Pi at the pin you have specified in config.txt
and that your GNSS is properly sending this signal. On some GNSS receivers PPS can be disabled.
Verify that chrony is working properly with chronyc sources
MS Name/IP address Stratum Poll Reach LastRx Last sample =============================================================================== #* GPS 0 4 377 17 +317ns[ +455ns] +/- 177ns ^- time-a-g.nist.gov 1 7 377 13 -3510us[-3510us] +/- 23ms ^- time-a-wwv.nist.gov 1 7 377 12 +164us[ +165us] +/- 40ms ^- time-a-b.nist.gov 1 7 377 74 -746us[ -746us] +/- 41ms
If it's not, check the contents of /etc/chrony.conf
. Specifically, make sure that the refclock SOCK
entry is correct, and make sure that GPSD is being started after chronyd.
Verify that your clients can get a valid response from the server. On windows I am fond of NTP Check