Intro
In the past two posts we have explained the basics of USB communication with the Arduino Uno (also applicable for Arduino Mega).

In this post we’ll put everything together and show you how to communicate between your Android application and the Arduino using nothing but the Android USB host API. Remember, this approach has nothing to do with Android ADK! Unlike Android ADK, your Android device will act as the USB host, while your Arduino board will act as the USB device.
For the following application to work, you will require an Android device that supports USB host mode as well as the USB host API. Most Android 3.1+ tablets will suffice (some may require an USB OTG adapter). Also, the Galaxy Nexus has host mode enabled and matches the requirements (you will need an USB OTG adapter however).
This example consists of two parts:
-
The Android application that makes use of the USB API
A simple Android app that let’s you regulate the brightness of an LED on the Arduino using a slider. It also features a button to “enumerate” the USB device. -
Firmware for the Arduino that does some serial I/O with the Android app
Very basic firmware for the Arduino. An interrupt is generated when a new byte is received. The received data controls the brightness of the Arduino’s on-board LED.
(implemented via usleep-style software pwm in the main loop).
The Arduino firmware
In the main loop the firmware asserts and clears the LED pin of the Arduino (PB5). Here is a shortened excerpt:
int main( void ) { //initialization initIO(); uart_init(); sei(); uint8_t i = 0; volatile uint8_t pause; for (;;){ //this is the main loop pause = data; PORTB |= (1 << LED); for (i = 0; i < pause; i++) _delay_us(10); PORTB &= ~(1 << LED); for (i = 0; i < 255-pause; i++) _delay_us(10); } } |
During a period of 2550[us], the LED is asserted for a duration of pause*10 [us] and cleared for (255-pause)*10[us]. Simply put, this is a very simple software PWM.
During that time, “data” and consequently “pause” may be changed within an interrupt routine form the serial USART port. This happens when the Android side sends data to the Arduino. The interrupt routine is extremely basic:
ISR(USART_RX_vect) { //attention to the name and argument here, won't work otherwise data = UDR0; //UDR0 needs to be read } |
The RX data has to be read in the ISR (interrupt service routine) from UDR0; have a look at the Atmega328P reference manual for further details. Since we are doing no multi-buffering shenanigans the handling is extremely simple (no need to call cli() or anything).
The rest of the code is initialization of the I/O pins and UART functionality. Download the complete example here: led_pwm.c

The Android app
The Android application uses the basic knowledge of the preceding blog post Arduino USB transfers. During USB initialization, the Arduino USB serial converter is set up and after that, communication is done using the bulk IN endpoint of the very same serial converter.
With both the aforementioned firmware installed your Arduino board and the Android application installed on your phone or tablet, you will be able to control the brightness of the Arduino Uno’s built-in LED with a slider on your Android device. Again, please note that this will only work with devices that actually support both USB host mode (hardware, kernel requirement) as well as the Android USB host API (Android OS requirement).
The source code is available here: UsbController.tar.gz*
* You may need to change the PID value in UsbControllerActivity.java on line 38, if you have an Arduino Uno Rev3 or higher. You can check the VID/PID value with ‘lsusb’ after connecting the Arduino to your computer.
Many parts of the code are probably familiar to Android SW engineers. The most interesting section is in the class UsbController where the Arduino device is set up and communication is initiated. So let’s have a closer look at the inner class UsbRunnable within UsbController:
private class UsbRunnable implements Runnable { private final UsbDevice mDevice; UsbRunnable(UsbDevice dev) { mDevice = dev; } @Override public void run() { //here the main USB functionality is implemented UsbDeviceConnection conn = mUsbManager.openDevice(mDevice); if (!conn.claimInterface(mDevice.getInterface( 1 ), true )) { return ; } // Arduino USB serial converter setup conn.controlTransfer( 0x21 , 34 , 0 , 0 , null , 0 , 0 ); conn.controlTransfer( 0x21 , 32 , 0 , 0 , new byte [] { ( byte ) 0x80 , 0x25 , 0x00 , 0x00 , 0x00 , 0x00 , 0x08 }, 7 , 0 ); UsbEndpoint epIN = null ; UsbEndpoint epOUT = null ; UsbInterface usbIf = mDevice.getInterface( 1 ); for ( int i = 0 ; i < usbIf.getEndpointCount(); i++) { if (usbIf.getEndpoint(i).getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) { if (usbIf.getEndpoint(i).getDirection() == UsbConstants.USB_DIR_IN) epIN = usbIf.getEndpoint(i); else epOUT = usbIf.getEndpoint(i); } } for (;;) { // this is the main loop for transferring synchronized (sSendLock) { //ok there should be a OUT queue, no guarantee that the byte is sent actually try { sSendLock.wait(); } catch (InterruptedException e) { if (mStop) { mConnectionHandler.onUsbStopped(); return ; } e.printStackTrace(); } } conn.bulkTransfer(epOUT, new byte [] { mData }, 1 , 0 ); if (mStop) { mConnectionHandler.onUsbStopped(); return ; } } } } |
After the USB interface has been claimed the Arduino USB serial converter is initialized by issuing the following control transfers:
conn.controlTransfer( 0x21 , 34 , 0 , 0 , null , 0 , 0 ); conn.controlTransfer( 0x21 , 32 , 0 , 0 , new byte [] { ( byte ) 0x80 , 0x25 , 0x00 , 0x00 , 0x00 , 0x00 , 0x08 }, 7 , 0 ); |
The first call sets the control line state, the second call sets the line encoding (9600, 8N1).
For communication, an additional thread is used to send data without blocking the Activity’s main UI thread. By notifying sSendLock of the UsbController the data will be transferred. After submission, the thread will go into “wait” again. This way, even if submission takes more time than expected, the Activity’s main thread will not be blocked and hence the app will not become unresponsive.

Also note that in the Android Manifest none of the XML-style device filters are needed, since enumeration happens by the user in the app when pressing the “enumerate” button. Device filters – and therefore automatic activity launch when connecting the Arduino – are not used in this example in order to make the code simpler to comprehend. However, this could be easily implemented with a few lines of additional code.
For developing this example we have used a Galaxy Nexus Phone with an USB-OTG adapter cable. It has also been successfully tested with an Android Tablet, the Acer Iconia Tab A500, this tablet does not need any additional adapter cables.
This post concludes the 3-Part Arduino USB communication series. Feel free to post any questions or feedback/ideas in the comments section or contact us via E-Mail (http://www.nexus-computing.ch).
All code you find in this post can be used under GPL for your own projects.
The following section “About Android and USB Host” again concludes why USB-Host is becoming more and more important for mobile devices and points out main differences between Android ADK (Android Accessory Development Kit) and the Android USB Host API.
EDIT: control transfers for FTDI equiped Arduinos
Since we got requested a lot if the FTDI Usb-Serial converter will work too, here ist the control transfer code that needs to be exchanged. No warranties though
conn.controlTransfer( 0x40 , 0 , 0 , 0 , null , 0 , 0 ); // reset conn.controlTransfer( 0x40 , 0 , 1 , 0 , null , 0 , 0 ); // clear Rx conn.controlTransfer( 0x40 , 0 , 2 , 0 , null , 0 , 0 ); // clear Tx conn.controlTransfer( 0x40 , 0x03 , 0x4138 , 0 , null , 0 , 0 ); |
Source Links
Android App: UsbController.tar.gz*
Arduino main: led_pwm.c
* You may need to change the PID value in UsbControllerActivity.java on line 38, if you have an Arduino Uno Rev3 or higher. You can check the VID/PID value with ‘lsusb’ after connecting the Arduino to your computer.
About Android and USB Host
Lately it has become more and more popular to use tablets or mobile phones to communicate with the outside world over USB. After all, many devices now feature a full USB Host, either with a USB-OTG converter or even with a full sized USB Type A interface. Also, the future promises even more host availability on mobile phones. This opens up an entire range of new possibilities for already existing hardware as well as newly designed hardware for phones.
Not too long ago, Android received its own USB API. It was at the Google I/O in summer 2011 when the “Android Open Accessory Development Kit” was announced and released. However it lacked of a few crucial points. The API implied that there is an external USB host, acting as a “master” if you will.
On the one hand, this means that an already existing USB device mode gadget cannot work with your Android device. Therefore, if a manufacturer wanted to support Android phones it was necessary to create new hardware as well as new firmware. Secondly, the new hardware had to be designed to power itself and also deliver power the Android device; this implied that mobile gadgets require their own power source. And secondly, there was another issue: only devices running Android 2.3.4+ were shipped with the new API. Even then, it was up to the manufacturer to actually include the required stack in the OS.
But wait, there is another way to communicate over USB. At the same time (Google I/O) the Android USB Host API has been published for Android 3.1+. Starting with the second half of 2011, Android devices appeared which supported USB OTG (although devices with Android version < 3.1 were not supporting the API). With an appropriate adapter it has become possible for Android to act as USB Host. This meant that already present USB hardware has become compatible with the OS. As long as the kernel on the Android device supported the USB standard driver of the hardware (mass storage, input, etc.), Android would be able to use it and therefore open up a new range of extra devices compatible with the system.
However, there are many devices that have not been “compatible” from the beginning. For instance, let’s say your common RFID reader. It most likely uses a USB-serial port and probably comes with a Linux or Windows driver as well as some software. Most Android tablets will come without the usb-serial driver for your RFID reader however. Therefore, if you want to load your driver you will need to root your tablet, determine the version of your current kernel, find the kernel sources online, hope that everything compiles to have your driver ready and then load it onto your tablet. In the end, when you finally have your kernel driver running, you will be required to write C code as well as some JNI glue to communicate with your Activity or Service in Android. All in all, this approach is not very straightforward.
Writing your own USB soft driver
There is a very elegant solution to aforementioned problem. It requires far less skills in hacking and porting than the mentioned approach. However, you will require some advanced knowledge in Android programming as well as some USB know-how.
You can write your own “soft driver” in Android. Since the USB Host API has been released, it is now possible to communicate with any USB device using the most commonly seen USB transfers (control, interrupt, bulk). In the end, your result will be portable across all Android devices that have USB host enabled and have Android version 3.1+. Moreover, this solution does NOT require root access to the tablet or phone. It is currently the only viable solution that does not require the user to have any know-how of rooting/hacking the device and risk losing warranty in the process.
The above Android application uses exactly this approach. It represents a very basic soft driver for the Arduino’s on-board USB-to-serial converter.
I tried this on both my 3.1 and 3.2 Google TV devices but no luck. I get an ArrayIndexOutOfBoundsException error with when tried to get the interface:
if (!conn.claimInterface(mDevice.getInterface(1), true)) {
When I change the index to 0, to code runs. The user is prompted for USB permission, but then then system logs shows an error that the USB device has been disconnected. Moving the slider in the UI does not do anything for the Arduino Uno.
Hey Leon
Is it possible that you have an Arduino of Rev. 1 that is equipped with a FTDI chip? If so, then you can try to initialize it with the commands:
instead of the ones for the Arduino serial controller.
Also please check with lsusb on your computer what interfaces you have on your Arduino.
All the best
Manuel
I have a Rev. 2 Arduino Uno. I think the issue is with Google TV and not your instructions. Also, I changed the VID + PID to the ones listed with enumerate since I did not see the Arduino VID listed. That means that the Arduino device is not recognized over USB.
I think I like your article! Nice!
Thank you for this post, exactly what I was looking for!
I am planning to use one of those cheap Chinese apad devices for a home controller (combining wifi, storage, sound and a good 7in touchscreen for around £50), but was not sure how to connect it to the other nodes. An ioio should work, but that’s not trivial to connect to an RFM12B radio. Those android accessory kit based arduino mega devices are rather expensive, and it’s not guaranteed the tablets will support that mode. USB OTG however is available, so from your article I think I should be able to connect to a JeeNode USB, which would be perfect.
You said this mode doesn’t _need_ the gadget to supply 5V – do you know if it possible to provide power in this mode?
Hello Thorsten!
Thank you for your feedback, we are were glad that the post helped you out
About the power supply: The Tablet will feed the 5[V] (in practice it’s more about 4[V]) to the Arduino UNO or in your case the the JeeNode.
Note that the JeeNode seems to be equiped with an FTDI chip. To initiate communication use the code snippet mentioned in the earlier comment.
All the best and keep us posted
Manuel
Hello!
We are working on a project that uses a FTDI USB-to-serial converter and have been struggling with communicating between Android and the device. Your comment for the FTDI chip helps, but maybe isn’t exactly correct for us. We are trying to write a soft driver for our device, and our controller uses a 56k baud rate, 8 data bits, 1 stop bit, and no parity. Do you have a link to any kind of reference or documentation on these control transfer codes? I have done a few Google searches but we have not found anything very helpful.
Our Android device uses 4 byte codes (3 letters and a ‘\n’) to communicate with the board, and I can do it using minicom on Linux, but nothing happens when we use bulkTransfer() on Android (but it returns 1 for each byte sent, so I think it is successful).
If this is too much to explain to us, then if you know of any documentation or links that would be helpful to us, then please let us know! Thank you for this blog post – it was very helpful already!
Thanks,
Zach and Zsolt
Hi Zach and Zsolt,
For this kind of information you need to have a look at the “libftdi” library which is open source.
Link: http://www.intra2net.com/en/developer/libftdi/download.php
In there you will find the setup routine for the 56k baud rate (the one in the ftdi example is 9.6k).
Have a look at the method:
In there you will find the correct control transfer for setting the baudrate.
Hope this helps you to get started
All the best
Manuel
Manuel,
Have you ever tried to run this in an android virtual device on a PC? That would make the development cycle a lot easier, since my tablet only has one (USB OTG) port. I tried, it didn’t find any ports, but maybe you got it to work?
Power is turning out to be a problem, as the tablet can only charge through USB – and I want it continuously powered (always on). But if it’s the host, it will want to provide power, not draw it. I found that there is a three way (A device, B device, charger) option exactly for this in the OTG standard (see ref 6 in http://en.wikipedia.org/wiki/USB_On-The-Go) but I’ve not come across anyone or anything actually implementing that. From my reading of the spec, it looks like a 240k resistor in the host plug should be all that’s required, assuming the tablet actuall follows that part of the OTG spec…
Hello Thorsten,
I did not forget about your comment here
There is actually a bit of an issue if you have a Galaxy Nexus or a Galaxy 10.1 Tab since those devices charge over USB. Now … I believe it is theoretically possible to supply the host side with 5V on the Hub, however, I did not test it. Did you have any new findings on this?
All the best
Manuel
I am interested in using a Galaxy Nexus to send data to an Arduino Rev3, but also be able to receive power somehow as well. Any progress on this possibility?
Hey Savcat,
This will work with the Gnex.
Check the few comments from me before on how to get started with sending data from the Arduino.
What you can do is for instance write a sketch and send data to your gnex with Serial.write(…).
On the Android you would issue a bulkTransfer to the Bulk OUT Endpoint of the Arduino Serial device.
Hope that gets you started
All the best
Manuel
Thank you very much, Based on you post i implemented a car controlled and powered by galaxy nexus
http://v.youku.com/v_show/id_XMzY0NjIzMDQ0.html
Wow that looks awesome
thanks for sharing!
All the best
Manuel
Great job. I am trying to build it on my Andoird-x86 platform, so we are not limited by the devices. Does anyone ever try it?
The Android-x86 group has a discussion for similar topic, for setup a demo project for Android-x86 and Arduino. The developer of Android-x86 told me that I have to root my device, load the FTDI kernel module before going to develop my USB host app. I am quite confused now.
Should I hack the kernel anyway? Or Galaxy Nexus has enabled support for FTDI already? Galaxy Nexus is quite expensive right now. I have to use Android-x86 for this moment.
“Please note that this will only work with devices that actually support both USB host mode (hardware, kernel requirement) as well as the Android USB host API (Android OS requirement).”
If I am right, the kernel requirement means some kernel module like uno.ko being modprobe’d in kernel.
I checked Android-x86-v3.2 in VirtualBox. Indeed, there is no FTDI kernel driver loaded.
dmesg | grep “usb”
…usbcore: registered new interface driver usbserial
…usbserial: USB Serial Driver Core
lsmod | grep “usb”
usbserial 23303 2 option, usb_wwan, Live 0xd0909000
Does it mean USBserial is supported in Android-x86 already? Just not for FTDI?
Hey there!
By Kernel Driver I mean the USB OTG Host Support. For the code you are actually required to not have the ftdi kernel driver loaded since you don’t want the USB device node to be already claimed by another application (the kernel driver). In my opinion: use rmmod to kick the driver as soon as the device is connected or use the terminos library to work with it and write some JNI glue… I think the first is the easier way to go
All the best with your project!
Manuel
Hey Manuel! I am trying to make this work in the ADT emulator, but I don`t know how to do it!
I always have the same answer: “enumerating”, “no more devices found”.
I have an FTDI chip connected to an USB port on my PC, but I don`t know how to tell it to the emulator. I have also tried to use the usb debugging with muy phone, but I have not been able to make it work.
I’d really apreciate any help.
Thank you so much!
Hey Paloma,
unfortunately the usb host api will not work on the emulator.
wish they would implement at least something for linux distros. Though I know permissions on the device nodes might become an issue. Still, too bad 
It’s a shame
You will have to go with a real device and try to find out if it supports the android usb host api. If your device does not support it there is always the possibility to look for support with a custom ROM from Cyanogenmod or others.
All the best
Manuel
Hi Manuel! Thank you!
Now I’m working with a tablet (UNUSUAL Votex Pocket) that performs the USB OTG mode. When I run the usbcontroller.apk and press “enumerate” nothing happens. I am testing with an FTDI chip and also with a pendrive (changing the PID and VID values). I have also ran the D2XXSampleActivity.apk with same results. Any idea about what I’m doing wrong?
Thank you so much in advance.
Hello Paloma,
The problem might be that your tablet does not support the usb host api. You are doing everything right but your OEM did something wrong. Although some devices are able to use USB OTG with flash storage or input device the API is missing (resulting in an empty list of USB devices).
If you have a rooted device you can add the file
android.hardware.usb.host.xml.
Check the other replies in the comments for more details.
All the best
Manuel
Thank you so much Manuel…you found my problem! =)
THANK YOU!
No Problem
Happy to help!
I previously left a message regarding article “Creating a Serial to USB driver using the Android USB-Host API” (http://android.serverbox.ch/?p=370)
where I asked how Slick USB 2 Serial Library was likely implemented. After reading this article, I think I finally answered my question. It appears that, like Manual Di Cerbo et al, they ported the FTDI USB Library (http://www.intra2net.com/en/developer/libftdi/) to Android as “soft driver”. Please correct me if I’m wrong.
I’ve been wanting to create an application to communicate with a device serially – send commands, read back results (typical usage, nothing complicated). I didn’t want to write (skill set minimal) / buy a USB to Serial driver (project for self) or root the Android device (make project easy). I’m assuming I can use this “soft driver” to do just that and concentrate on the application sending commands and reading data. Am I correct?
Hi Giovani,
I think as well, the purchasable solution is done the same way, however, I never had a closer look. We did not port the library (libftdi) but only took the setup method that is designed for the Vinco Board Serial driver. It appears that it works with other chips too though.
Generally the solution in the article will set you to go with all your requirements. Note though that it is up to the OEM to include Host Mode (Kernel side & Android API side) and not all Android 3.1+ devices (youngest ICS of GSII has no OTG support) will support USB OTG out of the box. With most tablets you should be generally on the clear side for USB Host. Also the Galaxy Nexus will work with an OTG converter.
Hope this gets you started
All the best
Manuel
Hello Manuel,
I am working on a project about the IEEE802.15.4/ZigBee. The ultimate goal is to setup a communication interface between the ZigBee wireless board and an Android phone application over USB. The preloaded firmware on the CC2531 chip on ZigBee board presents itself as an USB Communication Device Class (CDC). From your article I want to write my own USB soft driver using the USB Host API,but I am not know if the ZigBee board can work with the Android phone. How the Android phone enumerate the ZigBee board?Should I write the ZigBee kernel driver?
Do you think this approach is OK?If donn’t,please give me some suggestions. Thank you for this blog post – it was very helpful already!
Thanks,
Zlon
Hello Zion,
Thank you for your comment on our blog. You can use the approach on the blogpost to communicate with your zigbee device as if you would communicate over serial. No Kernel programming needed whatsoever. The CDC device means that a Serial Driver is in place. I am guessing it is an FTDI one, so setup is a bit different than from the Arduino (see the comments in the post and the FTDI serial driver post).
All the best
Manuel
Hello Manuel,
Thanks for your quick answer! The CC2531 isn’t the FTDI chip,but it is an TI one,and it has source code for CDC libraries. In your post, based on libftdi, you write soft driver using the Android USB Host API to connect an FTDI controller via USB. But the CC2531 is not an FTDI one,I write my own soft driver using the Android USB Host API,do I have to need the related libraries ?(The TI has not libraries in Android)
Thanks
Zlon
Hi Zion
The Arduino also uses the CDC ACM standard class. Try if our Arduino setup routine works with your TI chip. My best guess is it will
All the best
Manuel
Hello Manuel,
Very interessant article. I think that USB Host is the most exciting device for Smartphone.
I connect my Galaxy Nexus (4.0.2) to Arduino UNO via USB following your instruction and … great job. Every things work fine !
I try to connect my Galaxy S2 with the official release of ICS 4.0.3 but nothing works. It seems that the Galaxy S2 can’t communicate with Arduino. When I debug, it seems that Usb Device is not discovered.
Have you any idea ?
It’s probably a problem with the official GS2 Kernel but I am not sure.
Thanks
Thibault
You are completely right, I tried it too with the i9100 and it does not work, because for some (to me) unexplainable reason the engineers of Samsung did not feel like compiling the kernel (though for external hard drives there is still a switch in the settings) with USB OTG support. It is such a shame and yet not really surprising, especially if you look at it in context with what they are pulling off regarding ICS UI (everything that makes ICS awesome is missing, they successfully took the 4.0 source and downgraded it to 2.2, congrats you guys).
My hopes remain that they will bring an update that enables OTG again.
All the best
Manuel
Hi Manuel,
Thanks for your quick answer.
I also hope that there will be an update …
All the best
Thibault
Hi there!
Thanks for sharing this, very interesting! Right now I’m trying to set up communication with an arduino uno Rev 2 and a samsung galaxy tab with an usb host adapter. For some reason the enumeration does not find my uno (nor my FTDI development kit). However when I plug in some logitech headset it does find a VID and PID. Any suggestions how to fix this?
What I actually want to achieve is to fix communication with an FT230X chip, is that possible? Or is it only with FT232 chips (according to your other article).
Thanks!
Hi Lennert,
Yesterday I received my own USB Host Adapter for the Galaxy Tab (P7510). I haven’t had a chance to play around with it yet, but I will try it too (with the Arduino Rev. 3). My guess is, if it does not work, then it’s a Samsung mess up, I heard already of similar problems. I will get back to you as soon as I know more.
All the best
Manuel
Hi Manuel,
Alright, I’ll keep track of this website. I also wonder if that is my problem with FTDI chips, can’t wait to hear from you!
Greetings,
Lennert
Hi Lennert,
Bad news, I just checked if the USB API works on the P7510 and it does not
at least with the current Honeycomb version. Hopes remain that Samsung is going to change that with ICS, yet history tells an entirely different story 
Your only way to fix communication right now is to go with another tablet, sadly. The Acer A500 works for sure, however, it is nowhere as nicely designed as the Samsung.
All the best
Manuel
Hi Manuel,
Hmm that’s a shame. I’ve bought a samsung galaxy tab 10.1 for development hoping that it would support everything I could think of. Do you think this has something to do that none of my FTDI chips are found by the samsung tablet? If I try to print the VID:PID I get nothing.
Greetings,
Lennert
Hi Lennert,
I tested it with the new Arduino Board that is equipped with the Atmel-Lufa variant of the serial converter. I think it is unrelated to the type of converter. Maybe there is a custom ROM for the P7510 which will work with the USB Host API.
All the best
Manuel
Archos G9
Hi Guys, since we seem to be getting a database of what works and what doesn’t, I would like to report that the Archos G9 (running ICS, and it has both OTG and a nice recessed Type A USB, nominally for a 3G stick, but also works for memory sticks): Type A port does not recognise an FT232. “”Cannot enable port1. Maybe the USB cable is bad?” I have not tried the OTG port (waiting on an adaptor to arrive).
Hi Neurobe,
Thank you for the input!
Hope it works with OTG.
All the best
Manuel
Lennert,
Try connecting via a hi-speed hub. Let us know the result!
Hi Manuel,
This is the source of the problem with the Archos G9:
Beagleboard HW Manual:
“NOTE: Beagle USB Host only supports HS USB (480Mbp/S). Low Speed and Full Speed devices are not supported unless they are connected through a USB Hub prior to connection to the Beagle. The OTG port does support LS and FS devices.”
Manuel, are you certain that on the Acer A500, the Type A USB port supports LS & FS devices?
tks, neurobe
Hi Neurobe,
I am certain that it works with FS devices (the Arduino USB-Serial controller) as well as with HS devices (our Oscilloscope with the FX2LP is one).
All the best
Manuel
Hi Manuel,
I returned my Samsung galaxy tab and bought a Acer Iconia A200. Works like a charm! It also detects my FT230 chip
Thanks!
Lennert
summarising for two USB port tablets…
USB Type A USB micro
—————— —————
Archos G9 Host HS only Full OTG functionality
(requires hub for FS) (ie works fully)
Iconia A200 Host USB peripheral only
(and A500?) (ie works fully)
hope this is useful.
Post lost formatting so I will need to narrate..
Archos G9 USB Type A port works as Host but only at high speed. Use a HS hub to connect lower speed devices.
Archos G9 USB micro port works fully as OTG port
Acer Iconia A200 USB Type A port works a sa fully functional Host port (all speeds)
Acer Iconia A200 USB micro port works as a peripheral USB device only.
tks
Thank you so much Neurobe! This is very helpful!
All the best
Manuel
Hi.
great blog, very informative!
We’ve got a Galaxy Tab 10.1 P7510 and connecting a FTDI device doesn’t work as some of you have written.
I’d like to build the kernel with the setting:
CONFIG_USB_SEC_WHITELIST = n
I’ve checked out a kernel from
https://github.com/GalaxyTab101/samsung-kernel-galaxytab101
But it doesn’t build for me, have never done this before.
If anyone is keen to try, please let us know! @ZiglioNZ
thanks!
An update: I’ve downloaded and built “GT-P7510_OpenSource_Update1” from Samsung’s web site.
Now I’ve got zImage but don’t know what to do with it.
‘Fastboot’ doesn’t work out of the box with Samsung devices (of course, what was I thinking…).
So I need to find a way to test this kernel
Hello Emanuele,
Have you tried heimdall for flashing the tablet?
All the best
Manuel
Hey Emanuele,
Sorry to answer that late…
In Samsung builds you link the initramfs statically to the kernel. This is done via kernel compile option (initramfs=”somepath” or similar). 3MB is very possible, however, without the initramfs.
All the best
Manuel
Hi Manuel,
no, I’ve never heard about heimdall before, I’ll have a look.
I was gonna try with Odin that seems to be the standard way with Samsung.
It puzzles me that the zImage I’ve build is just 3MB!
So, sorry another question, would updating the kernel leave the ‘platform’ bit intact?
I’m going to look for an ‘official’ kernel just in case something goes wrong.
Hi:Hi Manuel,
Learned a lot from your blog and all discussions!
I have got a Galaxy Tab 10.1 P7510 , facing the same problem to enumerate the usb-convert2serial device, I don’t know how resolve it, whether I should root the tablet or build my own ROM.
If anyone faced the same problem and find a way out, please let us konw, tks!
Hi Vincent,
I think that rooting the tablet won’t help you, since Samsung white-listed only certain devices in the kernel. So not even root would help you
Also, I did not check if there are any good ROMs for it, since I concentrate on developing with my A500 (which even got ICS recently).
All the best
Manuel
Hi Manuel,
Thanks for sharing your project. I’ve downloaded your source code, but I met a problem when compiling with led_pwm.c. It said that “error: ‘PB5’ was not declared in this scope”. So I rewrote it to “#define LED 15” in line 32 and compiled with no error. However, it didn’t work with android app. Is it correct?
Thanks for your help.
Sorry, I mean I rewrote it to “#define LED 13″ in line 32 .
Amazing. Thanks for that code. I’ll use it for my boardcomputer.
Hi Manuel,
I have a problem with connect to tablet Yarvik TAB 224 (OS 4.0.3)
Tablet no transfer byte.
Can you help me please ?
Petr
In my case compilation was OK, but the LED didnt work.
After changing the code a little bit (operation Turn On the LED goes first) the
program is turning ON the LED but doesnt turn it OFF. What is the problem?
for(;;) {
pause = data;
PORTB &= (1 << LED);
for(i = 0; i < pause; i++)
_delay_us(10);
PORTB |= ~(1 << LED);
for(i = 0; i < 255-pause; i++)
_delay_us(10);
}
I have tried manually setting the pause variable but it is the same.
Hi!
After I compiled the code and the debugger sent it to my MID7022 tablet, it gives an error with the “if (!conn.claimInterface(mDevice.getInterface(1), true)) {” line.And then it closes the app. According with the debugger, the error is: UsbDevice – > arrayIndexOutOfBoundsException.
I am not using it with an arduino, but with a Prolific usb->serial, with the correct PID and VID!
Any clue??? Thanks!
public void run() {//here the main USB functionality is implemented
UsbDeviceConnection conn = mUsbManager.openDevice(mDevice);
if (!conn.claimInterface(mDevice.getInterface(1), true)) { // ERROR
return;
Hi Felipe,
Check on which interface your bulk endpoints are running (using libusb -v for instance).
With getInterface(1) the second interface is selected and my guess is, you need the first one.
Also please note that the setup routine in this example is for the Atmega16u2 with LUFA and does probably not comply with the profilic.
Hope that helps
All the best
Manuel
Hi Manuel,
I thought that this setup example was for the FTDI…..no surprise it not connected, lol!
Just for note, I had more lucky with the FTDI_USB example of yours ( http://android.serverbox.ch/?p=370 ) It connected right away with my FT232RL chipset!
Thanks for the reply!
Hi Manuel,
In your post you mentioned “this will only work with devices that actually support both USB host mode (hardware, kernel requirement)”
I want to understand what you mean by “kernel requirement”.
I have been using a very cheap tablet that runs ICS and has a working USB host controller (tested with USB flashdrive, mice). So the “hardware” requirement is fulfilled.
But I wasn’t able to use a USB-serial device with the tablet. I knew that the problem was with kernel modules as cdc-acm, ftd_sio.ko, etc were missing. So I got the cdc-acm.ko module for my kernel and loaded using insmod. Now, when I connect my device, the cdc-acm process fires and I can see my device as /ttyACM0. All well so far..
I have made an app similar to yours that retrieves list of devices connected using UsbManager.getDeviceList() API. This works on higher end tablets like Acer Iconia, Xoom, etc. But it fails for the current tablet (based on Allwinner A10) I have.
Is this due to the kernel requirement? If, so what can I do to enable the host dunctionality with CDC ACM devices?
Thanks!
-Arvind
Hi Arvind!
With “Kernel requirement” I meant that the kernel has to support USB OTG for devices that only feature a micro USB port. Also the Kernel must not have a “USB Device whitelist” in place like the Galaxy Tab does.
To me it sounds like the Android USB Host API has not been completely implemented on your tablet. Is your device simply not enumerated when using getDeviceList() or is there an error thrown?
All the best
Manuel
Arvind,
Apparently some of the Allwinner A10 ICS 4.0.3 tablets (mine is a Coby 7042-4) don’t come with the XML definitions for USB Host permissions. Check out post #29 on this thread: http://forum.xda-developers.com/showthread.php?t=1499124&page=3
Add that XML file to your tablet and reboot it. Next time you run Manuel’s code it will prompt you for permissions and correctly enumerate your USB devices. I struggled with this for days. Hope this helps you along, and thanks to the author and those who contributed.
Thank you a lot for clearing that up!
tabletguy and Manuel,
Thanks! It worked. Phew.. I had almost given hope on CDC devices thinking that the drivers were missing etc. and moved onto HID :P. Thanks to the author (sztupy on XDA) indeed!
On another note, I noticed that HID devices don’t show up on the deviceList. Any workarounds for this, or is it how it’s supposed to work?
Basically I noticed that cdc-acm.ko wasn’t there on my tablet by default, so I went looking for device classes that don’t require drivers (like HID). But I guess I’d be moving away from the Host APIs in that case, wouldn’t I?
Another thing noted is that usbserial.ko is present on almost every device.. even on phones without Host hardware. Any idea what it is for?
Regards,
-Arvind
Hey Arvind,
About the HID: I actually never tried to connect. However, since the interfaces of the HID device is probably already claimed by the input driver, it would be difficult to use them in the app.
To communicate with the Arduino USB-Serial Converter or an FTDI you should not have the kernel module in place, but rather use the Usb Host API as demonstrated in the post. However, if you already went through the trouble of rooting the tablet and compiling the kernel module, you could for sure just use the “terminos” C library to communicate with the serial device and then write some sort of JNI wrapper to communicate from your application.
Regarding Serial Driver: I noticed too, that on the A500 a devicenode /dev/ttyACM0 is created. Maybe it is just the default configuration of the Kernel and the OEM did not really look closely into it.
All the best
Manuel
Hi.
Basic question but I assume answer may be useful for many readers: is it possible to test attached examples from virtual android device run on PC instead of real android device? I uploaded soft to arduino uno and built code in eclipse. I connected arduino to PC’s USB port and started virtual device with Android 4.0. Now I am wondering where is the problem as changes in slider position do not impact brightness of the LED.
Regards
Michal
Hey Michal!
Sadly the emulator does not support USB forwarding. Thus, it is not possible to communicate with the Arduino with the mentioned method. However, you could give Virtualbox or a similar Virtualisation Software a try with Android x86.
All the best
Manuel
Hi Manuel,
Thank You very much for wonderful article.
My intention is to print labels from Android device (phone or tablet) on Brother QL-series printer (via USB).
By now – I am able to communitate with printer from simple desktop Java app using libusb library (under Windows7).
Next I would like to do the same from Android device (connected with Brother QL-printer via USB).
I would be very happy, if You could answer a few questions:
1. As I understand – the Android device should act as USB host (cause Android device initiates conversation with printer). Am I right ?
2. As I understand – I need Android device 3.1+ (2.3.4 will be NOT enough, since it cannot act as USB Host). Am I right ?
3. Does every device with Android 3.1+ (with has USB host feature) support Open Accessory Development Kit (ADK) in USB host mode ?
4. If answer to question 4. is NO, then do You know any cheap tablets that support ADK in Host USB mode (cheap tablets like GoClever, Lark, Vordon, Omega) ?
Thank You for answer.
Best Regards,
Mateusz
Hi Mateusz,
1. Yes, the Android side has to be USB Host capable
2. Correct, the USB Host API is only supported since 3.1+
3. There are devices that support both, the USB Host API as well as the USB Accessory API (the Xoom I think is one of them). Technically this also could work at the same time as long as the device supports the Accessory APK and has a USB Host port. However, you cannot use the Accessory API over USB Host, this will not work.
4. So, if you have two physical USB Ports AND as well a micro USB Port (like Acer A500, A200 for instance), then it *might* be possible to use an Accessory at the same time as a normal USB device. If I understand you correctly this is what you want to do, right?`:)
All the best
Manuel
Manuel,
I am grateful to You for Your help
Questions 1 and 2 are now clear.
But I would like to clarify questions 3 and 4. As far as I know – I don’t need an Accessory API. I only need the USB Host API (Android will be USB host, the printer will be USB device). So the only thing I need is a tablet that can act as USB host and supports USB host API. You have mentioned about USB port kinds (standard USB and micro USB).I wonder if USB port size (standard/micro) has anything to do with USB Host support.
Case 1: If tablet has at least one USB standard port (standard size) – does it mean it supports USB Host ?
Case 2: If tablet has only micro USB port with OTG (with special adapter) – does it mean it support USB host ?
Question: If tablet has hardware support for USB host (case 1 or 2), does it mean that it allow to access USB from android application level (using USB Host API) ?
Do You know any website with list of devices that support USB Host API ?
Thank You for Your answer.
Best Regards,
Mateusz
Hello Mateusz,
I am happy to help out
If you see a device with a full sized USB host A Port then you can be sure that the device actually supports USB Host. However, I came across cases where people found out that the USB Host API was not in place or they had to tweak something to get it to work.
Then, some devices support USB OTG. Some don’t. Although almost all the hardware parts would support it, some OEMs cut it out of the Kernel. The Galaxy Nexus is one of the devices that do support USB OTG. The Galaxy S2 does not.
Also the Galaxy 10.1 Tabs do not support the USB Host API *although* they support USB OTG for mass storage. They just whitelist only mass storage, so you cannot use the API (That is incredibly stupid in my eyes and there is no justification for this – it is pure idiocy of Samsung nothing else).
To wrap up: Some of the tablets that have a USB A Type connector offer you to communicate with your USB device using the Android USB Host APIs. And some of the devices that support USB OTG offer you to talk to your device using the Android USB Host API. In Both cases, it is just *some* devices. So before you pick your device, check first if you find any information about the API compatibility.
I myself have been looking for a site with a list of devices that support the USB Host API. Google knows what devices support it, since there is a “uses-feature” filter in the Android Manifest for the Play Store (Android Market). I did not come across any lookup table/library where I would find such an information
I hope this clears things up at least a bit
All the best
Manuel
Hi Manuel,
Thank You very much for comprehensive answer
Now I understand everything in this subject.
I also found a website with devices database that support ADK Host API.
I hope it will be very helpful for all developers:
http://www.androidzoom.com/android_applications/tools/usb-host-diagnostics_bzrzc.html
http://usbhost.chainfire.eu/
Unfortunately large part of devices seem not to support USB Host API.
There is a big fragmentation in this matter.
That’s a pity …
Best Regards,
Mateusz
Manuel,
Sorry to bother You, but I would like to ask You one more question.
If the tablet has only one USB port – can I connect more than one USB device using USB hub ?
For example connect USB printer and USB 3G modem to the tablet, at the same time.
Thank You for Your answer.
Best Regards,
Mateusz
Hey Mateusz!
Thank you for your comment about the site
Yes, you can connect to several devices, we tested it.
All the best
Manuel
Hi Manuel,
Thank You very much for fast answering, and sharing Your great knowledge.
Best Regards,
Mateusz
Thanks for sharing your knowladge.
Can you help me to create some serial terminal code? I need to send alfanumerical commannds to arduino UNOv3 and NANO and read alfanumerical responses. One of the controllers has grbl firmware. It respond to commands like: G0 X50 -Y10 Z0, arduino nano will respond to single numbers and letters like 1, 2, c, d, ets. i’ve found some source https://github.com/ksksue/Android-USB-Serial-Monitor-Lite, but it use FTDriver.
thanks!
I would also like to thank you. With your examples I have been able to transfer blocks of data to an Arduino and verify the transfer was correct. However, in going back to the Galaxy Nexus from the Arduino, block transfers are failing. Some of the bytes at the start of the transfer are correct, but the full transfer is not received. This is true whether I use a bulk transfer or an asynchronous transfer, all at 9600. Would you care to comment if this problem might be on the Android side or the Arduino side? Or both? Any suggestions would be appreciated. Thank you!
Hello Bob!
I noticed that reading from the serial device (Bulk IN transfers) are to be handled a bit differently. Check if the length of the request is > -1, since by default the request will just return -1. If something happens to be in the serial buffer, then the length of the bulk transfer will be != -1 .
As far as I know, the request length is only available when you use the synchronous usb library. So you need to handle threading etc. your self.
We are using something like this:
As soon as I have some time to clean up the code, I will post some code of how to deal with I/O in a modular fashion.
I hope this helps you for the moment
All the best
Manuel
Thank you, Manuel. I believe my code is functionally identical to yours:
Both the asynchronous version, commented out here, and the bulk transfer yield a few correct values of the 8 byte transfer from the Arduino but never the whole buffer. Other forums have pointed out the transfer count is not available for asynchronous transfers, a failing of this version of Android. The Arduino code is:
This sends an 8 byte buffer back to the host after receiving the input buffer and a small delay to verify the transfer was correct. I’m beginning to suspect a timing problem as you have working code but I have not been able to figure it out. Thanks again!
Manuel, I may have found a problem with my code. I changed the transfer rate from the original 9600 to 115200, but, more importantly, I increased the priority of the thread that was actually doing the transfers. Previously, I had set it below the priority of the user interface; it is now set to 10. I have not done extensive testing but it does seem to be working now.
Hi Bob!
Thank you for sharing this! I am a bit astonished that you have to change thread priority, however, in actually makes some sense
I will look into this too during the next few days and share my findings. Please keep us posted about your further experiences. Thanks again 
All the best
Manuel
Hi Manuel,
I have a good news : the USB host works fine on my new Galaxy S3.
So I can connect an FTDI 232 driver like on my Galaxy Nexus.
All the best
Thibault
Unexpectedly awesome!
Thank you for noting!
All the best
Manuel
I’d be very curios how did you manage to do that, as I am attempting the same and no luck so far
I have an Arduino 2009; would that be the source for error? Could you please provide more detail? A step-by-step walk-through would be just wonderful, if possible.
I am new to Android, have some experience with Arduino, but not much.
Any advice/code snippets you could provide me would be most helpful
cheers,
Adrian
Hi!
I just recently bought an Ainol Novo 7 Paladin tablet (the cheapest one that I could find) and I would really like to use it in a home automation project that I am working on. And I would like to use it in combination with Arduino and a Prolific PL2303 serial controller. I can get your example code to actually detect the controller (so at least part of the USB Host mode is working) but I don’t know how to proceed. I’ve been trying to find a simple easy to use library that would support simple character based communication but I haven’t been able to find anything simmilar. And I am starting to lose hope that I will ever get this thing to work. It would probably be better just to use a raspberry pi as a cheap realy that would send the data via network.
Hi Roli,
I just looked at the kernel driver of the pl2303 (http://lxr.free-electrons.com/source/drivers/usb/serial/pl2303.c?a=m68knommu).
I think the problem might be device initialization. Checkout the code in the
static int pl2303_startup(struct usb_serial *serial)
part, especially the vendor requests in the beginning. I think checking out that code could help you to get started.All the best
Manuel
To be completely honest – it doesn’t help that much. Simply because I have some trouble understanding how this actually works. I’ve never dealt with so low-level code before so it is a bit confusing.
But I just managed to find the slick usb serial library demo and I must say that the example application works great. Problem is that 99$ for such an library is a bit too much for me.
Hi Manuel,
I wasn’t able to use a USB-serial device with the the Galaxy Nexus(OS 4.0.4) and ARDUINO UNO R3.
But Windows 7 PC and ARDUINO UNO R3 Working(LED PWM Control) is OK by hiperterminal.
Could you send me firmware files(usbcontroller.apk, usbserial.hex for ARDUINO UNO R3(Micom ATMEGA16U2)?
I’m so soory my poor english…
Thnaks
Hi Manuel,
It’s my misstake…
wrong pid,vid…
Thanks.
Hi Manuel,
Thank you very much for sharing your knowledge and kindly answering the comments to your post.
I am trying to establish USB communication between an Arduino UNO and my GT-I9100 using the USB HOST API. I have rooted my device, upgraded it to Androdid 4.0.3 and recompiled a custom kernel (this has been a bit of a pain to be honest) with the configuration flags:
CONFIG_USB_OTG=y
# CONFIG_USB_OTG_WHITELIST is not set
# CONFIG_USB_OTG_BLACKLIST_HUB is not set
I have also installed and executed the diagnostic tools for USB Host mode mentioned by Mateusz in is previous comment on June 9, 2012:
http://www.androidzoom.com/android_applications/tools/usb-host-diagnostics_bzrzc.html
and the final veredict for my device has been “OS support YES” although the tool itsefl did not detect any device connected when I plugged my Arduino UNO board to my phone and my application does only detect USB Mass Storage devices while iterating over
HashMap devlist = mUsbManager.getDeviceList();
L.d(myParentActivity, "Number of devices: " + devlist.size());
Iterator deviter = devlist.values().iterator();
Do you have any idea about what can be wrong?
Many thanks in advance. Your help is greatly appreciated since I have been struggling with this for 3 weeks… :-s
Cheers!
Hi there,
As far as I know, the Samsung developers have created an intermediate library called libusb_host. I think they specifically manipulated the Android framework in a way the USB Host API is blocked. Now, “OS support YES” means that the Kernel supports USB Host, however, it does not mean the Android Host APIs will work.
Your best bet is to use a custom ROM (Cyanogen for instance) and try with that. Another option would be to use libusb via JNI and give your app root rights, however, then you need to re-implement the entire Host code in C/C++.
Samsung really sucks in that matter. They pulled that crap on all their devices but the Galaxy Nexus.
I hope you will be able to work it out somehow.
All the best
Manuel
Hi,
Thanks for this very useful post. I was trying your solution on a MILAGROW TabTop MGPT04 which supports both USB host mode as well as USB host API.
The problem I am having as even if my SkyeTek RFID reader is connected to the device via OTG cable still the application Log says “Device Not Found”. I have also tried with a couple of external storage devices and thumb drives but the USBManager always seems to return an empty list for connected devices.
Is is like that every device can’t be recognized by the android USBManager?
How and where can I find a list of supported devices by the USB host API?
Could you pls. help?
Continuing my Question…
I understand from your post that “Most Android tablets will come without the usb-serial driver for your RFID reader “…
But is there a way to know if my RFID reader is compatible with the Android tablet so that it can be accessed by host mode?
Also, could you pls. give a list of common devices like thumb drives etc. with which I can test the code?
Hey Sayan,
I believe what you are looking for is something like this:
http://usbhost.chainfire.eu/
If your devices cannot be accessed via UsbManager then chances are that the OEM just took out the USB API framework part from the Android Framework.
I hope that helps you a bit
All the best
Manuel
Thanks a lot, works like a charm! We modified the Arduino code to run a motor (through a Dagu motor controller) and this enabled us to use hardware PWM on pin 9 with Arduino’s simpler language features:
int incoming=0;
void setup(){
Serial.begin(9600);
pinMode(9,OUTPUT);
pinMode(13,OUTPUT);
digitalWrite(13,HIGH);
analogWrite(9,0);
}
void loop() {
if(Serial.available()>0){
incoming=Serial.read();
analogWrite(9,incoming);
}
}
We also had to modify the Android code to use our particular board’s VID and PID values (we used a Freetronics Eleven, which is otherwise 100% Uno compatible).
Hey Kracha,
Cool to hear that you were able to put everything to good use!
Do you have some more information about your project? It sounds pretty neat 
All the best
Manuel
Thanks for nice guide. However, I’m having trouble with your C code to work on Arduino. Could you please port it to Arduino IDE code? I’m not quite familiar with AVR Studio. Thanks.
Hey Pete,
We are not using Studio, we are using Eclipse. Check out our first Tutorial in the Series to get started.
All the best
Manuel
I would like to use the CDC ACM driver on my st18i.
Can anyone send the driver to me? Thanks.
Dear Manuel,
first of all many thanks for this great article. May be you can help me to sort out some basic questions about communication between the Android device as host and an attached FTDI USB2Serial device.
I want to connect the Android world to a TinyOS sensor network using a MIB520 USB Gateway wich is using a FT2232C Chip with 2 serial interfaces (one for programming the attached sensor mote and one for serial communication with the mote). I’m using the FTDriver project from here: https://github.com/ksksue
I’m receiving the expected data packages resp. serial messages from the gateway without problems. BUT sending makes me real headache for quite a wile now! I don’t get the MIB520 to accept my sent stuff as a valid message.
Do I have to prepare the data somehow? Do I need any additionaI headers or CRC to make the sent data valid? I tried to send back the received data byte by byte but no luck and debugging between the Out-endpoint and the USB gateway is not possible. May be you have some hints for me for further investigation of my problem?
Many thaks in advance and kind regards,
Steven
Hi Steven!
I am glad the article helped you to get started.
The FTDI should not be a problem, you should be able to send data through the bulk OUT endpoint there. What could be a problem though, is that the gateway offers more than one set of Bulk Endpoints.
Check on your PC with lsusb -v VID:PID what the endpoint numbers exactly are and then try to address them in the code directly.
In the code of the example we just take the first set of bulk endpoints, which might work for the IN endpoint, but probably the OUT ep is the wrong one.
Also for easier debugging I recommend using a PC and to run some pyusb script. (try this as starting point http://android.serverbox.ch/wp-content/main.py. Before running it though you need to remove the serial driver kernel module via sudo rmmod ftdi_sio (if you are using a linux host machine).
All the best
Manuel
Hi Manuel,
Thanks for your reply.
Just to inform you, I had downloaded USBHostController tool from http://www.androidzoom.com/android_applications/tools/usb-host-controller_bxquw.html?nav=related
When I connect my USB devices(mouse/key-board/RFID reader) to the android tablet they are getting properly recognized buy the USBHostController tool but somehow from my own android application the devices are not getting recognized by the USBManagaer, it always returns me an empty list of devices attached.
I have tried with your code as well as I have developed a very simple test program to check for and list attached USB devices but that is also not working.
Pls. see below the code snippet and the Manifest file for my project :
Code Snippet:
===================================================
UsbManager usbManager = (UsbManager)getSystemService(Context.USB_SERVICE);
HashMap deviceList = usbManager.getDeviceList();
Iterator deviceIterator = deviceList.values().iterator();
Toast.makeText(this.getApplicationContext(), “Device Count : ” + deviceList.size() + “”, Toast.LENGTH_SHORT).show();
while (deviceIterator.hasNext()) {
found = true;
UsbDevice usbDevice = deviceIterator.next();
Toast.makeText(this.getApplicationContext(), “Product ID : ” + usbDevice.getProductId() + “”, Toast.LENGTH_SHORT).show();
}
Manifet File :
====================================================
I am struggling with this for a very long time.
Can somebody pls. help me out regarding this? Thanks a lot in advance…
Hey Sayan,
I just looked at the tool and it states
“The application does not use the USB Host API”
So your devices show up and are probably read out via some kind of lsusb command.
What that means is your device simply does not support the USB Host API. So the devices don’t show up in the UsbManager since the framework part is probably just stubbed out.
What device are you using?
All the best
Manuel
Somehow the Manifest file did not appear in my above post.
Here is the Manifest file for my project.
(I have removed the tags otherwise it was not getting posted)
====================================================
manifest xmlns:android=”http://schemas.android.com/apk/res/android”
package=”com.test.usb.connection”
android:versionCode=”1″
android:versionName=”1.0″
uses-sdk
android:minSdkVersion=”15″
android:targetSdkVersion=”15″
uses-feature android:name=”android.hardware.usb.host”
application
android:icon=”@drawable/ic_launcher”
android:label=”@string/app_name”
android:theme=”@style/AppTheme”
activity
android:name=”.MainActivity”
android:label=”@string/title_activity_main”
intent-filter
action android:name=”android.intent.action.MAIN”
category android:name=”android.intent.category.LAUNCHER”
intent-filter
activity
application
manifest
Hi Manuel,
Thanks for your prompt reply.
The devices I have used so far is a MILAGROW TABTOP MGPT04 (running ICS 4.0.3) and the other one is a Tazpad also running ICS.
Both these devices claim to support Android API-15. So the code shoul;d work fine on these tablets right?
Also, I have a question if as per your comment the USB Host API was stubbed out of these devices then how could my code compiled and runned without error on these?
Could you put some light to this?
Hey Sayan,
In short: the OEM of your device did not do the implementation of the Android Framework properly. The UsbManager is accessed via SDK, though implemented by the Android Framework. My guess is that some OEMs just lack the knowledge, manpower or the motivation to do the implementation of the Android Framework the right way.
Your code runs fine, but the Framework just gives you an empty list of USB devices back.
I hope that shed some light on the problem.
All the best
Manuel
Hi Manuel,
Thanks for the clarification.
I will try to check with the device vendor regarding this.
Meanwhile I would liek to know is there any other way to check if the Android framework has been properly implemented on the device to support USB host API or not?
Also, in case it is not properly implemented by the OEM is there any work-around to access USB devices programmatically?
Appreciate your help.
Regards,
Sayan
Hey Manuel,
We plan on using this in a quadcopter control system, where the Nexus sensors are used to stabilise the craft. We needed a way to get the output of the phone’s orientation calculations to control the motors, so your Android-to-Arduino USB code has come in very handy for this. Now we just need to write the control code :O
Thanks again!
Hello Kracka,
Thank you for your comment, we are happy you found help in the articles
Are you using a galaxy nexus? If so, keep in mind, that you cannot power the phone and use OTG at the same time, and power will be drawn more quickly than without USB attached.
Your project sounds really interesting and I hope it will be a success
All the best
Manuel
Hi
First, thank you for writing such informative / clear articles.
I did have a few question though.
I’m trying to let my arduino communicate with my android.
I have a desire HD, that apprarently doesn’t support USB host mode. I’m running a custom rom 4.0 so I should have all the OS requirements fixed.
The arduino won’t be powered through usb as host mode isn’t working, but can I still use the USB api and use your code ?
And let it be powered by android if the phone has host mode enabled ?
Or should I use the ADK ? But I really don’t like it as they don’t have the host mode.
And if I power my arduino from something else, do I still need the usb otg cable ?
Sorry for all the questions, but I’m a bit stuck on how to set up my development.
Thank you very much.
Hello John,
I am glad you like the articles
In order for USB OTG to work, you need to configure the kernel properly. For that you need to recompile your kernel and flash it onto your phone. If you run a custom ROM I am almost certain, that you will find a howto for kernel config.
Then, when OTG is activated on the kernel side, you should be able to attach a device via OTG converter and see it powered. If it is not powered, then you can still use a powered hub (this is only a guess though).
Also if you are running 4.0, you should be able to attach a mouse/keyboard and use it in the system.
If that does not work, then you are out of luck with USB Host and you would have to use the ADK for your project.
I hope that points you into the right direction
All the best
Manuel
Hi, thank you very much for this post.
I’ve got a question?
The Arduino firmware (led_pwc.c) is written for AVR compiler?
Is it possible doing the same thing in the Arduino IDE?
Kind regards
Hi Manuel,
Thanks for putting together this very informative write-up.
I have a question on a project I am about to undertake as follows:
I am planning to connect a Google Samsung Galaxy Nexus HSPA+ phone running JellyBean in USB-Host mode, via OTG cable to a peripheral board in USB-Slave mode. This Peripheral board has a FTDI USB/UART chip.
Will your approach here work in this scenario to communicate between the phone and the peripheral?. Or do I need to load the FTDI USB/UART chip driver into the Samsung Galaxy Nexus.
Thanks!,
Tek
Hi Tek!
I am glad the posts helped you
This will absolutely work, I have tested it myself. You are good to go
Note however, the GN cannot be charged at the same time as being in USB Host mode. I have tried it over the POGO Pins without any success
All the best
Manuel
Hi Manuel,
Thanks for the quick response!. I have another follow-on question:
Can the Galaxy Nexus in USB Host Mode receive data from the Peripheral(with FTDI (USB/UART) over USB also?. The reason I ask is that the example seems to emphasis that the Galaxy Nexus in USB Host mode can send data to the peripheral.
Would you be available for a short consulting work to advice our developers on how to make this work?. If so, please let me know, we greatly appreciate it.
Thanks,
Tek
Hi Manuel,
I have a RFID reader connected and trying to communicate with it from my android app. I can only find one Interface on the reader having two INTERRUPT Endpoints(IN and OUT).
From my understanding to communicate with INTERRUPT endpoints I’ll have to use asynchronous data transfer methods using request.queue() and conn.requestWait() methods but somehow I am not able to achieve things.
I need to sent this command : 02 00 0A 00 20 12 01 00 01 00 04 DA E9
to the reader and get response back. I was trying to do something like this :
conn.bulkTransfer(epOut, new byte[] {
(byte)0x02, (byte)0x00, (byte)0x0A, (byte)0x00, (byte)0x20, (byte)0x12, (byte)0x01,
(byte)0x00, (byte)0x01, (byte)0x00, (byte)0x04, (byte)0xDA, (byte)0xE9}, 13, 1000);
ByteBuffer buffer = ByteBuffer.allocate(128);
buffer.order(ByteOrder.LITTLE_ENDIAN);
UsbRequest request = new UsbRequest();
request.initialize(conn, epIn);
request.queue(buffer, epIn.getMaxPacketSize());
if (conn.requestWait() == request) {
byte[] data = buffer.array();
if(data != null) {
Toast.makeText(sActivityContext.getApplicationContext(), “Data Available”, Toast.LENGTH_SHORT).show();
Toast.makeText(sActivityContext.getApplicationContext(),
data.toString(), Toast.LENGTH_LONG).show();
}
}
But it was not retrurning proper response. Could you pls. help?
Regards,
Sayan
Hey Sayan,
I see that you are doing a Bulk OUT transfer in your code. Should that not be a Interrupt OUT transfer? You should also be able to queue and OUT transfer via async API calls.
The second part of the code seems correct to me. I am doing it very similar for the OsciPrime Oscilloscope, though it’s Bulk Endpoints there.
All the best
Manuel
Hi Manuel,
I have tried out this also :
—————————————————————————————————–
byte[] command = { (byte)0x02, (byte)0x00, (byte)0x0A, (byte)0x00, (byte)0x20, (byte)0x12, (byte)0x01,
(byte)0x00, (byte)0x01, (byte)0x00, (byte)0x04, (byte)0xDA, (byte)0xE9};
ByteBuffer epOutBuffer = ByteBuffer.wrap(command);
UsbRequest request = new UsbRequest();
request.initialize(conn, epOut);
request.queue(epOutBuffer, command.length);
if (conn.requestWait() == request) {
byte[] data = epOutBuffer.array();
if(data != null) {
Toast.makeText(sActivityContext.getApplicationContext(), “Data Availableâ€, Toast.LENGTH_SHORT).show();
Toast.makeText(sActivityContext.getApplicationContext(),
data.toString(), Toast.LENGTH_LONG).show();
}
}
But this also seems to not working properly.
Could you give me an working example of send/receive response using Interrupt endpoints please?
Regards,
Sayan
Hi Manuel,
i have tried developing a sample app to detect usb. but i was not success.
My code will look like this.
____________________________________________________________________
public class MainActivity extends Activity {
UsbManager manager;
HashMap deviceList;
Button scanButton;
UsbDevice device;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
scanButton = (Button)this.findViewById(R.id.button1);
scanButton.setOnClickListener(new OnClickListener ()
{
public void onClick(View v)
{
checkForDevices ();
}
});
}
@Override
public void onResume ()
{
super.onResume();
checkForDevices ();
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
protected void checkForDevices ()
{
manager = (UsbManager) getSystemService(Context.USB_SERVICE);
deviceList = manager.getDeviceList();
device = deviceList.get(“deviceName”);
//Collection devices = deviceList.values();
if (device != null)
Toast.makeText(this, “Device Found”, Toast.LENGTH_LONG).show();
else
Toast.makeText(this, “Device NOT Found”, Toast.LENGTH_LONG).show();
}
}
_________________________________________________________________
When i run this app, i always get the toast as “Device NOT Found”.
Since i’m new to android, i was not able to fix this problem for the past 3 days.
Can you please help me out.
Hi, I’m a newbie to Android environment …Would be grateful or some help / guidance. I want to run PrintRun? /Pronterface on an Android Tablet with a Host USB Port.
Pronterface is a 3D printer host software written in Python and available at https://github.com/kliment/Printrun.
Pronterface.py is the main executive file.
This Host has to link with Arduino Mega 2560 with Marlin Firmware.
Marlin is available at https://github.com/ErikZalm/Marlin.
Hi Manuel,
Thanks for the code. Can you explain me the code
‘conn.controlTransfer(0x21, 34, 0, 0, null, 0, 0);
conn.controlTransfer(0x21, 32, 0, 0, new byte[] { (byte) 0x80,0x25, 0x00, 0x00, 0x00, 0x00, 0x08 }, 7, 0);’
Can I set other parameters?
Thanks again.
Hi Andreas Rudolf,
I am using Uno rev-3 having “VID:PID = 2341:0043″.
On linux I am able to communicate with board (verified with lsusb), but when I connect with Android Tab 3.1 (with OTG support), could not get detect device using app, even mUsbManager.getDeviceList() not return any device entry having VID = 2341.
Note: Uno rev-3 using ATmega16u2 as USB-Serial converter (on chip driver).
Do I need to add driver in Android tab for that, if yes can you provide steps for that.
Thanks,
Jignesh
Hi Jignesh
A driver is not required for communicating this way.
We are using an Arduino Uno Rev 3 with ATMega16u2, VID=0x2341,
PID=0x0001as well. EDIT: VID=0x2341, PID=0x0043Have you installed the above Android app UsbController.tar.gz? The VID/PID values are already set at the top in UsbControllerActivity.java and should be changed accordingly (Right now it is PID=0x0001). Have you also installed the above firmware on the Arduino?
You said getDeviceList() does not return any device with VID=2341. Note that the VID and PID values returned by lsusb are in hexadecimal format. That is, VID is 0x2341 or 9025 as a decimal value. The returned HashMap by mUsbManager.getDeviceList() will be empty, if “no devices are attached, or if USB host mode is inactive or unsupported”. Can you check if the HashMap is empty? If so, maybe USB Host Mode API is unsupported on your particular tablet, or there is a problem with the OTG adapter. Either way, good luck
Best Regards
Andreas
Thanks Andreas for quick response,
I am using Samsung Galaxy Tablet-10.1. It having OTG support and works fine with mass storage device (able to see entry in HashMap retuned by mUsbManager.getDeviceList() );
But not able to work with other usb devices.
As per “http://stackoverflow.com/a/7587158/1635169” ; it look like Samsung kernel bug or samsung limiting features.
If I get chance to test it with another cheapest tab; I will update you, but it will takes some time.
I am appreciating your help, thanks again.
Jignesh
I can’t compile android apps, is the app on the market?
Hope you don’t mind me stopping by to plug my library for Android USB Serial driver support, which supports both FTDI chipsets as well as CDC-ACM, abstracted under a simplified interface. It’s opensource, and contributions would be welcome: http://code.google.com/p/usb-serial-for-android/
Hi Mike,
I am able to install USBSeriallib and USBSerialExample on Samsung Galaxy Tablet-10.1 (Android OS – 3.1) and connected FTDI usb to UART cable with it in loop back connection.
But in application it says “No Serial Device found”,
I thing it should detect FTDI usb to UART device.
As per “http://stackoverflow.com/a/7587158/1635169″ ; it look like Samsung kernel not supporting it.
If any body tried same way with other or Samsung Galaxy Tablet-10.1, please share your results.
Regards,
Jignesh
Jignesh,
The P7510 / P7500 do not support the Android USB Host API.
Cheers
Manuel
Hello Manuel,
first of all thank you for the article,
and sorry i am a bit late here as this post seems to be older.
I am new to electronics or i would say a learner, but i have very good experience of software development.
I have read a lot about the android, arduino, ADK, also the alternatives like IOIO and microbridge.
the objective is to create a USB device which can power my android device (so that i can be charged while connected) and communicate between device and android, the communication would be usual like providing the values from sensor to android and then android application will decide what actions to perform and communicate back to the device to trigger the other stuff connected to it.
my question is what combination should i use for the above requirement?
android + ADK
android + aurdino UNO (i already have one)
android + IOIO
my Android is HTC One X with 4.0.3 (Original)
any help would be appreciated, also please consider that i am a learner so it would be good if you can provide some good references as well.
Thank you very much
Tariq
Hello Tariq,
Thank you very much.
If you need power, then you should go with the ADK. If you need a matching hardware I would suggest you go with the Mega ADK http://arduino.cc/en/Main/ArduinoBoardADK.
It is pretty popular and has an active community. Arduino for the win
All the best
Manuel
Hi Manuel,
Thank you for the quick response, I am working on a prototype and i m sorry i can not share what the idea is but just wondering that while going for production we will have to embed this ADK in our devices, wont they become so expensive? would that be a good idea to embed the complete ADK in each device ? is there any cheap solution ?
Regards
Tariq
Sorry for the second post
just trying to be more specific.
i want to develop a dock so when the phone or tab is connected to it, an application will be launched on the tab automatically and display the information coming from sensors and let user chose the options. i.e. shutdown the machine if it is over heated. and the tab will keep on charging while connected.
Hello Tariq,
The ADK really seems to be the best option for you.
For a prototype you should look into the Arduino Mega ADK. I am sure you will find some example code for firmware as well as for the Android side software. You can refer to our ADK Post “Turn your Linux Computer into a huge accessory” to get started.
You would then attach your sensors to the ADK and use analogue inputs to measure them.
I hope this gets you started.
For production you would have to include the micro controller into your own hardware design. I don’t think this will be a lot more expensive than to go with a USB device only controller.
All the best
Manuel
Hi Manuel,
Thank you for your guidance,
I did some more research and found the following:
IOIO can also charge your phone/tab
https://github.com/ytai/ioio/wiki/Power-Supply
IOIO now supports Open Accessory Protocol which means you can now connect your Android to IOIO in Host/Accessory mode as you would do with ADK. the only difference is that you will need reference the IOIOLibAccessory library and the ADK library as well IOIOLibAccessory creates a wrapper around ADK library and use its native functions to communicate with android
https://github.com/ytai/ioio/wiki/IOIO-Over-OpenAccessory
both of these articles are written by ytai the inventor of IOIO
the best part about IOIO is that you can control the pins right from your android application and you don’t need to write the separate code for microcontroller and android.
hope this may help some one
thank you once again
Tariq
Hi,
I am using Arduino IDE to compile the firmware code and it cannot compile. Says the error “PB5” is not declared in the scope. Can you help me out?
Thanks
Hi Stan
PB5 is simply defined as 5. Thus, instead of “#define LED PB5”, you can simply write “#define LED 5” and everything should be ok.
Kind of strange that it is not defined when compiling with the Arduino IDE though.
Best Regards
Andreas
I just tried with a Samsung galaxy ii(T989) wit Cyanogenmod 10 and works nicelly. I had to make a few changes to make it work without problems in the Arduino IDE. I deleted all the serial port stuff and replaced with the ‘Serial’ class from Arduino.
I tried to use this tutorial with my arduino duemilanove and my google nexus s with 4.1.2 version, but I don’t have same result. When I connect the phone with the arduino, it doesn’t power on, and I don’t know why.
When I connect the arduino with my MAC it is recognized instantly.
Am I doing anything wrong or I have to do anything more than this tutorial? I just use the UsbController.tar.gz* file as apk and load the led_pwm.c on arduino.
Hello Joao,
the nexus s does not feature usb otg. You cannot communicate with it using USB Host, I am afraid.
All the best
Manuel
Hi,
Thanks for the fast response. I think that this is possible if I change the kernel. I will search about it.
Thanks
Hi Manuel,
Thanks for such a detailed post. It helped alot. I have some issues, I am using a Beagleboard Xm and pluggin in any USB device. Using above application I expect to see any device be listed when I try to access it through an application. Unfortunately not a single device can be found. Under Androidx86 and various real Android tablets, everything works fine with the exact same code, but the beagleboard never let me access USB devices. I used the ICS prebuilts offered by TI.
I am using UsbManager class in order to enumerate the android devices connected to the same but I am unable to get the devices list. I checked logs, its UsbDevice.getDeviceList returns empty list. Is there anything i need to change in the init.rc or elsewhere in order to get the device list?
however, my beagleboardXM works fine with keyboard and mouse connected thro’ USB.
Do you have any idea what could be possible reason
I’m trying this for long now! but no progress.:(
Hello Shreyas,
I am sorry that it seems not to work with the Beagleboard XM. Does the board get powered when you connect it?
If you get an empty list of devices back then usually it means either the board is not enumerated, or the framework part of the UsbManager has not been implemented correctly. What you could do is to try the “rowboat” build (http://code.google.com/p/rowboat/) and to check if the issue there persists as well.
One more thing I could imagine (though rather improbable) is that the device port /dev/ttyACM0 is busy and thus is not shown in the list of enumerated devices. However, we have devices with the ACM driver here as well and they seem to work.
Please keep me posted on your development, since we always get requests in the comments about devices not enumerating (empty list issue).
On a separate note, with the Linaro build on the Pandaboard we have been able to communicate.
All the best
Manuel
Hey there,
thanks for this awesome write-up! I managed to install the firmware just fine on my Arduino Uno, changed the PID to …43 in the app and also got it installed on my Odys Neo x8 which should support USB hosting and is connected to the board with the OTG adapter. The board gets powered properly but unfortunately, the led is being very low-dimmed and moving the slider doesnt change anything, also, the enumerate-button doesnt do anything. Any hints?
Best
tim
Hello Tim!
Coincidentally I know what the problem is!
You need to activate Brownout detection in the fuse settings of the Arduino board.
We had that too, but only sometimes.
This command should fix it
We did this for the mega, however you need to adjust the partno (-p) for the uno and I cannot find that one. Hope this gets you started though.
All the best
Manuel
Hello,
I have the same problem…
and I can not solve..
let me know if you solve.
luck
Emilio
You need an ICSP Programmer to change the fuses on the UNO. We used an “USBtinyISP” to update the fuses. I think you will find some on ebay.
All the best
Manuel
Wow, awesome speed you got there!

Can you tell me where to enter it? I’m running Mac OS X (could access Windows too…) and fairly new to Arduino
Hello Tim,
I did this in a terminal.. the command should look something like this
However, I am getting an error if I try. Maybe you need an ISP programmer.
For a quick fix try to connect a powered USB Hub to your Arduino.
Now all I get is this:
Reading | ################################################## | 100% 0.00s
avrdude: verifying …
avrdude: verification error, first mismatch at byte 0x0000
0x99 != 0x00
avrdude: verification error; content mismatch
avrdude: safemode: hfuse changed! Was 99, and is now 0
Would you like this fuse to be changed back? [y/n] n
avrdude: safemode: Fuses OK
avrdude: stk500_recv(): programmer is not responding
Hello Tim,
I get something similar. I think you can’t flash the fuses over the serial programmer but you probably would have to use an actual ISP programmer :(. I can’t fix it either
Have you tried to use a powered hub? This should prevent the board from having brownout problems.
But how can I connect the Arduino to an USB powered hub (which I got already) and to the tablet at the same time? :/
Hi Tim,
I checked again and I did not find any solution… it seems that the fuses are somehow locked … I bet it would work with an ISP.
Regarding the hub: I mean a hub that is powered with a 5V power adapter.
All the best
Manuel
Hey there,
I looked into the problem a little more and it seems, that the tablet isn’t finding any USB-devices since I build in some debugging logs into an extra TextView into the UI which isnt displayed…Any suggestions?
Hello
Nice and helpful article.
can you answer my below doubts please?
2.How do i know the board (arduino or any other ) i have works as USB host or device?
3.Is there any other alternative way to communicate to a external USB host with out using ADk(or Open accessory protocol) from my android device.Suppose I have host device connected to my android which gives me room temp every 5 min.How will i talk to this device from my android device with out using ADK/AOAP.
Hello Kozlov,
Thank you so much
1. The Arduino Due for instance enables you to connect as both Host or Device. You should check that one out.
2. If you have an external USB Host then the preferred way is to communicate using the ADK protocol. You could of course write your own implementation (turn to the source code of the Android ADB Daemon for that), however that will require a lot more effort and know-how than use the current ADK API.
Hope that helps you further
All the best
Manuel
Hi all,
First of all, thank you Manuel for these helpful articles and for providing a platform for like minded people.
I’m working on a home automation project with a z-wave USB stick. I’ve bought an Odroid-X development board which is pretty awesome. I want this board to be the main controller. It therefore needs to communicate with the USB stick. Inside the stick is a prolific 2303 chip with 3 endpoints. 1 bulk in, 1 bulk out and 1 interrupt. Is there anyone over here who got communications with this chip working. If not, does anyone want to collaborate on implementing the soft driver for the chip?
Thanks very much,
Willem
Hello Willem!
Thank you so much
I bet you can get the profilic to work. What you need to do is to find out what setup commands it uses. I think there is even a usb serial library that has that code snippet inside.
If not, then you need to look through the kernel driver, there it is for sure.
I will have a look into the matter as well.
All the best
Manuel
Does this method work only with Arduino UNO, or with the older Arduino’s (Duemillanove and the zillion clones), which use the FTDI USB/serial(TTL) converter ? I guess, one would have to modify the user-mode soft-driver logic to fir the FTDI serial protocol, right ?
Hello Jayanth,
This works with the FTDI as well, though with other setup transfers.
hello manuel,
I think your project is very interesting and I congratulate you for this.
I would like to know what exactly is the board arduino you used in the project.
sorry for my English, I do not speak very well…
Thanks,
Emilio
Hello Emilio,
We used an Arduino Uno Rev. 3 Board.
Hey,
I’ve found this project http://code.google.com/p/indiserver/
It has a basic PL2303 soft driver. But only for a specific product and vendor ID.
These are not the right ID’s for me, so I’ll extend this driver with the code for my device.
If it works, I’ll send the author of this indiserver project a message and post the results here as well :).
Regards,
Willem
Never mind, the code should work…
Have not gotten it to work myself though.
Hope this helps others!
Regards,
Willem
Hi all,
As of last sunday I’ve managed to get the right setup for my device.
I want to confirm that the above mentioned driver from the INDIServer project is indeed working great.
Now I can finally start with the implementation of the rest of my z-wave server :).
Regards,
Willem
Hi Willem!
Thanks for sharing!
All the best
Manuel
Impossible! I can’t get working my ZeniThink C91. I can’t understand it. Everything seems well but…
I use a Huawei 3G modem with this tablet with no problems at all. It means that it works as USB host properly.
I have checked the VID and PID codes of my Arduino UNO board. I have tried with an Arduino UNO rev.1 and rev.2.
I don’t know what more to try… this drives me mad!
Please, could anyone with a C91 whether got this tablet working this issue?
Thanks.
Hello,
The guide is for a rev 3 board.
However, the Arduino in the pictures is a rev.2 board.
I had some problems with my low cost START701 tablet (Android 4.0.3) until I found this article that describes how to enable USB host.
I implemented it and everything went smooth, even on my Arduino Duemlanove.
Thanks Manuel for your valuable helo,
Hello Mr. Manuel i have a tablet archos 7htv2 with a costume firmware Froyo inside and it supports OTG & USB host , and when i plug my Arduino Mega a new ttyACM0 device shown in Dmesg,
does it mean that this tutorial will help me to communicate with arduino even if it’s not honeycomb ? (
thank you for advance
Thanks for the post.
Is it possible that this could work with a prolific usb-serial device? Also how would uart fit into this?
Thanks
Hi Dylan,
it is possible, yet you will need to adjust the control transfers and possibly the polling mechanism. You would probably start by checking the kernel driver for those usb transfers or sniff them from your host machine (you could even use wireshark).
All the best
Manuel
hello, i’ve a question, from where do you extract the constants or parameters for the function controltranfer(…..)
i’m using this function but in other interface (android with FTDI) and i have some doubts there,
thanks!!
Laura
Hi Laura,
the parameters are extracted from the libftdi api (which is open source) and for the rev 3 arduino from the source of the firmware (lufa) running on the 16u2.
All the best
Manuel
Hello,
I have a problem with the connection.
I have ZTE Grand X In phone, and Arduino MEGA 2560 (not with FTDI chip) connected by USB OTG enabled cable.
The phone powers the Arduino MEGA board, but the board is reading nothing from the serial port.
I tried with Serial.available() and still nothing.
Any suggestions for this problem?
I adjusted the VID and PID parameters as correctly as in device manager.
I will really appreciate your help.
Thanks in advance
Nikola
Hi Nikola,
Are you able to grant your application permission for your Arduino? Is it listed in your device list via UsbManager?
All the best
Manuel
For the purpose of troubleshooting I add this get method to your UsbController class:
public HashMap devic()
{
return mUsbManager.getDeviceList();
}
And added TextView to your main activity so I can read the listed devices on the phone, and it gets updated in the slide event listener.
((SeekBar)(findViewById(R.id.seekBar1))).setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
if(fromUser){
if(sUsbController != null){
sUsbController.send((byte)(progress&0xFF));
//Here I update the text view with the listed devices.
x.setText(“Devices: “+ sUsbController.devic().toString());
}
}
}
});
I get empty set {} from the hush table toString() method.
What do you think does it mean?
Hi Nikola,
This means your device does not support the Android USB api I am afraid
All the best
Manuel
My board is Arduino mega 2560 Rev2, and PID is 0x0010 if that means anything
But i tried with usb Mouse and Keyboard and it works.
I can control the phone with them.
You still think that Usb API is not supported?
Can i fix it by rooting the phone, because my phone is not rooted?
Your hardware suppprts Usb Host, but Android is missing a crucial part of the API on you phone. Cyanogenmod will enable you to use it though almost for certain.
That will be my last try.
The app called USB DEVICE INFO from google play.
This application uses two different methods to collect information:
1. Android mode use the native android USB API.
2. Linux mode will parse /sys/bus/usb/devices/
The second Linux mode enumerates my device and its PID and VID and recognises the MEGA, but the first Android mode doesn’t.
Anyways you had been a great help for me. I am engineering student and this will be a part of my final project.
Thank you very much, and keep up the good work.
Hey Nikola,
Indeed some OEMs tend to include the Kernel driver for OTG and USB Host, yet they opt to go for a build without the file ./native/data/etc/android.hardware.usb.host.xml which contents are
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
<
permissions
>
<
feature
name
=
"android.hardware.usb.host"
/>
</
permissions
>
The file has to be in
for it to “activate” USB Host.
So if you are keen on trying, you can root your device, use “adb remount” to remount the system partition and use “adb push” to put the file into your etc folder and try again.
Please note all the consequences for your device warranty when rooting your system though.
Hope that gets you started
All the best
Manuel
I will try this method, and let you know what have I managed to do.
Thanks
Great work. I am looking forward to get this work on my andriod tablet. Will let you know the results
Hi
I am student and currently working on a project for my univerity. I am trying to write an app which is capable of reading date by using the TUSB3410(http://www.ti.com/product/tusb3410) and its USB to connect it with the C2500(http://www.ti.com/product/cc2500) connected via UART. Something like USB to serial.
I can get informations of the TUSB3140 like its vendor id or its endpoint so I can use the normal USB API. But it is rather tricky to receive the information of the cc2500. I dont know which methods I should use or which parameter are correct. So maybe you have an idea how the methods like controlTransfer() etc. should look like.
I hope you can help me with this problem!
Best regards, Patrick
Hello Patrick,
Indeed if you have another USB-Serial controller the setup is always a bit tricky.
I urge you to try and use wireshark while you connect the controller to your Host Machine and then check what control transfers are issued! This is a method guaranteed to work. If you are lucky please get back to us so we can refer to your work.
All the best
Manuel
Hi Patrick,
I am in a similar environment – needing to get the Android Serial USB OTG interface working with a TI Launchpad which uses the TUSB3140 module for UART USB like your setup does. I got things to work very well with the Arduino Uno – so I know the Android side can work – and I can see the Vendor ID and Device ID for the TI module when I iterate devices (Decimal 1105 for the vendor and decimal 62514 for the device), but things keep crashing and no data is ever exchanged as far as I can see.
Did you ever find a solution to the setup for the TUSB3140 in your project? Thanks.
Hi very nice! Loved it!
I have a small doubt. This code continously sends data from the android phone to the arduino. Is there anyway i can send discreet data .
For example, I want to send data((byte)0x03) to the arduino only on a button press.
When i put the following code on a button press
sUsbController.send((byte)(0x03));
The arduino crashes after sometime. I think its because the buffer is overflowing as the android code is continously sending the data(0x03) to the arduino. Any way i can make the android code send the data only once?
Hello Suhas,
You should always check the return result of “bulkTransfer” since it indicates the amount of bytes actually sent to the Arduino. Also be sure to always call Serial.read() / handle the interrupt properly, on the Arduino side.
All the best
Manuel
Is there example code that I could add for sending information back to the android device? Perhaps if I were to take a few analog reads from the arduino and I want to send them to be graphed on the android?
Hello Joseph,
We don’t have a read example, that is right, yet it is really simple. You only need a reference to the Bulk OUT endpoint and then send the data via bulkTransfer(…). The buffer you submitted as argument will then hold the data from the Arduino.
hope that helps you
all the best
Manuel
Hi! We are using your program for our project at school and we would like to ask you for some help. It would be very appreciated! We’re not that good at programming so yeah..
First of all we’d like to know how to send data from the arduino back (in our case, to an android nexus 7 tablet).
Secondly we need to know if your program is also executable on the arduino micro board (http://arduino.cc/en/Main/ArduinoBoardMicro). Currently we are using the same as you use(d) (Arduino Uno)
Thanks for your help in advance! Greetings from Austria!
Hi Andreas!
Thank you so much.
You can send data back by issuing a transfer to the bulk out endpoint and then you will receive the data that you are sending with Serial.write() on the Android side.
The only thing you have to change is to find and Reference the Bulk OUT EP in the Java side. The data is then stored in the buffer you transmit.
Hope that gets you started
All the best
Manuel
Thank you very much! It worked flawlessly!
Do you know if your program also works on the Arduino Micro? (http://arduino.cc/en/Main/ArduinoBoardMicro) We need to make the whole thing as tiny as possible…
Thanks again!
Hi Manuel,
I am also interested in receiving data back from the Arduino. I’m trying to follow your above advice, but I’m not sure how to proceed. Isn’t the bulk OUT EP used when you are sending data from the Android to the Arduino (in UsbController.java under synchronized (sSendLock), the line conn.bulkTransfer(epOUT, new byte[] { mData }, 1, 0); )?
Do I need to write another line withing the synchronized (sSendLock) that just uses epIN instead of epOUT and a variable to store data instead of new byte[] { mData } ? Or do I need to make a new object, say sReceiveLock, and write a similar synchronized (sReceiveLock) ?
Thanks,
Andy
Manuel,
Thanks so much for this article. I got the Android-Arduino transfer to work with this when other approaches weren’t working. I did discover something: using the main() method instead of loop() disables the PWM outputs using analogWrite, for some strange reason. I worked around it by converting main to a loop that exits after 1 loop.
But I, like about 10 others in this thread, really need to send data in the other direction also. I’m impressed that Andreas was able to use your hints to solve that, because nobody else has. I beg you to help us by elaborating a bit more how to do this transfer. Please? Or anyone else that has solved this–including Andreas.
Thanks, Bill
i get this error in the arduino program.
“sketch_mar15a:96: error: ‘PB5’ was not declared in this scope”
what could be the reason ? pls help
Hi there,
Amazing tutorials!
I got it work with my Nexus 7 and Arduino Mega 2560.
A few things to change for it to work on the Mega 2560 though:
– The LED pin is PB7.
– The USART_RX interrupt vector for Mega2560 is USART0_RX_vect
( I referred to http://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html#gad28590624d422cdf30d626e0a506255f)
– The PID of Mega2560 is 0x0042 (just do a lusb to see the correct PID)
– In the code to blink the LED, setting _delay_us(pause*10) is too fast, the LED would just dim. change delay_us to delay_ms would work.
Hello HG!
Awesome! Thank you for sharing with the rest
All the best
Manuel
Hello, Manuel.
Thank you for your great work.
I am trying to make your solution for Mega ADK, but it is not easy…
I uploaded your firmware code on mega adk, and also installed android application on Nexus S and galaxy nexus.
What I modified is PID(Mega adk’s was 0044) in anroid application, and I change LED value to 13(I am using vibrator) in firmware code.
But Mega ADK did not respond. It was still in power off status even I connected to Nexus.
Do I have to change more? Could you help me what do I have to change?
Thank you in advance.
Hello HongjoonKim,
The guide is not for the ADK / Accessory API but rather for the USB Host API. Still you can hook up your Mega ADK yet you will need to use an OTG converter. Sadly the Nexus S does not support USB OTG. The Galaxy Nexus on the other hand should do fine.
All the best
Manuel
Hello,
i just bought Arduino UNO rev 3 and i would like to connect it with Google Nexus 7 to swich on – off LED 13(L) can i do it? Or do yo have any code that helps me to achieve it?
Thanks very much for respond
You can do it with a slightly modified version of the software code on the Android side.
Nexus 7 works
All the best
Manuel
Can i ask you for code for Arduino side in format of ino? I am programming on Windows 7 with Arduino 1.0.4 so I am little clueless how to modifie Arduino program from C++ to work.
I have Arduino UNO rev 3 and Google Nexus 7
I tried to modify code for Arduino – http://pastebin.com/k9Z1cJjP
Also i modified MainActivity to – http://pastebin.com/7qt3MbuT
When i left PID on 0x0001 nothing will happend. When i changed it to 0x0043 then activity will failed on nullpointer exception caused by conn
if (!conn.claimInterface(mDevice.getInterface(1), true)) {
return;
}
Can you help me to get it working Please?
Hi Manuel,
I have google nexus s and TI’s MSP430 launch pad
I want to send data processed in launch pad to nexus s for display. I read most of the comments I couldn’t able get a complete info on how to proceed with this. In one of the post you told that USB OTG doesnt works with nexus s, so is there any way to make it work? I am very new to android environment. Pls help me, this is my mini project to be submitted to the college.
Thanks in advance
Hi, I want to make android version of my PC (C#) code which connects to a OBD-II scanner circuit through USB to RS232 cable. when I connect the device to my android tablet its shows up as /dev/ttyUSB0. I can send and recieve data through “slick USB 2 serial” terminal app successfully. Having almost no knowledge of android development I would like to seek help from you. if u could help, it would be highly appreciated. I only need a kick start for which I need a simple app which has a button and a text box. when button is pressed a string “abcd” is sent and the received data should be displayed in the text box. I searched a lot but couldn’t get any easier guide. I’m not even sure what content I need to read. Looking at what you have done I believe you could help me….
Regards
Thank you for your work on this. I did finally get it to work. I have the exact setup you describe here. Galaxy Nexus + arduino Uno. Oddly, I had to change the baud rate on the arduino side to 4800 to get it to work. Do you have any idea why this this is? I would investigate the control parameters, but I’m a bit out of my element here.
Thanks again.
I think perhaps this may be related to the USE_2X flag detailed here.
http://www.appelsiini.net/2011/simple-usart-with-avr-libc
i have a problem that my arduino uno can’t recive data from the tablet(i use haipad a13) and i can’t find the problem. can you give me a tip to solve this problem
i use android 4.1
hello,i want to achieve two smartphones communication .but i don’t know how can i do ? can you give me some advice ? i can do connection another device but send message not receive
Now whether a device can achieve this function ? What do I need to write their own drivers ?
Thank you again for the very informative article. I just wanted to confirm that this does work for Galaxy Nexus + Arduino Nano with FTDI chip. The only changes required were changes to VID/PID, and also changes to mDevice.getInterface(1) to mDevice.getInterface(0) as there seems to be only one interface exposed.
Forgot to mention change to the controlTransfer commands for FTDI as well.
I found out that this USB HOST API just can not find the HID device ,but the other device is normal, how can I use this api find the HID device? I test many device , you say that
Manuel Di Cerbo Post authorJune 4, 2012 at 15:20Hey Arvind,
About the HID: I actually never tried to connect. However, since the interfaces of the HID device is probably already claimed by the input driver, it would be difficult to use them in the app.
Does now it have any way to slove it ?
Hi!
You presented an awesome demo about Android USB Host Programming. But I want to know how to deal with the interrupt IN EP ( a typical hid device ) which required to poll periodically. Could you give me some approach or code snippet about this?
Hello Manuel,
I am working with Raspberry Pi. Based on your code I am able to list the devices. My device is a DIGI XStick which is receiving temperature readings from a wireless sensor. This Xstick is attached to RPi. I want to read the readings of temperature on the XSTICK. I know I need to use these
conn.controlTransfer(0x21, 34, 0, 0, null, 0, 0);
conn.controlTransfer(0x21, 32, 0, 0, new byte[] { (byte) 0x80,
0x25, 0x00, 0x00, 0x00, 0x00, 0x08 }, 7, 0);
But I don’t know how to use it from adb. After starting the activity and giving logcat | grep “>==<" devices are listed. Then if i type the above two lines nothing happens. If i do CTRL+C and come out to adb shell and then type these statements it will give syntax error. Please can you explain how to read the temperature readings on XStick using adb?
Many thanks for this article.
NKP
Is there a way to debug the code? Since there is a only one micro USB port in Android phone, is there a way to debug the code using emulator while the USB device is hooked to a PC USB port?
Using adb wireless connect ?
Enable it in phone by:
stop adbd
setprop service.adb.tcp.port 5555
start adbd
Connect it via adb in pc
adb kill-server
adb connect xxx.xxx.xxx.xxx
I use it in my new MK802. When I plugin the UNO R3 to MK802 via micro usb otg, the UNO does not perform normal.
I get the following via adb logcat:
usb 3g monitor v0.1 start
event { ‘add’, ‘/devices/platform/sw_hcd_host0/usb1’, ‘usb’, ”, 189, 0 }
event { ‘add’, ‘/devices/platform/sw_hcd_host0/usb1/1-1’, ‘usb’, ”, 189, 2 }
path : ‘/sys/devices/platform/sw_hcd_host0/usb1/1-1’
VID :size 5,vid_path ‘/sys/devices/platform/sw_hcd_host0/usb1/1-1/idVendor’,VID ‘2341 ‘.
PID :size 5,Pid_path ‘/sys/devices/platform/sw_hcd_host0/usb1/1-1/idProduct’,PID ‘0043’.
cmd=/system/etc/usb_modeswitch.sh /system/etc/usb_modeswitch.d/2341_0043 &,
excute ret : 0,err:No such file or directory
event { ‘add’, ‘/devices/platform/sw-ehci.1/usb2’, ‘usb’, ”, 189, 128 }
event { ‘add’, ‘/devices/platform/sw-ohci.1/usb3’, ‘usb’, ”, 189, 256 }
event { ‘add’, ‘/devices/platform/sw_hcd_host0/usb1/1-1’, ‘usb’, ”, 189, 3 }
path : ‘/sys/devices/platform/sw_hcd_host0/usb1/1-1’
The error continues display. It enters a loop to get some USB host profile. I perform ps through ssh, found a process:
/system/bin/busybox ash /system/etc/usb_modeswitch.sh /system/etc/usb_modeswitch.d/2341_0043
As expected, I cannot locate the file 2341_0043 in usb_modswitch.d directory.
It seems I cannot continue without such required file. Where can I download such USB host profile? Or any other way to skip or create it?
I solved it by putting the required permission files in /system/etc/permission/
Great document. It works!!! Thanks for the author.
I would like to ask a question here. Is there any way to skip the permission granting dialog? It shows such dialog after reboot the device.
My device is rooted. Hope this help. Looking forward to getting the solution. Thanks.
Hi,
This article is a godsend! I was able to get this running on a pro mini knock off by deek-robot. works a treat but it means i have to use a ftdi breakout that’s bigger than the pro mini! I was hoping to try this with a pro micro from sparkfun but it doesn’t seem to support the serial variables. when i compile through Arduino ide I get a litany of ‘xxxxxx’ was not declared in this scope. replace xxxxxx for UBRR0H through to UDR0
Is this because the libs aren’t in the firmware? is there any way i can update that?
Hi Manuel,
I am working with acer B1A71 tablet.
I have deployed most of my apps on it and working fine.
Now I want to make it as a USB host. I tried connecting my tab and the hardware with the help of an OTG cable ,but it didn’t work ( I Know its a stupid way of doing it)
How do I go about making it a USB host ?? Could you please help me out.. MIne is a rooted tablet and kernel version is 3.4.0. Not sure if it supports USB host API. I have no idea how to check if it supports that API.
Can you please help me out with this ?
Thanks in advance,
Mansi
I just wanted to mention that this works on a Mega ADK by utilizing 0x0044 for the PID. I have tried using Accessory mode FROM the ADK to the tablet with some results, but not all the way. This example you posted got me talking to the board. I used another app from Google Play to read the PID / VID.
Thanks for the post!
Hi,
This article is GREAT work and it helped me tremendously in getting an Arduino Uno to communicate with an Android tablet over the USB Serial connection. But now I have been trying to make the same thing work for a TI Launchpad and everything seems to be breaking. Does anyone know what the controlTransfer code would be for the TUSB3410 controller that is used on the TI Launchpad as the USB interface? I have even tried the Android USB Serial Monitor Lite app – since it handles numerous devices – and it also cannot open the TI Launchpad properly. Thanks.
Hi Manuel i connected and sent data from android tablet to arduino board. But i want to send data arduino to android too.How can i listen received datas in android? In imported packages i didnt see any receive function in java.What i should to do?
Is it possible to use the usb port to stream the cam using OTG as seen in htis video
http://www.youtube.com/watch?v=M_HaIp5GLgE
Thanks
Eric
Hello. I have one I could help you schedule one arduino to send data to the application in android but not how to make android application displays data onscreen arduino sends me. use your code to connect to arduino but I have no idea how dispositib resivir in android. thanks for the help.
Hi,
Thanks for a great tutorial. I’m very new in this field and need a hint. Managed to almost get everything working… Except that the led (for me on pin 13, arduino uno rev3) not get lighted.
I can see that RX led flashes when i move the slider. But nothing happens on the led for pin 13. I changed PID to 0x0043.
And so a little Christmas wish. I think a lot of people out there would be extremely gratefully if you added a section on how to read values from the arduino and present them in the android app.
Big thanks in advance!
/Fredrik
My Nexus S device can’t power up the arduino and the host mode is not enable on the device. any clue is valuable.
Hi. Im try this connection with Nexus 5 and arduino mega 2560.
Im little modify code :
int main(void) {
...
for(;;) {
digitalWrite(13, HIGH);
_delay_us(10000);
digitalWrite(13, LOW);
_delay_us(10000);
pause = data;
for (i=0;i<pause;i++){
digitalWrite(10, HIGH);
_delay_us(100);
digitalWrite(10, LOW);
_delay_us(100);
}
PORTB |= (1 << LED);....
return 0; // never reached
}
When I start it, diode is blinked. Also when I connect nexus via usb and push Enumerate.
But When I change slider, on board diode EX is blinked, but other dioded is stop blinked. like program crashed.
How I can debug it, or whot I do wrong ?
Thanks
Ohh. here is maybe problem
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // error in parts per mill, 1000 = no error
too long response when I wait for diode.
Hi.
Im using nexus 5 and arduino mega 2560.
Device us connected, but transfer is not working. when I change slider, then diode on board RX is blinked. but nothing else.
Im try add blink test(turn diod on) to method uart_putc, uart_getc, ISR. but diode is not turn on.
Hello
the reason for my post is a question about your blog Android + Arduino USB Host: How to communicate without the roots of your Android tablet or phone
use your code to create communication but send data to arduino there is a delay and values ​​are lost, I wanted to implement the arduino get the data and send back to help monitor android is lost or if the connection is failing
thank you very much for your attention
Work very fine also Arduino Mega rev3 with:
PID = 0x0042;//<-- Arduino Mega
I have used the android package for a demo in a talk during Linux Day 2013 @ Bari.
source: https://github.com/MikiNacucchi/DemoOpenHardware/
Thanks for your post.
I copy your conn.controlTransfer() setting to my exercise of Android USB Host Mode.
// Arduino USB serial converter setup
conn.controlTransfer(0x21, 34, 0, 0, null, 0, 0);
conn.controlTransfer(0x21, 32, 0, 0, new byte[] { (byte) 0x80,
0x25, 0x00, 0x00, 0x00, 0x00, 0x08 }, 7, 0);
I used the usb controller and it worked with a arduino mega.
my question is how could read a sensor from Arduino and receive the value placed in a text field in android.
from already thank you
GREAT!
Thank you very much! I have only one problem figuring out the baud rate for midi (31250, asynchron) for the controlTransfer.
can you please help me with that?
thank you very much!
cheers, van
I’ve got it:
conn.controlTransfer(0x21, 34, 0, 0, null, 0, 0);
conn.controlTransfer(0x21, 32, 0, 0, new byte[] { (byte) 0x12,
0x7A, 0x00, 0x00, 0x00, 0x00, 0x08 }, 7, 0);
Thank you a lot van for the update!
Great example! However do you have any code suggestion for reading from Auduino to Android. Thanks.
Manuel,
Sorry for duplicating this comment. Replying to your note in March stuck my comment back there where nobody may notice it.
Thanks so much for this article. I got the Android to Arduino transfer to work with this when other approaches weren’t working. I did discover something: using the main() method instead of loop() disables the PWM outputs using analogWrite, for some strange reason. I worked around it by converting main to a loop that exits after 1 loop.
But I, like about 10 others in this thread, really need to send data in the other direction also. I’m impressed that Andreas was able to use your hints to solve that, because nobody else has. I beg you to help us by elaborating a bit more how to do this transfer. Please? Or anyone else that has solved this–including Andreas. I know you like people to try on their own, but a bunch of people have tried and failed, including me–and I’m generally very good at this kind of problem. Thanks in advance.
Thanks, Bill
Hello Friends!!
Even Iam using android and arduino duemilanove to communicate over an USB interface using android’s USB host APIs. But when I try opening the connection using the UsbManager.openDevice(UsbDevice device) method of the UsbManager class, I get a NullPointerException. Iam new to this field and cannot figure out where the possible problem could be ? Hope someone will help me out with this
Thanks in advance!!!
hello there,
our controller uses a 38400 baud rate, 7 data bits, 1 stop bit, and odd parity. How to set up them in the sketch?
Thanks
Hello,
Nice tutorial, I’m from indonesia. I’ve following the instructions. And I’m using Smatfren Tab7.0 from hisense. I need to hack the USB Permission to connect with arduino device. And It works. Thanks anyway.
Sorry for bad english
Great example! It’s a pity to have a wired connection when you use a mobile device. Is there a way to use a bluetooth connection since every mobile device today is provided of a bluetoorh stack?
From Arduino side maybe a bluetooth adapter could do the job.
Hello
Im using the code :
Part Android :
package com.example.helloworld;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.util.Log;
import android.widget.TextView;
import android.hardware.usb.UsbManager;
import android.hardware.usb.UsbAccessory;
public class HelloWorldActivity extends Activity {
private static final String TAG = HelloWorldActivity.class.getSimpleName();
private PendingIntent mPermissionIntent;
private static final String ACTION_USB_PERMISSION = “com.android.example.USB_PERMISSION”;
private boolean mPermissionRequestPending;
private UsbManager mUsbManager;
private UsbAccessory mAccessory;
private ParcelFileDescriptor mFileDescriptor;
private FileInputStream mInputStream;
private FileOutputStream mOutputStream;
private static final byte COMMAND_TEXT = 0xF;
private static final byte TARGET_DEFAULT = 0xF;
private TextView textView;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
// mUsbManager = UsbManager.getInstance(this);
mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(
ACTION_USB_PERMISSION), 0);
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
filter.addAction(UsbManager.ACTION_USB_ACCESSORY_DETACHED);
registerReceiver(mUsbReceiver, filter);
setContentView(R.layout.activity_hello_world);
textView = (TextView) findViewById(R.id.textView);
}
/**
* Called when the activity is resumed from its paused state and immediately
* after onCreate().
*/
@Override
public void onResume() {
super.onResume();
if (mInputStream != null && mOutputStream != null) {
return;
}
UsbAccessory[] accessories = mUsbManager.getAccessoryList();
UsbAccessory accessory = (accessories == null ? null : accessories[0]);
if (accessory != null) {
if (mUsbManager.hasPermission(accessory)) {
openAccessory(accessory);
} else {
synchronized (mUsbReceiver) {
if (!mPermissionRequestPending) {
mUsbManager.requestPermission(accessory,
mPermissionIntent);
mPermissionRequestPending = true;
}
}
}
} else {
Log.d(TAG, “mAccessory is null”);
}
}
/** Called when the activity is paused by the system. */
@Override
public void onPause() {
super.onPause();
closeAccessory();
}
/**
* Called when the activity is no longer needed prior to being removed from
* the activity stack.
*/
@Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(mUsbReceiver);
}
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (ACTION_USB_PERMISSION.equals(action)) {
synchronized (this) {
UsbAccessory accessory = (UsbAccessory) intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
if (intent.getBooleanExtra(
UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
openAccessory(accessory);
} else {
Log.d(TAG, “permission denied for accessory ”
+ accessory);
}
mPermissionRequestPending = false;
}
} else if (UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals(action)) {
UsbAccessory accessory = (UsbAccessory) intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
if (accessory != null && accessory.equals(mAccessory)) {
closeAccessory();
}
}
}
};
private void openAccessory(UsbAccessory accessory) {
mFileDescriptor = mUsbManager.openAccessory(accessory);
if (mFileDescriptor != null) {
mAccessory = accessory;
FileDescriptor fd = mFileDescriptor.getFileDescriptor();
mInputStream = new FileInputStream(fd);
mOutputStream = new FileOutputStream(fd);
Thread thread = new Thread(null, commRunnable, TAG);
thread.start();
Log.d(TAG, “accessory opened”);
} else {
Log.d(TAG, “accessory open fail”);
}
}
private void closeAccessory() {
try {
if (mFileDescriptor != null) {
mFileDescriptor.close();
}
} catch (IOException e) {
} finally {
mFileDescriptor = null;
mAccessory = null;
}
}
Runnable commRunnable = new Runnable() {
@Override
public void run() {
int ret = 0;
byte[] buffer = new byte[255];
while (ret >= 0) {
try {
ret = mInputStream.read(buffer);
} catch (IOException e) {
break;
}
switch (buffer[0]) {
case COMMAND_TEXT:
final StringBuilder textBuilder = new StringBuilder();
int textLength = buffer[2];
int textEndIndex = 3 + textLength;
for (int x = 3; x < textEndIndex; x++) {
textBuilder.append((char) buffer[x]);
}
runOnUiThread(new Runnable() {
@Override
public void run() {
textView.setText(textBuilder.toString());
}
});
sendText(COMMAND_TEXT, TARGET_DEFAULT,
"Hello World from Android!");
break;
default:
Log.d(TAG, "unknown msg: " + buffer[0]);
break;
}
}
}
};
public void sendText(byte command, byte target, String text) {
int textLength = text.length();
byte[] buffer = new byte[3 + textLength];
if (textLength <= 252) {
buffer[0] = command;
buffer[1] = target;
buffer[2] = (byte) textLength;
byte[] textInBytes = text.getBytes();
for (int x = 0; x < textLength; x++) {
buffer[3 + x] = textInBytes[x];
}
if (mOutputStream != null) {
try {
mOutputStream.write(buffer);
} catch (IOException e) {
Log.e(TAG, "write failed", e);
}
}
}
}
}
Part Arduino :
#include
#include
#include
#define ARRAY_SIZE 12
AndroidAccessory acc(“Manufacturer”, “Model”, “Description”,
“Version”, “URI”, “Serial”);
char hello[ARRAY_SIZE] = {‘H’, ‘e’, ‘l’, ‘l’, ‘o’, ‘ ‘,
‘W’, ‘o’, ‘r’, ‘l’, ‘d’};
void setup() {
Serial.begin(115200);
acc.powerOn();
}
void loop() {
if (acc.isConnected()) {
for (int x=0; x<ARRAY_SIZE; x++) {
Serial.print(hello[x]);
delay(250);
}
Serial.println();
delay(250);
}
}
but in monitor serial I have an error (Error: OSCOKIRQ failed to assert)
You can help me please
hi,
my Android test app (90% derived from yours) controls an Arduino Uno R3 via USB OTG (send only needed); i’m making a robot heater that focuses a beam of infrared heat on a person, even when he/she moves, using servos (myhaser.com). Tablets (unrooted, JellyBean & KitKat) work fine, UsbManager lists the device, no problem. BUT my phone (KitKat 4.4.2, now rooted) does not. it powers the Arduino, even lists it at the Linux level. i see a new file /dev/ttyACM0. also, the folder, /sys/bus/usb/devices/ gets new subfolders: “1-1”, “1-1:1.0” and “1-1:1.1”, which have files and folders within them. for example, the file /sys/bus/usb/devices/1-1/manufacturer has the text “Arduino (www.arduino.cc)”. file /sys/bus/usb/devices/1-1/bDeviceClass has the text “02”. file /sys/bus/usb/devices/1-1/idVendor has the text “2341”. file /sys/bus/usb/devices/1-1/idProduct:is “0043”.
​​
my test app didn’t work on ANY phone (all tested ones powered up the Arduino). the app works on ALL tablets tried: on them, it connects as a serial device (57600, 8 N 1). I’ve also controlled it from the tablets using the ZTerminal app; in it, i have to choose “Prolific” (not FTDI) as the type of device.
what should i do? what changes should i make (the phone is already rooted)? i’d prefer a solution without rooting or writing a a second type of code for phones. but i’ll take anything i can get :-).
here are the details:
phone: Micromax A120 Colours 2 (indian brand) running KitKat 4.4.2. it’s based on the MT6582 or MT6589 hardware, i believe.
The phone reports the following info about the connected Arduino:
Device Path: /sys/bus/usb/devices/1-1/
Device Class: Communication Device (0x2)
Vendor ID: 2341
Vendor Name (reported): Arduino (www.arduino.cc)
Vendor Name (from DB): Arduino SA​ (this is a database that the USB reporting software dowlnloads from the internet)​
Product ID: 0043
Product Name (reported):
Product Name (from DB): Uno R3 (CDC ACM)
Additional Info
USB Version: 1.10
Speed: 12
Protocol: 00
Maximum Power: 100mA
Serial Number: 7493730393635180E122
These three apps are able to provide this info: USB Device List​, USB Device Info​ and USB Host Controller​. the last one also reports:​​
Usb Host Controller
Version number 0.44
S3C USB Host driver NOT found!
Root hub present, USB Host mode is active!
thanks for your help!
mahesh
Got something similar working from Galaxy Note 4 (Not rooted)
Development done on Mac Book pro.
Arduino device used: USBDroid connecting with OTG cable and larger USB port on Arduino board.
private static final int VID = 0x26BA; // USBDroid
private static final int PID = 0x0003; // USBDroid
Can’t remember which version of the IDE was used to compile the Arduino code, and it does not compile any more, as I am now getting errors all over the place because of trying to get USB Host files and stuff included in libraries….
But the original code downloaded to USBDroid works, and causes the LED to flash, when I move the scroll thingy on the Android app
Good evening, this is a nice tutorial.
But I have a question, I was now in all forums and no one could help me.
I need a program that simply reads the USB port. At Port data arrive as “22 00 22 33”.
And the incoming data to be evaluated.
So if, for example “22 00 22 33” then comes to my tablet the volume be increased.
I’ve already tried everything possible but I simply lack the experience away in terms android and the USB library and programming capability.
If anyone could help me and fancy hat can feel free to contact me
Email: pascal164@gmx.de
Similarly, if one makes me he would get a compensation for the effort, if desired
greetings from Germany
Pascal
hey,i have a problem about the device which receives the data from android.i want to use android communicates with Linux through the usb-serial port,how can i deal with data send to Linux?thanks