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 above but adds the required flag for Pending Intents when targeting SDK 31+.

V2.6 is available as an attachment to this post. It is identical to version 2.5 referenced above but adds the required flag for Pending Intents when targeting SDK 34+.
 

Attachments

  • UsbSerial2.3.zip
    99.2 KB · Views: 6,240
  • UsbSerial2.5.zip
    36.3 KB · Views: 921
  • UsbSerial2.6.zip
    36.3 KB · Views: 32
Last edited:

drponciano

Member
Licensed User
Longtime User
One more question. I made my program to work with USBSERIAL2.4 library changing usbtimeout to 1600 but, at 230400 bauds I get "newdata" from my connected device every 8000 bytes or so. Can I reduce the buffer size so I get less bytes every "newdata"? Thanks for your help.
 

drponciano

Member
Licensed User
Longtime User
Well, I'm trying to show real time biomedical signals and a 1 sec delay is just too much.
 

rtek1000

Active Member
Licensed User
Longtime User
Well, that I know, the data is received automatically, asynchronously, and they are not collected every second,

have you ever tried to modify the way your application shows the data?
 

rtek1000

Active Member
Licensed User
Longtime User
Hi,

I changed the example, and now we can see how much data is received (bytes / second).

You will see that the data continues to be received, only one activity is slow to show all the data, so you need to find a way to do the data processing before show.

To test, I use an Arduino Nano V3 with this code:

B4X:
int count = 0;

// the setup routine runs once when you press reset:
void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
}

// the loop routine runs over and over again forever:
void loop() {
  count++;
 
  Serial.println(count);
}

My test shows an average of 475 bytes / s
 

Attachments

  • USBserial_example2.zip
    8.5 KB · Views: 451

rtek1000

Active Member
Licensed User
Longtime User

drponciano

Member
Licensed User
Longtime User
Ok. Even if my app does nothing but notify the amount of serial data received (no graphics, no display, no nothing), "newdata" responds every 8k bytes or so. I do the same thing as you suggested with Wi-Fi and the "chuncks" of data are 1K so the "refresh" of signal display is smooth. Both apps work fine, display data correctly, the problem is the 8k. Thanks for your answers.
 

drponciano

Member
Licensed User
Longtime User
This is the simple app. When connecting to USB1, 230,400 bauds en receiving aprox 5 Kbytes/seg, Astreams1_newdata return when it gets 8kbytes.

B4X:
Sub Process_Globals
    ' Demo has been changed to support Ver_2.4 JeanLC
    Dim usb1 As UsbSerial   
    Dim usb2 As UsbSerial   
    Dim astreams1 As AsyncStreams
    Dim astreams2 As AsyncStreams
End Sub

Sub Globals

    Dim btnSend, btnOpen, btnClose As Button
    Private btnOpen2 As Button
    Private btnClose2 As Button
    Private btnSend2 As Button
    Dim nrecibidos As Int
    Dim let_fc As Label
    Private btnExit As Button
    Private Label1 As Label
End Sub

Sub Activity_Create(FirstTime As Boolean)
    Activity.LoadLayout("1")
    btnClose.Enabled = False
    btnSend.Enabled = False
   
    btnClose2.Enabled = False
    btnSend2.Enabled = False
    nrecibidos=0
    let_fc.Initialize("")
   

End Sub

Sub btnOpen_Click
    If usb1.UsbPresent(1) = usb1.USB_NONE Then    ' Ver_2.4
        Log("Msgbox - no device")
        Msgbox("No USB device or accessory detected!", "Error")
        Log("Msgbox - returned")
        Return
    End If
    Log("Checking permission 1")
    If (usb1.HasPermission(1)) Then    ' Ver_2.4
        Msgbox(usb1.DeviceInfo(1), "Device Information 1")    ' Ver_2.4
        Dim dev As Int
        'dev = usb.Open(115200, 1)        ' Ver_2.4
        dev = usb1.Open(230400,1)  '9600, 1)        ' Ver_2.4
        If dev <> usb1.USB_NONE Then
            Log("Connected successfully! 1")
            btnOpen.Enabled = False
            btnClose.Enabled = True
            btnSend.Enabled = True           
            usb1.UsbTimeout=1600
            astreams1.Initialize(usb1.GetInputStream, usb1.GetOutputStream, "astreams1")
        Else
            Log("Error opening USB port 1")
        End If
    Else
        usb1.RequestPermission(1)  ' Ver_2.4
    End If
End Sub

Sub btnOpen2_Click

End Sub

Sub Astreams1_NewData (Buffer() As Byte)
    nrecibidos=nrecibidos+Buffer.Length
    Log(nrecibidos)
    Label1.Text=nrecibidos
    'Log(BytesToString(Buffer, 0, Buffer.Length, "UTF8"))
End Sub

Sub Astreams2_NewData (Buffer() As Byte)

End Sub

Sub btnClose_Click
    astreams1.Close
    usb1.Close   
    btnOpen.Enabled = True
    btnClose.Enabled = False
    btnSend.Enabled = False
End Sub

Sub btnClose2_Click

End Sub

Sub btnSend_Click
    astreams1.Write("TR".GetBytes("UTF8"))
End Sub

Sub btnSend2_Click
   
End Sub

Sub btnExit_Click
    ExitApplication
End Sub

Sub AStreams1_Error
    Log("Error: " & LastException)
    astreams1.Close
End Sub
Sub Astreams1_Terminated
    Log("Terminated")
    astreams1.Close
End Sub

Sub AStreams2_Error
    Log("Error: " & LastException)
    astreams2.Close
End Sub
Sub Astreams2_Terminated
    Log("Terminated")
    astreams2.Close
End Sub


Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub
 

rtek1000

Active Member
Licensed User
Longtime User
It's ok,

You can see the data frame with another application, so you can check if you have a pause between data transmissions,

Try running putty.exe for PC and get the data, if it works fine, you can make a movie and pass me the link, I will try to repeat the data transmission time to test the sample code better.

Maybe you will need to use an interface to process the data before sending it to Android.

I made a system in a church tower that works from one year ago, 24 hours, and never stops.

But I did a slow system with protocol that sends the data at 4800 bauds and has a range of 100ms between transmissions.
 
Last edited:

rtek1000

Active Member
Licensed User
Longtime User
This is a part of my code, you can see that the data frame has a terminator (CR LF) and I can discard data that does not fit the format.

The pause between data transmissions allows the activity to be updated in another step.

B4X:
Sub Astreams_Serial_NewData (buffer() As Byte)
    Dim str1 As String
  
    str1 = BytesToString(buffer, 0, buffer.Length, "UTF8")

    str_data1 = str_data1 & str1
  
    connect_status = True
  
    cnt_timeout_uc_not_respond = 0
  
    If(CountChar(str_data1, Chr(13)) > 0) Then  
        If log_update Then
            log_com("Rec: ", str_data1)
        End If

        If(PositionChar(str_data1, Chr(13)) == 53) Then
        
          ' 2016/09/19 1 19:33:32 23-06 0 00 0 0 0 30 21 2208
          '  
          ' year date           0-4
          ' year date           1
          ' year date           2
          ' year date              3
          ' "/"                    4
          ' month date          5-7
          ' month date          6
          ' "/"                    7
          ' day date            8-10
          ' day date            9
          ' " "                    10
          ' day week            11-12
          ' " "                    12
          ' hour time           13-15
          ' hour time           14
          ' ":"                    15
          ' minute time         16-17
          ' minute time         17
          ' ":"                    18
          ' second time         19-21
          ' second time         20
          ' " "                    21
          ' hour silence init     22-24
          ' hour silence init     23
          ' "-"                    24
          ' hour silence end      25-27
          ' hour silence end      26
          ' " "                    27
          ' bell status          28-29
          ' " "                    29
          ' bell manual play       30-32
          ' bell manual play       31
          ' " "                    32
          ' amplif status        33-34
          ' " "                    34
          ' rf433 status          35-36
          ' " "                    36
          ' rf433 btn             37-38
          ' " "                    38
          ' temperature            39-41
          ' temperature            40
          ' " "                    41
          ' index received        42-44
          ' index received        43
          ' " "                    44
          ' prog bell num start 45
          ' prog bell num start 46
          ' " "                    47
          ' checksum            48-52
          ' checksum            49
          ' checksum            50
          ' checksum            51
          ' lf                    52
          ' cr                    53
          '
        
            date_year_uc = get_substring(str_data1, 0, 4)

        End If
   
      str_data1 = ""
      
      serial_send(Array As Byte(13)) ' ack for uc non restart screen
    End If
End Sub
 
Last edited:

rtek1000

Active Member
Licensed User
Longtime User
Yes, I tested in release mode.

The library 2.0 did not work more than 38400 baud (And the library fel does not find my cable usb)

---

I found several terminals for usb serial cable in the playStore.

All freeze a screen, when many data is sent, some begin to freeze when still at 9600 bauds.

Even on the PC, too much data per serial port and a problem too, the terminal application for PC serial port also freezes.

---

I do not know why, but the FTDI application can receive data even at 921600 bauds, but also go freeze with lots of data.

---

I use a code that changes a baud rate of the microcontroller each time I press reset.

It is best for me to operate up to 115200 baud for my microcontroller, even though it was able to send data up to 921600.

I know a microcontroller can get a lot of data on 230400 bauds, no problem, but if a PC (Intel I5) can not, then an Android can not.

---

I know there is another way to operate with the FTDI chip, for direct access to the USB device, for PC there is a DLL, but for Android I do not know if it is possible.
http://www.ftdichip.com/Drivers/D2XX.htm
 

rtek1000

Active Member
Licensed User
Longtime User
Sorry, FTDI direct access to the USB device is available for Android, at same link above.
 

drponciano

Member
Licensed User
Longtime User
Perhaps I have not made myself clear enough. My uProcesor is transmitting about 5300 bytes/sec at 230400 bauds. The same rate is used when transmiitting over WiFi whitout problems receiving or processiong the info even in debug mode. My problem is: when using WiFi, Astreams1_newdata is triggered every 1kbytes or so, and makes my display routine refresh the graphs 5 times per second which, more or less, makes it look "real time". When I'm reading from the USB serial port, Astreams1_newdata is triggered every 8k bytes so my display routine has to wait almost 2 secons to refresh the graphs which makes it look "unreal". I could make my display routine to compensate this and make it look less "chopped" but it would have a 2 second delay anyway which is bad for heart monitoring. :)
 

drponciano

Member
Licensed User
Longtime User
Well, well, well. I have worked with the 1 sec. delay (8000 byte packets) with my devices for a while. Not that I like it but... it works with Nexus Phones and tablets, Motorola, LG, Alcatel phones, HP tablets, Acer, and so on with same results. A few weeks ago I got a Samsung S7 phone. With that phone the serial transmission is SLOW, SLOW, SLOW using the same program and parameters. Any idea what is goimg on with this USB Libraries?
 
Top