mbed with Android ADK

mbed with Android ADK

Introduction

With the growth of android as the mobile OS of choice for many producers, Google recently released a accessory development library/kit (ADK) for developing hardware addons for devices. Although these libraries only work on version 2.3.4 or 3.1 or later, the ADK provides a robust USB serial link from platform to app. This cookbook page is about integrating it with mbed, and how to create apps with it.

The mbed side

The mbed side is composed of the USB host library, wrapped by the Android Accessory Class, which provides a stable connection to and from the system. In using the library one needs to develop a custom implementation, a few examples are shared later. The implementation includes the USB visible details of the device, such as name, manufacturer and version. It also provides a set of virtual functions which are used for call-backs when data is received or the sending is completing and start-up functions. USB is best suited to sending packets, rather than a serial stream, as it has a packet system, so a printf function is not implemented, instead there are char array outputs, which can be written to simply using a sprint function or direct char manipulation. The AndroidAccessory library was written primarily by makoto abe, and was then modified by yours truly ( Giles Barton-Owen) into a library which works pretty stably in read and write. The library and class are available here:

Import library

Public Member Functions

  AndroidAccessory (int rbuffsize, int wbuffsize, const char *manufacturer, const char *model, const char *description, const char *version, const char *uri, const char *serial)
  Create a AndroidAccessory object.
virtual void  init (int device, int configuration, int interfaceNumber)
  Init the device This is meant to be implimented by the user of the class.
virtual void  resetDevice ()=0
  Reset the device This is meant to be implimented by the user of the class.
virtual void  setupDevice ()=0
  Setup the device This is meant to be implimented by the user of the class.
virtual int  callbackRead (u8 *buff, int len)=0
  Callback on Read This is meant to be implimented by the user of the class.
virtual int  callbackWrite ()=0
  Callback after Write This is meant to be implimented by the user of the class.
int  write (u8 *buff, int len)
  Write over USB This sends the data in the buffer over USB in a packet.
int  write ()
  Write over USB This sends the data in the buffer over USB in a packet, sends _writebuff and _writebuffsize.
int  writeNC (u8 *buff, int len)
  Write over USB with no callback This sends the data in the buffer over USB in a packet, waits until the packet is sent, rather than doing a callback.
int  writeNC ()
  Write over USB This sends the data in the buffer over USB in a packet, waits until the packet is sent, rather than doing a callback, sends _writebuff and _writebuffsize.
int  read (u8 *buff, int len)
  Read the buffer USB This sends the data in the buffer over USB in a packet, waits until the packet is sent, rather than doing a callback.

The android side

As an embedded developer mostly I find android development a complete pain, so I have tried to abstract all of the USB part of the operating system clutter away into an easy to use library, providing byte array and string writing and a function call on new data. However android does not let it be quite that easy, one has to add some lines to the AndroidManifest.xml file. This really isn’t that tricky but is really essential, or it the whole app just crashes on boot. Details are available here down the page. An intent filter is also needed, so that the device knows that that app could well be started when the app is run, this is also documented on the developer site, previously listed, but need to be tailored to the particular device: in this case the device is "mbed" by "ARM" version "0.1". Although this library will only work with 2.3.4 targets, these can be run on any later android systems and the library would not be too hard at all to be modified for 3.1 (a few lines) to use the different libraries. The AdkPort library is very simple to use, and requires only a few lines to be added to the program:

private AdkPort mbed;
...
public void onCreate(Bundle savedInstanceState) {

		super.onCreate(savedInstanceState);
                ...
                mbed = new AdkPort(this);
                Thread thread = new Thread(mbed);
                thread.start();
                mbed.attachOnNew(new AdkPort.MessageNotifier(){ 
			@Override
			public void onNew()
			{
				byte[] in = mbed.readB();
                                // Do something with the data
                        }
                });
                ...
       }

The (beta but fairly stable and well tested on a XOOM and a Nexus One) library is available here: /media/uploads/p07gbar/adkport.zip

The library makes it fairly simple to use the ADK with android, abstracting it to a point where little knowlege is really needed, however a few things need to be kept in mind: this library only works with Google API level 10, meaning you will have to download that from the SDK and AVD manager (see instructions on the Google SDK docs here, which provides a complete guide. The API level 10 is available under Available packages - Third party add-ons - Google inc - Google APIs by Google Inc - Android API10, revision 2.

A demo

The tools made available by the ADK are staggering, a direct, high speed serial/bulk end point between a micro controller and a miniature computer (on now the worlds biggest mobile OS) and the scope for such a connection could be huge, however, here is a fairly simple, but fun demo that would easy to throw together (especially with certain USB and rotary pot equipped demo boards)...

/media/uploads/p07gbar/_scaled_imag0170.jpg /media/uploads/p07gbar/android-adk-sketch_schematic.png

The demo consists of a mbed hooked up to two rotary pots and a USB A female socket, with two 10K resistors to ground, and the VBUS of the mbed connected with the VBUS of the USB connector (external power could be used, but must be at 5V to power the USB bus). A micro USB lead is then connected to the Motorola XOOM tablet, which is running the demo app. The position of the pots dictates the current point on the screen where the line is being drawn to, and lines are drawn from the current point to the last point, and back to the start of the program. The screen is cleared by either tapping the screen, or shaking the XOOM quite strongly.

The messages are sent to the XOOM from the mbed once the mbed has recived anything over the port. It then sends 5 byte packets in the form:

ByteFunction/Value
0“P”
1Left pot low byte (float read *10000)
2Left pot high byte (float read *10000)
1Right pot low byte (float read *10000)
2Right pot high byte (float read *10000)

On the tablet, the values are scaled to the screen size, so the mbed has no knowledge of its target's size.

The complete Android Application is available here: /media/uploads/p07gbar/mbedadksketch.zip

And the mbed application here:

Import programADKEtchasketch_wbeta

A simple mbed+Android ADK etch-a-sketch example, see cookbook

The final demo

After implementing a simple pong game, as well as the etch-a-sketch demo, a red acrylic suround and backing was made for the project, and it was assembled into the finished demo: /media/uploads/p07gbar/_scaled_imag0173.jpg

I have also created a few serial port demos with a console to debug: /media/uploads/p07gbar/mbedwrapper.zip Which goes with:

Import programADKTerm

This program is just a simple serial port program for communication with mbedWrapper





21 comments:

04 Aug 2011

Thank you all so much! i will go to try!

16 Oct 2011

I tried to use the library for communication with an SGS2. But it seems that the android device doesn't return any interfaces (only the bare configuration descriptor) when the configuration descriptor (DESCRIPTOR_TYPE_CONFIGURATION) is called in this function int SetConfigurationAndInterface(int device, int configuration, int interfaceNumber, DeviceDescriptor* desc) Any ideas what the error could be?

17 Oct 2011

Firmware needs to be 2.3.4+ apparently(but doesnt work on SGS2 I9100GT, i think because it has some special USB OTG host drivers specific to it). You must also use the Android SDK API 10 or higher. I've tried many recent firmwares upto 2.3.5 XXKI3 and still dont work. Let me know if you have any success.

17 Oct 2011

Thanks for the feedback.

Sorry, forgot to mention those details. The firmware on the SGS2 is 2.3.5 (not official, but some 'leaked' version), before that i had the official Samsung 2.3.4 FW running. For the Android app i'm using the Google API Add-on for ADK, API level 10.

Is it correct that the Android App doesn't need to be running to get a connection going, without data transfer or anything off course?

1. connect SGS2 with mbed via usb, app on android not running 2. restart mbed

The android app i'm using now immediately gets an accessorylist from the USBmanager, and that list is null off course, then the app terminates. I'm guessing that the accessory protocol should be handled by the android kernel, or am i wrong here?

17 Oct 2011

R A i really wish I knew more but I have'nt been able to get this working. So I cannot speak from any real experience. What I have heard is that if you have your code running on the mbed and plug it into a ADK compatible device via USB. It should say USB Accessory Connected, then will launch your app or look for the associated app via the market place.

25 Oct 2011

Thanks for the reply. Meanwhile i tried everything within my power to get it to work. Recompiled the kernel with different USB options set, but no success. The Getprotocol from mbed to SGS2 always returns -1.

25 Oct 2011

Yer I gave up too with the SGS2, quite annoying. I went out and brought a A100(3.2) Acer tablet, and all works perfectly.

09 Jan 2012

Hy everybody! I'm approaching Android world in order to connect my hardware to smartphones by USB . I read on android developers website that smartphone manufacturer can or cannot insert adk with usb accessory with 2.3.4+, while 3.x version is ok . So how can I have this information? The problem is only in 2.3.4 or later versions, while with 3.x version there is't troubles

24 Jan 2012

Did you have to use a separate USB connector? Could you have had a separate power source and connected the on-board USB connector directly to Android device? Or is that USB connection only used for the programmer?

26 Feb 2012

/media/uploads/xiong_quan/2012-2-26_23-24-52.jpg

When I run the MbedWrapperActivity application under AVD of Google Inc. level 10, there is always report error as "force close". I also try the MbedADKSketchActivity under real "nexus s" after install apk successful, same report. I didn't install mbed via usb and connect it with cellphone, and I will try it. But even if I didn't install mbed via usb, there should not be this kind of problem. I hope there are some one try the code successful and give me some information about what I should do next.

26 Feb 2012

Quan, the app was written to be as simple as possible, and ( partly due to Google's poor documentation on the subject) does force close without the usb... it's possible to circumnavigate the floor but not without unnecessary complication in terms of example code

William Adler wrote:

/media/uploads/xiong_quan/2012-2-26_23-24-52.jpg When I run the MbedWrapperActivity application under AVD of Google Inc. level 10, there is always report error as "force close". I also try the MbedADKSketchActivity under real "nexus s" after install apk successful, same report. I didn't install mbed via usb and connect it with cellphone, and I will try it. But even if I didn't install mbed via usb, there should not be this kind of problem. I hope there are some one try the code successful and give me some information about what I should do next.

28 Feb 2012

Thanks for Giles Barton-Owen and Eric Williams's suggestion, and after two steps: 1. Using a separate power source instead of PC to power mbed board; 2. Plug in usg connector to cellphone and application is going to initialize auto instead of start the application by hand and connect USB link; There is two application for me to select (I install both MbedADKSketch and mbedWrapper), which means debugging under Android accessory protocol is successful. /media/uploads/xiong_quan/20120227473_1.jpg

I post one photo and hope would encourage more investigation of Android accessory protocol. Actually, I am going to implement Android accessory protocol with high speed rate (around the max of full-speed USB 12 Mbps) to transceive medical data for research. I hope to communicate with people who also want to investigate more on Android accessory protocol.

09 Mar 2012

Nice...implementing this weekend.

09 Mar 2012

It is excellent but i can´t initiallize the app, i have modified the app to run in 3.1 devices, the app its insatlled on my tablet Android 4.0.3 Kernel 3.0.8) and but i cant open the app.Can someone post your app running on 3.1 or later devices to check if something its wrong?. Thank you

Greetins.

01 May 2012

This is great stuff. Thank you so much.

Does anyone have recommendations on how to debug the ADK communications given that both the mbed device and the Android device's USB channels are monopolized?

I modified the AdkPort code to run using android.hardware.usb.*. I had successful communication between my Android and mbed devices working, but then it mysteriously broke. I cannot figure out what I've changed that is causing the failure. I've backed out my changes with no luck.

Any ideas on how to find the problem??

05 Sep 2012

I have 2.3.5 installed on my HTC desire HD. Can I use this application?

05 Sep 2012

Usman Javaid wrote:

I have 2.3.5 installed on my HTC desire HD. Can I use this application?

Is 2.3.5 later than 2.3.4? Seemingly so: should work... Hasnt been tested on this device tho so no guarantees

05 Sep 2012

William Adler wrote:

Thanks for Giles Barton-Owen and Eric Williams's suggestion, and after two steps: 1. Using a separate power source instead of PC to power mbed board; 2. Plug in usg connector to cellphone and application is going to initialize auto instead of start the application by hand and connect USB link; There is two application for me to select (I install both MbedADKSketch and mbedWrapper), which means debugging under Android accessory protocol is successful.

I post one photo and hope would encourage more investigation of Android accessory protocol. Actually, I am going to implement Android accessory protocol with high speed rate (around the max of full-speed USB 12 Mbps) to transceive medical data for research. I hope to communicate with people who also want to investigate more on Android accessory protocol.

I think that if you get two notifications like this, it means that there are two apps installed that claim ADK with the intent thing.

01 Oct 2012

@Michael Karlesky, Did you ever fix this problem? I'm having the same issue.

Michael Karlesky wrote:

This is great stuff. Thank you so much.

Does anyone have recommendations on how to debug the ADK communications given that both the mbed device and the Android device's USB channels are monopolized?

I modified the AdkPort code to run using android.hardware.usb.*. I had successful communication between my Android and mbed devices working, but then it mysteriously broke. I cannot figure out what I've changed that is causing the failure. I've backed out my changes with no luck.

Any ideas on how to find the problem??

Michael Karlesky wrote:

This is great stuff. Thank you so much.

Does anyone have recommendations on how to debug the ADK communications given that both the mbed device and the Android device's USB channels are monopolized?

I modified the AdkPort code to run using android.hardware.usb.*. I had successful communication between my Android and mbed devices working, but then it mysteriously broke. I cannot figure out what I've changed that is causing the failure. I've backed out my changes with no luck.

Any ideas on how to find the problem??

20 Mar 2013

Has anyone tried this on a KL25Z with it's built in host USB?