Synchronising to a Garmin GPS 18 LVC

You need both the NMEA 0183 data and PPS for accurate timekeeping.
Only the Garmin GPS 18 LVC and GPS 18 LVC-5m produce a PPS signal. The GPS 18-5 Hz produces 5 pulses per second.
These receivers appear to be no longer available. The GPS 18x LVC 5m appears to be simular.

Connecting the Garmin to a PC

The transmitted data from the Garmin is connected to the received data from the PC and vv. The PPS output is connected to the DCD pin.
Some people power the Garmin from the USB port. The USB data wires (green and white) are not used.
The black wires are connected to the RS232 ground pin.

GarminCableRS2329P25PUSBCable
+5VRed1Red
GNDBlackGND574Black
GNDBlackGND574
TXDWhiteRXD23
RXDGreenTXD32
PPSYellowDCD18
Garmin           9P 25P  USB

Red    ---------         Red

Black  ----*----         Black
           |
Black  ----*----  5  7

White  ---------  2  3

Green  ---------  3  2

Yellow ---------  1  8

Inside the cable there is a 3rd black wire and a shield. They seem to be connected to the other black wires. I did not connect the 3rd black wire, but I did connect the shield to the RS232 shield via a 47 nF capacitor. The USB shield is directly connected to the RS232 shield. I used a 25 pins connector connected to a RS232 tester.
The Garmin output voltage swings between 0 and +5 Volts, so the CD and RD LEDs will flash red but not green.

Configuring the Garmin with Minicom

If connected directly to Minicom, the Garmin appears to be online once per second. This is because the PPS is tied to DCD.
The circuit below can be used to avoid line status confusion;

Garmin		Minicom

Male    	Female
		9P	25P

RXD-----RXD	2	 3

TXD-----TXD	3	 2

GND-----GND	5	 7

      +-DCD	1	 8
      |
      *-DTR	4	20
      |
      +-DSR	6	 6

      +-CTS	7	 5
      |
      +-RTS	8	 4

SH------SH

Start Minicom with '-o' to avoid sending an init string. Exit Minicom with 'Ctrl-A,Z,Q' instead of 'X' to avoid a reset.

According to the Garmin documentation (687 kB; SLOW!) these sentences are enabled by default;

SentenceOutput by Default?Maximum Characters
GPRMCY74
GPGGAY82
GPGSAY66
GPGSVY (PC and LVC only)70
PGRMEY (PC and LVC only)35
GPGLLN44
GPVTGY (18-5Hz only)42
PGRMVN32
PGRMFN82
PGRMBY (PC and LVC only)40
PGRMTN Once per minute50

Sending the following string will restore these defaults;

 $PGRMO,,4

In order to avoid typos I send this string as a file (Ctrl-A,Z,Y).
As it turns out, the PGRMT IS enabled by default.
It takes about 0.8 seconds to send these sentences at 4800 bps. With all sentences enabled it takes longer then one second. Which means that the time is available only once per TWO seconds.

Configuring NTPD

The entry for a refclock in ntp.conf is;

 server 127.127.Type.Unit_Number
TypeDescriptionIdent
20Generic NMEA GPS ReceiverGPS_NMEA
22PPS Clock DisciplinePPS
28Shared Memory DriverSHM

PPS only works with a PPS enabled kernel. This applies to both the GPS_NMEA and PPS driver; If your kernel supports PPS, the GPS_NMEA driver can take care of PPS to. Furthermore, the desired clock has to be compiled into NTPD.
If you want to use PPS with a kernel without PPS support, you need to use a Shared Memory Driver.

SHM

The setup below uses a shared memory driver for PPS and a GPS_NMEA driver for the time. This means that you have to split the cable in two; one port gets all signals, the other just PPS and GND.
The Garmin is a bit late, so I added a 185 ms time1 fudge;

 server 127.127.20.0
 fudge  127.127.20.0 time1 0.185
 server 127.127.28.0 minpoll 4 prefer
 fudge  127.127.28.0 refid PPS

The GPS_NMEA driver wants a symlink in /dev/ telling it which is the source of the time. EG ttyS1;

 gps0 -> ttyS1

I created a file '77-local.rules' in '/etc/udev/rules.d/' for this purpose. It contains the following line;

 KERNEL=="ttyS1" SYMLINK+="gps0"

Replace 'ttyS1' with the tty you use.

A remote source, such as a remote GPSD, can also be used;

 gps0 -> 192.168.1.5:2947

David J. Schwartz's SHM driver (shm_linux_clock.c) reads data from ttyS0 and feeds it to the NTPD's shared memory. There is also a version (shm_splc.c) modified by Steven Bjork which supports parallel ports. And a newer version (shmpps.tar) by Philip M. White. You need to start this driver when the clock within 25 ms accurate.

Wheezy

Use of GPS_NMEA is problematic with Debian Wheezy, so I disabled it in ntp.conf.

GPSD

Alternatively you can use GPSD as a time source for NTPD. This only works properly with a 0.2 s PPS. GPSD however resets this to 0.1 s. To avoid this tell GPSD not to send anything to the Garmin with the '-b' option;
/etc/default/gpsd;

 START_DAEMON="true"
 DAEMON_OPTS="-b -n"
 DEVICES="/dev/ttyS0"
 USBAUTO="false"

The following lines in ntp.conf tell NTPD to use GPSD as a time source;

 server 127.127.28.0 minpoll 4
 fudge 127.127.28.0 time1 0.178 refid GPSa
 server 127.127.28.1 minpoll 4 prefer
 fudge 127.127.28.1 refid PPSa

Setserial

I added 'low_latency' to /var/lib/setserial/autoserial.conf to make things more accurate (ttyS0 is used for PPS);

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

Clients

If you run an acurate timeserver on yout LAN, you may want to reduce the poll interval on the clients a bit;

 server ntp.example.org iburst minpoll 6 maxpoll 7

'iburst' makes NTPD start with a poll interval of one second.
'minpoll 6 maxpoll 7': Start with one poll per 64 seconds and the gradually move to one poll per 128 seconds.