Opening up the Google ADK

The Google ADK Board

I thought I’d provide some details on what’s provided with the Google ADK board, and start sharing some of my experiments with it (more to come!)

First, the base board itself is an Arduino Mega 2560 with USB Host shield, pretty much identical to the official Arduino ADK board.

Google Arduino ADKArduino ADK

The Accessory Demo Shield sits on top, and provides quite a few goodies:

Outputs:
Relays (2)
tri-color LEDs (3)
Servo controls (2)

Inputs:
Pushbuttons (3)
Light sensor
Temperature sensor
Capacitive touch sensor
Joystick (X,Y, and push-switch)

Google Accessory Demo Shield

The ADK kit also includes a power supply and 2 sub-micro servos (Blue Arrow S03611).
Here are the connected pins (as configured in the demokit sketch):

pin pin pin
A0 RELAY1 0 <RX> 14 TOUCH_RECV
A1 RELAY2 1 <TX> 15 TOUCH_SEND
A2 LIGHT_SENSOR 2 LED3_RED 16
A3 TEMP_SENSOR 3 LED3_BLUE 17
A4 4 LED3_GREEN 18
A5 5 LED2_RED 19
A6 BUTTON1 6 LED2_BLUE 20 SDA
A7 BUTTON2 7 LED2_GREEN 21 SCL
A8 BUTTON3 8 LED1_RED
A9 JOY_SWITCH 9 LED1_BLUE
A10 JOY_Nint 10 LED1_GREEN
A11 JOY_Nreset 11 SERVO1
A12 12 SERVO2
A13 13 SERVO3
A14
A15

Curiously, the Shield board is built so that it blocks access to the headers for pins 22-53. There doesn’t seem to be any particular reason for this – there’s nothing important in that section of the board other than Google and Android logos.

Communicating

The demo kit lays out a basic structure for sending messages back and forth between the device and an Android application. The message is a 3-byte array consisting of a data type, the address of the intended recipient, and a value.
msg[0] : type of data
msg[1] : address
msg[2] : value

Messages from Android to the Arduino:
msg[0]:
0x2    LED    msg[1]:            msg[2]: value
0x0    LED1_RED
0x1    LED1_GREEN
ox2    LED1_BLUE
0x3    LED2_RED
0x4    LED2_GREEN
ox5    LED2_BLUE
0x6    LED3_RED
0x7    LED3_GREEN
ox8    LED3_BLUE
0x10    servos[0]
0x11    servos[1]
0x12    servos[2]
0x3    RELAYS    msg[1]:       msg[2]: true/false
0x0    RELAY1          (msg[2] ? HIGH : LOW)
0x1    RELAY2

For messages from the Arduino sketch to the Android device:
msg[0]
0x1    buttons        msg[1]              msg[2]: value (0/1)
0    BUTTON1
1    BUTTON2
2    BUTTON34
3    cap sensor
4    JOY_SWITCH
0x4    temp sensor    msg[1] = val >> 8    msg[2] = val & 0xff
0x5    light sensor   msg[1] = val >> 8    msg[2] = val & 0xff
(note: val is a 16 bit uint, converted to 2 bytes in msg[])
0x6    joystick       msg[1] = x           msg[2] = y

I don’t know how much value this is to anyone, but it may be nice to have for reference.
The supplied app and sketch provide basic methods of interacting with the inputs and outputs on the board. I’m not going to go into details on it here, perhaps in a separate post.
Rather, I’m going to dive right into making a custom app:

The Bare Minimum

When learning new technology, I like to strip out a lot of the provided demo and start with the minimum, and build up from there. So here’s the bare minimum to make an ADK app (ok, I’m still going to use the Usb and AndroidAccessory libraries, because I don’t feel like reinventing the wheel – I’m not a masochist)

Create a new Android application, referencing at least API level 12. I’m using 13 because my Xoom has 3.2 installed.

Edit AndroidManifest.xml:

Add an intent filter to the Activity for the USB_ACCESSORY_ATTACHED intent, and a reference to an xml file that will provide meta-data describing the device:

 <intent-filter>      
<action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"/> 
</intent-filter> 
<meta-data android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"     android:resource="@xml/accessoryfilter"/> 

Create the accessory filter:

In res/values/xml, create accessoryfilter.xml:

<resources>
<usb-accessory manufacturer="RandomRobotics" model="ADK" version="1.0"/>
</resources>

That’s all that’s required on the Android side. Obviously, our app does nothing, and will only react to an accessory being connected. There are plenty more things we can add to it later, such as responding to the USB_ACCESSORY_DETACHED intent, or enumerating devices that are connected when the app is run.

Let’s go ahead and do the Arduino code:

#include <Usb.h>
#include <AndroidAccessory.h>

AndroidAccessory acc("RandomRobotics", "ADK", "Bare ADK App", "1.0",
"http://www.randomrobotics.com/sw/ADK_BareMinimum.apk", "1234");

void setup()
{
Serial.begin(115200);
acc.powerOn();
}

void loop()
{
if (acc.isConnected()){
Serial.println("connected!");
delay(1000);
}
delay(100);
}

As you can see, I’m using the Usb and AndroidAccessory libraries supplied by Google (and based on circuitsathome code)

Create an accessory object with the following string information: manufacturer, model, description, version, uri, serialnumber.

This information identifies this particular device, and correlates to the information in the accessoryfilter.xml file in the app. The URI is useful because it can link to information about the device or even to the app itself, as I’ve done here. This means if the accessory is plugged into an Android device that doesn’t have an app installed that handles it, you can be prompted to download the app.

link_to_adk_app

If you click View, it will open the link in the browser, which will automatically download the .apk file. You can then install the file (assuming the “Unknown Sources” option is enabled in Settings>Applications so you can install non-Market apps). Now when you plug in this device the app will ask if it should run:

run_adkbareminimum

No comments yet.

Leave a Reply

Powered by WordPress. Designed by WooThemes