B4A Library PL2303 USB to RS232 adaptor driver

This is a driver for PL2303 based USB to RS232 adaptors. The PL2303 is a chip produced by Prolific Technology Inc. of Taiwan and is a very common chip to find in such adaptors. The driver requires version 0.92 or later of the USB Host library and needs a Honeycomb 3.1 or later device with USB host support .

This driver is not up to the standard that I would normally expect of myself. However it is unavoidably crippled by problems with the Android implementation of USB support and has been produced by reverse engineering a Linux driver as Prolific only provide chip operation details to their OEMs and do not publish an operation manual. Erel has suggested that I post it anyway as it is probably usable in at least some situations.

The specific problems that beset the Android USB support concern data transfer. There are two ways to transfer data in and out, asynchronously by queueing Requests and synchronously using the BulkTransfer method. Of the four possibilities two are broken in Android. Asynchronous reads will transfer fixed length arrays of data but there is no way of telling you how many bytes of the returned arrays contain valid data! I have also found a problem with synchronous writes. BlockTransfer is supposed to return a value of how many bytes it has written, or a -ve number if a fault occurred. However I was getting return values of -1 even though the data has been successfully sent! So we have a USB implementation that can't tell you how many bytes you have received nor how many bytes you have sent! :(

This driver implementation therefore has to use asynchronous writes and synchronous reads invoked by a Timer in order to provide some semblance of functionality. The use of synchronous reads limits the data rates that can be reliably supported without dropping data. If you have a PL2303 based adaptor then have a play yourself.
 

Attachments

  • USBpl2303_1.0.zip
    12.2 KB · Views: 2,830

NewB4a

Member
Licensed User
Longtime User
USBDetails

Hello agraham,
I still need help. I use the same Device, which run successfully with PL2303 USB to RS232. Now I'm using USBSerial2.3 as you suggested. Although I don't have the FTDI-Chip therefore it should run. But it doesn't (Errot usb.open()

Now I started USBDetails and got

Manufacturer,Product,Serial: not available
DEVICEName:/dev/bus/usb/001/004
DEVICESubclass 0
DEvice ID:3EAh
ProductID2303h
VendorID:67Bh

B4aInterfaceNumber:0
Interfaceclass:USB_CLASS_VENDOR_SPEC(vendor specific)
InterfaceSubclass:0

Can you get some causes because of this result?

Thanks
Tom
 

agraham

Expert
Licensed User
Longtime User
Your posts above are contradictory. In post #139 where you incorrectly treat the return of Open as a Boolean the value of "1" in the error message indicates that the port was opened as a USB_DEVICE which is correct. In that case I have no idea why the code in post #140 does not work. Make sure you have permission to use the port.
 

NewB4a

Member
Licensed User
Longtime User
Permissons?

Hallo Agraham (+Erel),

I now use USBserial 2.3. and the example of Erel


HTML:
Sub btnOpen_Click
   If usb.Open(19200) Then
      Msgbox("Connected successfully!","Connection")
      astreams.Initialize(usb.GetInputStream, usb.GetOutputStream, "astreams")
   Else
      Msgbox("No connection","Connection")
   End If
End Sub

I always get "No connection"

The manifest Editor looks correct to me:
HTML:
'This code will be applied to the manifest file during compilation.
'You do not need to modify it in most cases.
'See this link for for more information: http://www.b4x.com/forum/showthread.php?p=78136
AddManifestText(
<uses-sdk android:minSdkVersion="4" android:targetSdkVersion="14"/>
<supports-screens android:largeScreens="true" 
    android:normalScreens="true" 
    android:smallScreens="true" 
    android:anyDensity="true"/>)
SetApplicationAttribute(android:icon, "@drawable/icon")
SetApplicationAttribute(android:label, "$LABEL$")
'End of default text.
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" />)

Erel declared for his example and permissions and device-filter:
HTML:
These two steps were already done for the example project.

HTML:
Make sure you have permission to use the port.
What do you mean by this? Changing something in the manifest editor? What?

Must I change anywhere the EndorID or Product ID of my device as described in '141?

Besides: USBserial 2.3 is much very easy to use, better than USBPL2303.Unfortuately it won't run.

Thanks for patience
Tom

P.S. I don't have any longer the Error described in #139.
 

agraham

Expert
Licensed User
Longtime User
Does my demo in the UsbSerial 2.3 archive work if you connect pins 2 and 3 on the adaptor connector?
This line is wrong as Open does not now return a Boolean but an Int that indicates the type of device opened.
B4X:
If usb.Open(19200) Then
However if that really is how you are trying to open it you should be getting that runtime error "Cannot parse: 1 as Boolean" so either your code is not as you have posted or something very odd is happening.

It should be
B4X:
If usb.Open(19200)<> usb.USB_NONE Then

You can check you have permission with usb.HasPermission
 

NewB4a

Member
Licensed User
Longtime User
Hello agraham,

HTML:
If usb.Open(19200)<> usb.USB_NONE Then
With this line there comes up no error and "no connection" is reported.

As I have no FTDI-Chip at home, I tested it with an PL2303-Chip. Is the error in the device-filter of Erel, where the PL2303 is not mentioned, because device-Filter means 'this devices and no others'?

HTML:
<?xml version="1.0" encoding="UTF-8"?>
-<resources> 
<!-- 0x0403 / 0x6001: FTDI FT232R UART -->
 <usb-device product-id="24577" vendor-id="1027"/> 
<!-- 0x2341 / Arduino -->
 <usb-device vendor-id="9025"/> 
<!-- 0x16C0 / 0x0483: Teensyduino -->
 <usb-device product-id="1155" vendor-id="5824"/> </resources>

Tom
 

agraham

Expert
Licensed User
Longtime User
I have suggested that you check you have permission but you don't seem to have done it. If you are not explicitly checking for permission and asking for it if you have not then it won't work. This is all in the demo in the UsbSerial 2.3 archive.

res/xml/device_filter.xml in the UsbSerial 2.3 demo does include the PL2303.
 

NewB4a

Member
Licensed User
Longtime User
success!

High agraham,

what a simple idee of mine: I indeed used the wrong example, not that of 2.3.

Thank you for your help. Although at the moment I habe a PL2303 and not a FTDI, I hope this also will run.

USBserial2.3 indeed is a great help. Thank you for that.

Tom
 

ralphie911

Member
Licensed User
Longtime User
It's all there in the code if you look
B4X:
Dim rxdata As RxDataBlock
rxdata = USBpl2303.rxdata.Get(0)
RxDataBlock is a Type defined in the USBpl2303 module.

B4X:
Type RxDataBlock (data() As Byte, bytecount As Int)
Do what you will with the data it contains.

Hi Agraham, first of all I need to thank you for your fine work. So, THANK YOU.

I am a bit stuck and I am sure it's something I don't understand.

I am writing a MODBUS RTU interface using your driver. I can successfully send a command to the Modbus device which in turn responds properly as I have verified with a serial analyzer.

However, I cannot make any sense of the data that is returned. Also the data transmitted back is always the same, the "data" as is in your RxData array always changes slightly.

The actual hex data I am getting back is "01 06 00 0A 00 0B E8 0F" as checked with the serial analyzer but what is in the rxdata array is something like this: rxdata = [data=[B@412a5bc8, bytecount=8, IsInitialized=false]

What I don't understand at all is the B@412a5bc8 it almost looks like a memory address....

Could you please shed some light on this?
 

agraham

Expert
Licensed User
Longtime User
You are not accessing the array properly. Whatever you are doing to get that result is looking at the array object itself rather than indexing into its data as what you are seeing is the Java type name for a Byte array with some other information about it.
 

EduardoElias

Well-Known Member
Licensed User
Longtime User
Hi there,

I am using this library for while and it works great.

My problem is with permissions. I wanted that it asked for granting the permission once and after that never ask that again.

In some cases it just looses the permission and ask again, every 30 minutes.

On the device I am testing right now (android 4.01) it ask for permission again everytime I turn on the device. That is not too bad, however I wanted to avoid that.

The usb cable is never removed from the device.

When it opens the dialog asking for permission there is a check box to associate that USB device to that apk, however it seems to not cause any effect.

I am added to the manifest the same string as described for USBSerial 2.0 and placed the device list xml on the xml directory.

Is this a limitation, or what am I doing wrong?

Any help appreciated...

Eduardo
 

mikisquiti

Member
Licensed User
Longtime User
Found the solution

Here is guys:

The mentioned solution of changing the /system/etc/permissions worked!

The PL2303 demo found the usb->serial cable, at first time asked for permission to take the usb, i have accepted. Next time it found the pl2303 and could comunicate with pc. I have put a cable linking tablet and pc with teraterm and could receive the data sent by PL2303 demo

So, in my case, I was lucky my hardware was prepared and my Android4.0.3 came already rooted from factory. I changed the files and worked.

Eduardo Elias
Hi
I'M miki; I have the same problems to working with adapter prolific pl 2303; I try to modify the xlm file under /system/etc/permissions but on my tablet don't is possble to create o copy file in this directory. Could you hel me?
 

StarinschiAndrei

Active Member
Licensed User
Longtime User
You do not change this file at all, follor these steps:

1 - add a file named android.hardware.usb.host.xml on /system/etc/permissions
2 - containing the following lines:
<permissions>
<feature name="android.hardware.usb.host">
</feature></permissions>
3 - open in /system/etc/permissions file named handheld_core_hardware.xml or tablet_core_hardware.xml and add <feature name="android.hardware.usb.host"> into <permissions> section
4 - Reboot your device. Usb host api should work

You have to have root access to these files. After the changes and reboot it worked for me.
Hi eelias ,
I followed your instruction, but tablet_core_hardware.xml is read only. How can i chage it ?
Thank you
 
Last edited:

pixelpop

Active Member
Licensed User
Longtime User
I have a Kyros 4.3" mini tablet and have hit the Realtek WiFi vs. USB wall that has been discussed here. When I began, the USB port was not recognized by the USBSerial 2.3 demo app. I rooted the device and applied the mods suggested in post #50. Now the app recognizes the port, but as a Realtek WLAN.

Has anyone been able to come up with a work-around for this issue? Also, there are many 4.3" and 7" minis in the market. Has anyone had success using USB with any of these other devices (Chromo, Dragon, ProntoTec, etc.)?

Thanks!

Edit: Just for grins, I tried the USBSerial demo app on a Galaxy S3 and old Galaxy 10.1 tablet I had laying around. Both failed (no USB device attached). I didn't bother rooting either of them. The device I am trying to read is a Dymo postal scale with USB output. I'm starting to think my project is dead before it even got started. :-(
 
Last edited:

gtoner

Member
Licensed User
Longtime User
We need to find a solution for this Wlan problem. I have three cheap tablets: two 7 inch, a Coby MID7034 and a Azpen A701, and a 10 inch EKEN GC10X, all from Micro Center. My project needs both Wlan and usb serial. What can I (we) do to fix / workaround this problem? I have found that I can get wireless back if I go the settings and turn wireless off and then back on, but I can't ask my user to do this in a application environment. I need cheap tablets to make this application attractive.
 

pixelpop

Active Member
Licensed User
Longtime User
I will +1 this one...right now it's just irritating from a development standpoint, but my project ideally will be able to use wifi connections concurrently with USB usage.
 

pixelpop

Active Member
Licensed User
Longtime User
I tried the four DriverIDs available and found that this provides a successful connection to my scale:

usb.SetCustomDevice(usb.DRIVER_SILABS,2338,32771)

However, after getting a successful connection, I get this error and processing ceases:

Checking permission
Connected successfully!
Error: (NullPointerException) java.lang.NullPointerException


Any ideas? Thanks.

Edit: OK, maybe I was overthinking this. I found an article on the Internet that said these postal scales are actually HID devices. So I searched here for HID and found a forum question called "USB Interface HID Report Descriptor". Using the sample code in that thread, I got the proper response from the scale.
 
Last edited:
Top