Jorj's home page: Technophilia

the 2000 Bike Trip laptop replacement

The 1999 Bike Trip was a big success: not only did I survive 333 miles of biking, but my Toshiba Libretto (laptop), GPS, black and white parallel port QuickCam, and CDPD modem survived being carted along for the ride. My biggest fear on the trip was that I would kill the hard drive in the Libretto (since it had to be spinning at least some of the time while the laptop was snapping pictures, figuring out our GPS position, and sending it all back to home base). I decided then that, while my laptop did survive, it wouldn't be wise to tempt fate a second time.

For my 2000 bike trip, I'm building a small circuit based on a PIC microcontroller which will do 90% of what the laptop did in 1999. The circuit will talk to the GPS, figure out where we are, dial out on my cell phone (which replaces the CDPD modem from last year), tell the server on the other end where I am (or was), connect to the QuickCam, take a picture and send it while connected.

Initial concept design

The first step of this project was to decide which microcontroller to use. I decided on a PIC because I have some from previous projects: three 16C84s (two 4MHz and one 10MHz) from an internet camera controller which I never finished, and two 17C43s (33MHz) from an RC5 encryption cracker which some friends and I built. I wanted to use the 16C84 to keep the power consumption low and footprint as small as possible, but it just doesn't have enough I/O pins: I need two for serial (to talk to the phone), one to switch the serial line to the GPS, and 17 for the parallel port. For simplicity's sake, I went with the 17C43 instead; it's probably overkill, but it's got lots of I/O pins, and has an integrated UART to simplify the RS232 programming.

Phase one: QuickCam picture to serial port (completed)

The next step was to make a PIC microcontroller talk to the QuickCam. It took about a week, but the resulting circuit (pictured below) works. (If I had been more careful soldering together the parallel port, I would have had this working in about two days.) Here is the phase one source code for anyone interested. This is the perl script that does the decoding and turns it back into a picture (PPM format).

The pictures from the QuickCam (also below) are a little streaked, probably because of crosstalk on the non-shielded wires (or across the breadboard). I'm hoping that this will go away when I move the project to its final circuit board.

Stage 1 circuit: QuickCam

The wires coming off of the upper-left corner of the protoboard go to a parallel port, which the QuickCam is connected to. The wires that run off to the upper-right supply power (+5v and GND) from an external power supply. The large IC on the left is a PIC 17C43 microcontroller; to its right is a bank of LEDs (so that I can tell what it's doing). To the right of that is the oscillator (33MHz). At the bottom are a reset button and an LTC1318CN (RS232/422/Appletalk interface), which translates the signals from the PIC into levels that normal serial devices can understand (and vice-versa, eventually).

First quickcam picture Second quickcam picture

These two pictures are the first two that really worked. More pictures are available here. As I mentioned above, they're a little streaked, but I hope to fix that later. The important thing is that the protocol is working properly: I tell the camera what to do, and it does it. Right now, the picture is just spit out of the serial port, which a PC then captures and translates into a PPM file, which I then convert into a JPG. This is the same sequence that I'll go through in the final circuit: at 9600 baud, it takes about 40 seconds for these pictures to transfer, which is a perfectly acceptable length of time.

Phase two: improving picture quality (completed)

Now that the camera takes pictures, I needed to modify the software to be able to determine the best brightness for a picture. On the 1999 trip, I had a perl script which kept taking pictures at various brightnesses until it found a level that generated pictures that were considered "good enough". Also, the QuickCam is capable of taking three different sizes of pictures at two bit depths; I'd like to have it send pictures at 6 bits per pixel (the pictures above are at 4 bpp) and 320x240 (the same size as above), but also have (physical) switches to change this if I determine that they're taking too long on the trip for some reason. Since I won't have the laptop (and other gear needed to program a PIC) along, I'll need to have as much flexibility with the hardware as possible.

For portability during development, I've moved the circuit to a smaller breadboard. On the right is the PIC; next to it is the oscillator, then a MAX232, some DIP switches, and the reset button.

The schematic has changed slightly. I removed the LEDs on the parallel status port (except S5, which has a high-current red LED just to see when there's traffic). there are now switches on PORT A which control the scan mode (pin 1 controls 4 or 6 bit scanning; pin 2 sets the picture to 160x120 instead of 320x240, and pin 3 sets the picture to 80x60 instead of 320x240). Port E has two LEDs that show activity: pin 1 turns on when the "final" picture is being taken, and pin 2 changes state when a brightness-checking picture is taken. Also, the LTC1318 suffered an untimely death (probably because I mis-wired it and blew it up). I've replaced it with a MAX232, which is more specific (it's an RS232 driver, where the LTC1318 was an RS232, RS422, and AppleTalk driver).

And lastly, the source code... this is the PIC assembly code, and this is the perl script that decodes the pictures afterward. (Note: the perl script doesn't strip off the leading garbage spit out the serial port. Everything up to and including the last "SCAN:" should be removed first.)

Completely off-topic: that sneaky wife of mine took some pictures of me while I was finishing the code. (one, two.) The monitor on the left is our "television" (a Win98 box with an ATI All-In-Wonder 128). The monitor on the right is attached to my Toshiba Libretto 100CT. The QuickCam on top of the TV monitor is attached to the circuit on the table.

Phase three: GPSness

Once the camera is taking pictures that I consider acceptable, I'll need to connect the PIC to a GPS and have it snatch data from it. I was planning to use a low-power relay to switch the serial line temporarily to the GPS instead of the host computer (which will eventually become the modem). I've changed plans, because I forgot that my setup last year sent tracking data from the GPS once every two hours. The tracking data is rather large (bordering on gargantuan), so I'll need to talk to both the GPS and the modem at the same time. Instead, I've built a bit-banging serial interface to talk to the GPS. At the moment, I'm using the quickcam picture-taking code to test that the bit-banging serial port is sending the right data. (This is the source code.)

The GPS, in the configuration used in 1999, spits out data at 9600 baud. I wrote a small program that I call "garcmd"; it talks the Garmin protocol to the GPS. I need to re-implement a stripped-down version of this in the PIC, figure out where we are, and spit it out the USART serial port.

Phase four: cellularosity

The last (programming) step will be to make the PIC device talk to the cellular phone, dial a predefined number, authenticate itself, and then start the process above. A minor limitation of this system will be that I won't be able to queue pictures: in 1999, if there was a communications problem, the picture was saved until I could connect properly. This system won't be able to do that because the PIC simply doesn't (and can't) have enough memory to store a 320x240x6 picture. Technically, this PIC can address 64k of RAM, and I could just squeeze a picture into that, but I'd have to give up more than half of the I/O lines from the microcontroller, and wouldn't have enough left to talk to the camera!

This is the code that I used for this phase during the test-drive on the 8th and 9th of April, 2000. (I've replaced the phone number, username, and password used for the dial-up with 'X'es.) The test-run worked like a charm.

Phase five: putting together the pieces

At this point, everything should be functional on a protoboard. I'll need to put the pieces onto its own permanent circuit board, put it into a case, and power it via a laptop battery (probably a Powerbook 520 battery, since I have one or two of them hanging around).