GPS18 + FreeBSD
Home Page Up Using NTP Installing Performance Events Cable modem notes Monitoring with MRTG GPS18 + FreeBSD GPS18 + Windows NTP 4.2.4 vs. 4.2.5 Vista & Windows-7 Timestamp issues After reboot

 

Adding a FreeBSD NTP server based on an GPS 18 LVC device

Introduction 

I have been interested in precise timekeeping for a long time, and have run the excellent NTP software on my PCs for several years.  Recently, I have worked with Martin Burnicki of Meinberg on improving the performance of NTP in the Windows environment, however I remained envious of the reported precision of GPS systems with microsecond accuracies.  When the low-cost Garmin GSP 18 LVC became available, quite a few people reported using this device with UNIX systems, and this triggered me into purchasing a GPS 18 LVC to see what I could do with it.  Initial tests with just the serial 4800 baud NMEA output using Windows were disappointing.  Whilst the device worked, the accuracy and jitter were no better than could be achieved with a broadband Internet connection and servers from the NTP pool.  Realising that I had a spare old 133MHz PC, and hearing that UNIX could run on such a system, I decided to rise to the challenge.  This note is the result!

 

Hardware

PC Hardware

1995 PC with 133MHz Pentium processor, 48MB memory, and 10GB ATA disk.  Two serial ports (although one would be enough in this application).  Top of the line kit in 1995!

 

GPS Hardware

I used the Garmin GPS 18 LVC, which has a cable connection you can wire into your own system.  It needs 5V power at 60mA.  

It should be mounted where it has a clear view of at least 50% of the sky - ideally the whole sky.  I tried mine on a window ledge but the more recent windows we had fitted in 2005 do not seem to be transparent to the microwave signals.

The GPS is now on a small bracket just outside the window, with the thin aluminium bracket being shaped so that it is clamped by the window.  The unit is secured to the bracket by a single screw in the base.  The cable comes through the window and is clamped by the rubber sealing strips - they don't seem to do too much harm.  Whilst this worked initially, on 2006 Sep 22 I moved the GPS so that it now has a somewhat fuller view of the sky.

PDF - GPS 18 data sheet - GPS 18 technical specifications

 

How do I know how many GPS satellites are visible?

I have written a program called WXtrack which in its registered version has a View, GPS Visibility function which provides a plot of the number of satellites visible versus time of day.  You can select a threshold angle and the quadrants visible from your location.  For best accuracy, be sure to download the current Kepler data.

An oddity

During the initial tests of the GPS 18 LVC, after I had made up the RS-232 connector, I discovered that the Garmin supplied software would not connect to the device, even though the correct "sentences" could be seen via a terminal emulator.  I didn't understand why this was the case, and so I wrote a small program to send the command string to switch the device to 19200 baud (or 4800 baud).  Once I'd done that, the Garmin program worked OK.  Perhaps this is a common problem, as Tony Hoyle reported: 

Tony: "I got hold of one of these, and after much mucking around, it seems to work. (it's defaulted to startup in binary mode and no linux drivers can understand that, so you have to switch it into NMEA using the Windows config program, then switch binary mode off using a command from the spec sheet... the second step doesn't seem to be documented elsewhere)."

Me: "My GPS 18 LVC powered up in the correct mode (I think), but the Windows control program wouldn't talk to it. HyperTerminal saw the sentences correctly, though!  I wrote a small piece of software to switch it to 19200 baud, and back to 4800 baud, and it's OK now."

Tony: "Mine was the other way around - the Windows control program could see it but all hyperterminal (or minicom) could see was binary junk.  Had to switch it manually using $PGRMC1... you first get the windows program to enable text mode (forcing 'enable NMEA mode' does this) then quit it and start minicom, and issue a $PGRMC1 with 1 as the second digit (disable binary phase)."

Initial setup

For a long while after I first started the GPS it didn't report a sensible position.  I suspect it was taking a long time to read the almanac, and then to find the correct satellites.  It did eventually sort itself out, but only after about 30 minutes of exposure to a good fraction of clear sky.

The unit is quite a bit less sensitive than my other GPS, which has an add-on active antenna.

An attempted tweak

On 2006 June 06, I attempted to set the GPS 18 LVC into 2D mode, which means that it assumes a fixed height and would only need three satellites for a complete fix (as my sensor can only see half the sky).  This is done via the $PGRMC statement, setting the first value to "2", and the second to the sensor height in metres.  I will see if this makes any difference (I'm also unsure if the command "stuck").  I don't think this made any difference, as I believe it only affects the initial acquisition.

Moving the GPS 18 LVC

The opportunity recently arose to put the unit on the slope of the roof, which would mean that it only saw satellites above 25º elevation, but over a 360º degree arc of the sky.  This does appear better than the  previous 180º arc of about 5º elevation.  No longer do I see spikes of invalid GPS data (due to too few satellites), and now the winter is approaching the central heating transients are, perhaps, the cause of worst errors!

Interconnection - separate power

The Garmin has a 5V power requirement, which I met from a 7805 and a 12V regulated supply already to hand.  You could, instead, take the 5V from a USB port (see: Terje Mathisens' post).  I took this approach when I added a GPS 18x LVC on May 2009.

The Garmin TX, RX and ground data connections go to DB-9 RX, TX and ground connections.

The Garmin yellow PPS (pulse per second) line is connected to the DB-9 DCD (pin 1).  Mine is also connected to a LED via a 3.3K resistor so that there is a visual indication of the PPS signal.  I still see over 4V on of the PPS line.  Update: the LED was a little dark, so I changed the resistor to 1.5K and replaced the LED with a special low-current (2mA) one from Maplins.  Now easily seen in daylight - I await being dazzled at night!

LVC connection Colour DB-9 pin Function
PPS thin yellow 1 Data Carrier Detect
TXD thin white 2 Receive Data
RCV thin green 3 Transmit Data
GND thin black 5 Signal Ground
+5V power thick red
0V thick black

 

Interconnection - USB power

On a later arrangement, which happened to be with the newer and more sensitive Garmin GPS 18x LVC (note the "x") I used the +5V USB power from the PC to service the needs of the GPS.  It's well within the capabilities of the USB port.  The GPS went faulty at one stage and had to be returned to Garmin (who replaced it quite quickly - there is a suggestion that it's actually a firmware fault).  To avoid the hassle of having to solder the device connections to the RS-232 connector once again, I used a couple of 5-way DIN connectors (not ideal, I know) to connect the new GPS into the old cable, so now I have a 10m lead if I need it!  It makes for a very simple and "clean" interface.  Although I needed to have the GPS 18 on the roof outside, the GPS 18x is sufficiently sensitive to work indoors (at least on the top storey of the building).



The puck and the supplied cable, now terminated in a 5-pin DIN connector, with the other end going off to the PC, reusing the lead from the faulty GPS 18x LVC.


I built the yellow PPS LED and resistor into the RS-232 connector.

 

Software

Software installation

It seems to be acknowledged that FreeBSD is currently the best operating system for accurate time keeping, so that's what installed having no other particular preference.  It is also possible to use the same hardware with Linux 2.6, and Philip M White has described how to do this.

The FreeBSD formal documentation is here.

You can download the BSD 5.4 ISO disk images from here.  This is the version which I heard that other people use, and it has worked fine for me.  I can't comment from experience if newer versions are any better.

You can use the IsoBuster program to extract the floppy disk images from the ISO.

You use the fdimage program to make floppy disks to boot from if, like me, your CD-ROM doesn't boot.  There is a boot floppy, and two Kernel floppies.  There's a fourth fixit floppy, but I didn't appear to need that.  When choosing the type of distribution, be sure to install the source so that you can re-compile the Kernel.

It seems that I could have saved myself a lot of time by using Smart Boot Manager.  Geoff Rhodes writes:

"I notice that you were unable to boot from CD-ROM, so I thought you might be interested in Smart Boot Manager.  I got this several years ago (then as part of Ranish Partition Manager, I think) and it allows me to boot from CD- ROM on my 486, either by installing it onto the HDD, or more usually having SBM on a floppy.  I got really fed up with the time it took to use the floppy install method for W2K etc and this solves it quite neatly!

"It looks like SBM is now here:
http://btmgr.sourceforge.net/about.html or http://btmgr.webframe.org/"

Since I wrote my original comments, Ryan Doyle has written up his notes on setting up the Garmin 18 LVC on the (rather more recent) FreeBSD 8.0.

 

FreeBSD Unix commands

  • to shutdown:  shutdown -p now  (power down);  shutdown -r now (reboot)
  • to restart ntpd:  /etc/rc.d/ntpd restart
  • to logout:  logout
  • to choose the time-zone, and whether the BIOS clock works in UTC or local time, see the tzsetup command.

 

System software configuration

  • To allow remote login via Telnet, need to uncomment the telnet entry in inet.conf.  Telnet is only recommended for a small local system with no direct connection to the Internet.
  • To allow root to login via telnet, need to add the word "secure" to the ttyp0 entry in /etc/ttys.  Be careful if you enable this option!
  • A handy, free terminal emulator with VT100 etc. capabilities will make editing files easier if you have to work remotely from the FreeBSD box, and I've used Tera Term.  Of course, you need to edit the files allowing remote access locally first!

 

System software customisation

Need to add one line to the Kernel configuration:

    options PPS_SYNC

and recompile the Kernel.  On my 133MHz/48MB system this can take several hours.  Note the configuration suggestions below before you recompile the kernel.

Harlan Stenn comments:

Assuming an x86 box, you need to create a file - e.g. /usr/src/sys/i386/conf/PPS - and put the following in it:

#
# PPS -- Generic kernel configuration file for FreeBSD/i386 PPS
#
include GENERIC
ident PPS-GENERIC
options PPS_SYNC

and then add the following line to /etc/make.conf:

KERNCONF= PPS GENERIC

(Assuming you want to "cd /usr/src" and "make buildkernel installkernel") to build both kernels and only install the PPS kernel).  (Later: I do this if I want both the GENERIC and PPS kernels built, but the first one in the list is the one that gets installed).)

Kevin Oberman comments:

"The idea Harlan Stenn is putting forth is to create a very short kernel config file named PPS containing only those three lines.  That way, if you upgrade, any changes in GENERIC will automagically be folded in.  I would change one thing. I would change the name of the config file to match the IDENT.  It makes it easier to keep track of things."

Harlan Stenn continues: I also add the lines:

link cuaa1 refclock-0
link cuaa1 pps0

to the end of /etc/devfs.conf, and *sometimes* it looks like those links are not created soon enough in the boot sequence, but it's sporadic and I have not had time to chase it down yet. 

Per Hedeland comments:

Well, using PPS_SYNC shouldn't be *required* to use the PPS signal on FreeBSD - what it does is make the kernel discipline the local clock directly from the PPS signal, but FreeBSD also supports the PPSAPI, to let ntpd collect the timestamps from the PPS signal.  It should be possible to use this via the ATOM driver.  I haven't personally verified any of this though (hence the "should"s) - and I guess PPS_SYNC may give better results, but it could be interesting to try both variants.

Dag-Erling Smørgrav noted on the NTP-Timekeepers list:

The device name changed from cuaa to cuad in later versions.

There is some interesting information about configuring a single-board computer to do this job here:

 

NTP configuration

NTP is configured by the file /etc/ntp.conf.  My simple version contains:

#       ntp.conf
#
#
driftfile /etc/ntp.drift
#
#       The servers for sanity
#
server  0.uk.pool.ntp.org       iburst
server  1.uk.pool.ntp.org       iburst
server  2.uk.pool.ntp.org       iburst
server  ntp2.mcc.ac.uk          iburst
#
#       The GPS receiver on COM1 at 4800 baud
#
#       mode 1 = use $GPRMC statements
#       time1 = trimming offset
#       flag3 1 = enable Kernel PPS discipline
#
server  127.127.20.1    mode 1       prefer
fudge   127.127.20.1    time1 0.000  flag3 1  refid PPS
#

What does the fudge line do?

The fudge command allows me to adjust certain parameters of the specified server.  In this case, I alter:
  • the reference ID to the string "PPS"
  • flag 3 to the value 1, enabling the kernel PPS discipline
  • the time offset to 0.000 seconds
The latter adjustment does nothing, but had my pulses been the opposite polarity to the ones I actually have, the NTP software might have locked to the trailing edge of the pulse 200ms after the leading edge, and rather than change that in hardware I could have set time1 to +0.200 (or whatever) to get the correct time.

Useful NTP commands

  • To show the upstream systems:  ntpq -p
  • To show the state of the kernel:  ntpdc -c kern

Showing before and after PPS_SYNC enabled in the Kernel

    
E:\>ntpdc -c kern pixie
pll offset:           -3.75634 s
pll frequency:        45.503 ppm
maximum error:        0.485818 s
estimated error:      0.002825 s
status:               2001
pll time constant:    7
precision:            1e-006 s
frequency tolerance:  496 ppm
    
pixie# ntpdc -c kern
pll offset: -6.7e-08 s
pll frequency: 45.479 ppm
maximum error: 0.232597 s
estimated error: 0.001668 s
status: 2107 pll ppsfreq ppstime ppssignal nano
pll time constant: 6
precision: 1e-09 s
frequency tolerance: 496 ppm
pps frequency: 45.479 ppm
pps stability: 0.130 ppm
pps jitter: 1.183e-06 s
calibration interval: 128 s
calibration cycles: 23
jitter exceeded: 13
stability exceeded: 0
calibration errors: 1
 

How well does it work?

 Plot of offset for one day
(click this image for summary history plots)

Here is a graph showing the offset from UTC reported by the PC, with 20µs added so that the offset is positive.  (An ideal timekeeper would be a straight line at 20µs).  As the offset value reported by NTPQ is only accurate to 1µs, increasing the plotted time resolution would not provide more information.  Please remember that this is a lowly 133MHz processor system!  How I make these plotsPerformance historyAll NTP plots.

So far, with NTP, my experience in terms of the accuracy achieved appears to be something like this.  There are two levels of accuracy, one with Windows or FreeBSD of the order of 10 - 20ms, and one with the FreeBSD kernel PPS modification providing microsecond accuracies.  (There is also a nano modification to the UNIX kernels, but I don't quite know what that does as yet).

  • Multiple Internet sources to Windows NT/XP clients, excursions of the order of 10 - 20ms caused mainly by diurnal temperature variations.  The time constant on the NTP correction loop grows quite long to minimise NTP network traffic and load on NTP servers, and the lookup interval typically grows to 1024s.  This long time constant allows some drift.
  • Serial GPS source to Windows NT/XP.  At the default setting, 4800 baud, each bit occupies 0.2ms, and the uncertainty with which the GPS sends out the data, and the operating system can report the time the data was received, result in a somewhat higher short term offset jitter, and no better daily drift than with multiple Internet sources.  It's possible that the jitter would be less with a UNIX system, but I've not tested that.
  • Serial source to Windows XP with PPS support.  This provides some 250µs of offset jitter, which is a lot better than having just the serial input, but not as good as a FreeBSD system.  Performance graphs here.
  • PPS source to FreeBSD, with PPS_SYNC support in the kernel.  Even on a lowly 133MHz PC, with a GPS antenna seeing less than half of the sky, 10µs offset jitter is achieved.  It's too early to report long-term drift - judge for yourself by clicking the graph above.

 

System configuration updates require to run NTP

  • To start ntpd every time, add to /etc/rc.conf
        ntpd_enable="YES"
  • To point the pseudo GPS1 device to the actual serial port, add to /etc/rc.local
        ln -s /dev/cuaa0 /dev/gps1

 

Startup sequence after reboot - a set of ntpq -p reports

pixie# ntpq -p
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
 194.153.168.75  .STEP.          16 u  989   64    0    0.000    0.000 4000.00
 213.205.157.156 .STEP.          16 u  418   64    0    0.000    0.000 4000.00
 ns0.exa-network 130.88.202.49    3 u    9   64    1  2874.71  1421.71   0.015
 kryten.alphazed .STEP.          16 u  832   64    0    0.000    0.000 4000.00
 utserv.mcc.ac.u 194.81.227.227   2 u   10   64    1  2868.76  1417.38   0.015
 GPS_NMEA(1)     .PPS.            0 l   15   64    0    0.000    0.000 4000.00

pixie# ntpq -p
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
 194.153.168.75  .STEP.          16 u 1010   64    0    0.000    0.000 4000.00
 213.205.157.156 .STEP.          16 u  439   64    0    0.000    0.000 4000.00
 ns0.exa-network 130.88.202.49    3 u   30   64    1  2874.71  1421.71   0.015
 kryten.alphazed .STEP.          16 u  852   64    0    0.000    0.000 4000.00
 utserv.mcc.ac.u 194.81.227.227   2 u   30   64    1  2868.76  1417.38   0.015
 GPS_NMEA(1)     .PPS.            0 l   35   64    0    0.000    0.000 4000.00

pixie# ntpq -p
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
*194.153.168.75  195.66.241.10    2 u   20   64    1   20.722   -4.448   2.257
+213.205.157.156 130.149.17.21    2 u   19   64    1   27.903   -5.345   8.284
 ns0.exa-network 130.88.202.49    3 u   35   64    3   32.045    0.346 1421.36
+kryten.alphazed 129.69.1.153     2 u   19   64    1   22.097   -4.337   2.564
 utserv.mcc.ac.u 194.81.227.227   2 u   34   64    3   27.331   -3.080 1420.46
 GPS_NMEA(1)     .PPS.            0 l   37   64    1    0.000   -7.169   0.015

pixie# ntpq -p
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
*194.153.168.75  195.66.241.10    2 u   33   64    3   20.722   -4.448   3.898
+213.205.157.156 130.149.17.21    2 u   35   64    3   27.903   -5.345   8.538
 ns0.exa-network 130.88.202.49    3 u   51  128    7   32.045    0.346   7.119
+kryten.alphazed 129.69.1.153     2 u   32   64    3   22.097   -4.337   3.483
 utserv.mcc.ac.u 194.81.227.227   2 u   49  128    7   27.331   -3.080   8.172
 GPS_NMEA(1)     .PPS.            0 l   47   64    3    0.000   -0.624   6.545

pixie# ntpq -p
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
*194.153.168.75  195.66.241.10    2 u   16   64    7   21.446   -0.818   3.593
+213.205.157.156 130.149.17.21    2 u   15   64    7   27.903   -5.345   9.062
 ns0.exa-network 130.88.202.49    3 u   97  128    7   32.045    0.346   7.119
+kryten.alphazed 129.69.1.153     2 u   13   64    7   22.097   -4.337   5.230
 utserv.mcc.ac.u 194.81.227.227   2 u   96  128    7   27.331   -3.080   8.172
 GPS_NMEA(1)     .PPS.            0 l   28   64    7    0.000   -0.058   5.044

pixie# ntpq -p
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
+194.153.168.75  195.66.241.10    2 u    8   64   17   21.446   -0.818   4.854
+213.205.157.156 130.149.17.21    2 u    6   64   17   28.349    0.523   5.450
 ns0.exa-network 130.88.202.49    3 u   27  256   17   32.045    0.346   7.903
+kryten.alphazed 129.69.1.153     2 u    7   64   17   21.891    2.511   4.282
+utserv.mcc.ac.u 194.81.227.227   2 u   24  256   17   27.331   -3.080   8.057
*GPS_NMEA(1)     .PPS.            0 l   20   64   17    0.000   -0.007   4.150

pixie# ntpq -p
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
+194.153.168.75  195.66.241.3     2 u   16   64   37   21.446   -0.818   4.893
+213.205.157.156 130.149.17.21    2 u   14   64   37   26.764    1.313   4.579
 ns0.exa-network 130.88.202.49    3 u  101  256   17   32.045    0.346   7.903
+kryten.alphazed 129.69.1.153     2 u   81   64   36   21.891    2.511   4.282
-utserv.mcc.ac.u 194.81.227.227   2 u   98  256   17   27.331   -3.080   8.057
*GPS_NMEA(1)     .PPS.            0 l   31   64   37    0.000   -0.005   3.595

pixie# ntpq -p
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
+194.153.168.75  195.66.241.3     2 u   61   64   77   21.446   -0.818   6.598
+213.205.157.156 130.149.17.21    2 u   57   64   77   26.764    1.313   4.050
 ns0.exa-network 130.88.202.49    3 u  210  256   17   32.045    0.346   7.903
+kryten.alphazed 129.69.1.153     2 u   60   64   75   21.792    2.579   3.447
-utserv.mcc.ac.u 194.81.227.227   2 u  207  256   17   27.331   -3.080   8.057
*GPS_NMEA(1)     .PPS.            0 l   11   64  177    0.000    0.003   2.939

 

Retirement

After several years of faultless active service, this system was retired on 2009 March 24, as satisfactory performance had been obtained from a Windows system running a serial GPS NMEA port and a special serialpps.sys serial port drive with the ATOM reference clock.

 

Acknowledgements

I received much help from the kind folk in the comp.protocols.time.ntp newsgroup including Terje Mathisen, John Pettitt and Harlan Stenn.  Thanks, guys!

 
Copyright © David Taylor, Edinburgh Last modified: 2009 Dec 03 at 13:31