GPS SPEEDOMETER

I am building a speedometer for my lakester that I hope will give me reasonably accurate speed data during a run at Bonneville. In the past, I have tried to read the tachometer as I pass through the last mile marker to get some idea of my speed. Between the car vibrating, the wind buffeting my helmet, and the general anxiety of keeping the car straight at speed, I have been pretty unsuccessful. Oh, I could say it was doing maybe 7700 rpm, but it could have been almost anywhere betwen 7500 and 8000. It was just a guess.

By a process of absolute serendipity, I ended up with a small computer card with embedded BASIC and lots of I/O options that just begged to be put to some practical use. Web searches uncovered a GPS module that offers a speed output and a display card with large, bright LED's. Put them together and I just might have something that I can actually see at speed.

The computer card -- really, it's more like a 40-pin DIP chip -- is from EZsbc. The one I got is the EZsbc1. Uses an LPC2138 ARM-7 processor from NXP. It has a version of BASIC installed as the O/S. Programming it requires a PC running a terminal program (I used HyperTerm) and a USB port with a driver program. There is a download page on their website that explains how to do this and it is simpler than it appears (especially if you use HyperTerm and ignore all the setup info on TerraTerm). It should be possible to program this card from a Mac, as well. I hope to try this one of these days.

This card/chip has a lot of I/O pins, including dedicated SPI bus, TTL-level serial bus, I2C bus, and ADC inputs. A number of the pins can be used as PWM outputs, which seems to be quite the thing among the robot crowd for driving small motors.

I ended up ordering The Ultimate GPS breakout from Adafruit. This module has a GPS on a chip, with provision for using either the antenna on the chip or an external antenna, and a simple ASCII interface using TTL-level serial I/O.

The display is a 4-digit 1.2" LED module mounted on a backpack card with the driver chip and an I2C I/O. This card is produced by Adafruit as well but I bought mine from InterTex Electronics in San Antonio. This rascal proved to be rather difficult to interface to the EZsbc. Hard to decide who to blame...so I won't bother. But here's what happened.

Adafruit supplies C libraries for any of their products that are intended to be interfaced to a computer. The libraries are specific to the Arduino and the Raspberry Pi computer cards. They offer comprehensive instructions for assembling any cards that are kits and for hooking them up and running sample code. If, however, you are going to use something other than one of these computer cards to drive their cards, you are pretty much left to figure things out on your own.

In the case of the LED display, I managed eventually to find enough examples of driver code and explanations of how various folks got this card to work, that I came up with a general idea of how to manage this chip. The chip powers up in Standby mode, which means the LED's are all off. To start the chip driving the LED segments, you have to send it three commands via the I2C bus. Each command must be preceded by the card address -- which is 0xe0, no matter what Adafruit says in their instructions. (Yes, the chip 'address' is 0x70 but this is a 7-bit address and to get the chip to actually write the address internally so that the following command is processed, you have to left-shift the address and add a zero to form an 8-bit value, which happens to be 0xe0.) Thus, a triplet of 2-byte commands must be sent to the card. I sent them in this order:

0xe0 0x21 (enables the on-board oscillator)
0xe0 0xef (sets the brightness to max
0xe0 0x81 (sets the display to ON

It took me several days to get this right. Not that the commands were hard to figure out (everyone mentioned these) but because I hard-headedly refused to believe the scope display of the data on the I2C line. I was using the EZsbc BASIC command

I2CWR(,,,)

to send the commands. In particular, I would program

c$=chr$(0x21)
i2cwr(0xe0,0,c$,1)

which, it turns out, sends the bytes 0xe0, 0x00, and 0x21 to the card. When I finally realized that I was sending THREE bytes to the display chip, I changed the code to try

c$="x"
i2cwr(0xe0,0x21,c$,0)

and everything began working. The rest was pretty simple. I wrote some test code (see the downloads page) that lets me enter a number, parses out the digits, and displays them on the LEDs. The only 'trick' to this code is realizing that 1) you have to send the segment codes rather than the numbers to the chip and 2) the digits are located at addresses 0, 2, 6, and 8. The colons and decimal points are at address 4. The code listing should be self-explanatory. If you can't read BASIC then you're probably a C-programmer and Adafruit has you covered already