Google’s open accessory development kit on standard Arduino hardware
May 12, 2011
A lot of people have been put off by the price of the reference hardware kit, which is roughly $390. What’s worse, they appear to be sold out until end of May, and Microchip’s cheaper ($80) alternative doesn’t arrive until July. So instead of waiting I decided to write a guide on how to get an ADK-capable Arduino for about $55.
Since the ADK reference design is based on Arduino and Oleg Mazurov’s excellent USB host shield, it stands to reason that we should be able to build our own hardware kit from these components. I already had these parts lying around from my work on MicroBridge, so I decided to ‘port’ their code, which in reality means just changing a couple of pin definitions.
disclaimer: Since I don’t have a phone that supports accessory mode I have no way to verify that this actually works. What I can see however is the output from the Arduino which seems to indicate that everything is working as it should be. If anyone has actual Android hardware that supports ADK and would like to help me test this, let me know!
Hardware
In order to replicate this you’ll need two things:
- An Arduino board or compatible. You can get an Arduino from places like Sparkfun, although cheaper clones can be had on Ebay for as low as $20.
- A USB host shield. You have the choice of either Oleg’s USB host shield, which will run you $40, or Sparkfun’s cheaper variant which sells for $25.
You can either get a ‘regular’ 328p-based Arduino or an Arduino Mega. The higher price of the Mega gives you extra IO pins, which you might actually need since the host shield occupies pins 7-13.
Sparkfun’s shield is cheaper but has some drawbacks. Firstly it does not work with Arduino Mega variants because these boards have their SPI pins in a different location. Oleg’s 2.0 shield solves this by connecting to the ICSP header on the Arduino, which is in the same location on all variants. Second, Sparkfun’s shield requires an external power source to be connected the the Arduino board. Finally, it’s not stackable, which is really annoying when you’re trying to drive servos, motors, and so forth.
Here’s a picture of the setup I use. As you can see, I use Sparkfun’s shield and an Arduino Uno. Note also the external power supply to power the phone. If you get this combo from Sparkfun, it’ll cost you about $55 ex shipping.

USB host connection through Sparkfun's USB host shield
Firmware
While the ADK reference software includes Oleg’s USB library, they slightly modified the code, hardcoding the pin assignment to the max3421e chip. Unfortunately this breaks compatibility with the Arduino shields, so I had to patch their code a bit to make it work again. All I really had to do is add some #defines and it worked pretty much out of the box from there.
To try it out for yourself, download the ADK software package and follow the installation instructions on the ADK page. Instead of installing the USB host lib from their package, get the patched version here and copy it into the libraries directory of your Arduino installation. Remove all the stuff from demokit.pde that uses the demo shield (joystick, RGB leds), and you should be good to go.
You should see the following output on the serial port:
Start Device addressed... Requesting device descriptor. found possible device. swithcing to serial mode Data packet error: 5could not read device protocol version Device addressed... Requesting device descriptor. found possible device. swithcing to serial mode Data packet error: 5could not read device protocol version
Et cetera. This means that the electrical wiring to the shield is in working order and the max3421e is finding the phone. The ‘Data packet error: 5′ means that my phone is not responding to the non-standard control request, which it shouldn’t, since it’s not an accessory-capable device (yet).
Conclusions
As far as I can tell following this guide should give you a slightly more economical Android accessory device compared to the reference kit. Until I get my hands on a phone I cannot test it, so if anyone out there has a capable device or knows how to hack support for it onto a rooted ZTE Blade, let me know. When ADK makes it into Cyanogen mod I’ll certainly flash it on one of my blades and let you know how it goes.
Finally, if anyone out there has one of those cool ADK demo kits and wants to lend me one, feel free to contact me. I’d like to port MicroBridge to it so that it can be used it with pre-2.3.4 devices.
update: much thanks to RobotFreak and Follower for confirming that this setup works! Apparently some versions of avr-libc require ‘PORTB1′ instead of ‘PB1′ to compile correctly. Check the comments of this post for more details and RobotFreak’s video.
May 13, 2011 at 3:17 am
You can also compile Accessory code against my standard library for the shield. In Accessory class change a single NewInTransfer() function call to inTransfer()call. You will also need to change pin assignments in demokit.pde to make it compatible with standard-sized Arduinos. demokit.pde compiles in ~16K.
compiles in ~16K
May 13, 2011 at 9:04 pm
Hi Oleg,
I tried making the change you suggested (newInTransfer to inTransfer) and it partly works but not entirely.
It fails when sending data from the Android device to the accessory (e.g. with the sliders on the “Out” tab of the demo app). From what I can tell this is because the “new” version returns a length and without it the Accessory library misses the first byte of the message.
–Philip;
May 13, 2011 at 9:30 pm
Thank you for sharing this
– I was looking for ways to get accessory code compile against the standard library and it seems the easiest way would be to make a release which includes NewInTransfer().
May 13, 2011 at 9:40 am
Do you have an idea which bandwidth and latency can be achieved with this setup?
It could be a nice low latency audio i/o option for android devices!
I own a Nexus S, which should support accessory mode, but I don’t have an USB host shield lying around…
May 13, 2011 at 10:19 am
I haven’t done any such tests, but Ytai did some with his pic24-based IOIO and reports he gets “~3ms one-way latency, ~300KB/sec throughput”.
http://ytai-mer.blogspot.com/2011/04/meet-ioio-io-for-android.html
I’m assuming you’ll get similar numbers with this, although I can’t guarantee anything. I foresee problems though because Android is not an RTOS. You might get occasional hick-ups due to the other processes doing heavy lifting or just the GC kicking in.
For a low-latency audio option I’d probably just use the Audio jack
May 13, 2011 at 11:02 am
> For a low-latency audio option I’d probably just use the Audio jack
In fact, no. See http://code.google.com/p/android/issues/detail?id=3434
Android does not support low latency audio by design. This is a major issue which makes the development of usefull audio applications impossible for android devices. And there is much interest for audio apps, just look how much apps for musicians exist in the iPhone / iPod world. All these apps cannot be ported to android due to missing low (<10ms) latency audio.
The reported latency and bandwidth should be ok for audio recording / playback, but you're right that the android os could be not RT capable. On the other hand, it uses a decent linux kernel which in fact is RT capable, so maybe… GC should'n be a problem when using the NDK.
May 13, 2011 at 3:10 pm
[...] With such a ridiculous asking price, it was only a matter of time before someone tried getting the ADK software running on vanilla Arduino hardware. [Inopia] wrote in letting us know that he did just that. [...]
May 13, 2011 at 6:30 pm
[...] With such a ridiculous asking price, it was only a matter of time before someone tried getting the ADK software running on vanilla Arduino hardware. [Inopia] wrote in letting us know that he did just that. [...]
May 13, 2011 at 8:38 pm
Hi,
Well done, Romfont. I can confirm, that your USB-Host patch works on an Arduino Uno with the Sparkfun Host shield!
The only thing I had to change were the Pin definitions for the ATmega328P to PORTD7 and PORTB1 instead of PD7 and PB1.
Now I need to attach some sensors and actors.
More news, later on.
Greatings RobotFreak
May 13, 2011 at 9:20 pm
Hi romfont…
(I’m follower from the Hacker News comments.
)
As suspected, we did both take the same approach except yours was neater
and I also tested your patch.
I needed to make a couple of changes to get it to work because I have the first revision of the SparkFun host shield (with date code: “2-25-10″). As documented in a few places, the GPX and RST pins on this revision are backwards.
This means defines MAX_GPX & MAX_RESET in Max3421e_constants.h need to be swapped and the same for RST* & GPX* in Max3421e.cpp.
In addition, I think there’s an issue with the version of (avrdude or libc or something) that doesn’t accept PB1 etc as a pin name, it needs to be expanded to PORTB1, for example. I seem to recall this was an intentional backward-incompatible change made at some point because the short-naming was deprecated.
I’ve posted a badly hacked version of the demokit.pde file at http://pastie.org/1897847 which compiles for me & allows me to connect a button to pin A0 and an LED to pin 5 and have the button press show up on the phone and the LED2 red slider control the LED. Part of the reason why it’s such a mess is because I was trying to track down why the code didn’t seem to work with Oleg’s library directly.
But I figured people might like something to play with now so haven’t tidied it up.
–Philip;
May 13, 2011 at 10:32 pm
Some images and code including the hacked up demokit sketch & twice patched library to support version 1 of the SparkFun shield: http://rancidbacon.com/p/android-arduino-accessory/
Thanks for your work & documentation.
Have fun.
May 14, 2011 at 12:06 am
I have tested succesfully a servo, a RGB LED and a Sharp GP2D12 distance sensor attached to my DIY DemoKit. Video can be found here:
Code and some pictures can be found at:
http://letsmakerobots.com/node/26839
Greatings RobotFreak
May 14, 2011 at 4:37 pm
Awesome! Thanks a bunch for proving this works.
May 14, 2011 at 4:20 am
[...] Source [...]
May 14, 2011 at 6:22 am
[...] With such a ridiculous asking price, it was only a matter of time before someone tried getting the ADK software running on vanilla Arduino hardware. [Inopia] wrote in letting us know that he did just that. [...]
May 14, 2011 at 12:25 pm
[...] With such a ridiculous asking price, it was only a matter of time before someone tried getting the ADK software running on vanilla Arduino hardware. [Inopia] wrote in letting us know that he did just that. [...]
May 14, 2011 at 6:17 pm
[...] long after the Open Accessory Kit was announced, romfont posted a great set of instructions on getting this work with a standard [...]
May 15, 2011 at 2:04 am
[...] setup certain code modifications are necessary. One such modification has been posted on Romfont. I tried it and the code works well, however, this approach has issues. First, it creates yet [...]
May 15, 2011 at 2:11 am
I added ADK compatibility to the standard library -> https://www.circuitsathome.com/mcu/programming/android_adk_compatible_usb_host_library_release
May 15, 2011 at 6:59 pm
I’ve just released a “cut down” version of the demo app & sketch called “TinyAccessory”. It has a single instance of 4 different input/output types and the Android app has lots of the extra code removed so it’s somewhat easier to follow how things work.
The goal is to provide people with a simpler starting point–I’ve also uploaded the .apk if you can install demo signed apps on your device.
More details: http://rancidbacon.com/p/android-arduino-accessory/#20110516
May 16, 2011 at 2:20 am
[...] long after the Open Accessory Kit was announced, romfont posted a great set of instructions on getting this work with a standard Arduino: A lot of people have been put off by the price of the [...]
May 16, 2011 at 6:02 am
[...] Google’s open accessory development kit on standard Arduino hardware « Romfont (tags: arduino android code adk accessory) [...]
May 18, 2011 at 6:32 pm
[...] Shield” setup certain code modifications are necessary. One such modification has been posted on Romfont. I tried it and the code works well, however, this approach has issues. First, it creates yet [...]
May 18, 2011 at 9:31 pm
Hey there,
I’m getting a USB Host shield soon because of this so thanks. About getting support on blade, you will need to apply the changes similar to those here https://github.com/arco/buzz-kernel-2.6.35/commit/dbc60d74fed521a4c24539384f3c675ef0ce7ac0#diff-6 for it to work. Hope that helps, in needs to be applied to your kernel.
June 7, 2011 at 9:40 am
First, thanks for your work.
I tried without success with HTC Desire + 2.3.4 (GingerVillain2.4/2.5, Oxygen, Cyanogen 7.1 nightly), using Arduino Uno + Sparkfun USB Host Shield / your lib patch or Oleg Patch. Compile/upload ok, but nothing when i plug my phone (with 9V 1A pwr sup. in Uno pwr plug). Does someone manage to get Accessory Mode with an alternative phone mod yet ? Is Accessory Mode present in AOSP ?
June 8, 2011 at 9:29 pm
[...] Currently the best wired common denominator, the Open Accessory program allows you to use a third-party accessory as the USB host, even on devices that lack USB host support. You just need a device with Android 3.1, 2.3.4, or greater. In a much-ballyhooed feature, there are prototyping possibilities with the open Arduino platform. Google’s own hardware is obscenely pricey, though, at around $400. Instead, DIYers will want to use a standard Arduino. Two early examples: Android ADK with a standard Arduino Uno and USB Host Shield Google’s open accessory development kit on standard Arduino hardware [...]
July 18, 2011 at 5:13 am
I am wanting to do my first Arduino project, and the finished product will eventually be controlled via android tablet. Is it easy enough to start with this method, or should I build my prototypes using a stock microcontroller without having to edit the libraries and worry about the droid aspect later?
August 6, 2011 at 6:57 pm
[...] Currently the best wired common denominator, the Open Accessory program allows you to use a third-party accessory as the USB host, even on devices that lack USB host support. You just need a device with Android 3.1, 2.3.4, or greater. In a much-ballyhooed feature, there are prototyping possibilities with the open Arduino platform. Google’s own hardware is obscenely pricey, though, at around $400. Instead, DIYers will want to use a standard Arduino. Two early examples: Android ADK with a standard Arduino Uno and USB Host Shield Google’s open accessory development kit on standard Arduino hardware [...]
August 14, 2011 at 1:06 pm
[...] http://romfont.com/2011/05/12/google%E2%80%99s-open-accessory-development-kit-on-standard-arduino-ha… [...]
September 6, 2011 at 10:57 pm
[...] su sitio web, posteó los pasos de como instalar el ADK en un Arduino + USB Host Shield (ver post aquí). No le bastó y 3 días después, publicó un post, donde “hackeó” el protocolo ADB [...]
January 21, 2012 at 10:10 pm
[...] (Android to Arduino Bridge via ADB). Because he didn’t own a Android phone with v2.3.4 he asks for help to test his firmware. The firmware works with some minor modifications and is attached to this blog [...]
January 29, 2012 at 7:27 am
[...] see if I can build a board with just plain Arduino board and Oleg’s USB Host Shield. It turns out it is possible and with the release of Oleg’s second version of the USB Host Library, it is much [...]
March 9, 2012 at 1:33 am
[...] update-12-maio: já não quero isto.. primeiros rumores apontam para um preço de 400 dollars e só vai estar disponível lá para Junho.. (http://romfont.com/2011/05/12/google%E2%80%99s-open-accessory-development-kit-on-standard-arduino-ha…) [...]