A GPS based Raspberry Pi Stratum 1 NTP server
I decided to make my own Stratum 1 NTP server for the home. No, I don’t need the accuracy, but localising stuff like that is always interesting. So, I recently purchased an Uputronics GPS HAT from Pi Hut which is marked Raspberry Pi GPS+RTC Rev 6.4. It arrived next day along with some other bits. I also got another PoE HAT and already had a Pi 4. Raspbian installed on an SD card – this time I remembered to first set it up to work via ssh – and the Pi booted ok with the GPS board flashing it’s ‘time pulse’ LED once per second.
I followed instructions on the web, in particular from the two websites shown at the bottom of this post. Initial setting up of the Pi involves the use of raspi-config to stop the serial port login shell but leaving the port enabled, and disabling serial getty and bluetooth. At this point, doing cat /dev/ttyAMA0 should return data from the GPS receiver but all I got was garbled characters. More on that later.
The next step was to enable PPS support which involves modifications to /boot/config.txt and a module adding to /etc/modules, plus downloading pps-tools. Running sudo ppstest /dev/pps0 looked ok but again, more on that later.
Next was to install gpsd and modifying /etc/default/gpsd plus setting it up to run at boot time. After a reboot running sudo service gpsd status returned valid information.
The gpsd-clients package was installed which includes gpsmon. Running gpsmon showed that all was not well. It generated a few lines but nothing that meant any sense.
I then returned to sudo ppstest /dev/pps0 and noticed this time that all it was giving was timeouts. I may well have missed this in my haste earlier as it reports ok, but then gives timeouts. An, unfortunately not recorded web page suggested adding arm_64bit=0 to /boot/config.txt and after rebooting sudo ppstest /dev/pps0 now produced a valid line, once per second. Ok.
Retracing my steps I ran gpsmon again to take a closer look and noticed that in the few lines it managed to display was the entry ‘”bps”:9600’.
That was the lightbulb moment.
The GPS board defaults to 115200. Stopping gpsd and running minicom -b 115200 -o -D /dev/ttyAMA0 produced valid GPS data. Modifying /etc/default/gpsd to set the baud rate to 115200 (GPSD_OPTIONS=“-n -s 115200”) fixed the issue.
But, gpsmon still does not produce all the output that I had expected, in particular it does not populate the time and date fields. Running cgps does show valid information and suggests that all is well and there is something I am missing regarding gpsmon. At the end of the day it all appears to be working fine.
The next package installed was chrony. This all went to plan and running chronyc and its sources and sourcestats options showed valid data after the system had settled down for a couple of minutes after boot.
The final leg of this journey was to set up various systems to use the new NTP server. On the Pi systems this is typically done via /etc/systemd/timesyncd.conf and then restarting systemd-timesyncd; the Mac was done via System settings –> General –> Date & Time, and the various network switches and wi-fi APs each had their own way but each was obvious. Of course one thing to remember is these are all static systems that never leave the house. Setting a local IP into a mobile system would not be that great an idea.
The final thing that tripped me up was that in chronyc options such as clients would give an error. Running chronyc under sudo fixed those.
And there it is in a tall metal Pi case also from Pi Hut and rather unceremoniously chopped with some cutters to enable the SMA connector to fit. This case has plenty of vertical space for the Pi, the PoE HAT and the GPS HAT.
Sources: https://austinsnerdythings.com/2021/04/19/microsecond-accurate-ntp-with-a-raspberry-pi-and-pps-gps/ https://www.jacobdeane.com/iot/2020/building-a-gps-based-time-server/