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.

Things to Keep in Mind

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.

  • Don't use the Pi for anything other than a network time server. A low and predictable system load will keep everything running smoothly.
  • Make sure the Pi is connected to a stable power source. Low-voltage brownouts impact the onboard clock significantly.
  • Use Ethernet when possible. Even on Pis that use USB-connected NICs (everything before the Pi4) the performance is better than WiFi, at least in my own testing.
  • Disable Bluetooth. On some Pis this is necessary because the Bluetooth interface uses the hardware UART. On all Pis Bluetooth will use additional power, clock cycles, and potentially introduce interference.
  • Add a hardware real time clock. The Pi uses a software RTC which is not very stable (±20ppm, or worse). A hardware RTC will improve short term stability (particularly useful if your GNSS loses its lock for any reason) and, if it's battery backed, will make sure the Pi comes up instantly with the correct date and time should it lose power for any reason. I highly recommend the DS3231. See DS3231 on Raspberry Pi.
  • Lower the CPU speed and prevent it from speedstepping. I have found that 700 or 800MHz is perfectly suitable. This has a few benefits: it lowers the power usage (thus lowering the chance of brownouts), lowers the idle temperature, and overall makes the clock more stable. This can be done at the firmware level (by editing config.txt in the boot partition) or in the OS level by changing the OS-defined CPU governor to userspace. This can easily be done through the dietpi-config or raspi-config utilities.
  • Use an operating system with low overhead. I'm a big fan of DietPi. Raspberry Pi OS Lite, Alpine, or Arch are also suitable, but you may experience configuration challenges. All of my writing assumes DietPi and applies to Pi OS as well. Alpine and Arch are very different.
  • Set a static DHCP address assignment, same as any other server should have.

Example config.txt

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

# disable splash screen

# disable audio

# enable I2C

# configure DS3231 as hardware RTC

# disable SPI

# enable UART (/dev/ttyAMA0)

# disable speedstep and lock CPU freq

# disable video core

# disable wifi and bt

# configure GPIO4 as the input for /dev/pps0

# set the activity LED to blink in a heartbeat pattern.
# This provides a quick visual indicator of the system status. 

Software Dependencies

These links include sample configurations.

Verify Operation and Troubleshooting

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.

Basic UART operation

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.

UART from the GNSS

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!

GPSD and GNSS operation

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:

Check PPS

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.

Chrony operation

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.

Client Test

Verify that your clients can get a valid response from the server. On windows I am fond of NTP Check

timepi.txt · Last modified: 2021/02/23 15:51 by john
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0