mik3y / usb-serial-for-android

Android USB host serial driver library for CDC, FTDI, Arduino and other devices.
MIT License
4.81k stars 1.58k forks source link

Unable to read from usb port, writing works well (FTDI). #201

Closed greblus closed 5 years ago

greblus commented 6 years ago

Hi guys.

I've been using usb-serial-for-android for a few years now in my port of AspeQt - Atari Serial Peripheral Emulator for Android and it worked very well with SIO2PC-USB converters based on FT232 chip, but I started getting reports from users saying that despite their device fully supports USB Host, AspeQt doesn't work. I couldn't reproduce this problem, but finally I got two such devices, both with Android 7.1 where I'm observing similar behavior.

What I've been able to conclude till now:

  1. Probably it's not due to missing permissions, in debug mode it shows they're granted: USB : Device found! USB : Received permission result OK USB : Device OK USB : Driver found for attached usb device D FtdiSerialDriver: claimInterface 0 SUCCESS USB : Device opened USB : setBaudrate: 19200

  2. One of AspeQt's features - loading of cassette images is working fine, possibly because it's only writing data to the usb port, without reading any Atari-specific data (eg command frame as in case of disks and exe files), so the communication is one way.

  3. I've also prepared an experimental version with d2xx library and is working - but it's much slower and closed-source, so I don't want to use it. But it's a good test for a user to make sure if device is fully supporting usb-host (otg).

Now the hard part - what do you suggest to check? I've been fiddling around with endpoints, indexes, making sure that I'm talking to correct device, no luck so far. The symphtoms are - no data incoming from ftdi chip. Same code works well on my LG X Power, with 6.0 and Lolipop based tablets. Have you experienced something similar?

Cheers, W.

matthel commented 6 years ago

I am facing the same issue on different smartphone running Android 7.1. The CdCAcmSerialDriver.read function never return any bytes. Have you any update on that?

Thank you.

greblus commented 6 years ago

Unfortunately after spending really a lot of time on it I haven't solved this issue yet. I'll have to create a standalone debug app without Qt dependency to make testing less time consuming.

dheeraj12190 commented 5 years ago

I am facing the same issue do you have any solution for this.

greblus commented 5 years ago

No. Unfortunately all my attempts failed so far and I've no idea why it's not working on newer Android versions while ftdi's d2xx library is somewhat working.

kai-morich commented 5 years ago

please try with kai-morich/usb-serial-for-android fork, maybe commit fcd8596bdd3c267731fc40b19818757399c73241 (enable async read for FTDI ...) solves your issue

dheeraj12190 commented 5 years ago

@kai-morich I have tried but still it is not working. could you please go through my code

        port.open(connection);
        port.setParameters(9600, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE);

        byte buffer[] = new byte[16];
        byte disc[] = {0x7E, (byte)0xA0, 0x07, 0x03, 0x61, 0x53, 0x65, (byte)0x81, 0x7E};
        // int numBytesRead = port.read(buffer, 1000);
        //Log.d(TAG, "Read " + numBytesRead + " bytes.");
        port.write(disc,100); // This one is working fine and data is transmitted 
        Toast toast = Toast.makeText(getApplicationContext(),"Data Sent", Toast.LENGTH_SHORT);
        toast.setDuration(10);
        toast.setMargin(50,50);
        toast.show();

        int numBytesRead = port.read(buffer, 200000); // Data is not read at this point and I have increased the timeout but function returns immediately
        toast = Toast.makeText(getApplicationContext(),"Data Sent and Read Bytes " + numBytesRead, Toast.LENGTH_SHORT);
        toast.setDuration(10);
        toast.setMargin(50,50);
        toast.show();
kai-morich commented 5 years ago

please try with

    port.setDTR(true);
    port.setRTS(true);

after port.setParameter(). if the other side has some kind of flow control implemented, it might not send data w/o these control lines, e.g. arduino needs this

another option is using

    ioManager = new SerialInputOutputManager(port, this);
    Executors.newSingleThreadExecutor().submit(ioManager);

I never used read in UI thread

dheeraj12190 commented 5 years ago

@kai-morich Thanks for your support and prompt response. this one is not working port.setDTR(true); port.setRTS(true); I am new to android can you elaborate second option. Thanks in advance.

greblus commented 5 years ago

UPDATE: Kai your latest patches solve the problem indeed! (I've tested them with newer Qt on Android and it works at full speed with HSINDEX=0 115200bps). You're the man. I think this project really needs you as the maintainer :1st_place_medal:

kai-morich commented 5 years ago

SerialInputOutputManager is a class in usb-serial-for-android library. Please look at the example for usage

dheeraj12190 commented 5 years ago

@kai-morich I have gone through the example. I have complied that it is running on my mobile. but when I used that in my app it is not going in OnNewData Event belowis my code

private final ExecutorService mExecutor = Executors.newSingleThreadExecutor();
private SerialInputOutputManager mSerialIoManager;
private final SerialInputOutputManager.Listener mListener = new SerialInputOutputManager.Listener() {
    @Override
    public void onNewData(final byte[] data) {
        MainActivity.this.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                MainActivity.this.updateReceivedData(data);
            }
        });
    }

    @Override
    public void onRunError(Exception e) {

    }
};
private void updateReceivedData(byte[] data) {
    final String message = "Read " + data.length + " bytes: \n"  + HexDump.dumpHexString(data) + "\n\n";
    Toast toast = Toast.makeText(getApplicationContext(),message, Toast.LENGTH_SHORT);
    toast.setDuration(10);
    toast.setMargin(50,50);
    toast.show();
}

        port.open(connection);
        port.setParameters(9600, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE);

        byte buffer[] = new byte[16];
        byte disc[] = {0x7E, (byte)0xA0, 0x07, 0x03, 0x61, 0x53, 0x65, (byte)0x81, 0x7E};
        port.write(disc,100);
        mSerialIoManager = new SerialInputOutputManager(port, mListener);
        mExecutor.submit(mSerialIoManager);

I don't know either it is Right or not. can you please help to make the things working thanks in advance.

greblus commented 5 years ago

This solved the problem and AspeQt-1.0.62 works great now on all my devices ;).