15 April 2010
11 April 2010
Google Maps on Linux
Open Source GPS HOW TO
Using a Garmin Edge to Plot Cycle Routes with Google Maps on Linux, Macs and Windows
By Martyn C Davis, 14-MAY-2006

On a recent organised cycling ride in the Test Valley down in Hampshire (I'm in the UK), a friend showed me his new toy; a Garmin Edge 305GPS-enabled bike computer. Being a bit of a gadget head I'd played around with GPS on bike rides before, but the old Garmin GPS 12 I'd had seemed almost the weight and size of a brick, it had a serial interface, and the best use I ever really got out of it was to tell me what my coordinates were, which I could then check back onto an OS map. It also had a hard time finding a signal when surrounded by tall buildings or tree cover.
I often find it quite boring riding around the same old familiar routes on my bike, but the alternative, which is figuring out a new route, then stopping every few miles to consult the sweaty OS map in my back pocket spoils the tempo of the ride. My ideal scenario would be to figure out a route beforehand, program it into a GPS, and let it lead me through the new ride. Seeing this new Garmin model rekindled my desire to get this working.
The Edge from Garmin is about the size of a SMALL mobile phone, it's light, and it's sensitive: it picks up a signal almost anywhere you are going to ride. Ideal, I thought. My friend's model was the 305, which does either heart rate or cadence, and has a barometric altimeter built in. The cheaper model, the 205, lacks the HR / cadence, and relies on GPS to calculate altitude, which is less accurate. I have a Polar watch which does all this, so I was happy to go for the 205.
First Impressions
My first impressions were pretty negative. After I'd ordered it from Wiggle I started looking around for information on the unit (OK, I know I should have done the research before ordering the thing, but I ordered it in a moment of gadget lust :). All the information I was getting back from my internet searches were people griping about how Garmin are using proprietary formats and weren't being very helpful (see, for example, this O'Reilly article on the subject).So I received the unit and had a pretty fruitless few days trying to bend it to my will. The software that comes with the device is crap. For one, it's a Windows application. I use Linux, and Mac OS, and run Windows approximately never, but I do keep one machine (referred to in this household as the toy machine which dual boots to allow me to test stuff and run games). Installing the Garmin software on this machine allowed me to have a brief look, and I didn't like it. It's not intuitive and it looks horrible. There's no way THAT's going to tempt me to use it. Also it's designed more for training than routing.
What do I want?
So, what do I actually want? I had a half-conceived idea that firstly I wanted to be able to use Google Maps to define a route. This would be fantastic, because not only can you zoom right in and out, but you can also see satellite imagery, which is becoming more and more detailed. This allows you to check a spot, say, to see whether it's a junction or just a bend in the road. I then would like to perhaps save that route to a GPX file (GPX is becoming an XML-based standard for GPS data transfer), which I could somehow then upload to the GPS unit. The supplied software and its help files make absolutely no mention of GPX, so (thankfully, as it's Windows) I shan't be using that.NB: There is a site which is quite popular with cyclists called "GMaps Pedometer" which offers the ability to define routes. It's good, but it has a somewhat different aim. You CAN get GPX out of it, but only through another site and the use of a bookmarklet - hence, for GPS, it's kludgy. Also you have no control over waypoint names etc.
The Linux Approach
Plugging the Garmin unit into my Linux laptop (running Ubuntu "Breezy") via USB, and checking the system logs by typing "dmesg", I see a heartening series of messages:[4309364.676000] drivers/usb/serial/usb-serial.c: USB Serial support registered for Garmin GPS usb/tty [4309364.682000] garmin_gps 5-1:1.0: Garmin GPS usb/tty converter detected [4309364.726000] usb 5-1: Garmin GPS usb/tty converter now attached to ttyUSB0 [4309364.726000] usbcore: registered new driver garmin_gps [4309364.726000] drivers/usb/serial/garmin_gps.c: garmin gps driver v0.23
Garmin USB support just works. Support is built into the kernel, so the device now sits on a pseudo-serial port called /dev/ttyUSB0. Hopefully I can find an application that will support it.
I tried a few applications without much success, and the one I kept coming back to was GPSBabel. The UNIX command-line-based version has about a million options and took a while to figure it out, but eventually I got it working. The command line required to transfer a GPX file to the unit is, assuming that your GPX file is called "foo.gpx":
gpsbabel -r -i gpx -f foo.gpx -o garmin -F usb:
I've written a small script to wrap this call to make it a bit easier to remember. You can grab a copy here.
Generating the GPX File
Next problem: generating my own GPX files! The Google Maps API is fantastic - it's great that Google have allowed third parties to make their own applications around their mapping service. This is definitely the way forward, and it didn't take much hacking before I developed a small javascript prototype application which allows me to click on the map, define a set of waypoints, naming them as I went along, and then generate a GPX file from them, which uploads OK to the Garmin device. Here's an example, which, if you copy and paste into a file, you could use to test with GPSBabel and my script.RICHMNDPK 1-START 2-RIGHT 3-RIGHT 4-END
The latest version of this application is now out. You can find it at www.marengo-ltd.com/map2
I welcome any feedback. Join the discussion at my blog: http://www.marengo-ltd.com/blog/. I'd love to hear from you even if it's only to tell me that you find the software useful.
Plans
My plans for the software are as follows:- Define routes (done)
- Export as GPX (done)
- Save to database (done)
- Load from database (done)
- Share routes with other users (done)
Conclusion
Well, reservations regarding the proprietary nature of Garmin aside, I have to say that now I've figured out how to plan routes and upload them to the device, I love it. It's got a quite loud beeper on it, to warn you of upcoming waypoints, and the battery life seems quite good. It charges via USB. If you are going on a long, multi-day trip, don't forget the charger, or your laptop and ITS charger. If you are going to be away from any electricity, there's always the USB Battery.You can find the latest release of the GPX generation software at www.marengo-ltd.com/map
Like I say, if you want to feed back any comments, please join the discussion at my blog: http://www.marengo-ltd.com/blog/.
I'll be interested to see how it works with other GPS units too - drop me a note to tell me what you've got it working with.
Finally, you may also contact me at my gmail address. Use my full name (including middle initial) as quoted at the top of this article, separated by dots (like, for example, "hector.h.monro", except with my name :), and append "@gmail.com" to it. Queries will be given much more attention if you accompany them with a small donation (see the PayPal link at the end of this page).
UPDATE: I've been asked by many people whether this is going to work under Windows. Good news... I've tested GPSBabel under XP and it does appear to. You can test this yourself by installing GPSBabel for Windows, and then, from wherever you installed the software, you can issue a command from the command line the following (assuming you've got the sample GPX file saved as "foo.gpx"):
gpsbabel.exe -r -i gpx -f foo.gpx -o garmin -F usb:
There's a windowed version of GPSBabel available from their site too if you are not comfortable with using the command line. There is a version for Mac OS X as well. All these work in the same way.
The only downside I see so far is that the current version of the Windows version of GPSBabel (1.2.7) doesn't seem to support the NAME of the route... all routes get imported with a name of "EMPTY", which is a bit confusing when you look at the route list, as you think "EMPTY" means "I have no routes", but that's the name of the route... I know that this has been fixed in the Linux 1.2.8 Beta release, so hopefully the Windows version will also be fixed.
So this means that the application should allow BOTH Linux users and their unfortunate Windows brethren to both easily plot routes via Google Maps for the Garmin Edge devices. Cool.
LCD4Linux-TUTORIAL
Linux-Options:
lcd4linux [-c key=val] [-F] [-f config-file] [-i[i]] [-o output] [-q] [-v]
| -c key=val | overwrite entries from the config-file (key and value have to be specified) |
| -F | do not fork and detach (run in foreground) |
| -f config-file | use configuration from 'config-file' instead of /etc/lcd4linux.conf |
| -i | enter 'interactive mode' (after display initialisation) |
| -ii | enter 'interactive mode' (before display initialisation) |
| -o output | write picture to 'output' (raster driver only) |
| -q | suppress startup and exit splash screen |
| -v | generate info messages |
| -vv | generate debugging messages |
| -h | print version number and a small help text, then exit |
| -l | list available drivers |
Start automatically during boot:
You have to create the startscript "/etc/init.d/lcd4linux" and generate the necessary runlevel entries by hand, e.g. with the command "ln -s /etc/init.d/lcd4linux /etc/rc5.d/S99lcd4linux".
Example for a startscript:
#! /bin/sh # # lcd4linux # PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin DAEMON=/usr/local/bin/lcd4linux NAME=lcd4linux DESC=lcd4linux test -f $DAEMON || exit 0 set -e case "$1" in start) echo -n "Starting $DESC: " start-stop-daemon --start --quiet --pidfile /var/run/$NAME.pid --exec $DAEMON echo "$NAME." ;; stop) echo -n "Stopping $DESC: " start-stop-daemon --oknodo --stop --quiet --pidfile /var/run/$NAME.pid --exec $DAEMON echo "$NAME." ;; reload) start-stop-daemon --stop --signal 1 --quiet --pidfile /var/run/$NAME.pid --exec $DAEMON ;; restart|force-reload) echo -n "Restarting $DESC: " start-stop-daemon --stop --quiet --pidfile /var/run/$NAME.pid --exec $DAEMON sleep 1 start-stop-daemon --start --quiet --pidfile /var/run/$NAME.pid --exec $DAEMON echo "$NAME." ;; *) N=/etc/init.d/$NAME echo "Usage: $N {start|stop|restart|reload|force-reload}" >&2 exit 1 ;; esac exit 0 Alternatively you can invoke LCD4Linux within the file /etc/init.d/boot.local.
HD44780 Wiring
95% of all trouble with displays connected to the parallel port are due to wrong wiring! There is no "standard", whereupon the wiring should be carried out. Thus LCD4Linux supports the so-called "soft wiring", which means that you can use (nearly) any wiring you like. You just have declare it in lcd4linux.conf. A HD44780 display typically has 16 connections (if only 14 are available, then the connections for backlight are missing). The connections have the following meaning:
| Pin | Name | Comment |
| 1 | GND | ground |
| 2 | VCC | supply voltage +5V |
| 3 | LCD_DRIVE | contrast voltage (0 .. +5V) |
| 4 | RS | Register Select (low=instruction, high=data) |
| 5 | R/W | Read / not Write (high=read, low=write) |
| 6 | ENABLE | starts data read/write |
| 7 | DB0 | Data Bit 0 |
| 8 | DB1 | Data Bit 1 |
| 9 | DB2 | Data Bit 2 |
| 10 | DB3 | Data Bit 3 |
| 11 | DB4 | Data Bit 4 |
| 12 | DB5 | Data Bit 5 |
| 13 | DB6 | Data Bit 6 |
| 14 | DB7 | Data Bit 7 |
| 15 | BACKLIGHT | backlight supply voltage |
| 16 | BL GND | backlight ground |
The parallel port has 25 connections:
| Pin | Name | I/O |
| 1 | STROBE | Out |
| 2 | DB0 | I/O |
| 3 | DB1 | I/O |
| 4 | DB2 | I/O |
| 5 | DB3 | I/O |
| 6 | DB4 | I/O |
| 7 | DB5 | I/O |
| 8 | DB6 | I/O |
| 9 | DB7 | I/O |
| 10 | ACK | In |
| 11 | BUSY | In |
| 12 | PAPEROUT | In |
| 13 | SELECT | In |
| 14 | AUTOFD | Out |
| 15 | ERROR | In |
| 16 | INIT | Out |
| 17 | SLCTIN | Out |
| 18-25 | GND | n/a |
The data lines (DB0..DB7 on the display, DB0..DB7 on the parallel port) are always connected directly (unless you are using the 4-bit mode - but that is intended for experts rather, and these are not reading this tutorial anyway :-). The interesting part is, how the display's control signal is connected with the 4 possible output lines from the parallel port:
display:
Pin 4: RS (Register Select) Pin 5: R/W (Read/Write) Pin 6: Enable
parallel port:
Pin 1: Strobe Pin 14: AutoFD Pin 16: Init Pin 17: SelectIn
For each control line you have to specify, which signal of the parallel port is used. This is done by the "Wire.xy"-entries.
E.g. if you are using the popular WinAmp wiring, it has to be defined like this:
Display Pin 4 (RS) => Parallelport Pin 16 (Init) Display Pin 5 (R/W) => Parallelport Pin 14 (AutoFD) Display Pin 6 (Enable) => Parallelport Pin 1 (Strobe)
The adequate soft-wiring entries have to be:
Wire.RW 'AUTOFD' Wire.RS 'INIT' Wire.ENABLE 'STROBE' Wire.ENABLE2 'GND' Wire.BACKLIGHT 'GND' Wire.GPO 'GND'
Wiring example:
If you want to connect a standard HD44780 display to the parallel port using the WinAmp-Wiring, do it like the following:
| LCD | Parallel Port | Power Supply | contrast pot (10k) |
| Pin 1 | Pin 18 | GND | Pin 1 |
| Pin 2 | - | +5V | Pin 3 |
| Pin 3 | - | Pin 2 (slider) | |
| Pin 4 | Pin 16 | ||
| Pin 5 | Pin 14 | ||
| Pin 6 | Pin 1 | ||
| Pin 7 | Pin 2 | ||
| Pin 8 | Pin 3 | ||
| Pin 9 | Pin 4 | ||
| Pin 10 | Pin 5 | ||
| Pin 11 | Pin 6 | ||
| Pin 12 | Pin 7 | ||
| Pin 13 | Pin 8 | ||
| Pin 14 | Pin 9 | ||
| Pin 15 | - | 100 ohm resistor to +5V | |
| Pin 16 | - | GND |
TROUBLESHOOTING
Problems when compiling:
- problems with user rights? install as root user
- error in configure.log? try different configure options
e.g. errormessage
#error "gd.h not found!" make: *** [Raster.o] Error 1
workaround: configure --with-drivers=all,\!PNG
Problems starting LCD4Linux:
- rights on /etc/lcd4linux.conf set correctly?
- is the display initialised when starting LCD4Linux?
- invoke LCD4Linux with the options "-Fvvq" and have a look at the debug-output
- check syntax in lcd4linux.conf