Tuesday, May 24, 2011

Android ADK with a standard Arduino Uno and USB Host Shield

A few weeks have past since my last post and a lot was going on. First off how great was Google IO? I hadn't the chance to participate personally but I watched a lot of sessions online and was amazed of what Google had up its sleeve. New APIs, services, best programming practices but most importantly a lot of great talks about Android. As a software and hardware tinkerer I was glad to hear that Google pushes into the direction of the internet of things. With the upcoming project Android @ Home and the introduction of the Accessory Development Kit (ADK), Google showed some future outlook into their internet of things strategy.

Here is the link for the keynote of day one where they announced the ADK, and the dedicated ADK session, in case you missed one of them.

So what was done to support hardware communication? With Android 3.1 and Android 2.3.4 Google implemented USB APIs to communicate with accessories via USB. The Android devices operate in USB slave mode so that the accessories need to provide USB host capabilities. To demonstrate what is possible when your device communicates with external hardware, Google developed a reference demo board and released it as open source. They based their reference board on the Arduino which is really great, because it is widely spread in the open hardware community. Their example firmware and Android software is based on their reference board to show what kind of sensors and actuators are easily accessible. So if you attended the Google IO and got your reference board on site, that's great news for you. You could just dive right in and tinker with it.

Unfortunately not everyone could get a ticket (me neither :( ), so those developers have to wait for compatible hardware boards being distributed some time at the end of the year, or they could order one from the japanese company which produced them for the Google IO. Unfortunately they are very pricey and cost about 400$.

Soon after hearing that I decided to port the firmware and software to my basic Arduino Uno and my USB Host Shield. It is no suprise that I wasn't the only one who did that.

So if you have the Arduino Uno and a USB Host Shield lying around you might just want to give the ADK a try.
The cool thing about it is that you register a USB Broadcast receiver on your device that can automatically detect when the device is connected to your board and start up the corresponding application.

Here the steps I took to make my setup work with the ADK:
  1. Read and understand the ADK section in the Android Developers Guide.
  2. Follow the installation process.
  3. Don't use Googles USB_HOST_SHIELD library. I used a patched version which I found here. If you are having trouble compiling the demokit.pde it may result from a wrong pin definition in the patched USB_HOST_SHIELD library. Just open the Max3421e.cpp file and change #define INT PB1 to #define INT PORTB1 and #define RST PD7 to #define RST PORTD7. You might also try to use the newly released original version of the USB_HOST_SHIELD library which now supports the ADK, but I don't know if it works.
  4. Strip down the demokit.pde to its bare essentials, meaning only the communication part.
  5. Strip down the example Android app to the communication part and implement your own use cases.
To make it a bit easier I provided my example Android app and my stripped down version of the demokit.pde at github. Feel free to play around with it. Note that my approach would be considered as a temporary hack or proof of concept rather than a good solution of the porting problem. So when new versions of the ADK will be released you would have to modify them again which would be painful.

Here is a quick demo of controlling the digital pins 2-7 in output pinmode:

As promising as the ADK is right now, I have a problem with having to connect my device via cable to the accessory. The future of the internet of things will be wireless, so as long as there are no Android devices which support a Zigbee like protocol, I will use my Arduino/Android Wifi approach which you might remember from a post in the past.

That being said...
I can't wait for Android @ Home at my home ;).