Connecting gpsd to ntpd

A project log for An NTP server using GNSS for time

A straightforward project to use an old Raspberry Pi

Ken YapKen Yap 07/17/2020 at 15:540 Comments

For this part of the project, I followed the instructions on the page GPSD Time Service HOWTO at the gpsd website in the links.

You may be wondering how a serial interface with significant delay could convey a very accurate time stamp. In fact it doesn't. Even if you measure from the leading edge of the first character, there is enough jitter in the chain to swamp the accuracy. The solution is a pin on the GNSS module called 1PPS (1 Pulse Per Second) or just PPS. Actually it can be configured to other frequencies, but usually 1 Hz is used. This hardware line is connected directly to the hardware and the CPU takes the edge of this signal as the time conveyed by the serial interface an instant later.

For this to work, the pulse output from the GNSS module must be connected to the CPU. Unfortunately in the module I have, only two power lines and two serial data lines are used. On custom built GNSS clock rigs, the PPS pin could be connected to a GPIO line.

So I have to live without PPS.

Next is how to send the time information from gpsd to ntpd. This is done by gpsd creating a Unix shared memory segment (shm) which ntpd reads. There is a set of magic IP addresses which are used to specify gpsd to ntpd as a "local time server".

# GPS Serial data reference (NTP0)
fudge time1 0.12 refid GPS

The IP address maps to the ID of the shared memory segment.

A few things. gpsd should be started with the -n argument so that it starts taking a fix even if no client is connected to it. The time1 parameter in the snippet above specifies the total delay in the data feed via the serial interface and chips. It's specified in seconds and can be estimated by watching the output of ntpq -p after the system has settled down. You can see that there is about 120 ms of delay there. Finally, following the recommendation, I replaced the ntp package with ntpsec which is a compatible, more recent, and more secure derivative of ntp. It was just a matter of doing an apt install.

Here is the output of ntpq -p. The GNSS module has a refid of .GPS. Offset is in ms so not as bad as it looks. I might tune the GNSS delay by and by.

     remote           refid      st t when poll reach   delay   offset   jitter
 0.debian.pool.n .POOL.          16 p    -  256    0   0.0000   0.0000   0.0019
 1.debian.pool.n .POOL.          16 p    -  256    0   0.0000   0.0000   0.0019
 2.debian.pool.n .POOL.          16 p    -  256    0   0.0000   0.0000   0.0019
 3.debian.pool.n .POOL.          16 p    -   64    0   0.0000   0.0000   0.0019    .INIT.          16 u    - 1024    0   0.0000   0.0000   0.0019
*SHM(0)          .GPS.            0 l   32   64  377   0.0000  -6.3869   5.0497
-pauseq4vntp1.da    2 u   70  128  377  17.3605   5.0752   0.5022
+time.cloudflare      3 u   33   64  377  16.8134   5.0694   0.5466    2 u    7   64  377  17.1365   5.6812   0.3424
-dns01.ntl02.pri    2 u   15  128  377  21.5701   4.7036   0.4717

So now I have an ntp server that uses GNSS as a source of time, in addition to servers from the Debian ntp pool.