< Day Day Up > |
Listening to a GPS from a Linux box is as simple as listening to any serial device: plug it in, make sure the driver (if any) is loaded, open the port, and read the stream. We tried connecting both the PocketMap CF GPS (using a CF-to-PCMCIA adapter) and the Deluo USB GPS. The PocketMap GPS was detected automatically as a serial port; we needed to load the Prolific 2303 USB/Serial module ( modprobe pl2303 ) for the Deluo GPS to be recognized (it appeared on /dev/ttyUSB0 , as did the Nokia 6200 described in Chapter 9). Most GPS devices use a format called NMEA 0183; however, many of them include proprietary extensions. The NMEA standard specifies a transport of RS-232 at 4,800 kbps, 8 data bits, 1 stop bit, and no parity, but some devices support higher speeds. The Deluo GPS that we used sends standard NMEA sentences in the sequence GPGGA-GPGSA-GPGSV-GPRMC. Each sentence is a line of comma-separated text that begins with $ TYPE (where TYPE is the NMEA 0183 sentence type) and ends with a checksum value, as shown in Example 10-1. Example 10-1. Sample output from the Deluo GPS$GPGGA,071110.000,3242.8536,N,11709.7626,W,1,05,01.5,00104.2,M,-34.0,M,,*50 $GPGSA,A,3,22,16,,14,20,,,,,25,,,02.5,01.5,02.1*05 $GPGSV,3,1,10,22,11,117,35,16,13,151,35,11,44,256,,14,26,056,35*78 $GPGSV,3,2,10,20,32,316,34,01,22,266,,30,09,052,,02,07,172,*76 $GPGSV,3,3,10,23,30,110,33,25,70,061,39*77 $GPRMC,071110.000,A,3242.8536,N,11709.7626,W,000.0,000.0,100204,013.0,E*7D The checksum is a two-digit hexadecimal value that's created by XORing the ASCII values of each character in the sentence, except for the leading $ and * that precede the checksum itself. For example, the Perl code shown in Example 10-2 verifies the checksum of each line in Example 10-1. Example 10-2. Verifying NMEA 0183 sentence checksums#!/usr/bin/perl -w # # gpscksum.pl--verify each NMEA 0183 sentence in standard input # use strict; my $count=1; while (<>) { my ($string, $cksum); if (/^$(.*)\*([0-9A-Fa-f][0-9A-Fa-f])/) { $string = ; # everything between leading $ and checksum $cksum = ; # hex checksum from NMEA sentence } else { die "Malformed NMEA 0183 sentence: $_\n"; } # Calculate the checksum my $my_cksum; for (my $i = 0; $i < length ($string); $i++) { $my_cksum ^= ord(substr($string, $i, 1)) } # Compare the checksums if ($my_cksum != hex($cksum)) { print "Checksum for line $count doesn't match: ", $my_cksum, "!=", hex($cksum), "\n"; } $count++; } The following tables describe the NMEA 0183 sentences listed in Example 10-1. Items in the Example column are drawn directly from Example 10-1. Table 10-1 describes the elements of the GPGGA sentence (GPS fix data). This sentence gives you information about the current position fix. Table 10-1. GPGGA sentence
Table 10-2 describes the GPGSA (active satellites) sentence. This sentence summarizes information about the satellites used to determine your current fix. Table 10-2. GPGSA sentence
Table 10-3 describes the GPGSV (satellites in view) sentence, which may appear multiple times. This sentence provides detailed information about each satellite, describing up to four satellites per line. Table 10-3. GPGSV sentence
Table 10-4 describes the GPRMC (transit information) sentence, which provides navigational data such as ground speed and course traveled. Table 10-4. GPRMC Sentence
10.4.1 References
10.4.2 GPSdGPSd listens to a GPS receiver and republishes the GPS information on the network in an easy-to-read format. It's included with GpsDrive, described later in this chapter, but you can also download it and install it yourself from the GPSd home page at http://www.pygps.org/gpsd/gpsd.html. To launch GPSd, specify the serial port with -p and ( optionally ) the speed with -s . If you use the -D option to specify a debugging level above 1, GPSd will stay in the foreground and display debugging info (if you are using an RS-232 connection for your GPS, the port will be a standard serial port such as /dev/ttys0 ): $ sudo gpsd -D9 -p /dev/ttyUSB0 -s 4800 command line options: debug level: 9 gps device name: /dev/ttyUSB0 gps device speed: 12 gpsd port: 2947 latitude: 3600.000N longitude: 12300.000W It doesn't start reading from the GPS until it gets a connection from a client. The simplest way to connect is via telnet to port 2947. GPSd understands several simple commands followed by a carriage return, as shown in Table 10-5. Table 10-5. Commands supported by GPSd
The first time you ask for latitude and longitude after launching GPSd, you might not get a valid result (and it may take a while to get a fix anyhow). But on subsequent requests , you should get valid data: bjepson@debian:~$ telnet localhost 2947 Trying 127.0.0.1... Connected to debian. Escape character is '^]'. p GPSD,P=0.000000 0.000000 p GPSD,P=32.714227 -117.162708 Here's a sample session showing some of the other commands: bjepson@debian:~$ telnet localhost 2947 Trying 127.0.0.1... Connected to debian. Escape character is '^]'. d GPSD,D=02/10/2004 07:11:14 a GPSD,A=103.500000 v GPSD,V=0.000000 r GPSD,R=1 $GPGSA,A,3,22,16,,14,20,,,,,25,,,02.5,01.5,02.1*05 $GPGSV,3,1,10,22,11,117,36,16,13,151,35,11,44,256,,14,26,056,36*78 $GPGSV,3,2,10,20,32,316,30,01,22,266,,30,09,052,,02,07,172,*72 $GPGSV,3,3,10,23,30,110,35,25,70,061,39*71 $GPRMC,071119.000,A,3242.8539,N,11709.7626,W,000.0,000.0,100204,013.0,E*7B r $GPGGA,071120.000,3242.8539,N,11709.7626,W,1,05,01.5,00103.1,M,-34.0,M,,*58 $GPGSA,A,3,22,16,,14,20,,,,,25,,,02.5,01.5,02.1*05 GPSD,R=0 But to really have fun with GPSd, you can use GPSd-aware applications such as Kismet and GpsDrive, described in the following sections. |
< Day Day Up > |