Android Question frames filters

fgh3966

Active Member
Licensed User
Good evening everyone.

USB device generates frames to the phone, and all frames contain the same number of characters, but they also contain several character fields of different sizes.
I thought of inserting a special character between each field.
It is be possible to filter the frames to find each field, then to send each field to their dedicated variables (label, etc.) ?

Thank you.

Regards
 

Brian Dean

Well-Known Member
Licensed User
Longtime User
It is be possible to filter the frames to find each field ...
I am sure that the device sending the information expects the data to be useful to the receiver, so there will be some way to interpret it. Without seeing some sample data I don't know what else to say.

I thought of inserting a special character between each field.
That seems to be a good idea.
 
Upvote 0

fgh3966

Active Member
Licensed User
THANKS
I thin add '#' symbol would be a separator (which takes one byte), then the next two bytes (representing the payload) are generated by a 16-bit counter. Then I would add another separator symbol '#' etc ...
Seems like the quickest solution to me.
Then add a checksum to verify the content of the message.

# 0x0a 0xa0 # 0xb1 0x25 # 0xcc 0xea # ...............etc ............

My program translate it to decimal data value are ( 0 to 65535 decimal )
 
Upvote 0

Brian Dean

Well-Known Member
Licensed User
Longtime User
It sounds as though you are writing both ends of this serial link - I did not realise that at first.
Then add a checksum to verify the content of the message.
A checksum might be a good idea. It is also often useful in serial messages to indicate the end a message (eg with a pair of separators "##").
 
Upvote 0

fgh3966

Active Member
Licensed User
the '#' character would be a separator character between the information (bytes).
To simplify '#' would only separate two bytes.
What do you think ?
How can I pass the buffer into a variable and test it?
 
Upvote 0

Brian Dean

Well-Known Member
Licensed User
Longtime User
I have worked with Bluetooth but not with USB, so I cannot guide you very much. I guess that you have looked at this tutorial which describes USB Host Mode - not sure if that is what you need. If it is then it looks like you wait for a UsbRequest_NewData event, and the data comes as a byte string ...
B4X:
Sub USB_NewData (request As UsbRequest, inDirection As Boolean)
        ' . . . .
        Dim input() As Byte = request.Buffer
        Dim count As Int = request.Buffer.Length
        For i = 0 To count - 1
            ' . . .                            ' Process one byte at a time
        Next
        ' . . . .
End Sub
Obviously I have not tested this. If it does not help you then I suggest that you start a new post asking how to handle USB communications.
 
Upvote 0

fgh3966

Active Member
Licensed User
I try this code and the symbol # which seems well identified to me, because I also tried other symbols which do not seem to be recognized.
But i can't decode data to hexadecimal format at decimal.
If someone could tell me the error?

trigger + decoder:
Private Sub serial_DataAvailable (Buffer() As Byte)
'    Log("New data: " & bc.HexFromBytes(Buffer))
    EditText1.Text = EditText1.Text & bc.HexFromBytes(Buffer) & CRLF
    Dim msg As String = bc.StringFromBytes(Buffer, "ASCII")
    
    If msg.StartsWith ("#") Then
        lblspeed.Text = msg.SubString2(1,4)
    End If
End Sub


Thanks in advance
 
Upvote 0

Brian Dean

Well-Known Member
Licensed User
Longtime User
In your first post you mention characters and labels, and I thought that your data was ASCII. I think that I was wrong and your data is 16-bit integers, although even in post #7 you are still putting your data into an EditText. I still don't really know whether you want to display your data as a number or as a hexadecimal value or as text.

Anyway, here is some code that will convert a string of 16-bit binary values received as a byte array into numeric values ...

B4X:
' Generate some sample data and convert it
Sub Button1_Click
    Dim data() As Byte = makeData
    decode(data)
End Sub

' Create some sample data : 16-bit big-endian values
Sub makeData As Byte()
    Dim data(4) As Byte
    data(0) = 17      ' 0x11
    data(1) = 34      ' 0x22  :  0x1122 = 4386
    data(2) = 68      ' 0x44
    data(3) = -119    ' 0x88  :  0x4488 = 17544
    Return data
End Sub

' Convert a Java signed byte value to unsigned integer value
Sub byteToInt(b As Byte) As Int
    Dim n As Int = b
    If (b < 0) Then n = n + 255
    Return n
End Sub

' Convert a string of byte pairs to 16-bit integers
Sub decode(data() As Byte)
    Dim i As Int = 0
    Dim n As Int
    Do While (i < data.length)
        n = byteToInt(data(i)) * 256 + byteToInt(data(i + 1))
        Log(n)                    ' Display the decimal value
        i = i + 2
    Loop    
End Sub
I am still not sure exactly what your data stream looks like, but I don't think that you should worry about field separators; you might be solving a problem that does not exist.
 
Upvote 0

fgh3966

Active Member
Licensed User
Hello and thank you very much.

How it is possible to store the full buffer-USB contents in a variable? Or rather a table?

Thank you 😶
 
Upvote 0

Brian Dean

Well-Known Member
Licensed User
Longtime User
How it is possible to store the full buffer-USB contents in a variable?
There are a lot of possibilities. You should start by thinking out your system design before writing any code, and then write a program to implement your design. I suspect that I would find myself putting the decoded values into a list ...
B4X:
' Read a string of byte pairs into a list as 16-bit integers
Sub decode(data() As Byte) As List
    Dim result As List
    result.Initialize
    Dim i As Int = 0
    Dim n As Int
    Do While (i < data.length)
        n = byteToInt(data(i)) * 256 + byteToInt(data(i + 1))
        result.Add(n)                      ' Create a list of the values
        i = i + 2
    Loop
    Return result
End Sub
I cannot say if this would be the best choice for you.
 
Upvote 0

fgh3966

Active Member
Licensed User
Thank you for all your answers, also you are right.
I had prepared a somewhat long message but I didn't want to confuse you.
New i trying to extract data from buffer and arrange it in memory.
I need consult b4x table or pointer
 
Upvote 0

fgh3966

Active Member
Licensed User
Into Beginner guide at -4.2

BytesToString (Data() As Byte, StartOffset As Int, Length As Int, CharSet As String) As String

Décode le tableau d’octets (bytes) en un objet String.
Data - Le tableau d’octets.
StartOffset - Le premier octet à lire.
Length - Nombre d’octets à lire.
CharSet - Le nom du codage de caractères.
Exemple :
Dim s As String
s = BytesToString(Buffer, 0, Buffer.Length, "UTF-8")

Good !

But how it possible to define Buffer.lenght ?

Thank you very much.
 
Upvote 0

Brian Dean

Well-Known Member
Licensed User
Longtime User
But how it possible to define Buffer.lenght ?
Aucun probleme! In your post #7 you show that the buffer is created by the serial link ...
B4X:
Private Sub serial_DataAvailable (Buffer() As Byte)
'    Log("New data: " & bc.HexFromBytes(Buffer))
. . . . . .
The length of the buffer is already fixed before it is passed to the subroutine. However a serial transmission is often received in several short bursts, and you have to make sure that you have received the entire message before you start to decode it. That is why I mentioned earlier that it is useful to have some specific marker to indicate the end of the data. Alternatively begin the transmission with a byte indicating the total length of the data record.
 
Upvote 0

fgh3966

Active Member
Licensed User
I had understood that the ByteToString function decoded the number of bytes indicated by its length parameter 😶

New i will search informations to understand how to transform or concatenate :
2 bytes into an integer (16 bits)
or even
4 bytes into word (32bits)

Regards
 
Upvote 0

fgh3966

Active Member
Licensed User
Hello all !
Finally using fb0=Buffer(0), fb0=Buffer(1), etc... i can select the necessary byte.
I can log data after using the Bit function : ToHexString(hex)) but MSB zeros are missing.
I try to print it into label and i'm searching solution.

Thanks for your help.
 
Upvote 0

Brian Dean

Well-Known Member
Licensed User
Longtime User
. . . but MSB zeros are missing.
You can add padding zeroes as follows (I assume that you are converting 16-bit binary values) ...
B4X:
    Dim value As string = Bit.ToHexString(n)
    Do While (value.Length < 4)  ' If result is less than four characters ...
        value = "0" & value      '   ... add a leading zero
    Loop
 
Upvote 0
Top