Friday, January 21, 2011

Interfacing RS-232 GPS to Arduino

If you missed prior posts, I have entered the 2011 Sparkfun Autonomous Vehicle Competition (AVC).

For reliable navigation around the Sparkfun building in Boulder, CO, I plan to equip the RC truck I purchased with a GPS, interfacing it to a microcontroller.

Garmin eTrex Legend

It so happens I have a Garmin eTrex Legend that I can use for prototyping until I buy a much better GPS module  for the robot. Like most GPS units, the Legend outputs NMEA 0183 serial data using RS-232 protocol. RS-232 uses +/-12V signals that will burn your average microcontroller's input pins to a crisp.

One can use a MAX232 to shift levels to MCU-friendly 0-5V or 0-3.3V but why dink around with that when a transistor, a few resistors, a prototype perfboard, and a few minutes with a soldering iron will do the job.

Some time ago I made a level shifter device to interface various microcontrollers with my PC. Since the GPS only spits out data and doesn't take commands from the MCU, the receive (RX) side of the level shifter circuit is all that's required to interface the Legend GPS.  The RX half of the circuit eliminates the D1 diode and C1 capacitor, and the TX circuit: Q1 transistor and R1, R2 resistors.  Leaving Q2, R3, R4, and R5.

Ditch the diode (D1) and capacitor (C1) and TX circuits
I soldered everything together on a Radio Shack copper-clad perfboard and added LEDs for power (green) and RX (red), then soldered the wires to a DB9 female connector so I could use the original Garmin cable.

Simple transistor level shifter
Incidentally, I discovered that the odd-ball Garmin GPS connector is available as a standalone part from this site. I ordered a pair and got them within a week or two. They're provided sort of like shareware. Get product first, try it, then pay. The product is really quite good, so I'll be sending a check soon. I swapped this custom connector in place of the DB9.

To read GPS data bytes, I used the NewSoftSerial library. I found that NSS is incompatible with newer Arduino Servo library routines so I had to disable those for now.  I plugged in the GPS and used a simple demo program to read in the NMEA sentences from the GPS and spit them out to the PC.

To parse the NMEA 0183 protocol, I used the TinyGPS library and modified the code to grab some additional information about the quality of the position fix. Namely, the number of satellites being tracked, and the horizontal dilution of position information.

The fix information will be helpful in prototyping a Kalman Filter to obtain the best heading and position estimates from the robot's GPS and rate gyro. In short, the algorithm will be able to establish an appropriate level of confidence in the GPS data. But more on that another time.

Now, if only there were some way to store the captured data for later analysis...

(Well, there is, but you have to wait for the upcoming article...)