Today I found out that you can plug in a regular HID keyboard into the Parrot Asteroid Smart and it will work. You know what else you can plug in that’s like an HID keyboard? An Arduino!! This means we can begin adding hardware controls to the head unit by mapping keyboard keys to software functions. This also means we can use the Arduino to wire up factory steering wheel controls of cars that are not compatible with Unika (Parrot’s steering wheel control interface).

So I’m setting off on a quest to program an Arduino to act as an HID device and to use this as a steering wheel adapter for my ’05 Pontiac GTO. The GTO uses a resistor ladder steering wheel interface, so this should be fairly easy to wire up.

In Part 1 of this tutorial, the goal is to get you to understand how to program the HID keyboard Arduino and at the end you should be able to plug it into your Asteroid Smart and navigate UP and DOWN.

HID Arduino

First things first, you need to turn your Arduino into an HID device. This part is actually fairly easy, though it may be time consuming. The first thing you need is to install a DFU Programmer. Instructions are on the Arduino site, however if you’re on a Mac and you’ve had MacPorts installed, but you’ve switched to Lion and now MacPorts don’t work, here are some tips.

ALSO!!!! If you just don’t feel like messing with MacPorts, or you hate it as much as I do , just skip this whole thing and compile the DFU Programmer source manually. It’s probably going to take less time.

Fixing MacPorts

Here’s the list of possible errors you may be getting truing to install the DFU Programmer with MacPorts:

Error: No valid Xcode installation is properly selected.
Error: Please use xcode-select to select an Xcode installation:
Warning: The Command Line Tools for Xcode don't appear to be installed; most ports will likely fail to build.

Error: org.macports.configure for port dfu-programmer returned: can't read "configure.compiler": can't read "developer_dir": can't read "developer_dir": no such variable
Please see the log file for port dfu-programmer for details:
/opt/local/var/macports/logs/_opt_local_var_macports_sources_rsync.macports.org_release_ports_cross_dfu-programmer/dfu-programmer/main.log
To report a bug, follow the instructions in the guide:
http://guide.macports.org/#project.tickets
Error: Processing of port dfu-programmer failed

The first thing you need to do is open Xcode, accept all the license agreements, then go to Preferences > Downloads and install the command line tools:

Then, run the following command to accept the Xcode license agreement:

sudo xcodebuild -license

Press “Q” to exit, then type in “Accept”.

Next, use “xcode-select” to point to the current Xcode installation:

sudo xcode-select -switch /Applications/Xcode.app/Contents/Developer/

Update to the latest version of MacPorts:

sudo port selfupdate

And finally, install the DFU Programmer:

sudo port install dfu-programmer

You should see something like this on your screen:

--->  Computing dependencies for dfu-programmer
--->  Configuring dfu-programmer
--->  Building dfu-programmer
--->  Staging dfu-programmer into destroot
--->  Installing dfu-programmer @0.5.4_0
--->  Activating dfu-programmer @0.5.4_0
--->  Cleaning dfu-programmer
--->  Updating database of binaries: 100.0%
--->  Scanning binaries for linking errors: 100.0%
--->  No broken files found.

Whew. That was fun wasn’t it? Oh who am I kidding, that sucked..

HID Firmware

You need to the HID firmware for your Arduino as well as the original firmware. I’m using the Uno R3 for this, by the way. Not sure if other models work, they probably do. You cannot upload a sketch to your Arduino when it’s in HID mode, so you’ll need to flash firmware between flashing sketches. Kind of annoying, but that’s life..

To flash the firmware, you need to put the Arduino into DFU mode. You do so by connecting the “Reset” and “GND” pins closest to the USB connector together:

Everything has to be hard on a Mac, you may need to do this additional step to download and build the latest version of the DFU programmer. If you’re getting the “dfu-programmer: no device present.” error, perform the following steps. Otherwise, skip over the compiling DFU Programmer source part.

Compiling DFU Programmer Source

Get the latest version tarball from here. Extract then compile it:

./bootstrap.sh
./configure
sudo make
sudo make install

If you used the method above, you want to cd into the “src” folder where the freshly built executable will be found. Run the following to verify you’re looking at the version you were trying to build:

$./dfu-programmer --version
dfu-programmer 0.6.0

Flash Firmware

Now, attempt to flash regular firmware to your Uno R3. Short the two pins to enter DFU mode and run this:

./dfu-programmer atmega16u2 erase --debug 3
./dfu-programmer atmega16u2 flash --debug 3 <path-to-firmware-file>
./dfu-programmer atmega16u2 reset --debug 3

Just for verification, here’s what it looked like on my screen:

$ ./dfu-programmer atmega16u2 erase --debug 3
target: atmega16u2
chip_id: 0x2fef
vendor_id: 0x03eb
command: erase
quiet: false
debug: 3
device_type: AVR
------ command specific below ------
validate: true
$ ./dfu-programmer atmega16u2 flash --debug 3 /Users/Yuri\ A/Uno\ Firmware/Arduino-usbserial-uno.hex
target: atmega16u2
chip_id: 0x2fef
vendor_id: 0x03eb
command: flash
quiet: false
debug: 3
device_type: AVR
------ command specific below ------
validate: true
hex file: /Users/Yuri A/Uno Firmware/Arduino-usbserial-uno.hex

Validating...
4058 bytes used (33.02%)

$ ./dfu-programmer atmega16u2 reset --debug 3
target: atmega16u2
chip_id: 0x2fef
vendor_id: 0x03eb
command: reset
quiet: false
debug: 3
device_type: AVR
------ command specific below ------

Also during this time all sorts of cool LEDs lit up on the Uno. Ok, try burning some simple sketch. You might need to unplug the Arduino and plug it back in for the IDE to see it. If you succeeded you can now successfully burn the firmware!

Test HID Input

With the default firmware on your Arduino, load the following sketch.

uint8_t buffer[8] = {0};
boolean dirty = true;

void setup() {
  Serial.begin(9600);
  // Set the button pins
  pinMode(8, INPUT);
  pinMode(9, INPUT);
  // Set internal pullups
  digitalWrite(8, HIGH);
  digitalWrite(9, HIGH);
}

void loop() {
  if (digitalRead(8) == LOW) {
    sendKey(0x51); // DOWN
  } else if (digitalRead(9) == LOW) {
    sendKey(0x52); // UP
  }
  delay(125);
  releaseKey();
}

void sendKey(int code) {
  buffer[2] = code;
  Serial.write(buffer, 8);
  dirty = true;
}

void releaseKey() {
  if (dirty) {
    buffer[0] = 0;
    buffer[2] = 0;
    Serial.write(buffer, 8);
    dirty = false;
  }
}

You’ll need to add two push buttons on pins 8 and 9 as in the picture below:

Now, flash the HID firmware:

./dfu-programmer atmega16u2 erase
./dfu-programmer atmega16u2 flash --debug 3 /Users/Yuri\ A/Uno\ Firmware/Arduino-keyboard-0.3.hex
./dfu-programmer atmega16u2 reset

No warnings here is good! Unplug your Arduino and plug it back into your computer. It should be detected as a keyboard. Test it on your computer to make sure you can press up and down 😀

Now go plug it into the Asteroid!!

Stay tuned for Part 2, where I will be attempting to add more controls and setting up a test rig (resistor ladder) to simulate my car’s steering wheel buttons.