Android Question felUSBSerial library does not receive data

yo3ggx

Active Member
Licensed User
Hello,

Im using the latest version of the felUSBSerial library (1.12) as described by Erel. When first connected, everything is working as expected, but at the second run, data can be send but nothing is received (usbserial_DataAvailable routien is no more triggered. If I'm using an USB Terminal application, data is received all the time from the same interface. The issue is not related to a specific chip, being the same for FT232 and CP210x.
Tried on several Android devices from 4.4 to 12 and the behavior is the same
After restart, reading is working again only at first run.
Any hint on how to troubleshoot this? Seems that the interface is left somehow locked only for read.

Than you.
 
Last edited:

yo3ggx

Active Member
Licensed User
Yes. Connection is closed. The problem is that after first run, data cannot be read from the serial port with any other app without full restart of the smartphone. What do you mean by "Don't handle it in the Activity"? I'm using the code from here.
 
Upvote 0

yo3ggx

Active Member
Licensed User
I've removed usbserial.close from the code when the app is closed. Now the other USB application receive data, but mine (with felUSBSerial) not, even after smartphone restart. Strange thing is that this worked in the past and I've changed nothing in the code in between. You said about starter service. What part of the code to put in the starter service?
 
Last edited:
Upvote 0

yo3ggx

Active Member
Licensed User
I've tried now with Wait For
B4X:
        USBSerial.Write(bt)
        Log("usb send: " & bc.HexFromBytes(bt))
        wait for USBSerial_DataAvailable(buffer() As Byte)
        Log("usb received: " & bc.HexFromBytes(buffer))

Still nothing received. Sending from Android is working, data is correctly received by the USB device.
 
Upvote 0

yo3ggx

Active Member
Licensed User
After I pulled all my hair out of my head, I found the root cause. In my app I'm using USBSerial library too, but just to get the devices and interfaces names using usbserial.devinfo. I'm not using only USBSerial because of missing CH340 support. After removing USBSerial Library, everything was working as expected. There is any way to get the usb serial devices names without using USBserial library? Digging through the forum, I found my post from 2016 here. Everything was working perfect for a while. I don't know what happen in between.
 
Last edited:
Upvote 0

yo3ggx

Active Member
Licensed User
I found the following comment in USBSerial.close: "
There is a bug in the Android USB Accessory handling when trying to reconnect to a disconnected Accessory.
In order to reliably connect to an Accessory with your program it is necessary to ensure that
the process of any previous instance of your program that communicated with the Arduino has been killed.
This is the reason why there is an Exit button that calls ExitApplication in the UsbSerial demo program
that you should use to kill the program. It is also necessary before restarting the program
or downloading and running a modified version again to physically disconnect and reconnect the Accessory again
If it is an Arduino ADK then pressing its Reset button will also work and will maintain the Accessory permission.
" and I strongly think my issue is related.
 
Upvote 0

agraham

Expert
Licensed User
and I strongly think my issue is related.
Very unlikely unless your serial device is an Android Accessory - which it almost certainly is not. You should be able to use UsbSerial.DeviceInfo. Just call it without calling Open and before initialising anything in felUsbSerial as DeviceInfo is effectively a stand-alone method and does not rely on anything being initialised or opened.
 
Upvote 0

yo3ggx

Active Member
Licensed User
I've used USBSerial only with .DeviceInfo, nothing more. I just add the definition:
B4X:
Dim usbs as USBSerial
without any other method or initialization, felUSBserial library does no more receive data, or behaves in an unpredicted way. Sometimes after a device restart data is read at first app run, then for any subsequent runs, data is no more received.
I'm using a FT232 based USB/Serial device (single interface) and one based on CP2105(two serial interfaces), don't know if this is important.
 
Upvote 0

agraham

Expert
Licensed User
If it works without the definition but fails with only the definition added then I am afraid that I cannot explain it. There must be a conflict between the two libraries but I've looked at the code for both libraries and I can't see any problem :( Without the definition but with the UsbSerial library selected in Libraries Manager tab does it still fail?

What is the information you need that isn't available from the UsbManager or the UsbDevice you are opening?
 
Upvote 0

yo3ggx

Active Member
Licensed User
No. If I just add the library, does not fail. I can get all the information I need from USBdevice through USBmanager using GetProductName, but this function was implemented in SDK 21, so cannot be used for older versions. How is your code getting the info for SDK < 21?

With USBSerial, I've used the following code to get required info:
B4X:
                            ' in j is deviceid'
                            Dim lst As List
                            lst = GetListFromString(SBsDev.DeviceInfo(j),CRLF)
                            x = ""
                            For l = 0 To lst2.Size - 1
                                z = lst2.Get(l)
                                If (z.ToLowerCase.Contains("manufact") And Not(z.ToLowerCase.Contains("not avai"))) Or (z.ToLowerCase.Contains("product :") And Not(z.ToLowerCase.Contains("not avai"))) Then
                                    If x.Length > 0 Then x = x & CRLF
                                    x = x & z
                                End If
                            Next
 
Upvote 0

agraham

Expert
Licensed User
Java:
 public String DeviceInfo(int paramInt) throws Exception {
    byte b1 = 1;
    StringBuilder stringBuilder = new StringBuilder();
    UsbManager usbManager = (UsbManager)BA.applicationContext.getSystemService("usb");
    HashMap hashMap = usbManager.getDeviceList();
    if (hashMap.size() == 0)
      return "No device found. Is an Accessory connected?";
    UsbDevice usbDevice = null;
    for (UsbDevice usbDevice1 : hashMap.values()) {
      if (b1++ == paramInt) {
        usbDevice = usbDevice1;
        break;
      }
    }
    UsbInterface usbInterface = usbDevice.getInterface(0);
    UsbDeviceConnection usbDeviceConnection = usbManager.openDevice(usbDevice);
    usbDeviceConnection.claimInterface(usbInterface, true);
    byte[] arrayOfByte1 = usbDeviceConnection.getRawDescriptors();
    byte b = arrayOfByte1[14];
    byte[] arrayOfByte2 = new byte[arrayOfByte1[7]];
    usbDeviceConnection.controlTransfer(128, 6, 768 + b, 0, arrayOfByte2, arrayOfByte2.length, 100);
    stringBuilder.append("Manufacturer : ").append(bytes0ToString(arrayOfByte2, b)).append('\n');
    b = arrayOfByte1[15];
    arrayOfByte2 = new byte[arrayOfByte1[7]];
    usbDeviceConnection.controlTransfer(128, 6, 768 + b, 0, arrayOfByte2, arrayOfByte2.length, 100);
    stringBuilder.append("Product : ").append(bytes0ToString(arrayOfByte2, b)).append('\n');
    b = arrayOfByte1[16];
    arrayOfByte2 = new byte[arrayOfByte1[7]];
    usbDeviceConnection.controlTransfer(128, 6, 768 + b, 0, arrayOfByte2, arrayOfByte2.length, 100);
    stringBuilder.append("Serial : ").append(bytes0ToString(arrayOfByte2, b)).append('\n');
    stringBuilder.append('\n');
    stringBuilder.append("DeviceName : ").append(usbDevice.getDeviceName()).append('\n');
    stringBuilder.append("DeviceClass : ").append(usbClass(usbDevice.getDeviceClass())).append('\n');
    stringBuilder.append("DeviceSubClass : ").append(usbDevice.getDeviceSubclass()).append('\n');
    stringBuilder.append("Device ID : ").append(toHex(usbDevice.getDeviceId())).append('\n');
    stringBuilder.append("ProductId : ").append(toHex(usbDevice.getProductId())).append('\n');
    stringBuilder.append("VendorId : ").append(toHex(usbDevice.getVendorId())).append('\n');
    stringBuilder.append('\n');
    for (byte b2 = 0; b2 < usbDevice.getInterfaceCount(); b2++) {
      UsbInterface usbInterface1 = usbDevice.getInterface(b2);
      stringBuilder.append("  B4aInterfaceNumber : ").append(b2).append('\n');
      stringBuilder.append("  InterfaceClass : ").append(usbClass(usbInterface1.getInterfaceClass())).append('\n');
      stringBuilder.append("  InterfaceSubClass : ").append(usbInterface1.getInterfaceSubclass()).append('\n');
      stringBuilder.append("  InterfaceProtocol : ").append(usbInterface1.getInterfaceProtocol()).append('\n');
      stringBuilder.append('\n');
      for (byte b3 = 0; b3 < usbInterface1.getEndpointCount(); b3++) {
        UsbEndpoint usbEndpoint = usbInterface1.getEndpoint(b3);
        stringBuilder.append("    EndpointNumber : ").append(usbEndpoint.getEndpointNumber()).append('\n');
        stringBuilder.append("    EndpointDirection : ").append(usbDirection(usbEndpoint.getDirection())).append('\n');
        stringBuilder.append("    EndpointType : ").append(usbEndpoint(usbEndpoint.getType())).append('\n');
        stringBuilder.append("    EndpointAttribute : ").append(usbEndpoint.getAttributes()).append('\n');
        stringBuilder.append("    EndpointInterval : ").append(usbEndpoint.getInterval()).append('\n');
        stringBuilder.append("    EndpointMaxPacketSize : ").append(usbEndpoint.getMaxPacketSize()).append('\n');
        stringBuilder.append('\n');
      }
    }
    usbDeviceConnection.close();
    return stringBuilder.toString();
  }
 
Upvote 0

yo3ggx

Active Member
Licensed User
When I'm trying to add as inline java code, I get the following error when compiling:
error: cannot find symbol
UsbManager usbManager = (UsbManager)BA.applicationContext.getSystemService("usb");
^
symbol: class UsbManager
location: class main
 
Upvote 0

yo3ggx

Active Member
Licensed User
After adding
B4X:
import java.util.HashMap;
too, I get another error:

error: incompatible types: Object cannot be converted to UsbDevice
for (UsbDevice usbDevice1 : hashMap.values()) {
 
Upvote 0
Top