If you need precise and accurate time for your projects while sampling a digital record or doing something that need precise timestamps you can use a Raspberry Pi with the Adafruit Breakout GPS module to build a stratum 1 NTP server for your projects. What is a Stratum 1?
The basic definition of a stratum-1 time server is that it be directly linked (not over a network path) to a reliable source of UTC time such as GPS, WWV, or CDMA transmissions.
Let’s see how to build one!
Materials that you will need
- Raspberry Pi Modell B Revision 2 512MB
- 8Gb MicroSD/SD Card
- A modified version of Debian Wheezy
- Adafruit Breakout GPS module
Thanks to David Taylor ( http://www.satsignal.eu/davids.html ) on how to build up the kernel-modded image ,i then discovered later you can even download a perfect Debian Wheezy image from this site without modify the kernel yourself : it has everything you need (NTP server configurations and PPS Kernel – RX GPIO signals for NMEA and NTPD, GPSD ec..) ( http://ntpi.openchaos.org/downloads/ntpi-pps-2013-04-12.zip ) .
Ok i’ll go quick to the point. First take your image with your kernel setted for NTP and PPS and flash it into a microSD card. In this way you will accomplish almost 80% of the job done. Once you have your image set , you can try it on the Raspberry (the HDMI is available, SSH too on port 22) enter with username pi and password raspberry. If works just fine , you login and everything seems operational then it’s time to connect the GPS module to the boards’s GPIOs pins . You will have to connect it in this way
Connect the Board 5v (GPIO 02) to the VIN pin of the GPS.The Raspberry works at 3.3v not 5v so be careful to never put 5v current in the headers pins! You can of course power the Adafruit GPS module with both since the PPS output is on 3.3v, also it’s even better to use the 5v to reduce the load on the 3.3 V regulator on the Raspberry Pi board. Then connect the GROUND , the RX GPIO pin to the GPS TX and PPS pins like in the image. (you don’t need to use the TX pin on the board since we are just reading the GPS NMEA output from the UART).You can solder everything if you need or use cables with tape for testing So now we should be ready to set up our server.
The server configuration file is located in /etc/ntp.conf file. I’ll copy here my personal configuration file to explain lines:
# /etc/ntp.conf, configuration for ntpd; see ntp.conf(5) for help driftfile /var/lib/ntp/ntp.drift # Enable this if you want statistics to be logged. statsdir /var/lib/ntpstats/ statistics loopstats peerstats clockstats filegen loopstats file loopstats type day enable filegen peerstats file peerstats type day enable filegen clockstats file clockstats type day enable # 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. # # Note that "restrict" applies to both servers and clients, so a configuration # that might be intended to block requests from certain clients could also end # up blocking replies from your own upstream servers. # By default, exchange time with everybody, but don't allow configuration. restrict -4 default kod notrap nomodify nopeer restrict -6 default kod notrap nomodify nopeer # Local users may interrogate the ntp server more closely. restrict 127.0.0.1 restrict ::1 # pps-gpio on /dev/pps0 server 127.127.22.0 minpoll 4 maxpoll 4 fudge 127.127.22.0 flag3 1 refid PPS # enable kernel PLL/FLL clock discipline # gpsd shared memory clock server 127.127.28.0 minpoll 4 maxpoll 4 iburst true prefer # PPS requires at least one preferred peer fudge 127.127.28.0 time1 +0.51 refid GPS # coarse processing delay offset server ntp1.ptb.de prefer # another stable preferred peer server 0.pool.ntp.org iburst server 1.pool.ntp.org iburst server 2.pool.ntp.org iburst server 3.pool.ntp.org iburst
Let’s start to analyze its most important parts:
Each hour NTP will save some datas into the ntp.drift file. If you open/cat the file you will notice a number: for example -2.979 . These are PPM or Part per milion and is the current difference drift of the quartz crystal of your motherboard. The basic formula to calculate it in ms is -2.979*86.4 ( 1PPM = 1 PPM = 1 part per million = 1 microsecond per second = 3.6ms per hour = 86.4ms per day ) that is -257.385 ms slow (if minus , if plus is faster) compared to the sys_peer source.
statistics loopstats peerstats clockstats filegen loopstats file loopstats type day enable filegen peerstats file peerstats type day enable filegen clockstats file clockstats type day enable
These file are NTP statistics overview. We’ll see later how to manage these datas and put them on a graph to monitor our server.
restrict -4 default kod notrap nomodify nopeer restrict -6 default kod notrap nomodify nopeer
Security restrictions: -4 apply to ipv4 and -6 to ipv6 kod : Send a kiss-o’-death (KoD) packet if the limited flag is present and a packet violates the rate limits established by the discard command. KoD packets are themselves rate limited for each source address separately. If the kod flag is used in a restriction which does not have the limited flag, no KoD responses will result.NOTRAP Decline to provide mode 6 control message trap service to matching hosts. The trap service is a subsystem of the ntpdc control message protocol which is intended for use by remote event logging programs. NOMODIFY Deny ntpq and ntpdc queries which attempt to modify the state of the server (i.e., run time reconfiguration). Queries which return information are permitted. NOPEER Deny packets that might mobilize an association unless authenticated. This includes broadcast, symmetric-active and manycast server packets when a configured association does not exist. Note that this flag does not apply to packets that do not attempt to mobilize an association.
# pps-gpio on /dev/pps0 server 127.127.22.0 minpoll 4 maxpoll 4 fudge 127.127.22.0 flag3 1 refid PPS # enable kernel PLL/FLL clock discipline
This is the kernel-gpio signal received as pps0 on GPIO – PPS pin (see header picture on top). Minpoll – Maxpoll at 4 creates 16 seconds ntpd poll reading , flag3 1 : Controls the kernel PPS discipline: 0 for disable (default), 1 for enable.
# gpsd shared memory clock server 127.127.28.0 minpoll 4 maxpoll 4 iburst true prefer # PPS requires at least one preferred peer fudge 127.127.28.0 time1 +0.51 refid GPS # coarse processing delay offset
The address used by gpsd to read NMEA data from the GPS Breakout to the GPIO Header of the Raspberry. Since UART signal has widely known offset problem, we just make the ntpd algorithm to belive in this data since we have a 1PPS kernel reference signal for the precise microsecond offset. (iburst, true and prefer) . The other thing we shall consider is to calculate the offset of the UART. You can use a time1 +0.000 at the beginning then when the offset become more stable try to make a ntpq -np command and see how much offset do you have. (mine was about -510.00 milliseconds but it’s still unstable) Check out also your UART – GPIO rx speed. Raspberrt usually has 9600 boud default . check with : ( should be ttyAMA0 )
root@ntpi:/dev# stty -F ttyAMA0 speed 9600 baud; line = 0; intr = <undef>; quit = <undef>; erase = <undef>; kill = <undef>; eof = <undef>; start = <undef>; stop = <undef>; susp = <undef>; rprnt = <undef>; werase = <undef>; lnext = <undef>; flush = <undef>; min = 1; time = 0; -brkint -icrnl -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke
If everything is working you should see this output :
As you can see we have a PPS with an offset of 0.002 microseconds that is used for reference and we are using NMEA GPS data input from UART. (you can check the NMEA output too with #cat /dev/ttyAMA0 ). For a complete description of ntpq query please check the official documentation at http://doc.ntp.org/4.1.0/ntpq.htm
First results as Stratum 1 in LAN and WAN environments.
Ntp saves two different kind of files in a directory of your choice (in this case /var/lib/ntpstats) and automatically zip them day by day. Be careful on the Raspberry to just activate this option when you need to monitor them. You can use MRTG software or NTP Plotter. I’m using this last one you can find a copy here http://www.satsignal.eu/software/NTPplotter.zip
This are the results of few hours in a normal day just after the first activation :
Raspberry Pi B 512 Mb , Kernel PPS Sync with Adafruit GPS Breakout Module – Offset Time Graph in μs
Normally i’ve got a stratum 1 offset of 1 microsecconds with a jitter of 2 microseconds as server.I’m actually testing my server in my LAN and in WAN environment connected to another server at the SID monitoring station, located to the other side of the city of Turin. I’m using a normal ADSL Gb ethernet at home for the server, wich is of course bad for a WAN env.. ( you can find more information on it here : http://www.sidmonitor.net/systems/index.html the server in sidmonitor is using FreeBSD 9.2 and use NTP as client. )
LAN client Test with another server in my home syncronized to the Raspberry :
The server is running ubuntu with 3.13.0-39 Kernel is an old IBM xseries 335. .DELT. is the Raspberry NTP ID , as you can see NTP easly choosed that source cause is the fastest stratum 1 available. In my internal LAN i’ve got a delay of 3.347 milliseconds and an offset of -0.453 milliseconds wich is just bad but not too much for my busy LAN and my little Cisco Router (the server is in wi-fi).
Then i’ve tried to sync the FreeBSD one to the other side if the city and this is the result of ntpq -np query :
The pubblic IP is covered for security reason. As you can see DELT Raspberry NTP server is working and operational, compared to the NIST and ACTS is of course much more fast since those atomic clocks are in the US, not here in Europe and NTP algorithm has just selected .DELT. as preferred time server for the stratum 1 offset/jitter offer . Much more fun since now synchronize all sidmonitor.net data upload and mirroring with a Raspberry!
As Stratum 1 with a 60$ receiver and a Raspberry, under best conditions of GPS satellites reception, i’ve got results around 500-450 nanoseconds,( 0.045 microsecs in the picture above) wich i think it’s a good result for a cheap NTP server. Will be possible to go below 40 nanoseconds?We’ll see!