UsbSerial: A serial port driver library for Android v4.5

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

If UsbSerial fits your needs and have help you with your project, please consider donating via PayPal to boost further improvements

If you are relatively new using Android, or just Usb Android api just checkout this simple app using UsbSerial with full source code available on Github

Or you can check out this amazing post about using the USB android API by the guys of BLECentral. The previous steps to use UsbSerial are very well explained there.

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);

79 thoughts on “UsbSerial: A serial port driver library for Android v4.5

  1. 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

  2. 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

  3. 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

  4. 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!

      • 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…….

  5. 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!

  6. 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?

  7. 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

  8. 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.

  9. 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.

  10. 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.

  11. 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?

  12. 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.

  13. 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

  14. 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?

  15. 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! 🙂

  16. 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

  17. 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

    • 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 🙂

  18. 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?

  19. 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.

  20. 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. 😦

  21. 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. 🙂

  22. 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

  23. 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

  24. 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.

  25. 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?

  26. 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

Leave a reply to lotfi Cancel reply