Posts

Andriod ADK-compatible USB Host Library release.

UHS Charging Android

UHS Charging Android


Android Open Accessory Development Kit, announced on Google IO the other day is a hot topic. Android Open Accessory support, introduced in Android 3.1 (tablet OS) and backported to 2.3.4 (phone OS), allows external USB devices to interact with Android phone/tablet switched to so-called “accessory” mode. Because phones are USB functions (AKA devices) this accessory device must act as USB host. Arduino USB Host Shield has been around for couple of years providing USB Host functionality for standard and Mega form factor official Arduinos, as well as several clones. Luckily for all Arduino enthusiasts out there, Google decided to adopt this very architecture for hardware component of ADK. As a result, said enthusiasts now have well defined and documented code layer to interact with Android devices, ready to run on Arduino board of their choice. Well, almost.

The ADK code is targeted for ADK hardware component, which is just Arduino Mega 2560 and USB Host Shield combined on a single PCB. However, they decided to move some pins around; as a result in order to use the code with standard “Arduino plus 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 another distro. Second, the code modification exercise would have to be repeated each time Google releases new version of ADK. Finally, it’s difficult to have both standard and Google USB librares installed in Arduino IDE at the same time. Given all that, I decided to take different approach.

Google’s variant of USB Host Shield library differs very little from official library. The only significant difference is newInTransfer() member function of USB class, which returns real length of received packet. In order to support AndroidAccessory component in official library, I simply added this function to the library code and made a new release – it is now available on gitHub. I placed it into “dev” branch for now – it will be moved to “master” after a period of testing.

To get Arduino part of ADK installed, get the new library from gitHub, then put AndroidAccessory directory with files into “%arduino/libraries”. After that, the following snippet can be pasted from this page directly into Arduino IDE window or downloaded from “examples” directory of USB Host library.

The following code was created by stripping down demokit.pde sample ADK sketch from non-essential code. I don’t know how to program Android device yet so at present I only worry about device detection step. Under Arduino-0018, this sketch compiles into 9K – there is plenty of room left even on 16K Arduino boards. The code is self-explanatory (or so I hope):

#include <Max3421e.h>
#include <Usb.h>
#include <AndroidAccessory.h>
 
AndroidAccessory acc("Google, Inc.",
		     "DemoKit",
		     "DemoKit Arduino Board",
		     "1.0",
		     "http://www.android.com",
		     "0000000012345678");
void setup();
void loop();
 
void setup()
{
	Serial.begin(115200);
	Serial.print("\r\nStart");
	acc.powerOn();
}
 
void loop()
{
  byte msg[3];
 
	if (acc.isConnected()) {
                Serial.print("Accessory connected. ");
		int len = acc.read(msg, sizeof(msg), 1);
                Serial.print("Message length: ");
                Serial.println(len, DEC);
        }
 
	delay(100);
}
ADK output

ADK output

Screenshot on the left shows the output. A Nexus S phone is connected to the shield and as can be seen here program goes through steps described in ADK doc, first detecting and then switching the phone in accessory mode. The majority of diagnostic output is generated by AndroidAccessory. Since I don’t have ADK application running on the phone, no messages are returned. The phone would also output diagnostic message reporting the fact that no accessory code is present on it.

While playing with the phone, I made some experiments. I heard that some phones draw excessive power from VBUS, overloading 5V power supply. I was unable to replicate that; in my setup, Arduino is running from USB power and phone charges nicely and everything else also works as expected. I was also curious to see if phone would run with 3.3V on VBUS. Well, it didn’t – so if you plan on using Android phone with 3.3V-only shield, such as ever-popular Mini make sure to provide 5V to VBUS, otherwise the phone won’t respond. Consult hardware manual for ways to provide 5V VBUS on 3.3V-only shields.

The Arduino-Android connectivity opens a lot of exciting possibilities. Modern phones have large displays and big CPUs; at the very least, it would be very easy to come up with an application similar to Wiring – a phone can act as a nice display and also provide processing power. Also, upcoming major release of USB library will include USB hub support so it would be possible to build projects integrating several USB devices and adding Android to the mix is even more exciting.

Please try the new library and let me know if you encounter any issues, especially with projects that were working fine with older revisions. If you do, just restore the library code from “master” trunk. I’m now going to spend some time setting up Eclipse and learning to code Androids. Stay tuned for the updates!

Oleg.

82 comments to Andriod ADK-compatible USB Host Library release.

  • Starfire-1

    Oleg –

    I was able to incorporate you dev library as well as checkout the new shield that you sent recently. All is OK to this point. Thanks!

  • Mathew

    How would one of these shields work with other avr devices, I use the pololu baby orangutan and custom avr boards (one based on at-mega 1284p) (all programmed with c/c++). I would love to use the android phone (nexus one, 2.3.4) to communicate with these..

    Would I go for your mini shield and it would connect directly or would i have to go through one of the mini arduino boards?

    I would basically want to communicate with my devices (all 5V) over TTL Serial.

    • If you want to use mini shield with 5V micro, add level shifters to control pins (See schematic for full-size shield.) You can also make standard mini-shield + Arduino Pro Mini 3.3V setup and level-shift serial pins. In any case, provide 5V to VBUS as Android phone won’t detect USB bus if VBUS is supplied with 3.3V.

  • MAPGPS

    Can we let Andriod act as USB Host?
    So the integrated FTDI in Arduino Nano can talk to Andriod via USB.

    Today’s Linux kernel already has ftdi_sio.ko driver module to support FTDI,
    and /dev/ttyUSB0 will be created after ftdi_sio.ko loaded.

    The key issue is, most of Andriod phones do not allow to load customized kernel…

  • I just got the USBHost Shield, built and tested it with the test project. Then I read the post about Android interfacing and go the second library package, renamed it to AndoirdAccessory and installed it where I had the prior lib. The example code will not compile, gives the
    following error

    adktest.cpp:3:30: error: AndroidAccessory.h: No such file or directory

    And in fact there is no file by that name in the package from GITHub.

    Please email me with some help oleg, I want to get started right away.

  • […] out his post for his solution. Filed under: arduino — by kgroce, posted May 18, 2011 at 12:31 pm […]

  • George

    This worked like a charm on my Arduino Mega2560. Thanks much.

  • Hi Oleg, nice work to get the code for ADK working on your host shield. This convinced me to buy one and try the same.
    Hope to receive it soon. Will be back for trouble shooting šŸ˜‰

  • gil

    Hi oleg
    I connected my samsung galaxy tab 2.2 to the usb host(I know it doesnt support Aceessory mode), and got this on the serial monitor:
    Start
    Device addressed… Requesting device descriptor.
    found possible device. swithcing to serial mode
    Data packet error: 5
    could not read device protocol version
    the host cant read device protocol, and it should be able to read the protocol anyway.
    can u please add a screen shot of what happens when you connect the USB Host shild to an android powerd device that doesnt support Accessory mode?
    thanks

    • Error 5 is STALL; USB device returns it when it receives a request which it can’t interpret. In this case, the “bad” request is Google vendor-specific request sent to switch device to accessory mode.

      • diego

        I’ve tested your code and it works, but I have the problem that my phone is a HTC with vendor id 0x0bb4. I have read that only the phones with a Google’s ID (0x18d1) have the accessory mode.

        So, do you know if ADK will be supported for all devices? or are there some tricks that I can do to make it work, such as change my phone’s vendor and product ID?

        Thanks

        • What OS version are you running on your phone?

          • diego

            I’m running the CyanogenMod 7.1.0 rom that is Android 2.3.4

          • If ADK is supported, the phone should switch to Google VID/PID from vendor’s, as documented here -> http://developer.android.com/guide/topics/usb/adk.html

          • diego

            The message I get executing your code is the following:

            Device addressed… Requesting device descriptor.
            found possible device. swithcing to serial mode
            Data packet error: 5could not read device protocol version

            Reading that page, this is what you get when the VID and PID is not Google’s and the library executes the method ‘switchDevice’ that is explained in “Attempt to start the device in accessory mode” section. Then it returns false and the sendString methods are not executed. I don’t think that the VID/PID will change, but I wish.

            If you know another solution, I’d like to hear it. Thanks a lot

          • Data error 5 is STALL which is a USB way to say “I don’t understand the request”. AKD code sends 3 different types of requests during initialization, you may want to find out which one results in STALL. VID/PID is not that important, you can bypass this test if everything else is OK.

          • diego

            I get error 5 when the request 51 (the first) is sent. When executing the following code, the dispatchPkt in the inTransfer in Usb.cpp file returns 5 instead of 0 (that means ACK, isn’t it?) and I don’t know why.

            while( 1 ) { // use a ‘return’ to exit this loop
            rcode = dispatchPkt( tokIN, ep, nak_limit ); //IN packet to EP-‘endpoint’. Function takes care of NAKS.
            if( rcode ) {
            return( rcode ); //should be 0, indicating ACK. Else return error code.
            }

            Thanks

          • It means ADK is not supported (you can get the same result from any random USB device – I’m currently writing ADK support for the new revision of USB library and test the code with whatever is lying around). This is new to me – I thought any Android phone running 2.3.4 would have ADK supported. I’m now wondering – are Nexus S and Nexus One the only phones that support ADK?

          • diego

            Could it be an issue of rooted phones or a problem with my custom rom? Tomorrow I’ll try with a friend’s Android device that is not a Nexus. If I find something new, I tell you. Thanks

            P.D.: In the videos I saw, there is always a Nexus One or Nexus S ¬¬

          • It seems that vendor 51 request is not specific to ADK. I have other two devices returning data to this request – one device id HID and another is UVC.

  • gil

    Hi
    thanks for your quick answer…
    I want my accessory to work on small bataries.
    do you have any idea what will happen if i try to connect USB host to an Accessory mode device, but will not supply 5v at 500ma?

    • It’s hard to say; self-powered USB devices vary in behavior. Some are quite happy with VBUS charged just to 3.3V, others won’t work at all in this configuration. You need to experiment with your particular device and see what happens.

  • Scott

    Has anyone tried getting the AndroidAccessory library to work with version 2 of the usb host library? I ran into issues with that, and can’t seem to wrap my head around it. Any suggestions or links to posts would be helpful. Thanks

  • Nate

    Does this only work for Android 2.3.4 (which I think is only in the Nexus One) or can other versions work as well?

    • The ADK interface was introduced in 2.3.4; currently, Nexus S and Nexus One are the only phones that support this interface.

  • bob1810

    This library won’t work on the Mega ADK,I tought it was meant to work on this “Official” board from Arduino.
    First I get the error “Failed to assert”,but when I change the following part in the file “Max3421e.cpp” :
    (This is from a post in the arduino-forum: http://arduino.cc/forum/index.php/topic,68205.0.html
    Scroll down to find the August 03, 2011 post by SKNight )

    boolean MAX3421E::reset()
    {
    byte tmp = 0;
    regWr( rUSBCTL, bmCHIPRES ); //Chip reset. This stops the oscillator
    regWr( rUSBCTL, 0x00 ); //Remove the reset
    while(!(regRd( rUSBIRQ ) & bmOSCOKIRQ )) { //wait until the PLL is stable
    tmp++; //timeout after 256 attempts
    if( tmp == 0 ) {
    return( false );
    }
    }
    return( true );
    }

    to :

    boolean MAX3421E::reset()
    {
    regWr( rUSBCTL, bmCHIPRES ); //Chip reset. This stops the oscillator
    regWr( rUSBCTL, 0x00 ); //Remove the reset
    while(!(regRd(rUSBIRQ) & bmOSCOKIRQ)) ;
    }

    The “failed to assert”-error is gone but nothing much happens.
    The “board_test.pde” shows no output at all on the terminal screen…

    • Arslan

      Hi, I am having the similar problem. I am using Mega ADK and getting nothing on the terminal after i change the USB host shield library as you have mentioned before.
      Does anyone know how to fix it?

  • subkhan

    Hi Oleg,
    Are Nexus S and Nexus One that only can work well with your usb host shield?
    I wanna get one that UHS, but I’m afraid Galaxy Ace (OS 2.3.4) won’t work
    Please let me know if you have tested other smartphones.

    Thank You

  • Memebrain

    hi Oleg-
    I’m using a Samsung Galaxy 5 with cyanogenmod 2.3.5 and cannot install the DemoKit app to the phone from Eclipse. I can run the app on the emulator but just can’t get it onto the phone. I’ve installed other simple apps to the phone from Eclipse.
    the error I get is:
    [2011-10-17 04:24:43 – DemoKit] Installing DemoKit.apk…
    [2011-10-17 04:24:47 – DemoKit] Installation error: INSTALL_FAILED_MISSING_SHARED_LIBRARY
    [2011-10-17 04:24:47 – DemoKit] Please check logcat output for more details.
    [2011-10-17 04:24:47 – DemoKit] Launch canceled

    Any ideas?

    • sergiosmail

      Hi Memebrain.
      You get this error when your device doesn’t support ADK library. Maybe CM doesn’t include support for ADK in his roms.
      I get this error with SGS2 and 2.3.4 rom (I9100XX KI3). Using 2.3.4 rom I9100XX KH3 I can install DemoKit.apk but the terminal doens’t recognized the accessory when pluged! Today I will test last firmware I9100XXKI8

  • John

    Hi Oleg,

    I’m using 3.2 on a 7″ tablet. I can connect and the tablet responds and launches the associated application and tells me it’s connected. But I can’t seem to send or receive data.

    I appear to be getting error 4 while attempting to receive data on the ATMega. I presume error 4 (NAK) is OK when there’s no data to receive? However I get this even when I have the tablet send out the data.

    When sending data from ATMega to Tablet I appear to get error 3 – which I think is “hrUNDEF”.

    At the moment I’ve no idea if the issue is on the ATMega end or the Tablet end. If I had to guess I’d say probably the tablet (after three or four attempts to send a message the process freezes and I have to use “Force Close”.

    Any ideas of how to debug this?

    Here’s the loop code
    [code]
    void loop()
    {
    byte msg[3];
    int rcode;

    if (acc.isConnected()) {

    // Receive
    static int lastIn = -99;
    rcode = acc.read(msg, sizeof(msg), 1);
    if (rcode > 0) {
    Serial.print(“Accessory Message Received. Length: “);
    Serial.println(rcode, DEC);
    if (msg[0] = 0x2)
    digitalWrite(13, (msg[1]==1 ? HIGH : LOW));
    }
    else if (rcode != lastIn) {
    if (rcode == -1) {
    Serial.println(“Error while receiving message: NAK or TIMEOUT”);
    }
    else if (rcode == -2) {
    Serial.print(“Error while receiving message: “);
    Serial.println(rcode, DEC);
    }
    else {
    Serial.println(“Zero bytes read”);
    }
    }
    lastIn = rcode;

    // Send (non-blocking wait of 10 seconds and then send once per second)
    static unsigned long gate = 10000;
    static byte counter = 0;
    static int lastOut = 0;
    if (millis() > gate) {
    gate = millis() + 1000;
    // if (lastOut == 0) {
    Serial.print(“Sending message with counter value = “);
    Serial.println(counter, DEC);
    msg[0] = 0x1;
    msg[1] = counter++;
    msg[2] = msg[1];
    rcode = acc.write(msg, 3);
    // if (rcode != 0 && rcode != lastOut) {
    Serial.print(“Error while sending message: “);
    Serial.println(rcode, DEC);
    // }
    lastOut = rcode;
    // }
    }
    }

    delay(100);
    }
    [/code]

    And here’s the terminal output
    [code]
    Start

    Device addressed… Requesting device descriptor.
    found possible device. swithcing to serial mode
    device supports protcol 1

    Device addressed… Requesting device descriptor.
    found android acessory device
    config desc
    interface desc
    interface desc
    In End Point:5
    Out End Point:4
    Connected, configured and ready for use…
    Error while receiving message: NAK or TIMEOUT
    Sending message with counter value = 0
    Error while sending message: 3

    [/code]

    • I would start with something which works, like Google ADK demo. I have a small example which works with Google’s demo which uses one switch and one LED.

  • JP

    Hi Oleg,

    do you know how to use the USB host library for chipkit UNO32?

    Thanks and best regards!

    JP

  • clteich

    Hey Oleg,

    i installed all libraries (adk, usb host shield) as described by google and you. when i start your demokit.pde, the acc.powerOn() seems to work properly, but then nothing happens on the serial monitor. my htc sensation (android 4.0.3) is connected to the shield and it’s charging, i use arduino ide 0023. the arduino board is via mini-usb conencted to my pc and the usb shield with a 9v battery.

    can you suggest anything for troubleshooting?

    thanking you in anticipation

  • Ron

    Thanks for this article.
    I have a Nexus S phone with Android 4.1 (Jelly Bean) installed. I’ve tried several of Simon Monks apps that use the phones USB Accessory capability. The phone is connected to the Arduino Uno(with USB Host shield). But the Arduino IDE serial monitor is outputing the following:

    Device addressed… Requesting device descriptor.
    found possible device. swithcing to serial mode
    could not read device protocol version.

    It seems that the USB::ctrlReq called from the AndroidAccessory::getProtocol is returning 0.;

    Any help would be greatly appreciated.

  • MarcoSD

    Great work on these USB host libraries! All the code I can find uses polling to talk to the MAX3421, rather than waiting for an interrupt (attachinterrupt). I wanting to conserve processor cycles. Has anyone looked into an interrupt-based interface to the MAX3421 for HID devices?

  • Vinod

    I got rcode as -1 at rcode = dispatchPkt( tokIN, ep, nak_limit );

    What may be the error..?
    I am connecting huawei y200t 4.03 with Arduino uno and itead USB Sheild. I am not connecting any external supply. Plz guide me in this. Thanks Oleg

    • Vinod

      Sorry, rcode as 4 instead of 0…! from dispatchPkt( tokIN, ep, nak_limit )….

      Thanks in advance Oleg

      • 4 is NAK. NAKs are caused by many things; often it’s simply because a device has nothing to send back.

        • Vinod

          Thanks, i used usbhost 2.0 library and i uploaded the code to the board, now its blinking. But when i disconnect and connect the board again, its not blinking…
          I have to re-upload once again to make blink.. Any suggestions will be helpful thanks

  • eng.Shahin

    Mr.Oleg ,
    i have Arduino Mega ADK board and when i open the serial monitor , this message appeared (Error: OSCOKIRQ failed to assert)
    what is the solution ,please ???
    i installed Arduino 1.0.1 with (adk_release_20120606.zip) Libraries
    thanks in advance…

  • nupur

    hello,
    i am trying to connect my ADK board through USB.
    But i don’t have android phone šŸ™ — i am low on budget.
    is there any way to connect my Android Virtual Device with board ??
    if not USB, can i try with bluetooth ??
    –plz help me out

  • allanonmage

    Hi there! I keep coming across this site and these few articles when I Google anything USB for Arduino. I guess I’m in close to the right place šŸ™‚

    I have an Arduino ADK Mega R3 and I’m wanting to turn on the USB host and attach a PS3 controller. I’m not clear if your library supports my hardware or not. This article and github make mention that it’s ADK compatible, but then talk about changing pins around. I thought I saw some forum posts newer than this article that said this library was not compatible with my board.

    Advice or directions please?

  • allanonmage

    Hey Mod, this is a little more clear:

    I was having a hard time finding info about the MEGA ADK board and how or if this library would work as all my googling and net surfing led me back to this site and project.

    Yes this library (USB_Host_Shield_2.0) will work with the Arduino MEGA ADk. You have to uncomment one line of code and that’s it:

    #define BOARD_MEGA_ADK
    which can be found in avrpins.h

    If you try it without the modification, you’ll get an error “OSC did not start”.

    I didn’t come up with this idea, Lauszus mentioned it at the URL below. My intent in regurgitating it is to answer the question for the next googler so they don’t spend 8 hours searching for this tidbit of info like I did.

    http://www.circuitsathome.com/mcu/hid-support-for-usb-host-shield-library-2-0-released

  • Jay23

    Hi All,
    I am building a Android app to work with a Arduino Uno over the USB. The app should show the temperature readings from a temp sensor. The sensor is working as I can confirm the reading from the serial terminal. But i have problems with USB to the Android telephone. Can get it to work. I am using a Sparkfun USB host shield and and am using Android phone with 4.0.1.
    Has anybody managed to get it work with the shield or should I use Arduino Mega ADK to get it to work?
    //regards, Jay

  • Ali_K

    Hi,
    Nice work you guys, I just love the things you come up with regarding the libraries. The best thing for fast projects.
    Well I have a problem, I am tiring to connect the Wiimote with the Arduino ADK and a Bluetooth dongle. The problem is this, that the Wii.ino example that you have on your website wound build. I don’t know what the cause is exactly, It seems that there are some libraries missing (I have added them (USB, Bluetooth…) it didn’t solve match) And that there is an problem with the definitions in the WII library.

    Some of the errors:
    In file included from Wii.ino:7:
    I:\arduino-1.0.2\libraries\Wii/Wii.h:21:17: error: BTD.h: No such file or directory
    In file included from Wii.ino:7:
    I:\arduino-1.0.2\libraries\Wii/Wii.h:111: error: expected class-name before ‘{‘ token
    I:\arduino-1.0.2\libraries\Wii/Wii.h:113: error: expected `)’ before ‘*’ token
    I:\arduino-1.0.2\libraries\Wii/Wii.h:116: error: ‘uint8_t’ has not been declared
    I:\arduino-1.0.2\libraries\Wii/Wii.h:130: error: ‘uint8_t’ does not name a type
    I:\arduino-1.0.2\libraries\Wii/Wii.h:156: error: ‘int16_t’ does not name a type

    Wii:94: error: ‘class WII’ has no member named ‘getAnalogHat’
    Wii:94: error: ‘class WII’ has no member named ‘getAnalogHat’
    Wii:94: error: ‘class WII’ has no member named ‘getAnalogHat’
    Wii:96: error: ‘class WII’ has no member named ‘getAnalogHat’
    Wii:98: error: ‘class WII’ has no member named ‘getAnalogHat’

    The funny thing is that everything else (I mean the examples that you give) work splendidly.

    I hope you have any idea about these.
    Thanks for the replay

  • Ali_K

    thanks for the update, it works fine now!!

    Best wishes ALJAŽ

  • milind

    hello all.

    i am trying to communicate my android phones with arduino mega adk. but none of the my phone models support USB mode.

    guys can you please list out which android device can support usb communication with arduino?

    thanks in advance.
    Milind kanani

  • milind

    thanks for your reply. my device is running on 2.3.4, the device does not have the usb.jar in system/framework. i have put that. but still its not working. i know that the issue USB mode of devices. so that i would like know which device can support usb mode. becouse most of device can’t support usb accessory mode. can you please shere which device do you use for your project?

    • All devices that is running api level 10 should support accessory mode, as it’s including in stock Android. If your manufacturer didn’t include in there build you will have to compile the kernel module yourself.

      I have used an HTC Wildfire, HTC Desire, Nexus 7 and Galaxy Nexus. All worked fine.

      You could try to install Cyanogenmod on your device: http://www.cyanogenmod.com/. I have used that previously because my phone HTC Wildfire was too old.

  • Henrique

    Hi, i’m having some problem with the ArduinoBlinkLED example. When i try to compile the code, arduino returns a error that says “Class USB has no member named init”

  • Vanessa

    Hi,

    I was wondering if the Arduino Uno – R3 would work with the USB Host Shield 2.0? I tried the Arduino Pro 5v and it didn’t work. I need 5v VBus.

    Thanks

  • ivkirchev

    Hi oleg,
    the task is to build a quadrocopter with a telephone on board so i can use GPS, camera and all king of sensors. the telephone onboard will communicate with anouther phone or computer.
    so for now i’ve taken the Arduino Mega ADK, and i’ve got HTS Desire. its an old phone so i dont care if something happens. but the phone does not support USB Host. so here is the problem. i cant connect them both… can you help me? 10x

  • ivkirchev

    android version 2.3.7.

  • ivkirchev

    So, 10x for the answer but some problems occurred…
    i have installed Android version 4.0.4 before i follow your instructions.
    after uploading the arduino skech and connecting the phone via usb, mass storage on – off appears. ndroid debugging is enabled. so the phone recognize the arduino board. i’ve installed the BlinkLED app but it can not start. that is the new problem… can you help me?

  • Manny

    hi, Has any one tried android AVFunctions with USB-IF ?

    I see it has MHL transceiver chip in samsung phones.

  • Z.Ricky

    https://github.com/Lauszus/ArduinoBlinkLED
    what does mean by that??
    If I need to coding the Apps client in Android,and then the Android Apps can connect the Arduino or control it
    how should I do??

  • THANK YOU VERY MUCH FOR THIS INFORMATION