StratumN/A
Combined time offsetN/A µs
Clock frequency offsetN/A PPM
Clock frequency wanderN/A PPM
Combined system jitterN/A
Clock jitterN/A
Total root dispersionN/A
Total roundtrip delay to the primary reference clockN/A
Time constant and poll exponentN/A
Minimum time constantN/A
PrecisionN/A
Leap warning indicatorN/A
Poll messages sentN/A
No replyN/A
Bad date or timeN/A
Bad formatN/A

Raspberry Pi Stratum 1 NTP server with PPS
Accurate timekeeping at low cost

Not my idea

u-blox NEO 6M GPS module with PPS on Pin 3 u-blox NEO 6M GPS module with PPS on Pin 3. Added an I²C EEPROM for configuration storage and a blinkenlight on the PPS signal. PPS Blinkenlight Connect the GPS module with these pins on the Raspberry Pi A test setup

A while ago, I read a post by David J Taylor on the NTP Pool mailing list about his experience with a Raspberry Pi and a u-blox GPS module. I always wanted to build a stratum 1 server with PPS clock discipline and this one promised good accuracy at low cost, so I went to reproduce his setup.

The module’s price has increased since David’s post. I bought one on eBay for £30, about the same price as a Raspberry Pi. Delivery from Hong Kong took a few weeks but it arrived eventually. The module comes readily assembled with backup battery, active GPS antenna, a 3.3V-TTL interface suitable for direct connection to the RPi and also contains a 5V-to-3.3V voltage regulator which allows it to be powered from the RPi’s 5V USB supply.

The u-blox NEO module is well documented. See the datasheet for hardware specs and the “Receiver Description and Protocol Specification” for configuration and protocol details.

Be careful with the tiny U.FL antenna connector. I’ll probably buy a pigtail and a larger antennna soon.

Hardware modification

The PPS signal is not routed to the pin header but it is available from pin 3 on the NEO-6M module.

Disable the serial console

By default, /dev/ttyAMA0 is a serial console for the kernel and also runs a getty process for logins.

Build the pps-gpio module

Build a custom kernel

This is based on the general RPi kernel compilation wiki and a forum thread and will update your kernel from 3.2 to 3.6.

Make a Raspberry Pi kernel image

Update the Raspberry Pi firmware

Load the pps-gpio module at startup

Reboot and check PPS

Reboot to the new kernel and look for pps messages in the kernel log.

$ dmesg |grep pps
[ 15.340304] pps_core: LinuxPPS API ver. 1 registered
[ 15.341978] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti
[ 15.354282] pps pps0: new PPS source pps-gpio.-1
[ 15.356159] pps pps0: Registered IRQ 188 as PPS source

Test PPS and GPS

Build ntp with ATOM PPS clock

The ntp package from the Raspbian distribution does not support the "ATOM" (PPS) reflock. You'll have to recompile it. To use the debian package sources, add a "deb-src" line to /etc/apt/sources.list:
deb-src http://mirrordirector.raspbian.org/raspbian/ wheezy main contrib non-free rpi

Configure NTP

         remote           refid      st t when poll reach   delay   offset  jitter
    ==============================================================================
    oPPS(0)          .PPS.            0 l   13   16  377    0.000    0.001   0.004
     SHM(0)          .GPS.           15 l   12   16  377    0.000   -1.313   1.787
    *ptbtime2.ptb.de .PTB.            1 u   36   64  377   23.057    1.086   1.125
    +rustime01.rus.u .PPS.            1 u   47   64  377   23.076    0.006   6.496
    +sv-aglasterhaus 129.69.1.153     2 u   47   64  377   22.806    1.684   6.108
    -ns2.derhil.de   131.188.3.220    2 u   45   64  377   23.166   -4.367   2.470
    -alpha.rueckgr.a 129.69.1.153     2 u   55   64  377   27.045   -2.468   3.929
    -ntp.perfact.de  130.133.1.10     2 u   45   64  377   31.004   -1.484   3.908
    associd=0 status=0115 leap_none, sync_pps, 1 event, clock_sync,
    version="ntpd ... Sun Jan  6 19:01:13 UTC 2013 (1)",
    processor="armv6l", system="Linux/3.6.11+", leap=00, stratum=1,
    precision=-19, rootdelay=0.000, rootdisp=1.195, refid=PPS,
    reftime=d494807e.342184bb  Mon, Jan  7 2013  0:00:14.203,
    clock=d494808b.d9329de3  Mon, Jan  7 2013  0:00:27.848, peer=36158, tc=4,
    mintc=3, offset=0.000722, frequency=36.518, sys_jitter=0.003583,
    clk_jitter=0.004, clk_wander=0.001