RJ Systems
Linux System Administration
Home Tech Linux Links Consulting







Valid XHTML 1.0!

Valid CSS!

IPv6 test

Synchronizing ntpd to a Garmin GPS 18 LVC via gpsd

Garmin
The Garmin GPS 18 OEM:
several versions were produced.
Garmin
The bare wire version:
the Garmin GPS 18 LVC.
Introduction

Accurate time synchronization is part of the foundation of any computer network. Users expect computers to keep accurate time regardless, it makes life easier for technicians when troubleshooting network problems, and it is crucial for time-dependent applications, such as Kerberos, or most anything that includes database replication.

Every computer motherboard includes an internal clock that continues to run on a battery even when the computer is switched off. For any operating system that is installed, this clock is the default time source. Unfortunately, motherboard clocks are anything but accurate and may drift by as much as several minutes a day. In some cases the only option may be to regularly reset the clock manually, but that is a crude and labor-intensive solution prone to human error. A far more efficient solution is to permanently synchronize every computer on a network to one or more accurate and reliable time sources.

One way to achieve this is to synchronize to a few of the many Network Time Protocol (NTP) servers available on the Internet. This is a popular solution that is definitely better than having no automatic time correction at all, but it also has certain drawbacks. First of all, most Internet links are also heavily used for other purposes; this inflicts varying delay times on NTP traffic, leading to decreased accuracy. Second, NTP was designed for use with symmetric network links, so those with typically asymmetric broadband connections (e.g. ADSL) can never achieve optimal results. However, the worst problem occurs when the Internet link becomes unavailable for any significant length of time. Typically, an NTP server will then revert to using its local clock and begin to drift as a result. If it drifts too far before the network link is reestablished, it may not resynchronize automatically, thus requiring manual intervention. This is the case with the most popular NTP server available for Linux, the NTP daemon (ntpd), the argument being that such a large time difference can just as easily be due to a problem with the remote system. At least one alternative NTP daemon, Chrony, does not exhibit this behavior.

A far more reliable solution is to maintain one or more accurate time sources locally. The traditional options for this approach have always included radio receivers for time signals, which are cheap, but not too accurate, and atomic clocks, which are extremely accurate, but complex and expensive. Nowadays, there is also a third option: a GPS receiver with pulse-per-second (PPS) output. These receivers are often very affordable and relatively simple, yet capable of providing (near) microsecond accuracy, making them by far the best value for money available. All a GPS receiver needs is a relatively good view of the sky: the less obstructed the better.

The Garmin GPS 18 LVC is one such receiver. This is a puck-like device in which both the antenna and electronics are integrated. It is 19.5 mm high by 61 mm in diameter and weighs just 110.6-160.6 grams depending on the length of the cable: 3 or 5 meters, depending on the model. It includes a microprocessor, which is to an extent programmable, and an internal clock that is disciplined by the GPS receiver. If it stops receiving signals from any GPS satellites, the internal clock will continue to provide a signal, although in that case it will not be anywhere near as accurate. Production of this particular model has been discontinued, but it is still widely available, e.g. via eBay, for less than $80.00. Within the Garmin GPS 18 family, only the LVC and the 5 Hz model (also discontinued) produce a PPS signal. The Garmin 18-5Hz produces 5 pulses per second for increased accuracy, but sells for 2-3 times as much. New versions of these models are now being produced as the Garmin GPS 18x.

This page attempts to describe how to configure a Debian 5.0 (lenny) system with the GPS daemon (gpsd 2.37) and the NTP daemon (ntpd 4.2.4) and turn it into a stratum 1 NTP server using a Garmin GPS 18 LVC. It assumes that a minimal Debian operating system is already up and running and that the computer has one available 9-pin serial port (/dev/ttyS0).


1. Hardware

The first obstacle to overcome is how to attach the Garmin GPS 18 LVC to the serial port of the computer. The cable from the GPS device consists of six or seven wires, plus a screen, that may or may not be terminated by a small plastic connector. The idea is to attach it to an RS-232 DE-9 connector, so cut off the mini-connector if it is included. The wires from the GPS device are as follows:

Yellow Measurement pulse output
Red Voltage in (+5V)
Black Ground
White Transmit data
Black Ground
Green Receive data
Black Ground
Screen Shielding

The Garmin GPS 18 also requires a 5V power source. This is not available from the serial port, but a simple solution is to sacrifice a USB cable for this purpose. All that is necessary is a short length of USB cable with an A-connector on one end and some exposed wires on the other: the screen, red (+5V) and black (ground) wires are the only ones required. These should be soldered, together with the GPS cable, onto a female RS-232 DE-9 connector as follows:

      Garmin    USB                 RS-232 DE-9
                                      pin no.

+5V   Red ---------------+
                         |
+5V             Red -----+

GND   Black ---------+
                     |
GND   Black ---------+-----+--------- 5  GND
                     |     |
GND   Black ---------+     |
                           |
GND             Black -----+

RXD   Green ------------------------- 3  TXD

TXD   White ------------------------- 2  RXD

PPS   Yellow ------------------------ 1  DCD

Scr   Screen --------------+--------- Screen
                           |
                Screen ----+


2. Setserial

Prepare the serial port, to which the GPS receiver is to be attached, for low-latency operation. To achieve this, install this package:

~# apt-get install setserial

It has no dependencies, so all that gets installed is:

setserial                         2.17-44.2                controls configuration of serial ports

Next, edit the associated configuration file, /var/lib/setserial/autoserial.conf, and modify it so that it reads:

/dev/ttyS0 uart 16550A port 0x03f8 irq 4 baud_base 115200 spd_normal skip_test low_latency

NB: Different machines have different UART models. Faster and more modern UARTS tend to have larger internal buffers (the 16550A has a 16-byte buffer), but for this particular task it is actually better if the UART does not use a buffer at all, since it can only add more delay.

To minimize CPU utilization, serial port traffic is usually delayed by 5 to 10 ms by default. In this case, however, the low_latency setting is used, because the slightly higher CPU load is well worth the tradeoff.

To activate this change, run the startup script once more:

~# /etc/init.d/setserial
Loading the saved-state of the serial devices... 
/dev/ttyS0 at 0x03f8 (irq = 4) is a 16550A (low_latency)
~# _

One more issue: the installer does not add anything to the /etc/rc2.d directory, so add a symlink there that points to /etc/init.d/setserial. This will ensure that, during the boot process, setserial will be run before gpsd starts:

~# ln -s /etc/init.d/setserial /etc/rc2.d/S19setserial
~# _


3. GPS daemon

The next step is to install the GPS daemon. This software will sit between the GPS device and the NTP daemon, making both the PPS signal and the NMEA 0183 data available to ntpd through a pair of shared memory (SHM) devices. It can also be used to create an interesting skyview webpage showing current GPS satellite positions.

Install these four packages:

~# apt-get install gpsd gpsd-clients libgps17 python-gps

As a result, 22 new packages will be installed, including 18 dependencies:

dbus                              1.2.1-5+lenny1           simple interprocess messaging system
dbus-x11                          1.2.1-5+lenny1           simple interprocess messaging system (X11 deps)
gpsd                              2.37-7                   GPS (Global Positioning System) daemon
gpsd-clients                      2.37-7                   Clients for the GPS daemon
lesstif2                          1:0.95.0-2.1             OSF/Motif 2.1 implementation released under LGPL
libdbus-1-3                       1.2.1-5+lenny1           simple interprocess messaging system
libdbus-glib-1-2                  0.76-1                   simple interprocess messaging system (GLib-based shared li
libexpat1                         2.0.1-4+lenny3           XML parsing C library - runtime library
libglib2.0-0                      2.16.6-3                 The GLib library of C routines
libglib2.0-data                   2.16.6-3                 Common files for GLib library
libgps17                          2.37-7                   C library for communicating with GPS devices
libice6                           2:1.0.4-1                X11 Inter-Client Exchange library
libsm6                            2:1.0.3-2                X11 Session Management library
libxaw7                           2:1.0.4-2                X11 Athena Widget library
libxmu6                           2:1.0.4-1                X11 miscellaneous utility library
libxp6                            1:1.0.0.xsf1-2           X Printing Extension (Xprint) client library
libxpm4                           1:3.5.7-1                X11 pixmap library
libxt6                            1:1.0.5-3                X11 toolkit intrinsics library
python-gps                        2.37-7                   Python interface to gpsd and testing environment
python-support                    0.8.4lenny1              automated rebuilding support for Python modules
python2.4                         2.4.6-1+lenny1           An interactive high-level object-oriented language (versio
python2.4-minimal                 2.4.6-1+lenny1           A minimal subset of the Python language (version 2.4)

Then, to ensure that gpsd will actually run, configure the daemon with the following command:

~# dpkg-reconfigure gpsd

A dialog will appear with some questions that should be answered as follows:

Start gpsd automatically on boot? Yes
Device the GPS receiver is attached to: /dev/ttyS0
Should gpsd handle attached USB GPS receivers automatically? No
Options to gpsd: -b -n

Explanation of the two options:

-b Broken-device-safety, aka read-only mode. This option prevents gpsd from writing anything to the device. In this case it is used to prevent it from shortening the pulse length of the LVC model from its default of 200 ms to a mere 40 ms.
-n Forces the clock to be updated even though no clients are active. By default, gpsd stops polling the GPS device when clients are no longer connected, and ntpd is not recognized as a client.

Afterwards, these settings are saved in /etc/default/gpsd and the daemon is started automatically.

The source code for gpsd includes a PHP script, gpsd.php, that can be used to generate a skyview webpage for the GPS. For example, see this gpsd webpage. It requires php and php-gd to run. The first time it is invoked, a file called gpsd_config.inc is created containing configuration information that should be modified accordingly.


4. Firmware reconfig

For accurate time keeping with the Garmin GPS 18 LVC, both the PPS signal and the NMEA 0183 data are necessary. This is for two different reasons. First, the PPS signal itself does not contain time and date information − this is found only in the NMEA 0183 data (along with latitude and longitude information). Second, it would be possible to synchronize the NTP daemon on the start of the NMEA 0183 data alone, except that this information is always sent 0.2 seconds too late. Therefore, both are required.

Once the GPS device has been connected to the serial port and gpsd has been started, check the configuration of the port with the stty utility:

~$ stty < /dev/ttyS0
speed 4800 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
~$ _

Among other things, this shows the speed at which gpsd is communicating with the GPS device: 4800 baud.

It should now possible to check the output of the GPS device with the gpspipe -r command − a utility that comes with the gpsd-clients package. In the beginning, the output from the device looks much like this:

$GPRMC,160516,A,5209.2521,N,00428.9913,E,000.0,140.8,270108,001.0,W*67
$GPGGA,160516,5209.2521,N,00428.9913,E,1,03,4.7,,M,46.8,M,,*65
$GPGSA,A,2,01,,,,,,17,20,,,,,4.8,4.7,*17
$GPGSV,3,1,11,01,28,046,38,04,15,301,00,11,52,152,00,12,03,357,00*7B
$GPGSV,3,2,11,13,10,201,00,14,01,035,00,17,44,274,32,20,85,276,40*74
$GPGSV,3,3,11,23,45,183,00,31,23,072,00,37,00,000,00*41
$PGRME,27.9,M,,M,31.2,M*0C
$GPGLL,5209.2521,N,00428.9913,E,160516,A*29
$GPVTG,141,T,142,M,000.0,N,0000.0,K*7D
$PGRMV,0.0,0.0,*72
$PGRMF,440,57930,270108,160516,14,5209.2521,N,00428.9913,E,A,1,0,141,\
5,1*2B
$PGRMB,,,,,,K,,,*2D
$PGRMM,WGS 84*06

This may seem fine, but the problem is that the device is only sending this information once every two seconds, as opposed to once every second as is required for ntpd. The device is simply not capable of sending its data any faster, so the objective here is to make it send less data. Apparently, the Garmin GPS 18 LVC sends this amount of information because certain features have been enabled beyond its factory defaults. Consequently, the problem can be solved simply by returning the unit to its factory defaults. To achieve this, the appropriate commands must be sent to the serial port to which the GPS device is attached. But first, start by installing one new package:

~# apt-get install tofrodos

Only this one package is installed as a result:

tofrodos                          1.7.8.debian.1-1         Converts DOS <-> Unix text files, alias tofromdos

Then create a file, called ~/send.txt, with just this single line:

$PGRMO,,4

This is the command that will return the device to its factory defaults.

Next, after saving the file it is necessary to convert it to DOS text format:

~# unix2dos ~/send.txt
~# _

Now send this commands to the serial port as follows:

~$ cat ~/send.txt > /dev/ttyS0

It is interesting to run gpspipe -r in another terminal to monitor the effects of the previous command in real time. When the command is executed, the output from the device should decrease markedly and begin repeating once every second, for example:

$GPRMC,235530,A,5209.2483,N,00428.9918,E,000.0,017.3,280108,001.0,W*65
$GPGGA,235530,5209.2483,N,00428.9918,E,1,05,2.3,,M,46.8,M,,*64
$GPGSA,A,2,08,,,15,,18,,,26,28,,,2.5,2.3,*10
$GPGSV,3,1,11,08,24,071,36,09,22,259,00,10,19,189,00,15,75,278,39*79
$GPGSV,3,2,11,17,13,120,00,18,28,311,41,19,02,009,00,22,00,335,00*7C
$GPGSV,3,3,11,26,87,203,41,28,54,077,38,43,00,000,00*41

This is considerably less information than before.


5. NTP daemon

The last software package to install is the NTP daemon: ntpd. It must be configured both to receive timing information from gpsd, as well as to provide a service to NTP clients. Start by installing its associated Debian package:

~# apt-get install ntp

Two packages are installed as a result, including one dependency:

libcap1                           1:1.10-14                support for getting/setting POSIX.1e capabilities
ntp                               1:4.2.4p4+dfsg-8lenny3   Network Time Protocol daemon and utility programs

After that, several edits to /etc/ntp.conf are required, starting with the addition of these lines:

server 0.debian.pool.ntp.org iburst dynamic
server 1.debian.pool.ntp.org iburst dynamic
server 2.debian.pool.ntp.org iburst dynamic
server 3.debian.pool.ntp.org iburst dynamic

server 127.127.28.0 minpoll 4
fudge  127.127.28.0 time1 0.183 refid NMEA
server 127.127.28.1 minpoll 4 prefer
fudge  127.127.28.1 refid PPS

These specific loopback addresses allow ntpd to access the two shared memory segments provided by gpsd. The refid names are arbitrary, but descriptive, while the value for the time1 parameter − 0.183 − is to compensate for the offset of the NMEA 0183 signal. However, other systems will likely achieve better results with a slightly different value.

Next, allow local clients to have unlimited access:

# Clients from this (example!) subnet have unlimited access,
# but only if cryptographically authenticated
#restrict 192.168.123.0  mask  255.255.255.0 notrust

restrict 192.168.1.0  mask  255.255.255.0 nomodify

This change allows all NTP clients in the entire 192.168.1.0 subnet to have unlimited access without requiring cryptographic authentication. However, because of the nomodify option they are still barred from modifying the state of the server. The network and netmask values should be modified accordingly.

Last, save the above changes and restart the NTP daemon to activate them:

~# /etc/init.d/ntp restart
Stopping NTP server: ntpd.
Starting NTP server: ntpd.
~# _


6. Positioning

The GPS broadcast signal easily penetrates less dense material, such as plastic, but not higher density materials such as brick. Therefore, for a GPS receiver to function reliably, its antenna must be positioned where it has a relatively unobstructed view of as much of the sky as possible. This is important, because if the device is not able to receive a signal from at least one GPS satellite at all times, the stability of its clock signal will suffer considerably.

To this end, the Garmin GPS 18, with its internal antenna, is waterproof and was designed to continuously withstand weather conditions in most parts of the world. In the example below, however, the the device is located indoors and fixed to the inside of a plastic skylight. In this case the original 5 meter cable needed to be extended by only a few meters.

Car windshield 
		mount Skylight
Attached to the inside of the skylight using a
car windshield mount.
GPS device attached to the skylight and featuring an improvised safety device.

The Garmin GPS receiver shown above is attached to the inside of the skylight with a simple plastic car windshield mount that works with a strong suction cup. Since the receiver has an internal (female) screw thread underneath, this was used to fix it to the windshield mount after drilling a small hole through the center of the mount's platform.

However, as an occasional failure of the suction cup is inevitable, a safety device was improvised to catch its fall and prevent any damage. In this case, the safety device consists of an old coat hanger, covered with white heat-shrink tubing for aesthetic effect, and bent into a shape like an arched fishing rod with a T-section near its base for lateral stability. The lower vertical section, meant to counter the force of a fall, extends down into the cable conduit.


7. Results

After the device has been reconfigured, positioned and connected, and all of the software has been up and running properly for a few minutes, use the following command to print a list of the peers and locally attached time sources known to the server, as well as a summary of their state. Here is an example:

~$ ntpq -p
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
-ntp0.nl.uu.net  .PPS.            1 u    4   64  377   19.293   -3.809   0.083
-ntp1.nl.uu.net  .PPS.            1 u   62   64  377   17.578   -3.404   0.240
-ntps1-0.cs.tu-b .PPS.            1 u   40   64  377   46.524    0.372   0.335
+ntps1-1.cs.tu-b .PPS.            1 u   52   64  377   46.309    0.430   0.308
xSHM(0)          .GPS.            0 l   14   16  377    0.000    9.767   2.473
*SHM(1)          .PPS.            0 l   13   16  377    0.000    0.000   0.001
~$ _

The values for delay, offset and jitter are in milliseconds. For locally attached time sources the delay is always zero, while the jitter value for the GPS measurement pulse appears to be only a few microseconds (thousandths of a millisecond). Other systems may not achieve results that are quite this accurate, but they will still be an order of magnitude better than what can be expected with a radio time signal receiver.


8. Quirks

Occasionally, things may get stuck, especially when the system boots up. This can be due to a communications problem between gpsd and the GPS device. For example, stty may show that the port speed has mysteriously changed to something other than 4800 baud, in which case it may not be enough to simply restart gpsd. A power cycle of the GPS device (in this case by momentarily removing the USB plug from its socket) followed by a gpsd restart may be the only solution. Seeing as the system is otherwise stable, a long-term solution may be to include a relay, operated through another serial port and controlled by a script that monitors the output from ntpq -p, and/or a second GPS device that ntpd can turn to in case the first one fails.


9. Further reading
  • Mills DL. 1992. RFC1305 − Network Time Protocol (Version 3) Specification, Implementation and Analysis. HTML at the Internet FAQ Archives.
  • Mills D. 1996. RFC2030 − Simple Network Time Protocol (SNTP) Version 4 for IPv4, IPv6 and OSI. HTML at the Internet FAQ Archives.
  • Mills DL. 2006. Computer Network Time Synchronization: The Network Time Protocol. CRC Press. ISBN-13 978-0849358050. 304 pp.
  • Taylor D. 2010. Adding a FreeBSD NTP server based on an GPS 18 LVC device. HTML at David & Cecilia Taylor's Web pages.

10. Other NTP solutions
  • TimeTools - manufacturer of Stratum 1 GPS NTP Time Servers and wall clocks.

11. Sources
  • GPSD Project. 1995-2010. Documentation. HTML at the GPSD Project.
  • Garmin. 2005. GPS 18 Technical Specifications. PDF at Garmin.
  • NTP Project. 2010. Documentation. HTML at the NTP Project.
  • Putten van der RJ. 2009. Synchronising to a Garmin GPS 18 LVC. HTML at Superput.


Last modified: 2017-08-02, 17:50

©2003-2020 RJ Systems. Permission is granted to copy, distribute and/or modify the
content of this page under the terms of the OpenContent License, version 1.0.