B4A Library UsbSerial library 2.0 - supports more devices

This is an expanded version of the original UsbSerial library. It has added support for Prolific PL2303 USB to serial converters, Android ADK devices and USB permissions. All devices use the same simple interface intended to be used with AsyncStreams and AsyncStreamsText. Note that AsyncStreams prefix mode is not supported. The library is based on the same open source project Android USB host serial driver library as the existing UsbSerial library but no longer needs a separate jar file as the project source code is incorporated in the library.

The specific enhancements to the library over the original UsbSerial library are :

UsbPresent, HasPermission and RequestPermission are added to identify any attached device or Accessory available to the library and deal with permission to access it.

SetParameters, which must be used after Open(), and the constants for SetParameters provides acess to all the serial line parameters instead of just baud rate.

DeviceInfo provides a string containing information about a device. This works for slave devices only.

Android Accessories, which are host mode devices, are recognised and can be used in the same way as the other slave mode devices.

Prolific PL2303 support is added.

Silicon Labs CP210x support is added - maybe only the CP2102 as I have no hardware to test.

The FTDI "status byte" bug on reading input that existed in version 1.0 of this library is hopefully fixed.


The usb-serial-for-android project and therefore also this library is licensed under the GNU Lesser General Public License v3. http://www.gnu.org/licenses/lgpl.html|http://www.gnu.org/licenses/lgpl.html
Copies of both the General Public License and Lesser General Public License are in the provided archive.

The user has to give your application permission to access the USB device before it can be opened. You can do this in two ways.

As with the original UsbSerial library you can add the following code to the manifest editor

B4X:
AddActivityText(main, <intent-filter>
        <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
    </intent-filter>
    <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
        android:resource="@xml/device_filter" />)
Then copy device_filter.xml from the demo in the attached archive to: <your project>\objects\res\xml and mark it as read-only. Note that this is an expanded version of the original device_filter.xml file.

Finally install the program and attach the USB device. A dialog will appear asking whether you want to start your program. If you check the “Use by default…” checkbox from now on when the USB device is plugged in your program will be started. If you don’t check the checkbox then you will be asked each time the device is plugged in.

A similar procedure can be used for Accessories as detailed in the “Using an intent filter” section here USB Accessory | Android Developers


Alternatively you can use the new HasPermission and RequestPermission methods without requiring any of the above steps. The demo in the archive incorporates both ways of obtaining permission.

EDIT:- Version 2.1 now posted. See post #4 for details

EDIT:- Version 2.2 now posted. See post #14 for details

EDIT:- Version 2.3 now posted. See post #26 for details

V2.4 is available here: http://www.b4x.com/android/forum/th...pports-more-devices.28176/page-11#post-259167
This update adds support for devices connected to multiple USB adapters.


V2.5 is available as an attachment to this post. It is identical to version 2.4 referenced aboce but adds the required flag for Pending Intents when targeting SDK 31+.
 

Attachments

  • UsbSerial2.3.zip
    99.2 KB · Views: 5,995
  • UsbSerial2.5.zip
    36.3 KB · Views: 611
Last edited:

nicodh

Member
Licensed User
Longtime User
Hello, i ran into a problem using this library.
I think i have found the problem but to be sure i ask (it's not silly to ask i hope).

My app works flawlesly in debug mode (rapid). I can comunicate with an arduino board without issues through usb. But once compiled in release or debug ( legacy) it does not work. Just connects but nothing more.

Looking for an answer i discovered the problem. I was using the level 8 API. And this library needs level 12 at least.

My question is why the app works in debug (rapid) mode? Is compilation done diferently (besides the debugger part).

Thanks for making me less dumb.

EDIT: Even with API level 12 it does not work in release. It seems to works more or less in debug(legacy)
 
Last edited:

nicodh

Member
Licensed User
Longtime User
Hello Erel, no error what so ever. Tried to check on the logs, nothing. I put a log() but nothing comes from the app.
 

nicodh

Member
Licensed User
Longtime User
Hello Erel, i will put an answer as soon as i have time. Probably this afternoon. Thanks.
 

nicodh

Member
Licensed User
Longtime User
Hello Erel, this is the communication code:

First sub is the connection button part: you can choose (in popup) if you use usb or bluetooth, depending on the choice:

B4X:
Sub mnuConnect_Click

    If con_type = 0 Then
        Dim PairedDevices As Map
        PairedDevices = serial1.GetPairedDevices
        Dim l As List
        l.initialize
        For i = 0 To PairedDevices.Size - 1
            l.Add(PairedDevices.GetKeyAt(i))
        Next
        Dim res As Int
        res = InputList(l, "Choose device", -1) 'show list with paired devices
        If res <> DialogResponse.CANCEL Then
              
            serial1.Connect(PairedDevices.Get(l.Get(res))) 'convert the name to mac address
          
        End If
      
    Else If con_type=1 Then
        If usb.UsbPresent = usb.USB_NONE Then
            Log("Msgbox - no device")
            Msgbox("No USB device or accessory detected!", "Error")
            Log("Msgbox - returned")
            Return
        End If
      
        Log("Checking permission")
'      
        If (usb.HasPermission) Then
            Msgbox(usb.DeviceInfo, "Device Information")
            Dim dev As Int
            dev = usb.Open(115200)      
            If dev <> usb.USB_NONE Then
                Log("Connected successfully!")
                usb_connect
                'btnOpen.Enabled = False
                'btnClose.Enabled = True
                'btnSend.Enabled = True          
              
            Else
                Log("Error opening USB port")
            End If
        Else
            usb.RequestPermission
        End If
    End If

After connection is made I call usb_connect:
B4X:
Sub usb_connect
    ToastMessageShow("Connected successfully", False)
    'TextReader1.initialize2(usb.GetInputStream,"ISO-8859-1")
    'TextWriter1.initialize2(usb.getOutputStream,"ISO-8859-1")
    astreams.Initialize(usb.GetInputStream, usb.GetOutputStream, "astreams")
    'Timer1.Enabled = True
    connected = True
    profile(0).Initialize
    profile(1).Initialize
    profile(2).Initialize
    profile(0).roll_rc.Initialize
    profile(0).pitch_rc.Initialize
    profile(0).yaw_rc.Initialize
  
    profile(1).roll_rc.Initialize
    profile(1).pitch_rc.Initialize
    profile(1).yaw_rc.Initialize
  
    profile(2).roll_rc.Initialize
    profile(2).pitch_rc.Initialize
    profile(2).yaw_rc.Initialize
    version.Initialize
  
  
  
    btnSend_Click
End Sub

And that's when it just does nothing else. I use astreams for the usb and textreader/writer for bluetooth (astreams get me a lot of errors while the textreader/writer does not) btnsend_click is:
B4X:
Sub btnSend_Click
    If connected Then
        Dim arr(10) As Byte
        arr(0)= Asc(">")
        arr(1)=Asc("V")
        arr(2)=1
        arr(3)=arr(1)+arr(2)
        arr(4) = 0
        arr(5) = 0
    End If
    send(arr)
End Sub
Sub send(buffer_send() As Byte)
    If con_type = 0 Then
        Dim textToSend As String
        textToSend=converter.StringFromBytes(buffer_send,"ISO-8859-1")
        TextWriter1.Write(textToSend)
        TextWriter1.Flush
    Else
        astreams.Write(buffer_send)
    End If
  
End Sub

the astreams data should be recieved as follow:
B4X:
Sub Astreams_NewData(buf() As Byte)
    Log("NewData")
    Log(BytesToString(buf, 0, buf.Length, "UTF8"))
    analize(buf)
End Sub

I was thinking on using the astreamstext but the problem is the end character is diferent each time (a crc check of the data).

The connection is made, i have the connection succesfull toast. but nothing else happens.
Do you see something bad?
Thanks erel
 
Last edited:

nicodh

Member
Licensed User
Longtime User
Yes Erel, the problem is only with USB.
What do you mean by the modal dialogs when it's connected?
I took the usb part (and the astreams part also) from the example on this thread.

I use some custom popups when labels are clicked, so i can change some settings.
 

nicodh

Member
Licensed User
Longtime User
Thanks Erel. I just erase all and rewrite all and now it works, following step by step your first post.
 

pixelpop

Active Member
Licensed User
Longtime User
Thought I would try this lib again armed with more knowledge. I used usb.SetCustomDevice(usb.DRIVER_SILABS,2338,32771) to set up my device. The usb.DeviceInfo message box correctly identifies it. I also log a "Connected successfully!". But when I hit the line astreams.Initialize(usb.GetInputStream, usb.GetOutputStream, "astreams"), I jump to the error handler and the error logged is:

Error: (NullPointerException) java.lang.NullPointerException

I have tried baud rates as low as 4800. Could baud rate be the problem or should I look elsewhere? I also edited the device_filter.xml file and added my device as the last entry:

<!-- Dymo Scale -->
<usb-device vendor-id="2338" product-id="32771"/>

Could that be a cause for the above error?

On a related topic, I have used both Usb and UsbSerial libraries. The Usb library provides a method to DIM the product and vendor IDs and then cycle thru the available Usb devices until one is found that matches. This library takes the first device it sees. The Usb library is working, but this one seems cleaner (if I can get it to work). Is there a preference on the method or the library I use?
 
Last edited:

pixelpop

Active Member
Licensed User
Longtime User
There was a long list of java errors, I just included what I thought was the relevant one.

After more thought, I think the problem is that UsbSerial just hits the first available USB device and goes with that one, which in this case (and many others) happens to be that Realtek WLAN issue. I don't believe that using SetCustomDevice actually redirects UsbSerial to the proper device, so it is still trying to talk to the WLAN. If UsbSerial had a function like "GetDevices" in the Usb library, this could be resolved. UsbSerial does have a GetDevice function, but I don't think this is the same as scanning all attached devices and then identifying the one that matches my vendor and product IDs.
 

pixelpop

Active Member
Licensed User
Longtime User
dymo_m10.png OK, using an unaltered version of UsbSerial Demo, why is it that Msgbox(usb.DeviceInfo, "Device Information") displays the correct device info, but dev = usb.Open(115200) generates the log entry "Error opening USB port"? The only option to Open is the baud rate and I have gone as low as 2400, but still get the error. Is there any clue in the device info that would identify the problem? Also, keep in mind that the Usb library works correctly with this device (returning 6 bytes of data, two of which contain weight information).
 

agraham

Expert
Licensed User
Longtime User
That doesn't look like a "proper" serial device from the device info. It classes itself as an HID and I guess there aren't any bulk transfer endpoints unless they are below the bottom of the message box but that looks unlikely because of the blank lines there.
 

pixelpop

Active Member
Licensed User
Longtime User
I agree that something funky is going on. Usb library works fine by using the "GetDevices" function. Is there a chance that this function could be replicated in the UsbSerial library?

PS - the image attached to my previous post included all that was displayed in the device info message.
 
Last edited:

pixelpop

Active Member
Licensed User
Longtime User
So that is probably at the core of my (and perhaps other users') misunderstanding. What is the core difference between the Usb and UsbSerial libraries?
 
Top