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: 6,210
  • UsbSerial2.5.zip
    36.3 KB · Views: 890
Last edited:

agraham

Expert
Licensed User
Longtime User
Needs Android 3.1, API level 12, or later with hardware host mode support. If you want to use on earlier versions use Try...Catch to catch the exception or check the version. I can't remember if one of the libraries has this but it's simple by Reflection.
B4X:
Sub GetApi As Int
    Dim r As Reflector
    Return r.GetStaticField("android.os.Build$VERSION", "SDK_INT")
End Sub

EDIT:- I missed that Erel had already replied!
 

Quaki

Member
Licensed User
Longtime User
Tahnks for the fast replyes :)
Erel i have read your's thread about AsyncStreamsText class I think it will help :)

agraham your idea about using IndexOf and SubString
HTML:
Every time you get some data add it to any previous data string and check if IndexOf finds both a "*" and a "#". Chop out the bit between them with SubString and shorten the string to keep any remaining data. Rinse and repeat.
is aslo very interesting can you create any example code ?It is could be very helpfull to analize example code especialy the part of choping and shorten the the string to kept the ramianing data :)
I was trying difrent way and the the code works almoust good but when the string once in a while comes without spliting the are two visible strings in label 2

B4X:
Sub Astreams_NewData (Buffer() As Byte)
   Log("NewData")
   Log(BytesToString(Buffer, 0, Buffer.Length, "UTF8"))
    s= BytesToString(Buffer, 0, Buffer.Length, "UTF8")
If s.StartsWith ("p") AND s.EndsWith ("k") Then
   Label1.Text = s
s=""
s1=""
Else

If s1.Length = 28 Then
s1=""
Label2.Text = s1
End If

s1 = s1 & s
Label2.Text = s1
If s1.Length = 28 Then

s1=""
End If
End If



End Sub

Best regards
 

michw

Member
Licensed User
Longtime User
Thanks for the tips:)
I had to set the root and add the file "android.hardware.usb.host.xml" with the entry
<permissions>
<feature name="android.hardware.usb.host">
</ feature> </ permissions>
into the folder / system / etc / permissions
Now it works to send and receive data.
Thanks so much!

Regards
 

koep

Member
Licensed User
Longtime User
Hi Andrew!

Is it possible to add a verification of the device (for example product string) we are about to connect to before opening the port, and if not correct then looping through the device list until correct device found?

Rgds,
Tapio
 

agraham

Expert
Licensed User
Longtime User
The underlying usb-serial-for-android code iterates the list of accessible devices and chooses the first one it recognises as being supported based on Vendor and Product IDs. Unless there is overwhelming need I don't want to change that behaviour by adding in a third variable.
 

Rigsby

Member
Licensed User
Longtime User
Version 2.2 now posted adds the SetCustomDevice method.

First Off - Thanks For The Update To The Library

It does seem to recognise the USB to Serial adaptor type OK, I have it working with FTDI & Prolific, but I wonder if you could possibly comment on how you could explicitly select 1 of the 4 driver types when you don't know either the vendor ID and productID. What values would you use ?

usb.SetCustomDevice(usb.DRIVER_FTDI,0,0)

It might not make any difference but I'd like to see if it does. Thanks, Rigsby.
 

Stulish

Active Member
Licensed User
Longtime User
I just have to say great library, i have been trying to get my Pacific type USB/Serial adapters working for a while with no luck, so then i went out and brought an FTDI version and found this was the RL version not the R version and i couldn't get this working either.

Now with the V2.0 lib i have all of them working flawlessly (it might also have something to do with the new OTG cable i brought, but having a lib that that is not specific to Pacific/FTD/...... is a lot better)

Thanks a lot Andrew

Regards

Stu
 
Last edited:

Stulish

Active Member
Licensed User
Longtime User
I have noticed a couple of times on my NEXUS 7, that the app can freeze for between 1 to 10 seconds then the tablet resets.

I will have to do some testing to see if it is a specific USB/Serial dongle attached or if it does it on any of my other android devices.

I will let you know after i have investigated.

Regards

Stu
 

koep

Member
Licensed User
Longtime User
Hi!

Is there any working example of write/read operation with usb-serial?

With roboclaw I have several different writes(questions) to the board and I need to be able to sort the incoming reads(answers) to correct places.

Now I have three consecutive write on timer tick but the problem is that newdata event is serviced after timer_tick finishes resulting in incoming ending up in wrong places.

I need some way to run on timer:

write1->read1->process1->write2->read2->process2->etc.

perhaps with counting i/o streams?


Rgds,
Tapio
 

agraham

Expert
Licensed User
Longtime User
You can't process a read in a Timer_Tick. The NewData event runs on the main thread so your timer code needs to exit before the NewData event is called.

You should probably do the first write in the Timer code to kick things off and do subsequent writes in the NewData event after you have read the data. Note that not all your data may arrive tidily in one NewData event so you may have to reassemble the messages over two or more NewData events.
 

koep

Member
Licensed User
Longtime User
Hi Andrew!

So you are suggesting something like:

msgno as int = 0 in process globals
--
timer_tick
write1
msgno = 1
--
newdata
select msgno
case 1
process1
msgno = 2
write2
case 2
msgno = 3
process2
write3
etc.

I tried to find solution in countinginputstream and countingoutputstream,
but readbytes(buffer(),0,3,0) keeps giving me compile error saying there is argument missing. Any ideas why?

Rgds,
Tapio
 

agraham

Expert
Licensed User
Longtime User
Yes, something like that although, like I said, all the data for one message may not arrive at the same time so you will probably have to reassemble complete messages.

You cannot use the streams from UsbSerial with CountingStreams, they are a stream subset meant to be used with AsyncStreams.

I've no idea about ReadBbytes without seeing the code. The only ReadBytes that takes four parameters I can find is in RandomAccessFile and I have no idea why or how you might be want to use that.
 

davelew1s

Active Member
Licensed User
Longtime User
Hi!
I am going to convert a VB program to B4A which is for a computer controlled radio......before I start I want to be sure I can communicate with it.
I've tried this sample an can connect and receive "H100" which means the radio is switched off, to turn it on I need to send "H101" & crlf ......that's where my problem is, i've tried all I can think of but nothing works....any help would be appreciated. Thanks Dave.
 

davelew1s

Active Member
Licensed User
Longtime User
Hi agraham! the crlf signifies the end of the command after initializing the radio it is not required. My problem sending the line this is the original

Sub btnSend_Click
astreams.Write("abcdef".GetBytes("UTF8"))
End Sub
I tried this astreams.Write("H101" & crlf .GetBytes("UTF8"))
and other combinations without any success. The only way I can be sure it has been sent is if the radio turns on.Is there anyway to monitor what is being sent, can this line ...astreams.Write("abcdef".GetBytes("UTF8"))... be sent to the log?
Thanks Dave.....
 
Top