Android Question USB HID communication HELP

walterf25

Expert
Licensed User
Longtime User
Hello all, i've been struggling with this issue for a almost a week now, i thought i'd make this post and hopefully get some answers.
I have a medical device that i need to communicate with and download the stored data in it, I can't give too much details about the device itself since i signed an NDA for this project.\
I can communicate just fine with the device i can send commands to it to wake up the device and and initialize the data download sequence.

The issue is that when i'm receiving the data, the data doesn't seem to be received completed, and there are also some other characters that i can see if i copy the data into a text file, I've been reading a few other posts here in the forums where some other members have provided some various examples on how to receive the data, i've tried all those examples but i seem to get the same results.

here's how the data should be received......
One reading should be like this in hex bytes
28 67 35 35 38 34 32 30 46 37 31 45 34 33 30 29 37 41
and converted to ascii it should look like this
(g558420F71E430)7A
The last hex byte is the is actually the last two numbers of the checksum.
And here's how the data is actually received....
5830)89

(g5
g553925
(58

(g55AFE464E7841D730)84

(g5664E579A3

(g535EA6B71D
005250
22B0F630)830)768C416630)7B4A97239706230)5B

5830)89

(g5
B30)61

(58

(g55AFE464E7841D730)84

(g5664E579A3

(g535EA6B71D

(g250
22B0F630)830)768C416630)7B4A97239706230)5B

5830)89

(g5

What can I do to receive the correct information?
I tried pasting the weird characters i receive but they don't seem to appear when i paste them on the forum, but from googling the characters one of them is an ACK, another is ENQ, another one is BEL, and another one is ETX and STX, how can i detect this characters in B4A since they don't get logged in the logs, i hope i can get some help with this, most importantly i want to be able to receive all the data being retrieved from the device, the device has 501 records, so i should be able to download all 501.

Thanks everyone for your help.

Walter
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
To analyze the data you can use ByteConverter.HexFromBytes.

I assume that you are not using prefix mode (you shouldn't in this case). This means that the messages can be broken into several messages or be merged. You are responsible for collecting the data and "parsing" it. See AsyncStreamsText class for an example of handling text messages.
 
Upvote 0

walterf25

Expert
Licensed User
Longtime User
To analyze the data you can use ByteConverter.HexFromBytes.

I assume that you are not using prefix mode (you shouldn't in this case). This means that the messages can be broken into several messages or be merged. You are responsible for collecting the data and "parsing" it. See AsyncStreamsText class for an example of handling text messages.
Hi Erel I think you're talking about usb serial library where you can use asyncstreams in this case I don't really see a way to use that unless I'm missing something.
I'm using the usb host library.
 
Upvote 0

walterf25

Expert
Licensed User
Longtime User
The first step is to analyze the data and understand why you receive this specific data. Is a message broken into multiple packets?
Hi Erel, i know and understand the data that is coming in, what i don't understand is why the data comes in intact sometimes and others it comes back sort of "corrupted", from what i have been reading it seems to be an issue with the usb host library, since it can't really receive the data asynchronously.
Each data packet consists of 64 bytes, and yes when i download all the readings the readings will come in in multiple packets, but that doesn't explain why i receive the weird characters i explained in the first post. I should be able to collect all the packets, but even if I do when i convert the hex bytes to ascii characters i still see those weird characters, and sometimes there's lost information as well.

I hope you can suggest a way to work around this Erel, is really important since this project is for a client of mine and is for a medical device company.
I've tried your example here and have also tried this other example and also this one and a few other i've found in the forums, all of them seem to work just fine but still i see the same issue described in post #1.

Thanks for your time and help Erel, i hope you can help me figure something out.
 
Upvote 0

walterf25

Expert
Licensed User
Longtime User
There shouldn't be any "weird" characters in the hex string.

The USB library is based on Android API. It doesn't add any data. You can see that the ADB example works properly.

Can you post the relevant code?
Hi Erel, here is the relevant code

here's how i connect:
B4X:
Sub btnConnect_Click
    'Find and initialize the device if it's not already available
    If Not(Nipro.USBAvailable) Then
        If Not(Nipro.GetDevice) Then
            Return
        End If
    End If
   
    btnConnect.Enabled = False
    'Start Processing
    If Nipro.USBAvailable Then
        Glucose.Start
    Else
        Log("Usb device not available")
        Return
    End If
End Sub

and here is the Nipro Class
B4X:
Sub Class_Globals
    Dim Manager As UsbManager
    Dim Interface As UsbInterface
    Dim Device As UsbDevice
    Dim Connection As UsbDeviceConnection
    Dim InEndPoint As UsbEndpoint
    Dim OutEndPoint As UsbEndpoint
    Dim USBAvailable As Boolean
End Sub

Public Sub Initialize
    Manager.Initialize
End Sub

'Get attached USB devices
Sub GetDevice As Boolean
    Dim usbdevices() As UsbDevice
    usbdevices = Manager.GetDevices

    'Iterate over devices and find the correct one
    For i = 0 To usbdevices.Length - 1
        Dim ud As UsbDevice
        ud = usbdevices(i)
        'Check if the interface is the one we want
        If GetInterface(ud) Then Exit
    Next
    'If not initialized (didn't find a suitable device)
    If Not(Device.IsInitialized) Then
        Log("Glucose Meter Device not found.")
        ToastMessageShow("Glucose Meter Device not found.",False)
        Return False
    End If
    Return True
End Sub

Sub GetInterface(ud As UsbDevice) As Boolean
    Dim Found As Boolean
    'Iterate over interfaces
    For a = 0 To ud.InterfaceCount - 1
    Dim inter As UsbInterface
    inter = ud.GetInterface(a)
    'Is it a midi USB device?
    If inter.InterfaceClass = 3 AND inter.InterfaceSubclass = 0 Then
        Found = True
        'Found our device and interface
        Device = ud
        Interface = inter
        'Find correct endpoints
        For b = 0 To Interface.EndpointCount - 1
          Dim endpoint As UsbEndpoint
          endpoint = Interface.GetEndpoint(b)
          If endpoint.Type = Manager.USB_ENDPOINT_XFER_INT Then
              If endpoint.Direction = Manager.USB_DIR_IN Then
                InEndPoint = endpoint
              Else If endpoint.Direction = Manager.USB_DIR_OUT Then
                OutEndPoint = endpoint
              End If
          End If
        Next
    End If
    Next
    If Found Then
        'Check we have permission to use the device
        If Manager.HasPermission(Device) = False Then
            Manager.RequestPermission(Device)
            If Manager.HasPermission(Device) = False Then
                ToastMessageShow("Permission not granted",False)
                Return False
            End If
        End If
        'Get the connection
        Connection = Manager.OpenDevice(Device, Interface, True)
        If Connection.IsInitialized Then
            USBAvailable = True
            Return True
        Else
            Log("Connection Failed")
            USBAvailable = False
            Return False
        End If
    End If
    'Return result
    Return Found
End Sub

And then i take care of the receiving part on another class...

B4X:
Sub Class_Globals
    Private mIsRunning As Boolean
    Private TH As Thread
    Private mModule As Object
    Private mUSBMan As NiproUSBManager
    Dim Interrupt As Boolean
End Sub

Sub Class_Globals
    Private mIsRunning As Boolean
    Private TH As Thread
    Private mModule As Object
    Private mUSBMan As MidiUSBManager
    Dim Interrupt As Boolean
End Sub

'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize(Module As Object,USBMan As MidiUSBManager)
    mModule = Module
    mUSBMan = USBMan
    TH.Initialise("TH")
End Sub
Sub Start
    TH.Start(Me,"USBInThread",Null)
End Sub
Sub USBInThread
    mIsRunning = True
    Dim inBytes(mUSBMan.inEndPoint.MaxPacketSize) As Byte
    Dim byteCount As Int
    'Parse the incoming data
    Do While True
        byteCount = mUSBMan.Connection.BulkTransfer(mUSBMan.inEndPoint,inBytes,inBytes.Length,0)
        If byteCount > 0 Then
            Log(BytesToString(inBytes, 0, inBytes.Length, "ASCII"))
            End If
        If Interrupt Then Exit
    Loop
End Sub

Sub TH_Ended(endedOK As Boolean, error As String)
    'Thread Finished
    Interrupt = False
    mIsRunning = False
End Sub

Thanks Erel.
 
Upvote 0

walterf25

Expert
Licensed User
Longtime User
You don't need to create another thread. Instead use Queue to send the request and handle the data received in NewData event. See ADB example.
Erel I've tried that as well, and i get the same results.

Thanks,
Walter
 
Upvote 0

walterf25

Expert
Licensed User
Longtime User
In that case this is the data that the medical device is sending.
I really doubt it Erel, i'm also using the software that comes with the device, which runs on Windows, and it works the way it should, i really think there is an issue with the way the library handles the input data.

Thanks,
Walter
 
Upvote 0

keirS

Well-Known Member
Licensed User
Longtime User
Ask the device manufacturer if they are using a UART to USB converter in the device. Apart from BEL all your strange characters are used for serial comms handshaking and framing protocol. It just might be there is a firmware issue with the device.
 
Upvote 0

walterf25

Expert
Licensed User
Longtime User
Ask the device manufacturer if they are using a UART to USB converter in the device. Apart from BEL all your strange characters are used for serial comms handshaking and framing protocol. It just might be there is a firmware issue with the device.
Hi Keirs, I believe they actually are using a uart to usb, the device has an RS232 communication circuit inside, they are using a smart usb HID cable which converts the rs232 protocol to usb hid.

Thanks,
Walter
 
Upvote 0

sorex

Expert
Licensed User
Longtime User
did you try lowering the baud rate to prevent data corruption or bad handshakes?
 
Upvote 0

walterf25

Expert
Licensed User
Longtime User
did you try lowering the baud rate to prevent data corruption or bad handshakes?
Hi sorex, how can i change the baudrate? I don't see a function for that with this library, i know with the usb-serial library you can do that, i can however send a command to the usb-hid cable to change the baudrate of the cable i've tried that but if i lower it i just don't get any data at all!

Thanks,
Walter
 
Upvote 0

sorex

Expert
Licensed User
Longtime User
that's bizarre indeed. odd stuff like PBXs etc... usually work (best) at 9600 baud.

did it pull in 64 bytes or is it more when you get the weird stuff?
 
Upvote 0

walterf25

Expert
Licensed User
Longtime User
that's bizarre indeed. odd stuff like PBXs etc... usually work (best) at 9600 baud.

did it pull in 64 bytes or is it more when you get the weird stuff?
I get exactly 64 bytes on every packet.
 
Upvote 0

sorex

Expert
Licensed User
Longtime User
did you try with a 1 byte read?

can you force that maxpacketsize to 1?

B4X:
Dim inBytes(mUSBMan.inEndPoint.MaxPacketSize) AsByte

if that works you might find out when it adds extra bytes, maybe it's internal also using a buffer with eob codes.
 
Upvote 0

keirS

Well-Known Member
Licensed User
Longtime User
Hi Keirs, I believe they actually are using a uart to usb, the device has an RS232 communication circuit inside, they are using a smart usb HID cable which converts the rs232 protocol to usb hid.

Thanks,
Walter

Then maybe they are using a USB driver that deals with the comms handshaking. One way to find out is to use a PC based USB analyzer (it's free) with their PC based software. You will at least be able to see what the data flow is between the PC and the device when it is working properly.

The only way I know of to get the same data for Android USB comms is to use a full blown hardware based USB protocol analyzer. These aren't cheap although they do occasional pop up on Ebay.
 
Upvote 0
Top