Code Monkey home page Code Monkey logo

usbserial's Introduction

UsbSerial Build Status AndroidArsenal Join the chat at https://gitter.im/UsbSerial/Lobby

UsbSerial wiki available. Read it first

Getting started
Create UsbSerialDevice objects
Asynchronous api
Synchronous api
InputStream and OutputStream I/O
Multiple Serial ports
Projects using UsbSerial
Debugging over Wifi
UsbSerial video tutorials

Support UsbSerial

If UsbSerial helped you with your projects please consider donating a little sum
Or consider buying DroidTerm Pro: A Usb serial port terminal using UsbSerial

Devices Supported

CP210X devices Default: 9600,8,1,None,flow off

CDC devices Default 115200,8,1,None,flow off

FTDI devices Default: 9600,8,1,None,flow off

PL2303 devices Default 9600,8,1,None,flow off

CH34x devices Default 9600,8,1,None,flow off

CP2130 SPI-USB

Known Issue

Due to a bug in Android itself, it's highly recommended to not use it with a device running Android 5.1.1 Lollipop. See issue #142 for more details.

How to use it?

Instantiate a new object of the UsbSerialDevice class

UsbDevice device;
UsbDeviceConnection usbConnection;
...
UsbSerialDevice serial = UsbSerialDevice.createUsbSerialDevice(device, usbConnection); 

Open the device and set it up as desired

serial.open();
serial.setBaudRate(115200);
serial.setDataBits(UsbSerialInterface.DATA_BITS_8);
serial.setParity(UsbSerialInterface.PARITY_ODD);
serial.setFlowControl(UsbSerialInterface.FLOW_CONTROL_OFF); 

If flow control is needed (currently only supported in CP201x and FTDI devices)

/**
Values:
    UsbSerialInterface.FLOW_CONTROL_OFF
    UsbSerialInterface.FLOW_CONTROL_RTS_CTS 
    UsbSerialInterface.FLOW_CONTROL_DSR_DTR
**/
serial.setFlowControl(UsbSerialInterface.FLOW_CONTROL_RTS_CTS);

There is no need to be polling if you want to perform a bulk transaction to a IN endpoint. Define a simply callback

private UsbSerialInterface.UsbReadCallback mCallback = new UsbSerialInterface.UsbReadCallback() {

		@Override
		public void onReceivedData(byte[] arg0) 
		{
			// Code here :)
		}
		
};

And pass a reference of it

serial.read(mCallback);

Changes in the CTS and DSR lines will be received in the same manner. Define a callback and pass a reference of it.

private UsbSerialInterface.UsbCTSCallback ctsCallback = new UsbSerialInterface.UsbCTSCallback() {
        @Override
        public void onCTSChanged(boolean state) {
           // Code here :)
        }
    };
    
private UsbSerialInterface.UsbDSRCallback dsrCallback = new UsbSerialInterface.UsbDSRCallback() {
        @Override
        public void onDSRChanged(boolean state) {
           // Code here :)
        }
    };
    
serial.getCTS(ctsCallback);
//serial.getDSR(dsrCallback);

Write something

serial.write("DATA".getBytes()); // Async-like operation now! :)

Raise the state of the RTS or DTR lines

serial.setRTS(true); // Raised
serial.setRTS(false); // Not Raised
serial.setDTR(true); // Raised
serial.setDTR(false); // Not Raised

Close the device:

serial.close();

I recommend using UsbSerial as shown above but if you want to perform write and read operations in synchronous way it is possible using these methods:

public boolean syncOpen();
public int syncWrite(byte[] buffer, int timeout)
public int syncRead(byte[] buffer, int timeout)
public void syncClose();

In Android usb api, when a usb device has been close it must be reopened

UsbDevice device;
...
UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
manager.openDevice(UsbDevice device)

How to use the SPI interface (BETA)

Support for USB to SPI devices was added recently but it is still in beta. Although I tried to keep the api as close to standard UsbSerial api as possible, be aware because the beta nature of this feature this api may change in the future. Only CP2130 chipset is supported at the moment.

UsbSpiDevice spi = UsbSpiDevice.createUsbSerialDevice(device, connection);
spi.connectSPI();
spi.selectSlave(0);
spi.setClock(CP2130SpiDevice.CLOCK_3MHz);

Define the usual callback

private UsbSpiInterface.UsbMISOCallback misoCallback = new UsbSpiInterface.UsbMISOCallback()
    {
        @Override
        public int onReceivedData(byte[] data) {
             // Your code here :)
        }
    };
//...
spi.setMISOCallback(misoCallback);
spi.writeMOSI("Hola!".getBytes()); // Write "Hola!" to the selected slave through MOSI (MASTER OUTPUT SLAVE INPUT)
spi.readMISO(5); // Read 5 bytes from the MISO (MASTER INPUT SLAVE OUTPUT) line. Data will be received through UsbMISOCallback
spi.writeRead("Hola!".getBytes(), 15); // Write "Hola!" and read 15 bytes synchronously

Close the device when done

spi.closeSPI();

Gradle

Add the jitpack repo to your your project's build.gradle at the end of repositories

/build.gradle

allprojects {
	repositories {
		jcenter()
		maven { url "https://jitpack.io" }
	}
}

Then add the dependency to your module's build.gradle:

/app/build.gradle

implementation 'com.github.felHR85:UsbSerial:6.1.0'

TO-DO

  • RTS/CTS and DSR/DTR implementations for PL2303 and CDC

usbserial's People

Contributors

arneball avatar autowp avatar changwoo avatar eyedol avatar eziosoft avatar felhr85 avatar ge0rg avatar gitter-badger avatar green-green-avk avatar janimm avatar jaromor avatar jimcondon avatar jkhan777 avatar josejuansanchez avatar leviticusmb avatar mws-rmain avatar pawitp avatar phuongnam0907 avatar quangctkm9207 avatar rabidaudio avatar rafaellehmkuhl avatar stephanebg avatar t2t-sonbui avatar twsmith85 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

usbserial's Issues

UsbSerialDevice Null Pointer

java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.nio.ByteBuffer.isDirect()' on a null object reference
at android.hardware.usb.UsbRequest.dequeue(UsbRequest.java:156)
at android.hardware.usb.UsbDeviceConnection.requestWait(UsbDeviceConnection.java:230)
at com.felhr.usbserial.UsbSerialDevice$WorkerThread.run(UsbSerialDevice.java:213)

Line 213:
UsbRequest request = UsbSerialDevice.this.connection.requestWait();

May need to null check UsbSerialDevice.this.connection != null before requestWait() is called.

This happens every once in a while if a UsbSerial device (Arduino in my case) is detached while running. I'm using the UsbSerialDevice.UsbReadCallback for reading so I could work around this issue by directly reading the interface but the callback is more convenient for my event driven applicaiton.

can't write after setting parameters immediately

serial.setBaudRate(115200);
serial.setDataBits(UsbSerialInterface.DATA_BITS_8);
serial.setStopBits(UsbSerialInterface.STOP_BITS_1);
serial.setParity(UsbSerialInterface.PARITY_NONE);
serial.setFlowControl(UsbSerialInterface.FLOW_CONTROL_OFF);
//serial.write("sa".getBytes());
serial.read(mCallback);
//serial.write("sa".getBytes());

serial.write does not work if you uncomment either of the commented lines, or both. In the demo application, it works by pressing a button. I would like to write to it as soon as it is ready. Is there a synchronous version of the functions?

device is closed in native_control_request ISSUE

Hello,

I don't know if this is an issue of the UsbSeria libraryl or my implementation is bad.

Anyway this UsbSerial it's great!

I had the following code in a click event.
It works fine one or two times, then I get "device is closed in native_control_request".

It fails in this piece of code with the following error because "position" it's still "-1" after "wait()".

11-03 20:58:29.836: E/AndroidRuntime(7937): FATAL EXCEPTION: Thread-445
11-03 20:58:29.836: E/AndroidRuntime(7937): java.lang.IllegalArgumentException
11-03 20:58:29.836: E/AndroidRuntime(7937): at java.util.Arrays.copyOfRange(Arrays.java:2691)
11-03 20:58:29.836: E/AndroidRuntime(7937): at com.felhr.usbserial.SerialBuffer$SynchronizedBuffer.get(SerialBuffer.java:152)
11-03 20:58:29.836: E/AndroidRuntime(7937): at com.felhr.usbserial.SerialBuffer.getWriteBuffer(SerialBuffer.java:83)
11-03 20:58:29.836: E/AndroidRuntime(7937): at com.felhr.usbserial.UsbSerialDevice$WriteThread.run(UsbSerialDevice.java:218)

public synchronized byte[] get()
{
if(position == -1)
{
try
{
wait();
} catch (InterruptedException e)
{
e.printStackTrace();
}
}

        byte[] dst =  Arrays.copyOfRange(buffer, 0, position);
        if(debugging)
            UsbSerialDebugger.printLogGet(dst, true);
        position = -1;
        return dst;
    }

Here is what I have in my onclick event....

It is a 4.2.2 Android (Rikomagic MK802IV)

            UsbManager lclMan=(UsbManager) getSystemService(Context.USB_SERVICE);


            UsbDeviceConnection lclusbConnection=lclMan.openDevice(dev);



            PL2303SerialDevice us=new PL2303SerialDevice(dev, lclusbConnection);
            us.debug(true);
            Log.d("SPOOL","TENGO EL OBJETO");
            us.open();

            String b="HOLA MUNDO\nHOLA MUNDO\nHOLA MUNDO\nHOLA MUNDO \n";



            us.setBaudRate(57600);

            us.setDataBits(p.getBaudRate());

            us.setParity(p.getParity());

            us.setStopBits(p.getStopBits());

            us.read(mCallback);

            us.write(b.getBytes());



            us.close();

serial.read(mCallback) issues

I am creating an android app that is going to run a program on an arduino. I am trying to have the data received by the arduino to be callable from another method, but i am having trouble calling the data. What i get when i push the button on android is the quoted text and null, then after the first press, there is no null shown. Almost as though there is no data being received. However when I add a tvAppend method call in the try case in onReceivedData. An expected measurement is shown. Rather than just having the data shown, I would like to have the data be callable from another method. Thank you and below is the code

public class MainActivity extends AppCompatActivity {
public final String Action_USB_Permission = "com.example.myapplication.USB_PERMISSION";
Button tempButton

UsbManager usbManager;
UsbDevice device;
UsbSerialDevice serial;
UsbDeviceConnection connection;
String sdata;
 @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);


    usbManager = (UsbManager) getSystemService(this.USB_SERVICE);
 tempButton = (Button) findViewById(R.id.buttontemp);
  textView = (TextView) findViewById(R.id.textView);}

 public UsbSerialInterface.UsbReadCallback mCallback = new UsbSerialInterface.UsbReadCallback() {
    @Override
    public void onReceivedData(byte[] arg0) {
        try {
            sdata = new String(arg0,"UTF-8");

        }
        catch (UnsupportedEncodingException e) {
            e.getStackTrace();
        }
    }
};
 private final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(Action_USB_Permission)) {
            boolean granted = intent.getExtras().getBoolean(UsbManager.EXTRA_PERMISSION_GRANTED);
            if(granted) {
                connection = usbManager.openDevice(device);
                serial = UsbSerialDevice.createUsbSerialDevice(device,connection);
                if(serial != null) {
                    if(serial.open()){ //set serial connection parameters.
                        setUiEnabled(true);
                        serial.setBaudRate(115200);
                        serial.setDataBits(UsbSerialInterface.DATA_BITS_8);
                        serial.setStopBits(UsbSerialInterface.STOP_BITS_1);
                        serial.setParity(UsbSerialInterface.PARITY_NONE);
                        serial.setFlowControl(UsbSerialInterface.FLOW_CONTROL_OFF);
                        serial.read(mCallback);
                        tvAppend(textView, "Serial Connection Opened!\n");
                    }else{
                        Log.d("SERIAL","PORT NOT OPEN");
                    }
                } else {
                    Log.d("SERIAL", "PORT IS NULL");
                }

                } else {
                Log.d("SERIAL","PERM NOT GRANTED");
            }

            } else if (intent.getAction().equals(UsbManager.ACTION_USB_ACCESSORY_ATTACHED)){
            onClickStart(startButton);
        } else if (intent.getAction().equals(UsbManager.ACTION_USB_ACCESSORY_DETACHED)){
            onClickDisconnect(disconnectButton);
        }

        }

    };
private void pushcmd(String command) {
    serial.write(command.getBytes());
}
private String gettemp() {
    pushcmd("T\n");

    serial.read(mCallback);

    return sdata;
}

 public void onClickTemp(View view) {

    tvAppend(textView, "\n Measured temperature " + gettemp());
}
}

Provide a default `device_filter.xml` resource

The USB Host SDK provides an intent filter for USB attach events, that can be used to auto-launch your app when a certain USB device is attached.

It would be great to have such a device_filter.xml file as part of the usbserial source code (or even AAR), based on the vendor/product IDs supported by UsbSerial. It is possible to create a momentary snapshot of the supported IDs thanks to the consistent style in the deviceids directory, using this black magic incantation (you just need to mix in some XML boilerplate):

perl -lne 'print "\t<usb-device vendor-id=\"$1\" product-id=\"$2\" />" if /new ConcreteDevice.0x([0-9a-f]{4}), 0x([0-9a-f]{4})/i' java/com/felhr/deviceids/*.java

However, it would be nicer and cleaner to have the XML either auto-generated in the build process or (manually?) updated with new device IDs. It is probably also possible to replace many of the entries by a vendor/class or similar combination, instead of listing all supported IDs.

main program for communication usb serial

hallo @felHR85 ,
first of all thank you for your usb serial library,
i would ask about main program for simple read and write via usb serial with using your library, (Im using Prolific usb-to-serial PL2303)
I newby on developing android so its hard enough for me to start writing code,,
this is a code I write, and yes there is an error when I click button, its force closed,
hope you have a little time for helping me,
Thanks

package com.android.testcomserial;

import android.app.Activity;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import com.felhr.usbserial.PL2303SerialDevice;
import com.felhr.usbserial.UsbSerialInterface;

public class MainActivity extends Activity {

//UsbManager usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
private static UsbDevice device;
private static UsbDeviceConnection usbConnection;
private final PL2303SerialDevice pl2303 = new PL2303SerialDevice(device, usbConnection); 

Button buttonWrite;

    @Override
    protected void onPause() {
        super.onPause();
        if (pl2303 != null) {
            try {
                pl2303.close();
            } catch (Exception e) {
                Log.e("LOG", e.toString());
            }
        }
        finish();
    }

 @Override
 protected void onResume() {
        super.onResume();
        if (pl2303 == null) {
            Toast.makeText(getApplicationContext(), "No serial device.", Toast.LENGTH_LONG).show();
        } else {
            try {
                pl2303.open();
                pl2303.setBaudRate(115200);
                pl2303.setDataBits(UsbSerialInterface.DATA_BITS_8);
                pl2303.setParity(UsbSerialInterface.PARITY_NONE);
            } catch (Exception e) {
                Log.e("Error setting up device: ", e.toString());
                //pl2303.close();
            }
        }       
}


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    buttonWrite = (Button)findViewById(R.id.buttonWrite);
    buttonWrite.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            pl2303.write("DATA FROM ANDROID".getBytes());

        }
    });

}

 private UsbSerialInterface.UsbReadCallback mCallback = new UsbSerialInterface.UsbReadCallback() {

    @Override
    public void onReceivedData(byte[] arg0) 
    {
        // Code here :) // what should I write here??
        Toast.makeText(getApplicationContext(), "new data receive", Toast.LENGTH_LONG).show();
    }
 };

}

Problem with the read callback from Arduino

Hi,

I have an issue in the read callback when connecting the arduino. It seems that I receive my bytes twice and sometime the callback is triggered but the package received is empty.

I only send a byte array with the arduino every 2 seconds and I just print what we receive with android.

Also I don't understand how the package is received. Sometimes I can get the whole array in one simple array and sometimes it's received truncated and the callback is called several time to get the whole array.

Thank you

Read with Length

Hi..

are this library can read specific length like on C programming:
byte[] readBuffer = serial.read(5); //to read only 5 bytes in C

Regards,
TJ.

About the syncOpen syncWrite syncRead Metheds

Hi,
Can you provide the example of how to use those methods?
Thanks a lot!
This is my usage,is it right?

` private void asyncWrite(byte[] data) {
synchronized (serialPort) {
if (this.serialPort != null)
serialPort.syncWrite(data, 0);
}
}

private byte[] asyncRead() {
    int readSize = 0;
    byte[] result = null;
    synchronized (serialPort) {
        if (this.serialPort != null)
            readSize = serialPort.syncRead(asyncBuffer, 0);
        if (readSize > 0)
            result = new byte[readSize];
        if (result != null)
            System.arraycopy(asyncBuffer, 0, result, 0, readSize);
    }
    return result;
}``private class AsyncConnectionThread extends Thread {
    @Override
    public void run() {
        serialPort = UsbSerialDevice.createUsbSerialDevice(device, connection);
        if (serialPort != null) {
            if (serialPort.syncOpen()) {
                serialPortConnected = true;
                serialPort.setBaudRate(ModbusConfig.BAUD_RATE);
                serialPort.setDataBits(UsbSerialInterface.DATA_BITS_8);
                serialPort.setStopBits(UsbSerialInterface.STOP_BITS_1);
                serialPort.setParity(UsbSerialInterface.PARITY_NONE);
                serialPort.setFlowControl(UsbSerialInterface.FLOW_CONTROL_OFF);
                // Everything went as expected.
                Intent intent = new Intent(ACTION_USB_READY);
                context.sendBroadcast(intent);
            } else {
                // Serial port could not be opened, maybe an I/O error or if
                // CDC driver was chosen, it does not really fit
                // Send an Intent to Main Activity
                if (serialPort instanceof CDCSerialDevice) {
                    Intent intent = new Intent(ACTION_CDC_DRIVER_NOT_WORKING);
                    context.sendBroadcast(intent);
                } else {
                    Intent intent = new Intent(ACTION_USB_DEVICE_NOT_WORKING);
                    context.sendBroadcast(intent);
                }
            }
        } else {
            // No driver for given device, even generic CDC driver could not
            // be loaded
            Intent intent = new Intent(ACTION_USB_NOT_SUPPORTED);
            context.sendBroadcast(intent);
        }
    }
}`

AndroidStudio stops recognizing device after disconnect from Arduino.

Hello, I've coded the example of this project inside my program and works excellent on CM13.1 on a Galaxy S3, but on a more new device BQ Aquaris E6, the AndroidStudio is not recognizing the Smartphone after disconnect the cable. I must say CM13.1 has android v5.1.1 and the other one has v4.4.2

So the process I do is:

  1. install program with studio
  2. stop app from stduio (the app is uploaded)
  3. connect to arduino by OTG cable, the app automatically opens.
  4. the program is working fine. But studio is not reconizing the device until reboot the smartphone.

unable to print results

serial.setBaudRate(115200);
serial.setDataBits(UsbSerialInterface.DATA_BITS_8);
serial.setStopBits(UsbSerialInterface.STOP_BITS_1);
serial.setParity(UsbSerialInterface.PARITY_NONE);
serial.setFlowControl(UsbSerialInterface.FLOW_CONTROL_OFF);
serial.read(new UsbSerialInterface.UsbReadCallback()
{
    @Override
    public void onReceivedData(byte[] arg0)
    {
        String data = new String(arg0);
        System.out.println(data);
        //Toast.makeText(getContext(), data, Toast.LENGTH_SHORT);
        //Log.i("", data);
        for(byte f : arg0)
        {
            System.out.println((char)f);
        }
    }
});

using a toast or trying to log it causes an exception. Printing it character by character works okay. But printing the whole thing as a string doesn't work at all. I have tried using utf-8 as well and a try catch, that doesn't change anything. How are you supposed to get results? I've seen SerialPortExample but that is far too complex to be "client" code.

Feature request: Unbuffered write

In my application i need unbuffered synchronous write to provide equal spacing between the end of each and start of subsequent transmits. (using ScheduledExecutorService.scheduleWithFixedDelay)

Transmit time can be greater than delay between transmits. Thats means write buffer overflows if used buffered write.

ScheduledExecutorService service = Executors.newScheduledThreadPool(N);
service.scheduleWithFixedDelay(new Runnable() {
  @Override
        public void run() {
            Serial.write(buffer);
        }
}, 0, delay, TimeUnit.MILLISECONDS);

Quick patch to add unbuffered synchrowrite: autowp@a6ab307

Maybe that needs not only for me and unbuffered interface appears in the library

Is recieving data working similer to Interrupt service routine

Thanks for the codes,
I want to ask that if I want to store data every time while data arrived to receiving pin (may be in an array) than in which method I should do it even if my program is busy somewhere else. I'm using your example codes directly and in MainActivity a method named 'handleMessage' you are updating the TextView but I have doubt that will it called each and every time the data arrived to Rx pin no matter where our program is busy in some other method or class, If not then where I should update the textView so that i will not miss any data arrived on Rx pin. (like we can do in Embedded c by generating interrupt call routine).
Thanks

How to list the device using USBSerial?

Dear @felHR85 ,
I want to list all of usb device that plug in my android device (example my android device has 3 usbs port). It's possible if I want to list all if device that attached to my android.
Please take a look at it.
Thanks

Will it work for CP2101

Hey, Thanks for the code,
I want to use CP2101 to communicate with UART, do I need to do any other thing like modifying the kernel or I can use it directly.

Dont work on android 4.4 x86

Defines but not receiving data from arduino nano, but it works fine on android 4.4 nexus 7.
What to do with android 4.4 x86? Thanks!

Kitkat/ Port is Null or not open

Hi, I tried your library with a number of different devices.
The connected cable always stays the same (FTDI chipset).

I tried 2 devices with Android Lollipop, 1 with Marshmellow and they work very well.
On the other hand, when I try the same app on 2 devices that have kitkat installed and another one that still has Jellybean, the behavior is quite strange.

I can register the Receiver
It does find the device (usb device is not empty)
I then request permission
in Broadcast Receivers onReceive() method permission is granted

But as soon as it reaches the following line:
serialPort = UsbSerialDevice.createUsbSerialDevice(device, connection);
serialport on my Samsung Note 2 (Kitkat 4.4) cannot open or port is null (another Kitkat device).

What puzzles me is the following. From time to time when I detach and reattach the cable, the connection all of a sudden can be opened and logcat shows
I/FTDISerialDevice: Interface succesfully claimed
I/FTDISerialDevice: Control Transfer Response: 0
Unfortunately, I cannot realibly predict, if and when this happens.

Do you have an idea what the reason for this behavior might be. As a sidenote, I also found out that for Version < Lollipop the permission dialog does not always appear, as it should. If I understand correctly the call usbManager.requestPermission(device, pendingIntent); should trigger it

An issue when writing data right after a syncOpen call

Just in case you're trying to send a one off message to the Arduino at the start of the connection, you have to sleep/delay some time in order to let the Arduino breath (I presume).

        ... UsbConnection and UsbDevice init stuff ....
        serial = UsbSerialDevice.createUsbSerialDevice(device, usbConnection)

        if (serial.syncOpen()) { // setup for ch340
            serial.setBaudRate(9600) 
            serial.setDataBits(UsbSerialInterface.DATA_BITS_8)
            serial.setParity(UsbSerialInterface.PARITY_ODD)
            serial.setFlowControl(UsbSerialInterface.FLOW_CONTROL_OFF)

            //
            // here be dragons! don't let the "syncOpen" name fool you.
            //
            Thread.sleep(2000); // sleep some. YMMV with different chips.
            //  
            // without this delay the write below does not occur. 
            //    

            serial.syncWrite(byteArrayOf(yourMagicByteValues), timeout);
         }

Might be a good point to mention in the docs. Thanks for the great lib!

Issue reading data from the serial port

Hello,
I'm having some difficulties using the UsbSerial library: I'm developing an application that runs on Android 4.0.4 (I'm using the synced methods) and I'm trying to read some bytes from the serial port. I made some testing and it seems that the syncRead() method only reads bytes one by one. And if I try to send more bytes simultaneously, it loses them; it looks like the buffer is not properly working.

Is there some documentation to refer to? Or do you have any advice?

Many thanks, Francesco

Example calls thread.run() instead of thread.start()

In UsbService.java of the example application the BroadcastReceiver calls the thread to start with run().

new ConnectionThread().run();

This will merely call the thread run() code on the current thread. To correctly call this code in a separate thread this should be changed to call start().

new ConnectionThread().start()

Non sense test for excluding usb root hubs

In UsbService line 182

if (deviceVID != 0x1d6b && (devicePID != 0x0001 || devicePID != 0x0002 || devicePID != 0x0003)) {
                    // There is a device connected to our Android device. Try to open it as a Serial Port.
                    requestUserPermission();
                    keep = false;
                }

The second term of the && clause (devicePID != 0x0001 || devicePID != 0x0002 || devicePID != 0x0003) is always true.

I propose this fix

if (deviceVID != 0x1d6b && (devicePID != 0x0001 && devicePID && 0x0002 && devicePID && 0x0003))

Also can you document what this codes means ?

Thank you

consistent read/write bytes problem

I use Android 4.3 and write an app using UsbSerial to send a byte to my Arduino with Silicon Lab CP21xx device. I am based on your example code so that everything is OK. The problem is the byte I am sending is not correctly received at Arduino side. For instance if I want to send byte 0x38, then:

byte[] cmd = HexData.stringToBytes("0x38");
serialPort.write(cmd);

On the Arduino side, I have a very simple code as follows

if (Serial.peek() == -1)
    return;
char cmd = Serial.read(); // get the byte
Serial.print(cmd); // send back to verify content
if (cmd == 0x38)
// ....

The callback on the Android side is:

private UsbSerialInterface.UsbReadCallback callback = new UsbSerialInterface.UsbReadCallback(){
    @Override
    public void onReceivedData(byte[] args) {
            ToasterNotifier.flash(activity, "received:" + HexData.hexToString(args)); // show a toast
    }
};

The problem is, the byte I sent and the feedback is not identical! For instance if I send 0x38 (the number 8), then I get 0xF8 and then 0xFE (two separate times). The weird thing is, if I use DroidTerm (it is claimed that DroidTerm uses the library UsbSerial) to communicate with my Arduino program, it outputs correctly the sent byte and the if in my Arduino program is validated.

(I set baud rate, parity, stopbits,... identical between DroidTerm and my Android app).

Could you explain what did I miss here? Thanks!

Any device below Android 4.2, API level 17 is not receiving Data

There is a known bug, repaired yet in new releases of Android OS, that makes Usb asynchronous api useless. UsbSerial is using async api to perform Read operations.
UsbSerial must be able to change from sync to async api (async default) and must implement a buffer based read thread like it is now implemented in Read operation thread

How can I communicate with more than one usb serial devices having same type of drivers at the same time

Hello felHR85 I used your library to communicate with usb serial devices and its working as i want it to.

Now requirement is little tricky here as I want to communicate using more than one usb serial devices at same time. but i am failing to do this.

Issue happening with me is that if I connect first device via usb hub to android tablet, I am able to send and receive data . now I connect another device to the usb hub and the first device is also attached. what is happening that I am only able to get the values from second device only.

I need to get values from both machines simultaneously.

Problems reading correct data

Arduino send the string "12"
here's the code
//////////////////////////////////////////////////////////////////////////////////////
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
}
String str="12";
void loop() {
Serial.print(str);
}
///////////////////////////////////////////////////////////////////////////////////////////
But on the app i recieve "1212" or "2121"

///////////////////////////////////////////////////////////////////////////////////////////
String str=new String(arg0,"UTF-8");//converts the byte to a string//wonder if this is the part that messes up the data
try {

              //if(isFloat(str)==true)//if she say heyyy she want the D!!!
              Log.i("UsbArduino",str);
              if (mHandler != null)
              { mHandler.obtainMessage(MESSAGE_FROM_SERIAL_PORT, str).sendToTarget();}

          }
          catch(Exception e)
          {
              e.printStackTrace();
           //   Log.e("Error","Intents...?");
          }

Support of new devices petitions

Currently UsbSerial supports FT232, PL2303, CP210x, CH34x and CDC serial devices. If you know any Usb to Serial converter which is not supported please, list them here.

Felipe

Wrappers for UsbSerial

I think the next step of UsbSerial would be adding wrappers for the most important Android frameworks

  • Xamarin
  • PhoneGap
  • Jquery Mobile
  • React Native

There are more but these are probably the more important ones.

Felipe

arduino controlling

hi; I just wanted if there is any example on how to recieve data from socket and send it to aruino then do the reverse thing, I have a very vry little experience with android, but I did it in pc with rwtx.. library; so I'll be so thankful to you.

FT232RQ "USB device not supported"

Using the FT232RQ chip, when the usb device is plugged into tablet I receive both "USB Ready" followed by "USB device not supported".

Both serial read and write do not function.

Android Device is Switched on with USB Device Not Working

Hii
The code is working great thank you. However , when the android device is switched on with the usb device connected, the APP does not receive the data.
However plug out the usb cable and reinsert it , we receive the data. Could you fix it?

Add example sample

Please add a module with an example sample. It is simpler to look at code sometimes.

CDC_SET_CONTROL_LINE_STATE always 0x0003

Hi,
I noticed that with CDC you always set
CDC_SET_CONTROL_LINE_STATE = CDC_CONTROL_LINE_ON = 0x0003

This causes problems when connecting to my 3D Printer (Arduino Mega board with Marlin firmware): strange characters are sent to printer, I need to do an hard reset before getting it to work.
Problems disappear if I modify your code to set CDC_CONTROL_LINE_OFF = 0x0000.

I do not know much about flow control... but maybe in this case it is better to set CDC_CONTROL_LINE_OFF by default, or anyway when flow control is OFF.
What do you think?

BTW, great lib!

Reset arduino

Is there any way to reset arduino using this lib?

I've tried setting DTR low, waiting 22ms and then setting it high again, but it didn't work.
Is there anything i'm missing?

USB/Serial device doesn't show up in UsbManager#getDeviceList()

I need to use this (os a similar) library to interface with a device which is connected like this:

but it doesn't show up when I call usbManager.getDeviceList(). I do get multiple devices, but not the one I connected like above (I know the other devices' vendorIds, plus the list size doesn't change when I plug/unplug the device).

NullPointerException in WorkerThread

This occurs if I do rapid start/stop operations:

11-30 14:26:55.400 E/AndroidRuntime: FATAL EXCEPTION: Thread-242
11-30 14:26:55.400 E/AndroidRuntime: java.lang.NullPointerException
11-30 14:26:55.400 E/AndroidRuntime:     at com.felhr.usbserial.UsbSerialDevice$WorkerThread.run(UsbSerialDevice.java:211)

How to all data at once instead of getting it character by character

I am using example provided with this library, my problem is that I am getting data character by character inside onReceivedData() method. I want to know how to get data in one string so that I can pass it to activity and set it in my view.

I need to read data continuously is there any facility like this available in the libarary

separate input line ?

I would make a suggestion to have a separate input line.

I communicate with my arduino micro (USB-CDC),
and I display a menu to the user.
So the user has to choose of several menu items (e.g. "enter 's' to go to settings" and so on ...
it goes on in several submenus ...

So instead of having the "Ansi escape sequences" -Box on the bottom of the screen,
it would be nice if one can switch that to a seperate input line,
where the user can input one or several chars and terminate with 'enter' then

the next question is if you support a FF form feed character to clear the screen ?
decimal 12 = "\x0C"

BBC micro:bit - can't switch to baud rates other than 9600

Hi there,

I'm trying to get an Android phone to talk to a BBC micro:bit, which is similar to an ARM mbed. It presents a composite device to the host; a Mass Storage class for loading firmware, a HID class, and a Communications class with CDC Interrupt endpoint and a CDC Data endpoint. The micro:bit is recognised by Mac OS X and Linux without additional drivers and can be used with terminal software.

The micro:bit uses the same USB VID/PID as the NXP LPC1768 - 0d28:0204.
However, the micro:bit uses a nRF51822 as its main processor and an Kinetis KL26 as a USB controller.

Output of lsusb -vvv:

Bus 003 Device 076: ID 0d28:0204 NXP LPC1768
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               1.10
  bDeviceClass            2 Communications
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0        64
  idVendor           0x0d28 NXP
  idProduct          0x0204 LPC1768
  bcdDevice           10.00
  iManufacturer           1 MBED
  iProduct                2 MBED CMSIS-DAP
  iSerial                 3 9900023431864e45002e10060000005000000000cc4d28bd
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength          122
    bNumInterfaces          4
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0x80
      (Bus Powered)
    MaxPower              500mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass         8 Mass Storage
      bInterfaceSubClass      6 SCSI
      bInterfaceProtocol     80 Bulk-Only
      iInterface              7 USB_MSC
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x02  EP 2 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               0
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        3
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      0 No Subclass
      bInterfaceProtocol      0 None
      iInterface              6 MBED CMSIS-DAP
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.00
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      33
         Report Descriptors: 
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               1
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x01  EP 1 OUT
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               1
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         2 Communications
      bInterfaceSubClass      2 Abstract (modem)
      bInterfaceProtocol      1 AT-commands (v.25ter)
      iInterface              4 USB_CDC
      CDC Header:
        bcdCDC               1.10
      CDC Call Management:
        bmCapabilities       0x03
          call management
          use DataInterface
        bDataInterface          2
      CDC ACM:
        bmCapabilities       0x06
          sends break
          line coding and serial state
      CDC Union:
        bMasterInterface        1
        bSlaveInterface         2 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x83  EP 3 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0010  1x 16 bytes
        bInterval              32
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        2
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass        10 CDC Data
      bInterfaceSubClass      0 Unused
      bInterfaceProtocol      0 
      iInterface              5 USB_CDC1
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x04  EP 4 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x84  EP 4 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               0
Device Status:     0x0000
  (Bus Powered)

I have purchased DroidTerm PRO, but haven't tried writing my own Java code yet, so I haven't got any additional debug logs yet.

On the micro:bit I have a short program that repeatedly sends a string to the USB serial output at 115200 baud every second. DroidTerm PRO recognises that there is an "LPC1768" attached, but no text appears. It works fine on a Linux PC or Mac.

I have another program that scrolls characters across the screen of the micro:bit when they are received from the computer over serial. Again, this works on the desktop, but not with DroidTerm PRO. However, the LED on the micro:bit blinks when I send a character from DroidTerm - so something is happening! :)

Do you have any ideas what might be wrong, or some hints for debugging this?
Thanks!

Xamarin wrapper/binding project

Hi! Can you make a wrapper for Xamarin to be able to use your library in C#?? I tried to do it by myself but I have some problems binding the .aar.

NullPointerException in WorkerThread.run

Greetings,

We are using this library in our application to talk with various usb serial devices. We have encountered rare instances where our service would crash with the following stack trace:

Fatal Exception: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.nio.ByteBuffer.isDirect()' on a null object reference at android.hardware.usb.UsbRequest.dequeue(UsbRequest.java:156) at android.hardware.usb.UsbDeviceConnection.requestWait(UsbDeviceConnection.java:230) at com.felhr.usbserial.UsbSerialDevice$WorkerThread.run(UsbSerialDevice.java:213)

Our service would then restart and then works just fine.
Apparently this isn't something new, other people have had similar problems. It seems that this is a problem in the aosp usb subsystem:
https://code.google.com/p/android/issues/detail?id=185219

We initialize and read from the UsbSerialDevice like this:

    try {
        usd.open();
        usd.setBaudRate(115200);
        usd.setDataBits(UsbSerialInterface.DATA_BITS_8);
        usd.setParity(UsbSerialInterface.PARITY_ODD);
        usd.setFlowControl(UsbSerialInterface.FLOW_CONTROL_OFF);

        UsbSerialInterface.UsbReadCallback ucb = new UsbSerialInterface.UsbReadCallback() {

            @Override
            public void onReceivedData(byte[] data) {
            //Some code
            }
        };
        usd.read(ucb);
    } catch (Exception e) {
        LOG.error("while initializing usd {}", e);
        usd.close();
    }

And when we need to write data we just call write(byte[] buffer)

Any ideas on how to fix this? I was thinking of just wrapping the call to requestWait() in WorkerThread to catch the NPE and ignore it.

Set vs append

Rather than appending text, how could I set textview. When I change append to set in runuithread, it is not refreshing on the newline, it has more than a line of data it is spitting out, so it is only supposed to display "A: # B: #" but it'll display "A: # B:# A: " almost like the read usb is too fast for the set textview...any suggestions?

Serial Read on Android API 17

I'm able to write bytes using the library to an Arduino Mega ADK by writing a 1 or 0 to the COM port, but when trying to read bytes, the callback is never accessed. For every write to the Arduino, a response is sent back to Android but it cannot be read. I've tried using DroidTerm as well but same result. Tested and working on Android 5.1.1 but doesn't work for 4.2.2.

UsbSerialDevice.isSupported() Enhancement

It would be nice to have a way to determine if a device is supported without having to instantiate and then abandon a driver to do so. An android device might be used to control a set of external devices on a machine, for example, and allow the user to pick which functionalities are present on each specific device. Attempting instantation of a driver for each device found on the OS is not an efficient method for building a list to present to the user.

I propose the following as a static method on the UsbSerialDevice class:

public static boolean isSupported(UsbDevice device)
{
    int vid = device.getVendorId();
    int pid = device.getProductId();

    if(FTDISioIds.isDeviceSupported(vid, pid))
        return true;
    else if(CP210xIds.isDeviceSupported(vid, pid))
        return true;
    else if(PL2303Ids.isDeviceSupported(vid, pid))
        return true;
    else if(CH34xIds.isDeviceSupported(vid, pid))
        return true;
    else if(isCdcDevice(device))
        return true;
    else
        return false;
}

This method would need to be maintained with new drivers as added per the createUsbSerialDevice() method.

TAG: Enhancement

Usb host reading wrong values

Hi, I am trying to read from a mbed board LPC1768. The device provides CDC data (10) interface along with 3 more interfaces (i checked withlsusb -v command in a linux pc). Inside the onReceivedData(), i am using the following code.

public void onReceivedData(byte[] arg0)  {
    String data = new String(arg0, "UTF-8");
    if (mHandler != null) {
        mHandler.obtainMessage(MESSAGE_FROM_SERIAL_PORT, HexData.hexToString(arg0)).sendToTarget();
    }
}

And inside handler i am retrieving the hexdata and printing as follow.

public void handleMessage(Message msg) {
    switch (msg.what) {
        case UsbService.MESSAGE_FROM_SERIAL_PORT: String data = (String) msg.obj;
                                                  mActivity.get().display.append(","+data);
                                                  break;
       default: break;
    }
}

I am sending {A,B,C ..... H} each character every 1 second and repeating the sequence continuously. But at the usb host side i am getting data for every 1 seconds but data are 0xff0xff0xfe, 0xff0xff0xff, 0xff0xff0xfe... which is irrelevant to what i am sending. I have just started to study about Usb host class so finding difficulty in debugging this. Where could be the problem? Do you need any more information to debug this issue?

Problem converting received data to float

I want to get the received data and add to my chart, but I can't convert the received data to float.
Here's my code:

public void onReceivedData( byte[] arg0) {
            String data_tv = null;
            try {
                data_tv = new String (arg0,"UTF-8");
                data=data_tv;
                data_tv.concat("/n");
                tvAppend(textView, data_tv);
                float fdata = Float.parseFloat(data_tv);

            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }       
        }

I've tried this, but it doesn't work.
float f = ByteBuffer.wrap(arg0).order(ByteOrder.LITTLE_ENDIAN).getFloat();
Please help!!!!!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.