This is an important question these days. We are running into more situations where timing is important, especially when audio and video codecs are concerned. If there is too much time differential, the codec will unlock. More often, digital transmission methods require precise timing to prevent jitter and dropouts. Some equipment has 10 MHz or 1PPS inputs. Some equipment does not and relies on NTP to keep things in sync.
While searching online for GPS time sever, I came across this post where Austin built a Stratum 1 level time sever with a Raspberry pi and an inexpensive GPS receiver. I thought to myself; damn that sounds interesting. While a Raspberry pi is a hobbyist toy, the same setup can be done with a more serious computer to create a solid NTP server for a facility or LAN.
A little about NTP time servers; Stratum 0 server is directly connected to an atomic clock. Since GPS satellites have atomic clocks, that makes them a Stratum 0 server. Stratum 1 servers are connected to Stratum 0 servers. Stratum 2 servers are connected to Stratum 1 servers and so on. The time accuracy for a Stratum 1 server is 10 microseconds.
First, I wiped my SD card and loaded a fresh install of Raspberry pi OS. Then followed along with the instructions. For this install, I opted for the cheaper GPS receiver, the GT-U7 (not an affiliate link) from Amazon for $10.99. It comes with a cheap little antenna, which actually worked sitting inside on my desktop while I was configuring the software.
This little module is designed for a drone but works well in this application. The 1PPS output looks clean on the scope. Here is the pinout between the GT-U7 and the Raspberry pi:
GT-U7 pin | pi pin | Use | Color |
vcc | 1 | +3.3 vdc | Green |
gnd | 6 | ground | Brown |
txd | 8 | rxd | Orange |
rxd | 10 | txd | Red |
pps | 12 | GPIO 18 | Yellow |
I found this really nice aluminum case in a pile of disused junk at a transmitter site. It used to be for a digital TELCO STL circuit. I figured it would be nice to put the Raspberry pi and GPS receiver in a suitable home.
Raspberry pi 3 is mounted on a piece of scrap sheet steel designed to slide into the aluminum case.
We have several of these nice Panasonic GPS antennas left over from various installs. I pressed one into service on the roof of my house.
Panasonic CCAH32ST01 GPS antenna
I think a high-quality antenna is pretty important to get consistent good performance from this setup. There are three slight problems, however. Unfortunately, this antenna has been discontinued by the manufacturer. Also unfortunate, the GT-7U boards have one of those little IPX RF connectors. Fortunately, I found a short jumper with an F SMA connector. Finally, it requires +5 VDC and the GT-7U runs on 3.3 VDC. The pi does have a 5-volt rail, so I used this 2-way power divider to feed 5 volts to the antenna from one port and the received RF from the antenna goes to the GT-U7 from the other port.
If you are interested, here are the commands to get this thing running:
sudo apt get update sudo apt get upgrade -y sudo apt install pps-tools gpsd gpsd-clients chrony
The next step is to make sure the serial port is turned on and enable the ssh login shell since this is going to live in the basement and I don’t want to run down there to fool around with it.
sudo raspi-config
Then go to interface options, serial interface, and enable. The login over the serial interface can be left off. If ssh access is needed, enable ssh, then exit.
Once those packages have been downloaded and installed, some config file editing is needed. You may use whichever method you like, I tend to use nano. First, the /etc/config.txt and add the following to the file:
‘dtoverlay=pps-gpio,gpiopin=18’ 'enable_uart=1' 'init_uart_baud=9600'
The uart needs to be enabled if you want to receive NMEA data (NMEA stands for National Marine Electronics Association) It is helpful to see if or how the GPS is working.
Next, the /etc/modules and add:
'pps-gpio'
Reboot, then see if the pps module is working:
lsmod | grep pps
The output should look like this:
Next, there are a few more configuration files that need to be edited.
/ect/default/gpsd – there is a default file that comes with the package, it needs to be modified to start the daemon automatically and look for the pps signal on ttyS0.
START_DAEMON="true" USBAUTO="true" DEVICES="/dev/ttyS0 /dev/pps0" GPSD_OPTIONS="-n"
Reboot
Now check and see if the GPS module is working by typing cgps or gpsmon. The output should look something like this:
It did not take the module too long to find and lock onto GPS. If you don’t see something like this in five minutes or so, go back and check your wiring, and make sure that the data connections are made right. The GT-U7 has a little red LED that is lit when the PPS pulse is not being sent. If this light is not on at all, check your power connection. If it is on steady, check your antenna. If it is flashing, but you are not seeing any output in cgps or gpsmon, check your data connections.
Next and last configuration file is the /etc/chrony/chrony.conf file. At the top of the file, I added the following lines:
#custom lines for PPS server time-a-g.nist.gov iburst server time-d-g.nist.gov server 3.us.pool.ntp.org server time.windows.com server time.apple.com # add refclock pps refclock SMH 0 delay .1 refid NEMA refclock PPS /dev/pps0 refid PPS #my home network allow 192.168.1.0/24
Leave the rest of the file alone. Basically, the time servers are added to compare the GPS time and act as a backup. The hosts on my home network are allowed to query this host and use it as an NTP server.
Restart Chrony:
sudo systemctl restart chrony
Wait a couple of minutes and check the chrony console to see what is happening: chronyc sources. Should look something like this:
This was after the server had been running for a day. Chrony is great because it measures the hardware performance and creates a delay file. This is used to anticipate any hardware-added delays that the system might have. The last sample column is of interest, the number indicates the offset between the local clock and the source at the last measurement. The far column is the margin of error or greatest variation +/- of the expected values. A value of 0.0000000042 seconds or 0.042 microseconds is pretty good for an $11.00 piece of hardware. Now every host in my house is syncd to satellite within 0.042 microseconds, in lockstep through the time-space continuum.
If I were to do this professionally, I would use better hardware. I think the pi 4 has better serial and ethernet interfaces, more RAM, and a quad-core processor. Last I looked they were $75.00 at Newark.
The GPS module was the cheapest I could find on Amazon. I am slightly concerned about the longevity of this device. Perhaps it will run for a long time, or perhaps not. A quick search brought up several “hats” (plug directly into the 20-pin header). These range in price from about $30.00 to $60.00. What is required of any GPS module is 1PPS output. The configuration would be about the same although some use GPIO 4 instead of 18.
This is Austin from the referenced post! Nice to see another solid writeup. I see you specify a delay of 0.1 in your chrony.conf. You can enable statistics and let it run for a while to fine tune this value to the average delay of the NMEA sentences over serial. Some detail here – https://austinsnerdythings.com/2021/09/29/millisecond-accurate-chrony-ntp-with-a-usb-gps-for-12-usd/.
Start by setting your NMEA source to noselect. Then go to section #5 for the millisecond post for how to determine the offset.
Hey Austin, thanks for the reply. I will fool around with the NEMA delay settings, I just kind of guessed at it when I first set this up. Your post has a much more scientific method.
Thanks for this post. I am always impressed by the different number of roles that the Raspberry PI (or any other Linux based system for that matter) can be used for within the radio industry when needed for very little cost. I admit that I have had concerns about using PI’s in mission critical areas, but it certainly is a functional option and I can see the value, even if just to have a few on the shelf, configured and ready to go for “emergency” type situations where you need a quick and cheap solution until a better solution is obtained. So far this list of applications has included:
-GPS Clock
-Automation / playout system (I’ve run Rivendell on a PI)
-IP based STL send or receive codec
-Remote broadcast codec
-OnAir light / Clock display
-CD Player
-Remote control / monitor (via its GPIO pins and / or USB)
-Audio Logger
-Remote access unit
-RDS Generator
I also recently came across a commercial product that takes Livewire and creates an MPX signal output. As any good engineer does one of the first things I did is take it apart and found it was just a Raspberry PI with a HiFiBerry card running the Stereotool software that creates the MPX signal.
I’m sure there are a bunch of other uses that I’m not thinking of right now, but it is a very versatile single board computer, especially considering its low cost.
Thanks for the list, Lorne! I have played around with a Pi and made a remote OTA TV station monitor using an HD Home Run. That was also a fun project. I’ve had this Pi 3 for about 4-5 years now, wiped the SD card, and reloaded the OS countless times. I’ve never had any issues with the hardware side of things. The Pi 4’s are better.
Hi Paul,
I have not checked in here for a while, but I was interested to see this NNTP post. I too am building an NNTP server with a Pi4b and the Adafruit ultimate GPS module and an external active antenna using Austin’s guide https://austinsnerdythings.com/2021/04/19/microsecond-accurate-ntp-with-a-raspberry-pi-and-pps-gps/#comment-598 and N4BFR’s https://n4bfr.com/2020/04/raspberry-pi-with-chrony/2/ guides. I have good GPS lock and data, good PPS data but I’m stuck at geting chrony to see the data. Did you find any issues not discussed by Austin?
PS: The K9AY kit I got from you and packaged is going strong! Aloha! Gary
Hi Gary, Glad to hear the K9AY is still working! If you are seeing GPS data, I would look at the GPIO pin that the Adafruit unit is using for PPS. I think it uses pin 4, so the /etc/config.txt should be changed to:
‘dtoverlay=pps-gpio,gpiopin=4’
Hope that helps!
Aloha Paul, Hardware is all good. I did find a fat finger error in chrony.conf and all is good! Happy to see you are still posting!