This is an update of the previous post. I’m now using Raspbian Buster with NTPsec (which I package in Debian).
Hardware:
- Raspberry Pi 3B+ (or older 3B): Adafruit, Uputronics, or The Pi Hut
- Power Supply: Adafruit
- SD Card (8+ GiB, Class 10 highly recommended): the 32 GiB Samsung EVO Plus offers the best performance
- Mini Heatsink (optional): Adafruit or The Pi Hut
- GPS Antenna: Adafruit or Uputronics
- Uputronics GPS Expansion Board: AirSpy.us, Uputronics, or The Pi Hut
- Pi GPS Case: Uputronics (Black) or The Pi Hut (Black) or The Pi Hut (Clear)
I’m in the U.S., so I ordered only the GPS board and case from Uputronics to save on shipping.
Other GPS HATs (and cases) can be used. Consult the Stratum-1-Microserver HOWTO for GPIO pin changes.
1. Download a Raspbian Buster image, typically the Raspbian Buster Lite image, which is command line only.
2. Unzip the image:
$ unzip 2019-09-26-raspbian-buster-lite.zip
3. Write the image to a Micro SD card:
$ sudo dd if=2019-09-26-raspbian-buster-lite.img of=/dev/mmcblk0
4. Insert the SD card into the Raspberry Pi. Stick the heatsink to the processor. Assemble the case with the Raspberry Pi in it as you go. Connect the GPS antenna and place it near a window. Connect a keyboard, mouse, and monitor. Power up the Raspberry Pi.
5. Login as “pi” as the username and “raspberry” as the password. Set your own password:
$ passwd
Alternatively, add your own user and delete the “pi” user:
$ sudo adduser YOURUSERNAME
$ sudo usermod -a -G adm,audio,cdrom,dialout,games,gpio,i2c,input,netdev,plugdev,spi,sudo,users,video YOURUSERNAME
$ exit
Log back in with your username.
$ sudo deluser pi
6. Set your locale:
$ sudo apt update
$ sudo apt install locales
$ sudo dpkg-reconfigure locales
7. Set your time zone:
$ sudo dpkg-reconfigure tzdata
8. Set your hostname:
$ sudo vi /etc/hosts
$ sudo vi /etc/hostname
9. Optimize system performance:
$ sudo sed -i "s|$| nohz=off|" /boot/cmdline.txt
$ sudo vi /etc/default/cpufrequtils
Set: GOVERNOR="performance"
10. Reconfigure serial for GPS:
$ sudo apt -y purge bluez bluez-firmware
$ sudo sed -i "s|console=serial0,115200 ||" /boot/cmdline.txt
$ sudo vi /boot/config.txt
Add these lines to the end:
dtoverlay=pi3-disable-bt
enable_uart=1
dtoverlay=pps-gpio,gpiopin=18
11. Update and install software:
$ sudo apt -y dist-upgrade
$ sudo apt -y install cpufrequtils gpsd gpsd-clients pps-tools ntpsec ntpsec-ntpviz
Note: Installing ntpsec-ntpviz is optional, and skipping it will avoid bringing in Apache.
12. Configure gpsd:
$ sudo sed -i 's|DEVICES="|\0/dev/ttyAMA0 /dev/pps0|' \
/etc/default/gpsd
$ sudo sed -i 's|GPSD_OPTIONS="|\0-n|' /etc/default/gpsd
$ sudo mkdir -p /etc/systemd/system/ntpsec.service.d
$ sudo vi /etc/systemd/system/ntpsec.service.d/gpsd.conf
[Unit]
After=gpsd.service
Wants=gpsd.service
$ sudo mkdir -p /etc/systemd/system/gpsd.service.d
$ sudo vi /etc/systemd/system/gpsd.service.d/stationary.conf
[Service]
ExecStartPre=/usr/bin/gpsctl -t 'u-blox' -b -x '\\x06\\x24\\xFF\\xFF\\x02\\x03\\x00\\x00\\x00\\x00\\x10\\x27\\x00\\x00\\x05\\x00\\xFA\\x00\\xFA\\x00\\x64\\x00\\x2C\\x01\\x00\\x3C\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00' $DEVICES
The stationary.conf bit is not required. This sends a command to the GPS to put it into “stationary mode”. By telling the GPS module that it is not moving, it can optimize its calculations, which should slightly improve timing performance. However, whether this matters for NTP-level accuracy is doubtful. I have no done any analysis.
13. Configure ntpd:
sudo vi /etc/default/ntpsec
Set:
IGNORE_DHCP="yes"
sudo vi /etc/ntpsec/ntp.conf
Add these two lines before the "pool" entries:
server 127.127.28.2 minpoll 1 maxpoll 1 prefer
fudge 127.127.28.2 refid PPS
Note: If you want to be able to set the clock without network access, also comment out:
tos minclock 4 minsane 3
15. Reboot:
$ sudo reboot
16. Check that things look right:
$ watch ntpq -p
After a bit, you should see “SHM(2)” selected, which will be indicated by an asterisk in front of that line.
When finished, you can kill the watch
command with Control-C.
If the PPS is not working, first check the GPS status:
$ gpsmon
Once the GPS is locked, check the PPS status:
$ sudo ppstest /dev/pps0
Sources: