Linkedin Profile
Tags:
programming
seattle
things that bug me
wall art

9/2008
8/2008
7/2008
6/2008
5/2008
4/2008
3/2008
2/2008
1/2008
12/2007
11/2007
10/2007
9/2007
8/2007
7/2007
6/2007
5/2007
4/2007
3/2007
2/2007
1/2007
12/2006
11/2006
10/2006
9/2006
8/2006
7/2006
6/2006
5/2006
4/2006
3/2006
2/2006
1/2006
12/2005
11/2005
10/2005
9/2005
8/2005
7/2005
6/2005
5/2005
4/2005
3/2005
2/2005
1/2005
12/2004
11/2004
10/2004
9/2004
8/2004
7/2004
6/2004
5/2004
4/2004
3/2004
2/2004
1/2004
12/2003
11/2003

GPS on Leopard
2008-06-09

A while back I bought Microsoft Streets and Trips 2007 from the company store, and got a nice, small USB GPS with it. I messed around programming the GPS on Windows (post) and hooked it into my blog, but then I moved over to a Mac running Leopard as my daily machine and lost my neat GPS recording capability. No more! On Sunday I hacked together some code to pull data from the GPS on OS X.

nmea print out.

I found a few posts from people trying to do the same thing, so I am going to outline the steps involved now, and show some code in a later post.

1. USB to Serial - The GPS device uses the RS232 serial standard over USB. This won't appear as a serial device without the right driver, so download the BF-810 USB to Serial adapter from here and install it.

2. Vendor and Product ID - The driver installed in step 1 needs some tweaks before it will work, and to make those tweaks you need to know two numbers: The vendor and product IDs. Plug in the GPS and fire up IORegistryExplorer, and then look under IOUSB group (command-6) for the GPS. It will be the entry with USB Vendor Name = Prolific Technology Inc. If you are lazy like me you can also find it by yanking the GPS out of the machine and watching it go red in the explorer. Note that the values here are in hex, so it is a great opportunity to dust off your hex to decimal skills.

3. Edit kext - Plug the vendor and product IDs for your device into the kernel extension Info.plist file /System/Library/Extensions/ProlificUsbSerial.kext/Contents/Info.plist. This is just a plain old xml file, so sudo fire up your editor of choice and replace whatever values are there under idProduct and idVendor with your own.

4. Reload kext - With our product and vendor IDs in place, it is now time to reload the driver. First up, run "sudo kextunload -b com.prolific.driver.PL2303". It is ok if this unload command fails. Now run "sudo kextload -b com.prolific.driver.PL2303". Provided the device is plugged in, you should now be able to see a device file called cu.usbserial in the /dev directory on your file system (ls /dev/cu*).

5. Time to code - Apple has a useful serial programming in C tutorial here. The demo accesses a modem, but the code only needs a few tweaks to pull NMEA data off the GPS. I started by stealing swathes of the demo and hacking on them to re-target it at the GPS. The important changes are:

5.1 Discovery - There is no need to discover the device dynamically, just hard code the device path and get rid of a couple of hundred lines of code right away:

	char* gpsPath = "/dev/cu.usbserial"; 
	fileDescriptor = OpenSerialPort(gpsPath);

5.2 Config - The device is configured using the termios structure, and you'll need this to get the baud, parity, stop bits and word size right:

	cfsetspeed(&options, B4800); 
	options.c_cflag &= ~PARENB;
	options.c_cflag &= ~CSTOPB;
	options.c_cflag &= ~CSIZE;
	options.c_cflag |= CS8;

5.3 Reading data and NMEA parsing - Data isn't read back from the device in a predictable sequence, so you will need to scan the input as it is read and work out when the sequence starts. Luckily the NMEA data structure is simple to parse: every line starts with a $, holds some comma separated values, and ends with a checksum. Parse away!

Tags: programming

Back to weblog