Sunday 23 October 2011

Garmin Forerunner 405 in Ubuntu 11.04

I recently decided it was time to improve my fitness. Keeping fit is one of those areas where I struggle to keep motivated, so I decided to bribe myself using the only currency I respect: gadgets.

After much deliberation and research, I chose a Garmin Forerunner 405 because of it's GPS accuracy and size. Linux compatibility was high on my list of concerns, and there aren't many articles to be found in Google about support for the 405. Thanks to this article, my apprehension was assuaged.

The Forerunner 405 comes with USB dongle called ANT+ that's used to communicate wirelessly with it, however Ubuntu doesn't correctly recognize the device out-of-the-box.

Setting up the ANT+ Dongle 

Plug the ANT+ stick in and run lsusb


noel@behemoth:~$ lsusb
Bus 003 Device 004: ID 0fcf:1008 Dynastream Innovations, Inc. 
Bus 003 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 002 Device 004: ID 17ef:1003 Lenovo Integrated Smart Card Reader
Bus 002 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 008: ID 0a5c:217f Broadcom Corp. Bluetooth Controller
Bus 001 Device 006: ID 04f2:b217 Chicony Electronics Co., Ltd 
Bus 001 Device 004: ID 147e:2016 Upek Biometric Touchchip/Touchstrip Fingerprint Sensor
Bus 001 Device 003: ID 0765:5001 X-Rite, Inc. 
Bus 001 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub


The highlighted row above is the entry for ANT+. The important information is the USB vendor_id:model_id (0fcf:1008); it's what we'll use to tell Ubuntu how to set the device up.

Adding a udev Rule

Armed with the USB vendor ID and model ID of the ANT+, we can add a simple udev rule to make sure the usbserial kernel module is loaded for the ANT+.

Make sure you plug out the ANT+ before continuing.

sudo vim /etc/udev/rules.d/garmin-ant2.rules

Add the following on a single line:

BUS=="usb", SYSFS{idVendor}=="0fcf", SYSFS{idProduct}=="1008", RUN+="/sbin/modprobe usbserial vendor=0x0fcf product=0x1008"

You can see udev reacting to the ANT+ stick by running udevadm monitor before plugging it in.


noel@behemoth:~$ udevadm monitor
monitor will print the received events for:
UDEV - the event which udev sends out after rule processing
KERNEL - the kernel uevent

Plug in the ANT+ stick. You should see the following data output to the console:



KERNEL[1319380921.077220] add      /devices/pci0000:00/0000:00:1c.6/0000:0e:00.0/usb3/3-3 (usb)
KERNEL[1319380921.085927] add      /devices/pci0000:00/0000:00:1c.6/0000:0e:00.0/usb3/3-3/3-3:1.0 (usb)
KERNEL[1319380921.145292] add      /module/usbserial (module)
KERNEL[1319380921.145617] add      /bus/usb-serial (bus)
KERNEL[1319380921.145664] add      /bus/usb/drivers/usbserial (drivers)
KERNEL[1319380921.145723] add      /bus/usb-serial/drivers/generic (drivers)
UDEV  [1319380921.145742] add      /module/usbserial (module)
UDEV  [1319380921.146218] add      /bus/usb-serial (bus)
UDEV  [1319380921.146477] add      /bus/usb/drivers/usbserial (drivers)
UDEV  [1319380921.146493] add      /bus/usb-serial/drivers/generic (drivers)
KERNEL[1319380921.193433] add      /devices/pci0000:00/0000:00:1c.6/0000:0e:00.0/usb3/3-3/3-3:1.0/ttyUSB0 (usb-serial)
KERNEL[1319380921.193638] add      /devices/pci0000:00/0000:00:1c.6/0000:0e:00.0/usb3/3-3/3-3:1.0/ttyUSB0/tty/ttyUSB0 (tty)
KERNEL[1319380921.193861] add      /bus/usb/drivers/usbserial_generic (drivers)
UDEV  [1319380921.194619] add      /devices/pci0000:00/0000:00:1c.6/0000:0e:00.0/usb3/3-3 (usb)
UDEV  [1319380921.194695] add      /bus/usb/drivers/usbserial_generic (drivers)
UDEV  [1319380921.204297] add      /devices/pci0000:00/0000:00:1c.6/0000:0e:00.0/usb3/3-3/3-3:1.0 (usb)
UDEV  [1319380921.209858] add      /devices/pci0000:00/0000:00:1c.6/0000:0e:00.0/usb3/3-3/3-3:1.0/ttyUSB0 (usb-serial)
UDEV  [1319380921.243784] add      /devices/pci0000:00/0000:00:1c.6/0000:0e:00.0/usb3/3-3/3-3:1.0/ttyUSB0/tty/ttyUSB0 (tty)

You can see that the usbserial module has been loaded and the /dev/ttyUSB0 device has been created.

noel@behemoth:~$ ls -l /dev/ttyUSB0 
crw-rw---- 1 root dialout 188, 0 2011-10-23 15:43 /dev/ttyUSB0

The ANT+ stick is now set up as a USB serial device at /dev/ttyUSB0. This allows Gant to communicate with the Forerunner 405. 

Now that the device is properly recognized by Ubuntu, we can start working on Gant. 

Installing and Using Gant

Gant is a small program that interfaces with the Forerunner 405 and dumps your training data to the hard drive. You will have to compile and run it from source. Make sure you've got git and build-essential installed from the package manager:

mkdir -p ~/Development/Native/

cd ~/Development/Native/

git clone git://get-open.com/gant

cd gant/

make

Once that completes successfully, Gant is ready to communicate with your Forerunner 405. First you'll have to make a one-off pairing between Gant the your Forerunner 405.

Put Forerunner 405 into pairing mode:
Menu > Settings > ANT+ > Computer > Pairing > On

Also, make sure that communication is enabled:
Menu > Settings > ANT+ > Computer > Enabled > Yes

You may need to also set "Force Send". This seems to send all data on the device, whether or not the data's been downloaded from the device before.
Menu > Settings > ANT+ > Computer > Force Send > Yes

Pair gant with the Forerunner 405 (once off)
./gant -f Forerunner-405 -a auth405

You will be prompted to confirm the pairing on the device. Once complete, you'll have a file auth405 in the current directory. This will be used to authenticate all future communication between Gant and the device.

You should now be able to transfer your data from the Forerunner 405:
./gant -nza auth405 > output

Alternatively you can move the authorization file to your home directory; Gant looks for it there automatically:
cp ./auth405 ~/.gant
./gant -nz > output

If it completes successfully, you should end up with one more *.TCX files in the current directory. You can now upload these to Garmin Connect, or import them into a desktop training app like PyTrainer

Enjoy!