Building a StratumOne clock with a simple GNSS module
Inspired by Kenneth Finnegan's awesome NTP server on a Raspberry Pi blog post, I wanted to build a StratumOne NTP server for my local network as well.
I just didn't know how, though.
I did know that I needed to provide PPS, pulse-per-second, via the GNSS module. Apparently plugging the PPS pin to the DCD (Data Carrier Detect) pin of the serial interface.
Sooo, what do I need?
Obviously a GNSS antenna...
And of course, a Serial-to-USB module with a pinout that has a DCD pin.
After the parts have arrived, I have wired the GNSS module like below:
After verifying that the serial port working and the GNSS module printing data, I have proceeded to setup gpsd and the necessary things for PPS.
To note: I am using Ubuntu 21.04 (Hirsute Hippo). I'm also going to assume you have your Serial-to-USB module on
Setting up UART module for low latency data transmission and PPS support
Create a file under
/etc/udev/rules.d, I'm going to use
/etc/udev/rules.d/pps-sources.rules for setting up the perms for PPS and low latency mode on ttyUSB0:
KERNEL=="pps0", OWNER="root", GROUP="dialout", MODE="0660" KERNEL=="ttyUSB0", RUN+="/bin/setserial -v /dev/%k low_latency irq 4"
Create a systemd template service under
/etc/systemd/system, I'm going to use
/etc/systemd/system/ldattach@.service for enabling the line discipline 18 for PPS support on ttyUSB0:
[Unit] Description=Line Discipline for GNSS Timekeeping for %i Before=ntpd.service chronyd.service chrony.service gpsd.socket [Service] ExecStart=/sbin/ldattach 18 /dev/%i Type=forking [Install] WantedBy=multi-user.target
We now need to run
sudo systemctl enable --now ldattach@ttyUSB0.
Aaand let's go to gpsd.
Setting up gpsd
sudo apt-get install gpsd gpsd-tools gpsd-clients for the full gpsd experience.
# Devices gpsd should collect to at boot time. # They need to be read/writeable, either by user gpsd or the group dialout. DEVICES="/dev/ttyUSB0 /dev/pps0" # Other options you want to pass to gpsd GPSD_OPTIONS="-n" # Automatically hot add/remove USB GPS devices via gpsdctl USBAUTO="true"
Restart gpsd with
sudo systemctl restart gpsd and wait for a short while. After that, launch
ntpshmmon. You should see data coming from
NTP1 (these are the GPS and PPS time data respectively).
Well, we have time tracking! Let's go to chrony.
Setting up chrony
sudo apt-get install chrony
My baseline config for
# Fallback source server setup, change these based on your location server time.ume.tubitak.gov.tr server ntp.bsdbg.net server 0.tr.pool.ntp.org initstepslew 30 time.ume.tubitak.gov.tr ntp.bsdbg.net 0.tr.pool.ntp.org confdir /etc/chrony/conf.d keyfile /etc/chrony/chrony.keys driftfile /var/lib/chrony/chrony.drift ntsdumpdir /var/lib/chrony logdir /var/log/chrony maxupdateskew 100.0 rtcsync makestep 1 3 leapsectz right/UTC allow all noclientlog
And for using the PPS data as time source, I create a file on
# set larger delay to allow the NMEA source to overlap with # the other sources and avoid the falseticker status refclock SHM 0 refid GPS precision 1e-1 offset 0.130 delay 0.99 refclock SHM 1 refid PPS precision 1e-7 # apparmor configs for both chrony and gpsd are borked for the SOCK protocol, ignored #refclock SOCK /run/chrony.ttyUSB0.sock refid GPS precision 1e-1 offset 0.130 delay 0.99 #refclock SOCK /run/chrony.pps0.sock refid PPS precision 1e-7
After restarting chrony and waiting for a while, this can be seen on
chronyc sources -v:
The asterisk shows the currently used source.
There we go!
Copyright 2018-2021, linuxgemini (İlteriş Yağıztegin Eroğlu). Any and all opinions listed here are my own and not representative of my employers; future, past and present.