The Museum of HP Calculators

HP Articles Forum

Explore the World with HP-IL/RS-232/71B + GPS

Posted by Egan Ford on 8 Sept 2007, 3:32 p.m.

## Abstract

This article describes how to connect an NMEA compliant RS-232 GPS receiver to a 71B to find your position and to set your clock. This article does not describe why you would want to do that.

## GPS, NMEA, and RS-232

The National Marine Electronics Association (NMEA) defined a RS-232 communication standard for devices that include GPS receivers. The GPS receivers can output geospatial location, time, headings and navigation-relevant information in the form of ASCII comma-delimited message strings[1].

Example NMEA output:

```\$GPRMC,163814,A,5331.6289,N,11331.8077,W,0.0000,0.000,050907,,*35
\$GPGSA,A,3,04,23,01,31,20,25,02,16,13,,,,1.6,0.8,0.7*3E
\$PGRME,0.00,M,0.00,M,1.54,M*1E
\$GPGSV,3,1,12,04,16,291,36,23,80,285,42,06,10,034,00,01,08,108,33*74
\$GPGSV,3,2,12,31,23,064,39,20,41,192,41,25,25,244,41,02,11,327,43*7C
\$GPGSV,3,3,12,16,51,105,38,27,07,244,33,13,47,291,46,138,28,171,34*4F
\$GPGGA,163815,5331.6292,N,11331.8077,W,2,09,0.80,704.4,M,-19.783,M,,*46
```
For the purposes of this article we are only interested in the line that starts with \$GPGGA. \$GPGGA is our fix--our position at some time and is formatted:

```\$GPGGA,UTC Time,Latitude,N/S,Longitude,E/W,,,,Elevation,Units,,,,*Checksum
```

This GPS continuously streams this data out the GPS RS-232 interface. To capture this into the 71B for processing we need an RS-232 interface.

## GPS to 71B via HP-IL/RS-232

The HP 82164A is an HP-IL to RS-232 interface. This interface allows HP-IL-based hosts such as the 71B to communicate with RS-232-based devices.

The above animation illustrates a perfect world scenario. The data flows effortlessly from the GPS to the 71B. However, in our imperfect world some understanding of flow control and coordination is required to make it appear as if it was a perfect world.

The following is a crude simplistic generalization that better illustrates what really takes places as data streams from the GPS to the 71B.

1. The 71B makes a request for a line of data terminated with a linefeed (LF). The 71B can request data as lines or bytes. This is accomplished using the 71B ENTER statement. Plain text lines are obviously easier to work with and fortunately that is what NMEA has specified. When the ENTER command has received a complete line it will instruct the HP-IL talker (the HP-IL/RS-232 interface in this case) to stop sending.

2. With communications halted the 71B can process data obtained from ENTER without loss of additional data.

3. The HP-IL halt has a ripple effect. The HP-IL/RS-232 interface will need to capture in its 109 byte receive buffer the GPS stream to prevent data loss while the 71B processes the current data set.

4. The HP-IL RS-232 receive buffer has a user definable threshold that is less than the size of its 109 byte receive buffer. When the threshold is exceeded a halt transmission is sent to the GPS. The threshold (default 24 bytes) setting depends on how fast the RS-232 transmitter (GPS) responds to a halt transmission command (XOFF in this case). E.g. my GPS is slow to respond, so I had to reduce this threshold to 12 bytes. The buffer needs room to continue to capture data while the halt transmission command is being sent and processed. If the threshold is too large we run the risk of an overrun and data loss. Slower GPS devices will need a smaller threshold.

5. When the GPS is instructed to halt transmitting data it starts to fill up it's transmit buffer. Not shown in this animation is what happens when the GPS buffer fills up. The GPS cannot request that the satellites stop transmitting. The cached data must be discarded to make room for new data. The non-stop flow of data is a challenge with collecting and processing GPS output. Most data communications require that no data be lost, flow control can halt traffic for long periods of time while the host processes data. Often lost data can be requested and resent. This is not the case with GPS, the data is not cached, it is temporal and has less value the older it is.

6. Fortunately the circa 1985 71B can process the data faster than the data can be collected and sent by the GPS. When the 71B requests the next line of data, the HP-IL/RS-232 interface flushes the buffered data.

7. When the HP-IL/RS-232 receive buffer falls below the threshold it issues a start sending message (XON in this case) to the GPS. The GPS rapidly flushes its buffer and the cycle starts all over again with no data loss.

This works for three important reasons:

1. The GPS collects and produces data slower than its RS-232 transmit rate of 4800 bit-per-second. This allows buffers to be flushed without loss while collecting more data.

2. The 71B is fast enough to process the received data before the GPS buffer fill up. We are partially responsibility for this by keeping our data processing logic small. If our code was too complex it may take longer to run than the GPS buffer to fill up and data will always be lost. In situations like this it may be better to not process the data, but just capture it into the relatively large buffers of 71B RAM and then process later. The data will not be as fresh, but is still as accurate since GPS transaction are time stamped using a time source independent of the 71B. E.g. say you wanted to track movement. The logic to process movement data real-time could be time consuming, it may be better to collect all the data, and then when movement has stopped process the data.

3. Buffers. They exist in all asynchronous digital communication devices. Without them as programmers we would have write very tight time sensitive code or have a way to request lost data. The temporal nature of GPS receivers prevents this.

## Equipment Setup

Use the following diagram to assemble your 71B GPS data receiver.

Obviously not something to pack on your next camping trip. Of course when smash your GPS receiver screen, you'll wish you had a way to obtain a fix.

## Source Code

Lines 10-20: Initialization. D0 (0 or 1), if set to 1 every line of text received from the GPS will be displayed. This can slow down the processing of the data, leading to buffer overruns. U (-12 to 12) is your UTC offset. D (0 or 1), DST (Day Light Savings). A (0 or 1), display elevation, and E\$ (M or FT) is the elevation units.
```10 DESTROY ALL @ OPTION BASE 1 @ STD
20 D0=0 @ U=-7 @ D=1 @ A=1 @ E\$="FT" @ DIM G\$[100]
```
Lines 30-70: HP82164A initialization. The most important settings are in bold. The 12 is the receiver buffer block size in bytes (24 is the default). When 12 bytes have been received, the GPS is sent an XOFF and does not resume until the buffer has been cleared by the 71B. If you experience corrupted data decrease this number. SBC sets the 4800 BPS rate, and LI5 disables DTR control. If LI5 is not set the data will be duplicated (unexpected buggy behavior). FYI, the HP82164A default settings are 9600 BPS 8N1 XON/XOFF.
```30 X=DEVADDR("HP82164A")
40 SEND UNT UNL LISTEN X MTA
50 SEND DDL 2 DATA 13,10,13,10,17,19,5,6,106,17,12,17
60 SEND UNT UNL
70 REMOTE @ OUTPUT :HP82164A ;"SBC;LI5" @ LOCAL
```
Lines 80-140: Data collection loop. Lines terminated with LF are collected one at a time, if they do not start with \$GPGGA, then get the next line, else verify that the checksum is a match, if the match fails get the next line. Keep this loop tight to avoid buffer overruns.
```80 ENTER :HP82164A ;G\$
90 IF D0=1 THEN DELAY 0,0 @ DISP G\$
100 IF G\$[1,6]="\$GPGGA" THEN 120
110 GOTO 80
120 K=LEN(G\$)-2
130 IF G\$[K,K]<>"*" THEN 80
140 CALL CHECKSUM(G\$,K\$) @ IF G\$[K+1,K+2]<>K\$ THEN 80
```
Lines 150-190 displays the time and synchronizes the 71B clock to the GPS clock (accurate within a second). If there is no valid fix it jumps back to the data collection loop.
```150 G\$=G\$[8,LEN(G\$)]
160 IF G\$[1,1]="," THEN DISP "TRACKING SATELLITES" @ WAIT 5 @ GOTO 80
170 H=VAL(G\$[1,2])+U+D @ IF H<0 THEN H=H+24
180 M=VAL(G\$[3,4]) @ S=VAL(G\$[5,6])
190 CALL SYNCTIME(H,M,S)
```
Lines 200-270 extracts and displays your position.
```200 L0=VAL(G\$[8,9]) @ L1=VAL(G\$[10,11]) @ L2=VAL(G\$[12,16])*60
210 L3=VAL(G\$[20,22]) @ L4=VAL(G\$[23,24]) @ L5=VAL(G\$[25,29])*60
220 DISP USING "#,'T: ',ZZ,':',ZZ,':',ZZ,' L: '";H;M;S
230 DISP USING "#,K,' ',K";L0;L1 @ DISP "'";STR\$(L2);'" ';G\$[18,18];" ";
240 DISP USING "#,K,' ',K";L3;L4 @ DISP "'";STR\$(L5);'" ';G\$[31,31];
250 IF A=1 THEN CALL ALTITUDE(G\$,E\$)
260 DISP
270 END
```
Calculate checksum subroutine. XOR the numeric value of each character between the \$ and the * and return a 2 digit hex checksum.
```280 SUB CHECKSUM(S\$,K\$)
290 K0=NUM(S\$[2,2])
300 FOR I=3 TO LEN(S\$)-3 @ K0=BINEOR(K0,NUM(S\$[I,I])) @ NEXT I
310 K\$=DTH\$(K0)[4,5]
320 END SUB
```
Synchronize time subroutines. This routine builds a SETTIME compliant string and calls SETTIME.
```330 SUB SYNCTIME(H,M,S)
340 T\$=""
350 CALL PAD(H,N\$) @ T\$=N\$&":"
360 CALL PAD(M,N\$) @ T\$=T\$&N\$&":"
370 CALL PAD(S,N\$) @ T\$=T\$&N\$
380 SETTIME T\$
390 END SUB
400 SUB PAD(N,N\$)
410 N\$=STR\$(N) @ IF N<10 THEN N\$="0"&N\$
420 END SUB
```
Elevation subroutine.
```430 SUB ALTITUDE(S\$,E\$)
440 C0=0 @ A0=0 @ A1=0
450 FOR I=1 TO LEN(S\$)
460 IF S\$[I,I]="," THEN C0=C0+1
470 IF C0=8 AND A0=0 THEN A0=I+1
480 IF C0=9 AND A1=0 THEN A1=I-1
490 NEXT I
500 A=VAL(S\$[A0,A1])
510 IF S\$[A1+2,A1+2]="M" AND E\$="FT" THEN A=INT(A*3.281+.5)
520 DISP " A:";A;E\$;
530 END SUB
```

## Example Output (D0 = 1)

```\$GPRMC,163814,A,5331.6289,N,11331.8077,W,0.0000,0.000,050907,,*35
\$GPGSA,A,3,04,23,01,31,20,25,02,16,13,,,,1.6,0.8,0.7*3E
\$PGRME,0.00,M,0.00,M,1.54,M*1E
\$GPGSV,3,1,12,04,16,291,36,23,80,285,42,06,10,034,00,01,08,108,33*74
\$GPGSV,3,2,12,31,23,064,39,20,41,192,41,25,25,244,41,02,11,327,43*7C
\$GPGSV,3,3,12,16,51,105,38,27,07,244,33,13,47,291,46,138,28,171,34*4F
\$GPGGA,163815,5331.6292,N,11331.8077,W,2,09,0.80,704.4,M,-19.783,M,,*46
T: 10:38:15 L: 53 31'37.752" N 113 31'48.462" W A: 2311 FT
```
Before you come knocking on my door or try looking in my backyard from Google Earth[2] please note that this is not output from my GPS, but output that I cut and pasted from a GPSd server in Canada. I am sure they would love a visit from you. I like visitors too--the invited kind.

## Testing

As you can imagine dragging a 71B + HP-IL/RS-232 w/ power + GPS outside may not be practical. Fortunately for me, my GPS works indoors. However, if you are not so lucky and need to test GPS software, you can get real data from a number of freely accessible GPSd[3] servers on the Internet--Google for gpsd (e.g. http://gpsd.mainframe.cx/).

Once you have obtained a set of data (10 or so lines should be fine), configure your PC serial terminal software (e.g. HyperTerminal) with 4800 BPS, 8N1, XON/XOFF, and terminate lines with LF (Hint: HyperTerminal/Properties/Settings/ASCII Setup/Send line ends with line feeds). Then cut/paste the output.

## Development Environment

My development environment consists of a 200 Mhz Pentium Overdrive-based Red Hat 9 Linux workstation with 32MB of RAM and an HP 82973A HP-IL ISA card. I use the registered version of EMU71[4]+DOSEMU to emulate an HP-IL equipped 71B. Exploiting Linux allows me remote access from my notebook to develop and test 71B/HP-IL applications quickly and easily. After development is complete it takes only a few seconds via HP-IL to transfer the application to a physical 71B for final verification and timing. This workstation can also extend the functionality of a physical 71B by emulating an HP-IL display, printer, and floppy.

## Summary

Using the 71B to process GPS data would have been a hit in 1985. Today it is of no practical use other than a learning aid, setting your 71B clock, and some mild entertainment.

## References

Edited: 9 Sept 2007, 12:34 p.m.

 Password: