Although I talked some months ago about this library and I even use it for DroidTerm, DroidTerm PRO and other professional projects, the post I wrote no reflects the truly current state of this work. It is fairly stable and has been used So here it is, a more formal and helpful description of UsbSerial for Android.
A brief list of Apps and wrappers using UsbSerial. Contact with me if you have a nice project to show 🙂
UsbSerial repository
Another awesome tutorial by Hariharan Mathavan from All About Circuits
How to add UsbSerial to your project
Thanks to StephaneBg UsbSerial can be easily added to your Android Studio project via Jitpack. First add the jitpack repo into your project build.gradle.
allprojects { repositories { jcenter() maven { url "https://jitpack.io" } } }
And then add the dependency to your module’s build.gradle
compile 'com.github.felHR85:UsbSerial:4.5'
Devices supported
Currently UsbSerial supports three of the most used USB to serial chipsets:
– FTDI FT232 (I am not going to brick your device, trust me 🙂)
– Silicon Labs CP210x
– Prolific PL2303HX (at least HX version)
– CH340/CH341
A new feature added here is a CDC generic driver, so it should be possible to connect devices which fits into Communications Device Class. I am open to suggestions about new supported chipsets.
UsbSerial internals: A brief description
– Internally UsbSerial works as a Producer-Consumer handler, what you write is put into a buffer and it will be consumed by a Consumer thread when previous data is sent.
– Write operations can be queued from multiple threads without problems
– Received data is received through a callback, there is no need to be polling.
– Two 16kb internal buffers for Write and Read operations.
– Android 4.2.1 or greater devices rely on Asynchronous USB api for read operations. Prior versions (Android 3.1 oldest version supported) use synchronous api due to some Android bugs. Write operations use always synchronous USB api. UsbSerial handles all of this so there is no need to worry.
– PL2303, FT232 and CP210x drivers use a list of known vid and pids to identify a correct device.
– CDC driver can be loaded automatically for a device if it has a CDC interface.
How to use it
First of all you need both UsbDevice and UsbDeviceConnection objects correctly initialized.
// This snippet will open the first usb device connected, excluding usb root hubs UsbManager usbManager = (UsbManager) getSystemService(Context.USB_SERVICE); UsbDevice device; UsbDeviceConnection connection; HashMap<String, UsbDevice> usbDevices = usbManager.getDeviceList(); if(!usbDevices.isEmpty()) { boolean keep = true; for(Map.Entry<String, UsbDevice> entry : usbDevices.entrySet()) { device = entry.getValue() int deviceVID = device.getVendorId() int devicePID = device.getProductId() if(deviceVID != 0x1d6b || (devicePID != 0x0001 || devicePID != 0x0002 || devicePID != 0x0003)) { // We are supposing here there is only one device connected and it is our serial device connection = usbManager.openDevice(device); keep = false; }else { connection = null; device = null; } if(!keep) break; } }
With those objects correctly initialized it is easy to start
// A callback for received data must be defined private UsbSerialInterface.UsbReadCallback mCallback = new UsbSerialInterface.UsbReadCallback() { @Override public void onReceivedData(byte[] arg0) { // Code here } }; //... //... UsbSerialDevice serialPort = UsbSerialDevice.createUsbSerialDevice(device, mConnection); if(serialPort != null) { if(serialPort.open()) { // Devices are opened with default values, Usually 9600,8,1,None,OFF // CDC driver default values 115200,8,1,None,OFF serialPort.setBaudRate(115200); serialPort.setDataBits(UsbSerialInterface.DATA_BITS_8); serialPort.setStopBits(UsbSerialInterface.STOP_BITS_1); serialPort.setParity(UsbSerialInterface.PARITY_NONE); serialPort.setFlowControl(UsbSerialInterface.FLOW_CONTROL_OFF); serialPort.read(mCallback); }else { // Serial port could not be opened, maybe an I/O error or it CDC driver was chosen it does not really fit } }else { // No driver for given device, even generic CDC driver could not be loaded }
And write what you want to send through serial port!
serialPort.write("Hola!".getBytes());
If you need to use flow control signals just check out this post
UsbSerial now allows USB to SPI bridges
Download the jar file here Actually it is better to add UsbSerial using gradle as described above!!
Happy coding and reach me if you do something nice with UsbSerial! 🙂
Update (03/07/15):
Thanks to Martin Blom now it is possible to use UsbSerial with multi-interface devices (like this). The best way would be
int iface = 0; UsbSerialDevice serialPort = UsbSerialDevice.createUsbSerialDevice(device, mConnection, iface);
will it works with cp2103 usb to uart adapter?
It should work but I am not totally sure. Please, installDroidTerm app and give it a try.
Can we receive data with this library faster than 1hz, or the OTG cable which we use have some restriction for that? Do you have some info for this issue?
What device are you using? I’ve configured multiple supported devices wit greater speeds than 1hz and it worked ok. Maybe as you point is a limitation of the OTG
I’m using Novatel gps antenna connected to android device with OTG cable, but can’t make it to receive more than 1hz, and wondering if it’s from the cable. Have you tested with OTG cable before?
I always use a OTG cable, the problem shouldn’t lie there unless there is some problem with it.
Maybe the antenna uses a Usb-serial adapter not compatible. Did you try using DroidTerm?
Yes, I’m using DroidTerm and configuring antenna to 5hz, but the DroidTerm still log on 1hz
The antenna is CH34xSerialDevice, if it’s matter. You say that OTG cables don’t have any restrictions about hz right?
Mmm CH34x is the last chipset I added. What baudrate speed are you setting in DroidTerm? Maybe I have a bug in the CH34x driver
I’m trying with 9600 and 115200.
On some boudrates the coding become strange, something like chinese characters, I’m not sure where should I investigate the code, for that issue.
That’s probably because the device does not support those baudrates
At least 9600 should work fine
With 9600 working fine about encoding, but with frequency not more than 1hz
If the encoding works fine I don’t really know. It could be an error with protocol
Ok, thanks, I investigating now.. I think there is some relation between baud rate and frequency.
Hi Filip,
Thanks for the library. I am thinking of using in my project. I saw a TODO on CTS/RTS signals. I need those for my project. Do you have any plans of incorporating those in your library soon.
Or can you guide me to do that?
Thanks,
Asit
Hi Asit,
This is the first request I have received about adding RTS/CTS signals. At this moment is not in my roadmap. What chipset are you using?
Hi Filip,
I need support for PL2303 and CDC Generic driver.
Thanks,
Asit
It could be possible to add RTS/CTS for PL2303 eventually. It is not in my current roadmap though.
I don’t own any CDC device that implements RTS/CTS functionality
I need RTS function also.
Hi Felhr85! Im looking for some code that allows me to read / write on my android serial usb adapter (CH340). Your DroidTerm runs very well, but I need to send data using a terminal on my android (like terminal emulator), not a specific app like DroidTerm. My final goal is to run a python script that send sensoring data to a raspberry via serial usb. THANKS!
Forgot questioning…. Is it possible to use your UsbSerial library 3.1 to do so?? The problem is that as a newbie, I couldnt understand how to install the driver on the phone. I imagine I need to use the jar file to load the library (JAR file) and then run the Javascript to load the driver and then use usb.write() to finally send data. Do you have a step-by-step procedure to intall your drivers and run it ? Thanks a lot!
Hi Paulo,
The way to use UsbSerial is inside an Android app you have to code and build. They are not the kind of drivers you install in the OS like the Windows app. Maybe you could use directly through python using the Android scripting layer if that layer allows to use .jar files but I am not sure. http://pythoncentral.io/series/python-sl4a-android-scripting-layer-tutorial/
got it…. What APK builder do you recommend me to use in order to create a simple app that loads a shell in my android and also loads your CH340 driver (at the same time)? Once drivers are loaded I could use python serial library to read/write on the serial…….
hello FELHR85, You are a life saver ;)…
Thank you so much for share this library and android service sample, I’m a hobbyst, so I not know so much.
On CH34xSerialDevice.java have no parameters for baud rate = 57600, you know where I can get values to add parameter for CH34X_57600?
Greate work!
Hi! I dont really know at this moment. The CH34x family is kind of obscure one with little documentation available. You could check the linux drivers for some info and if you achieve it I would add it without doubt!
I added your usbserial to my code in android studio. I’m trying to port processing code to android. The original processing program reads serial and operates on the data and displays it. I get the toast messages when I connect my cp21xx device but I cant figure out why the data doesn’t show up in my processing code. I’m a hobbyist too and wonder if it has to do with timing or threads which is all above my understanding of android at this point. Any ideas?
THANKS A LOT! Works like charm.
How do I include this in my Android Project? Is there a gradle link I need to add? Thank you so much
Put the jar file in the libs folder and add compile files(‘libs/usbserial.jar’) in your build.gradle!!!
Ah there is a jar. But where´? I did not find any jar in the github repo…
Hi
I have a Basic4Android app and now getting serious serial usb comm limitations. I jump to Android Studio just to try your library and I can print without probkems to my usb ticket printer.
To use your library inside Basic4Android I should build a Jar library, and after use inside B4A.
It is possible to build such Jar library instead an aar?
Regards
Abilio
Hi Abilio,
If you need a .jar you can download it from github https://github.com/felHR85/UsbSerial/releases/tag/v3.2
Hope it helps!
Felipe
Hi Felipe,
Thanks for your kind and dedicated support.
Now it is already possible to use your library on BAsic4Android.
https://www.b4x.com/android/forum/threads/felusbserial-alternative-usb-serial-library.62216/#content
B4A courteously has implemented your library and it’s working perfectly.
Kind regards,
Abilio
I am glad Erel implemented it!
Best regards
Hiya felhr, I made some progress finally. I’m now able to read my data and call some functions to manipulate(parse out integers and floats) it. I’m still using your example to textview it. I need to figure out how to send that received and manipulated data from the MainActivity to a new Activity that will display it in a PApplet. Its probably very simple to an expert.
Hi Abilio,
I am trying to interface with a USB device. Would you please share a simple example of B4A? My email address is owaisnajam@yahoo.com
Thanks and regards,
Awais
Hi Abilio,
I am also trying to interface a USB device. Would you like to share a simple example of B4A? My email adress is owaisnajam@yahoo.com
Thanks and regards,
Awais
Hi Awais,
Sorry for answering only today. I sent to you an example by mail.
Regards,
Abilio
Thanks Abilio for your reply.
I would like to add about FTDI-Android USB serial interfacing. Please check http://www.ftdichip.com/Android.htm. There is lot of info with examples. I installed example apk from http://www.ftdichip.com/Drivers/D2XX/Android_Java_D2xx.zip and found that you can even access the memory of FTDI chips from your Android device. Just have a look. Hope that Felipe will add something new in his library.
With kind regards,
Awais
First, thanks for the UsbSerial, great library with great examples. Have you used this library to access an Arduino Leonardo/Micro bootloader? To access the bootloader you have to connect at 1200 baud to reset the board and then connect at 9600. I’ve been able to do this on my laptop with python but can’t get UsbSerial to work.
I’m having an issue implementing this on a device that has a hub that has a thermal printer, card reader, and scanner attached to it. I only want to access the scanner, but when I run your demo application it says USB Connected followed by Device not Supported. This happens three times and the app crashes each time when I try to scan. The third time I run the application it works. I’m assuming it is trying to connect to every device on the hub, is there a way I can make it only connect to the scanner and ignore other devices?
Just to follow-up. I fixed the issue. I used a utility in Android to find the VID and PID of the specific device I needed and changed the source to only connect if the device matches those specific identifiers.
Nice update of flow control. Keep it up, Felipe.
With kind regards,
Awais
Man. I love that you have offered so much useful code. I used it to write my app that reads from a CP210X. This Arduino is wired directly over USB and works with no delays. I decided to try a 3DR telemetry radio which also uses the CP210X chip, but it doesn’t work so nice. I only see data in my app every 10 seconds or so. I added a 20 ms delay on my Arduino and that is the best but it still seems to be starting and restarting the delivery of data to my fragment. I tried slower baud rates too and it doesn’t matter. I have a MainActivity and a fragment and the Usbservice. I have a simple method in main that returns the String (msg.obj) as DataString which I initialized as public static String DataString = ” “; My fragment then uses mActivity,getActivity to get the DataString. I can’t understand why the wired CP210X works great but the radio CP210X has so much trouble. Your DroidTerm works fine with the radio. Should I not make msg.obj a String and wait until it is in my fragment to convert?
You should create a javadoc for this library…
Good suggestion, I will add it to the TODO list.
Hello Felipe,
Thanks for the UsbSerial, great library with great examples. Works like charm.
How can I detect if the device stops sending data, do you have a method for this in the library or do you have a suggestion for that?
Thanks again for this great library which saved my hours.
Bonjour
Usbserial is fine
I want to compile the project on my tablet with AIDE (Android IDE from playstore = ide with java/c++ compiler ). AIDE knows import github project.
But when compile , “unknown entity ‘R’ ” error.
It’s a recurent error but i don’t Know from where : AIDE, import GIT or gît project her self.
Can you help me with same test on your Android device
Thanks ans Regards
I dont know anything about AIDE. Try to clean or rebuild the project. R errors are sometimes related with the project structure
Would it be possible to stream 15 data bits instead of just 5, 6, 7, or 8? I tried to modify forked git files to include a 15 bit option, but I could never get that to compile in Android Studio and allow me to use DATA_BITS_15. Is this possible?
Why would you need 15 bits? As far as I know 5,6,7 and 8 are all the possible values being 8 the most common by a large margin.
Thanks for this brilliant library. I have been implementing the usb serial with FT232 using the USB Host API but there is no luck as some data are lost. I have no clues about why this happened but your library worked well with FT232. Keep developing great library for us! 🙂
please explain how to add the library to the project in android studio.
please explain step by step.
Do we need to copy java files separately to a folder or do we have to import it as a module.
when we import it as a module it gives error in Android_build_sdk_version.
Plz help
Hi Nitish,
Check the following links.
http://www.allaboutcircuits.com/projects/communicate-with-your-arduino-through-android/
https://blog.medien.ifi.lmu.de/swh/2016/04/19/team-6-the-interaction-between-arduino-and-an-android-smartphone/
http://pccar.ru/showthread.php?t=23635
Regards,
Awais
i have tried to use it, the usb have been indicated that the USB is ready, but when i input the command and send it, it looks like the device didnt recieve the command,
can you help me ? where gone wrong ? maybe a little tips will help
Hi Felipe,
Where can I find the latest usbserial.jar file?
Thanks and regards,
Awais
will this work with Android 2? Do I need to ‘root’ my phone? Do I need USB host mode?
Android USB host mode support was added in Android 3.1. If you own a 2.x device you should root your device and code in C/C++ using libusb which it’s a mess.
thanks felhr. I will code for Android 4. At this level, some phones have usb host mode automatically enabled; some phones do not. Do I need host mode enabled to use ‘UsbSerial’ ? Also, do I need to root my Android 4?
Probably your Android 4 has usb host mode available. It’s pretty common.
Don’t worry about rooting your phone its not needed. Just follow the USB tutorial 🙂
Thanks for the UsbSerial, its very good job.
I wrote you with a cuestion about how to change the baud rate, I have solved the problem!!! I did according your answer and I am using satandar baud rate (230400); but I added a delay of 100ms after the change of the baud rate. With this I can change the baud rate without lost comunication !!! Thanks very much
I have a new cuestion, when I read the serial port only I read 256 bytes, but were sent 1024. Only is posible to read 256 bytes or I am making a mistake?
How can I get a JAR version of the latest library? I need to use Eclipse for this project. I downloaded that last JAR version you had, but it’s missing some functions that you have since added/changed.
Hello David,
I’ve added a jar with the current maste branch. You can find it here:
https://github.com/felHR85/UsbSerial/tree/master/usbserial/eclipse_lib
Please give it a try.
Can anyone confirm this works with Nexus 7 (2013) with Android 6 or Samsung Galaxy S7 with Android 7? I keep getting empty list from usbManager.getDeviceList()… Maybe my Arduino clone is at fault here? Or maybe a faulty USB-cable…?
At this moment I have no OTG-friendly device to test this with. 😦
UPDATE: Indeed a faulty cable… The library works just fine ♥
How does UsbSerial decide when it is time to pass the received buffered data to onReceivedData? If I want to have the transferred bytes grouped in one onReceivedData call, could I maybe achieve that by sending some special character? Maybe 0…?
Nevermind, after some more thinking I realized that wouldn’t be viable.
My own timeout & buffer will have to do. 🙂
In the library, I found that there is a serialInputstream & a serialoutputstream. However, I cannot find how to use it. seems that, the usb serail data only can be read by using onReceivedData. is there any tutorial to show how to use it?thanks
It uses the MIT License https://opensource.org/licenses/MIT
Also, when I leave the activity where usbserial is setup, I lose connection so the usb device. Should I be saving the setup in saveInstanceState from onCreate in order to prevent losing the connection? Or is that not possible? I’ve recently started with learning this and would appreciate any help.
Thank you
How many bytes get reads in onReceivedData(byte[] arg0) method? In other words, what is the arg0.length? Does it read a fix number of bytes from the buffer every time or no? I see a number “16384” in the queue. What’s that? Thanks.
Thanks for the great work. Interesting, I cannot change the baud rate. I am using a CDC virtual COM port terminated with a cypress psoc5 (doing the CDC protocol) Windows (putty) is able to change the baud rate, but android is not. Anytime I even query the line settings via resp = usbConnection.controlTransfer(0xA1, 0x21, 0, 0, data, data.length, 5000); I get “-1” returned, and an array of zeroes in data. I realize this may not even be any issue with your serial lib, but I wonder if others have tripped across this. This “issue” shows up with a nexus 6 on 7.1.1 and also galaxy S4 on 5.0.1. I weep. Anyone have any ideas?
Hello, the library work fine for me in a project, but there is a problem, the permession popup display every time the USB cable is attached, doesn’t remembrer the permession, can you help
Hello, i need to make comBreak for 25ms, how can i do it?
Even Though My SerialPort is not Null, I cannot Open() connection! It throws NullPointer Exception to the serialPort Object.