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?
A GNSS UART module with PPS output...
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 /dev/ttyUSB0
.
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.service
[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"
# Other options you want to pass to gpsd
GPSD_OPTIONS="-n -G"
# 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 NTP0
and 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 /etc/chrony/chrony.conf
:
# 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 /etc/chrony/conf.d/pps.conf
:
# 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!
(Update: 2022-08-09): Some portions of the config was taken from https://www.maximaphysics.com/Centos_7_GPS_Setup.html
. I've lost the URL at the time I wrote it so I've only just recently found it.
Copyright 2018-2024, 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.