GPS for NTP Time Sync - Success with Voyage and ALIX

| |

Following up my last blog post, I have finally got a Garmin GPS18/USB unit from my friend working in Asia Link to test for time sync for NTP. Right now, I have an ALIX board running Voyage Linux 0.4. It is an ideal platform to test the kernel support in Voyage with the USB-based GPS device.

Voyage kernel immediately recognizes GPS18/USB device at boot, it connects to /dev/ttyUSB0 according to dmesg:

garmin_gps 1-3:1.0: Garmin GPS usb/tty converter detected
usb 1-3: Garmin GPS usb/tty converter now attached to ttyUSB0
usbcore: registered new interface driver garmin_gps
drivers/usb/serial/garmin_gps.c: garmin gps driver v0.28

First, install the required Debian package for gps and ntp:

apt-get install gpsd gpsd-clients ntp ntp-simple
gpsd-clients package provides client utility programs to interact with gpsd for getting GPS data from the device. Since the client program includes xgps that requires X libraries, around 30MB will be consumed after you install them.

Next, modify /etc/default/gpsd and add the daemon and device options:

DAEMON_OPTS="-n -D2"
DEVICES="/dev/ttyUSB0"
Now, restart the daemon or you may want to run in foreground for debug purpose:
### restart gpsd daemon
voyage:~#/etc/init.d/gpsd restart

### Run foreground with debug level 4
voyage:~#gpsd -N -D 4 -n /dev/ttyUSB0

Running cgps utility, I can obtain the following (You will know where I am by interpreting the Lat/Lon). cgps runs on serial or console terminal and connects to local port 2947, which is the default port that gpsd listened to for serving queries from client programs:

# cgps localhost 2947

                               CGPS Test Client
+-------------------------------------------++---------------------------------+
|    Time:       2007-07-12T14:41:50.00Z    ||PRN:   Elev:  Azim:  SNR:  Used: |
|    Latitude:    22.350774 N               ||  20    32    127    00      N   |
|    Longitude:  114.060063 E               ||  28    44    335    94      Y   |
|    Altitude:   n/a                        ||  25    33    189    00      N   |
|    Speed:      0.1 mph                    ||   4    07    220    00      N   |
|    Heading:    127.1 degrees              ||   8    58    252    94      Y   |
|    Climb:      n/a                        ||  11    56    034    00      N   |
|                                           ||  17    29    290    92      Y   |
|    Horizontal Err:  +/- 350 ft            ||  27    48    213    00      N   |
|    Vertical Err:    +/- 401 ft            ||  19    13    057    00      N   |
|    Course Err:      +/- 179.1 deg         ||                                 |
|    Speed Err:       +/- 478 mph           ||                                 |
|                                           ||                                 |
+-------------------------------------------++---------------------------------+
+-------------------------------------------++---------------------------------+
|Command:                                   ||Status:  2D FIX (60 secs)        |
+-------------------------------------------++---------------------------------+
GPSD,O=20 1184251310.00 0.005 22.350775 114.060064   96.65 106.95 122.49 127.120
5    0.033  0.000 179.0826 213.90        ? 2
GPSD,Y=20 ? 9:20 32 127 0 0:28 44 335 94 1:25 33 189 0 0:4 7 220 0 0:8 58 252 94
 1:11 56 34 0 0:17 29 290 92 1:27 48 213 0 0:19 13 57 0 0:

If the GPS sensors does not detect enough satellites, the status will show "NO FIX". Since GPS18/USB is hanged near the window, it does not always get good signals. I found that the Status will change to "2D FIX" only when gpsd has found 3 satellites with good signal-to-noise ratio (SNR).

There are two more native way to interact with gpsd for retrieving GPS data - by telnet or gpspipe. Since gpsd listen to port 2947, you can just "telnet" to it. Once connect, type 'p' or 'd' followed by return will query for position and time respectively. More information could be found from gpsd project site.

voyage:~# telnet localhost 2947
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
p
GPSD,P=22.208111 114.038674
d
GPSD,D=2007-07-12T15:48:47.00Z
^]
telnet> quit
Connection closed.
Using gpspipe, you can dump the NMEA sentences sent from gpsd.
voyage:~# gpspipe -r localhost 2947
$GPGSV,3,1,10,20,18,040,00,28,49,169,00,09,02,289,00,04,53,307,93*78
$GPGSV,3,2,10,08,01,178,00,02,28,270,00,23,13,088,00,17,57,033,00*74
$GPGSV,3,3,10,10,06,209,00,13,15,117,00*75
$GPRMC,173728,V,2220.8118,N,11403.8665,E,0.0000,0.000,120707,,*39
$GPGSV,3,1,10,20,18,040,00,28,49,169,00,09,02,289,00,04,53,307,93*78
$GPGSV,3,2,10,08,01,178,00,02,28,270,00,23,13,088,00,17,57,033,00*74
$GPGSV,3,3,10,10,06,209,00,13,15,117,00*75
$GPRMC,173729,V,2220.8111,N,11403.8674,E,0.0000,0.000,120707,,*31
The Garmin GPS18 technical spec. contains the information of NMEA 0183 sentence format.

Here comes to the main course - NTP time sync from GPS. Follows the instruction from gpsd project site, I modify /etc/ntp.conf with the followings.

server 127.127.28.0 minpoll 4 maxpoll 4
fudge 127.127.28.0 time1 0.035 refid GPS

server 127.127.28.1 minpoll 4 maxpoll 4 prefer
fudge 127.127.28.1 refid GPS1
Forget about GPS1 at the moment, GPS1 is for PPS-capable device and it seems that GPS18/USB is not. Now, check with "ntpq -p"
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
*SHM(0)          .GPS.            0 l    9   16  377    0.000   43.119   5.442
 SHM(1)          .GPS1.           0 l    -   16    0    0.000    0.000   0.002
So, you should see ntp sync is now working. If gpsd did not get enough satellite signals you can see that "reach" value dropped to less than 377, or even 0 for no signal at all.