NTP: GPS Stratum-1 Time Server

From MattWiki


Start with a fresh Raspian SD card.

Getting the System Ready

Start by running sudo raspi-config

In the initial configuration menu...

  • select Expand Filesystem.
  • select Interface OptionSSH and enable it.
  • select Interface OptionSerial Port, Answer No for a login shell.
  • select Finish
  • Reboot

Immediately after reboot...

sudo apt update
sudo apt dist-upgrade
sudo rpi-update
sudo apt install libcap-dev libssl-dev pps-tools
  • Add dtoverlay=pps-gpio,gpiopin=4 to the end of /boot/config.txt
  • Add pps-gpio to the end of /etc/modules
  • Reboot

After the reboot verify that /dev/pps0 exists.

Build and Install NTP

cd /usr/src
sudo mkdir ntp
chown pi:pi ntp
cd ntp
wget https://archive.ntp.org/ntp4/ntp-4.2/ntp-4.2.8p15.tar.gz
tar -xzf ntp-4.2.8p15.tar.gz
cd ntp-4.2.8p15
./configure --enable-all-clocks --enable-parse-clocks --disable-local-libopts --enable-step-slew --without-ntpsnmpd --enable-linuxcaps --prefix=/usr
make -j5
sudo apt remove ntp
sudo apt install ntpdate
sudo make install

Edit /etc/ntp.conf and adjust it as follows...

# pool.ntp.org maps to about 1000 low-stratum NTP servers.  Your server will
# pick a different set every time it starts up.  Please consider joining the
# pool: <http://www.pool.ntp.org/join.html>
server 0.debian.pool.ntp.org iburst
#server 1.debian.pool.ntp.org iburst
#server 2.debian.pool.ntp.org iburst
#server 3.debian.pool.ntp.org iburst
server 127.127.20.0 mode 84 minpoll 3 iburst prefer
fudge 127.127.20.0 stratum 1 flag1 1 flag2 0 flag3 0 flag4 0 time1 0.0 time2 0.280 refid GPS0

# Access control configuration; see /usr/share/doc/ntp-doc/html/accopt.html for
# details.  The web page <http://support.ntp.org/bin/view/Support/AccessRestrictions>
# might also be helpful.

Delete /etc/dhcp/dhclient-exit-hooks.d/ntp to prevent dhcp from overwriting the ntp config.

Create the file /etc/udev/rules.d/99-gps.rules with the following contents...

KERNEL=="pps0",SYMLINK+="gpspps0"
KERNEL=="ttyAMA0", SYMLINK+="gps0"

Run sudo udevadm trigger to create symlinks /dev/gps0 and /dev/gpspps0

Build and Install gps-tools

cd /usr/src
sudo mkdir gps-tools
sudo chown pi:pi gps-tools
cd gps-tools
wget https://github.com/f5eng/mt3339-utils/archive/gps.zip
unzip gps.zip
cd mt3339-utils-gps
sudo cp epoinfo epoloader eporetrieve gpsinit gpssend gpsstatus /usr/local/bin/
sudo cp *.conf /etc/

Test GPS

  • Run sudo ppstest /dev/pps0. You should see timestamp every second. CTRL-C to exit.
  • Run gpsinit -s 115200 -f /etc/gpsinit_nav.conf /dev/ttyAMA0 to initialize the GPS unit for testing
  • Run gpsstatus /dev/ttyAMA0. Do you get a GPS or DGPS fix within 10 minutes? If not,

Read the README at https://github.com/f5eng/mt3339-utils for instructions on how to initialize the GPS unit and why it's important.

Set up the GPS Unit for timekeeping

Run gpsinit -s 115200 -f /etc/gpsinit_time.conf /dev/ttyAMA0 to initialize the GPS unit

Start and test ntpd

sudo update-rc.d ntp defaults
sudo service ntp start
sudo ntpq -pn

If the ppstest previously passed, you should eventually see...

     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
oGPS_NMEA(0)    .GPS0.           1 l    1    8  377    0.000    0.001   0.004
xx.xx.xx.xx     PPS(1)           2 u    2    8  377    0.398   -0.072   0.212

The 'o' in the first column indicated that ntp is using the GPS for time.

Notes:

If you're Pi isn't network connected, you can set the system clock directly from the gps using the gpsinit command as long as ntpd isn't running.

$ gpsinit -s 115200 -i set_system_clock /dev/ttyAMA0

To do this at startup, edit /etc/rc.local and add the following lines at the bottom before the final 'exit 0'

service ntp stop
/usr/local/bin/gpsinit -s 115200 -i set_system_clock /dev/ttyAMA0
service ntp start