Android Question Serial communication via Bluetooth - receiving invalid characters

ernschd

Active Member
Licensed User
Longtime User
Hello,

we have developed device that sends HEX data in ASCII format via Bluetooth.
Now I have received data with B4A, which the device theoretically can not send at all. These are control characters like NUL, ACK, STX, and also special characters like @.
To be on the safe side, I have included the possibility to save the data from the serial buffer directly.

My questions: can the error with the invalid characters be due to the conversion with the ByteConverter or the UTF-8 encoding?
And am I doing the direct save with the RandomAccessFile correctly? I really want to save only the data that arrives from the Bluetooth device.

Thanks a lot in advance.

Here is an shortened snippet of the code:
B4X:
Private w3Raf As RandomAccessFile
Private BStreams As AsyncStreams
Private w3Init As Boolean
Private Serial1 As Serial
Public btdevice1 as string

Sub Service_Create
    Serial1.Disconnect
    Serial1.Initialize("Serial1")
End Sub

Sub Service_Start (StartingIntent As Intent)
    Dim pairedDevices As Map = Serial1.GetPairedDevices
    ' Searching Bluetooth Device
    '...
    
    Serial1.Connect(btdevice1)
End Sub

Sub Serial1_Connected (Success As Boolean)
    If Not(Success) Then Return
    If BStreams.IsInitialized Then BStreams.Close
    BStreams.Initialize(Serial1.InputStream, Serial1.OutputStream, "BStreams")
End Sub

Sub BStreams_NewData (Buffer() As Byte)
    If writeLog Then
        ' Saving Buffer directly
        If Not(w3Init) Then   
            w3Raf.Initialize(RawPath, "BtRAW.txt", False)
            w3Init = True
        End If

        w3Raf.WriteBytes(Buffer, 0, Buffer.Length, w3Raf.CurrentPosition)   
    End If
        
    ' Processing Buffer
    Dim bs As ByteConverter
    Dim cominput As String
    cominput = bs.StringFromBytes(Buffer, "UTF-8")
    '...
End Sub

Sub Service_Destroy
    If BStreams.IsInitialized Then BStreams.Close
    If Serial1.IsInitialized Then Serial1.Disconnect
    If w3Init Then
        w3Raf.Close
        w3Init = False
    End If
End Sub
 

Brian Dean

Well-Known Member
Licensed User
Longtime User
This might not be the problem, but at this line of code ...
B4X:
w3Raf.WriteBytes(Buffer, 0, Buffer.Length, w3Raf.CurrentPosition)
... you are adding the full buffer content to the file. How do you know that the sending device has filled the buffer? If it has not (or not yet) filled the buffer then you would obviously be collecting some junk.
 
Upvote 0

ernschd

Active Member
Licensed User
Longtime User
The description of Method says: "the NewData event will be raised with new data as soon as it is available".
So I thought that the buffer is always filled by the serial port, and then the NewData event is called.
 
Upvote 0

Brian Dean

Well-Known Member
Licensed User
Longtime User
I think that this sentence ...
... the NewData event will be raised with new data as soon as it is available
... means that it will be raised as soon as any new data is available. But in any case, how do you know that the sending device will always send the exact amount of data needed to completely fill the buffer? Unless you have fixed size messages then the last buffer will almost always be partially full.

But I don't think that it works that way. I am working on a Bluetooth project at the moment and the NewData event simply means that something new has arrived. If you are using AsyncStreams then you will see that there is an InitialisePrefix method that allows you to specify the amount of data expected in a message as a prefix. This, I believe, is specifically designed to handle this problem. In this mode the NewData event (I quote) "will be raised only with full messages". Of course, this requires that you have control of the sending device to add a prefix (the message length) at the start of each message.

Have you tried pre-filling the buffer with (say) zeroes and then reading the buffer content only as far as the first zero?
 
Upvote 0

agraham

Expert
Licensed User
Longtime User
Unless you have fixed size messages then the last buffer will almost always be partially full.
Not true! The buffer is filled with the received data. However fixed length messages will not arrive in their entirety but will probably be split into several packets that need re-assembling. This is purpose of AsyncStreams prefix mode. Read the tutorial.
 
Upvote 0

ernschd

Active Member
Licensed User
Longtime User
Does anyone know if specifying the encoding at
B4X:
bs.StringFromBytes(Buffer, "UTF-8")
affects the buffer data?
 
Upvote 0
Top