With the prices of GPS modules dropping to extremely
affordable levels (about
$4 CDN), I decided to swap out the U-Blox
NEO-6M GPS module for one that had a 5th pin -- a PPS
(Pulse-Per-Second) contact that I could use to
implement a high-accuracy NTP
(Network Time Protocol) stratum
1 time server! In other words, using the
primary (stratum 0) time clock sources available on GPS
satellites to make my own secondary (stratum 1) shareable
computer time source.
My primary source of information on how to do this came
from these excellent sources:
The wiring for the GPS module that I used is as follows:
NEO-6M
Raspberry Pi
VCC
3V3
GND
GND
RXD
TXD (GPIO14)
TXD
RXD (GPIO15)
PPS
PWM0 (GPIO18)
Power (VCC/3V3) and Ground (GND) pins are basic. The
Receive-Data (RXD) and Transmit-Data (TXD) are used to
receive and transmit the serial-based
GPS data stream (notice that reversal when connecting the
pins i.e. the GPS 'transmit' pin is connected to the
Raspberry Pi 'receive' pin, and vice versa). The
magic comes from the Pulse-Per-Second
(PPS)
GPS pin being connected to the Raspberry Pi Pulse-Code-Modulation
(PCM) pin (also acting as Pulse-Width-Modulation
(PWM0)).
When a good GPS satellites lock has been achieved, my GPS
will transmit useful time (as well as position) data (at
9600 baud) using various NMEA
sentence structures. The one that the NTP utility
uses to extract time are the following:
Here is a sample NTP time statistics from my time
server soon after it was running:
pi@raspberrypi ~ $ ntpq -p
remote refid st t when poll reach delay offset jitter ============================================================================== LOCAL(0) .LOCL. 10 l 45h 64 0 0.000 0.000 0.000 oGPS_NMEA(0) .GPS. 0 l 8 16 377 0.000 0.003 0.002 *192.95.27.155 200.98.196.212 2 u 37 64 377 51.341 1.001 166.392 +kirdu.smartacti 213.251.128.249 2 u 3 64 77 42.552 10.272 99.637 +host1.hosttechn 213.251.128.249 2 u 20 64 377 38.465 10.301 161.560 +zero.gotroot.ca 30.114.5.31 2 u 65 64 376 34.556 0.719 52.451
In
this sample, the GPS source is providing a time accuracy of 0.003
microseconds (3 millionths of a second) to my computer network! This
time source is good enough to join (if I chose to do so) the list of
other NTP time sources used by millions of computers around the world: How do I join pool.ntp.org?
If everything is working OK, and a PPS lock has been
established (sometimes tricky inside my home), this text will show the
NTP statistics results:
UPDATE: After upgrading my Raspberry Pi linux version to Raspbian/Debian 9 'Stretch',
my GPS/PPS functionality stopped working -- which I have now finally fixed by doing the following -- since I found out that the '/dev/ttyAMA0' device was being used by the 'login' process, which was interferring with 'ntp' from getting at it as well:
Type: "sudo raspi-config"
Pick: "5 Interfacing Options Configure connections to peripheral"
Pick: "P6 Serial Enable/Disable shell and kernel messages on the serial connection"
Answer 'No' for: "Would you like a login shell to be accessible over serial?"
Answer 'Yes' for: "Would you like the serial port hardware to be enabled?"
Type: "sudo reboot"
I also did the following, but was not sure whether it was necessary or helped:
UPDATE: I also activated the same feature on my backup server:
an Orange Pi PC Plus (info here, purchased here and here). I chose this particular model since it was the best 'bang-for-the-buck' that I could find in the Orange Pi series, was less expensive than the boards offered by the Raspberry Pi foundation, and had an 8GB eMMC flash memory module on it (to avoid eventual wear-out of removable SD cards). A good resource comparing the various Orange Pi models is here.
The wiring for the GPS module that I used is as follows:
NEO-6M
Orange Pi
Pin
VCC
+3.3V
1
GND
GND
9
RXD
PA13 (UART3_TX)
8
TXD
PA14 (UART3_RX)
10
PPS
PA6 (PWM1)
7
Currently the 'best' source of Linux distros for the Orange Pi boards comes from Armbian, rather than from the manufacturer itself (which provides almost no support, and with non-100%-functional software!). A useful discussion forum for the Allwinner H3 boards with mainline Linux kernel is here.
For 'legacy' kernel, no PPS features are present, so a new kernel needs to be compiled (lots of work!):
For 'mainline' kernel, PPS feature is already present, but needs to be activated:
Add to the '/boot/armbianEnv.txt' file, specifically entries for 'overlays' to activate 'pps-gpio' and 'uart3' (if that is the pins you have decided to use), and 'param_pps_pin=PA6' (again, if that is the pin you have opted to use for the PPS signal):
Here is what my NTP configuration file looks like, which also supports the running of a parallel GPSD process:
# /etc/ntp.conf, configuration for ntpd; see ntp.conf(5) for help
# Local
server 127.127.1.0
fudge 127.127.1.0 stratum 10
# GPSD
server 127.127.28.0 mode 17 minpoll 4 maxpoll 4 iburst true prefer
fudge 127.127.28.0 flag1 1 refid GPS
# GPS with PPS enabled
server 127.127.22.0 mode 17 minpoll 4 maxpoll 4 iburst true prefer
fudge 127.127.22.0 flag1 1 refid PPS
#server 127.127.20.0 mode 17 minpoll 4 maxpoll 4 iburst true prefer
#fudge 127.127.20.0 flag1 1 refid GPS
# Internet time servers for sanity
server 0.pool.ntp.org iburst prefer
server 1.pool.ntp.org iburst
server 2.pool.ntp.org iburst
server 3.pool.ntp.org iburst
# By default, exchange time with everybody, but don't allow configuration.
restrict default kod nomodify notrap nopeer noquery
restrict -6 default kod nomodify notrap nopeer noquery
# Local users may interrogate the ntp server more closely.
restrict 127.0.0.1
restrict -6 ::1
# Drift file etc.
driftfile /var/lib/ntp/ntp.drift
# stats
enable stats
statistics loopstats
#statistics loopstats peerstats clockstats
statsdir /var/log/ntp/
#filegen peerstats file peers type day link enable
#filegen loopstats file loops type day link enable
filegen loopstats file loopstats type day link enable
The default 'ntp' app from the respositories doesn't appear to support PPS properly (without patching), so I got and compiled the 'NTPsec' fork, which has the bonus of providing the 'ntpmon' app. Some instructions for compiling NTPsec are here, but basically they are:
cd $HOME/Downloads git clone --depth 1 https://gitlab.com/NTPsec/ntpsec.git cd ntpsec sudo ./buildprep ./waf configure ./waf build sudo ./waf install
In order for the NTP logging to work properly, the directory '/var/log/ntp' needs to be created for every reboot, and with the correct (open) permissions. Add the following to '/etc/rc.local':
mkdir /var/log/ntp chmod 777 /var/log/ntp
After that is set up, I start the NTP process this way:
sudo service ntp start
For GPSD, here is what the '/etc/default/gpsd' configuration file looks like:
# Default settings for the gpsd init script and the hotplug wrapper.
# Start the gpsd daemon automatically at boot time
START_DAEMON="true"
# Use USB hotplugging to add new USB devices automatically to the daemon
USBAUTO="true"
# Devices gpsd should collect to at boot time.
# They need to be read/writeable, either by user gpsd or the group dialout.
DEVICES="/dev/ttyS3"
# Other options you want to pass to gpsd
GPSD_OPTIONS="-n -b -G "
The way to start the process is thus:
sudo service gpsd start
If everything is working OK, and a PPS lock has been established (sometimes tricky inside my home), this text will show the NTP statistics results:
Using 'ntpviz', here are some GnuPlot graphs over time showing interesting data: