B4R Tutorial [B4X] B4RSerializator - Send and receive objects instead of bytes

Status
Not open for further replies.

Erel

Administrator
Staff member
Licensed User
B4R v1.50 includes a new type named B4RSerializator (in rRandomAccessFile library).
B4RSerializator solves a difficult and common task. Sending messages with multiple fields to other platforms.

B4RSerializator takes an array of objects with numbers, strings and arrays of bytes and returns an array of bytes.

You can then send the array of bytes to other B4A, B4i, B4J or B4R applications and use the attached B4RSerializator class to decode the array of bytes back to an array of objects.

It works both ways. You can convert the array of bytes in the B4A, B4i or B4J application and convert it back to an array of objects in the B4R application (or in any other platforms).

Differences between B4RSerializator and B4XSerializator

B4XSerializator is supported by B4A, B4i and B4J. B4RSerializator is supported by all 4 tools.
B4XSerializator is more powerful and supports more types including complex types. B4RSerializator supports numbers, strings and arrays of bytes. Note that booleans are converted to 0 or 1.

B4RSerializator is more lightweight and produces more compact output (optimized for smaller messages).

Usage

It is very simple to use B4RSerializator.
Example:
B4X:
'ser is a B4RSerializator object
'sending side
astream.Write(ser.ConvertArrayToBytes(Array("Sent from B4A", DateTime.Time(DateTime.Now), 1000)))

'receiving side
Sub Astream_NewData (Buffer() As Byte)
Dim data() As Object = ser.ConvertBytesToArray(Buffer)
If data.Length = 0 Then Return 'invalid message
Dim LuckyNumber As Int = data(2)
For Each o As Object In data
  Log(o)
Next
End Sub
Note that in B4R ConvertBytesToArray there is a second parameter:
B4X:
Dim be(10) As Object 'used as a storage buffer. Can be a global variable
Dim data() As Object = ser.ConvertBytesToArray(Buffer, be)
The storage buffer size must be equal or larger than the number of items in the message.


B4RSerializator class is attached (compatible with B4A, B4i and B4J).
B4R type is included in rRandomAccessFile library.

Example of socket connection between Android and ESP8266 is attached.
The B4R example depends on rRandomAccessFile v1.8+.
 

Attachments

Last edited:

Mostez

Active Member
Dim be(10) As Object 'used as a storage buffer. Can be a global variable
Dim data() As Object = ser.ConvertBytesToArray(Buffer, be)
which array of them will be used to get data from i.e. myitem = array(index)
 

Mostez

Active Member
I tried this code, but when i just start to send a single character i get this error:
Out of bounds error. Array length = 150, Index = 65535

B4X:
private Sub ReadPCstream(Buffer() As Byte)
    
    Dim Ser As B4RSerializator
    Dim BE(150) As Object 'max data len is 105 bytes
  
    Dim PCBuffer() As Object = Ser.ConvertBytesToArray(Buffer,BE)
    If PCBuffer.Length = 0 Then Return 'invalid message
 

Erel

Administrator
Staff member
Licensed User
Dim BE(150) As Object 'max data len is 105 bytes
It can be much smaller. It needs to be equal or larger than the number of items, not bytes.

How did you create the message on the PC side?
 

Mostez

Active Member
i send a 100 bytes string from serial terminal, but even when I just press connect on serial terminal i get the error before sending anything
 

Erel

Administrator
Staff member
Licensed User
This is not how you use B4RSerializator. You should use the class on the PC to convert the array of objects to bytes and then convert it back to an array of objects on the Arduino. It saves you the need to parse the message yourself.

See the example attached to the first post. It should be simple to convert it to B4J.
 

Dan Davis

Member
Licensed User
Has anybody found a solution to #5? I also am getting this error when sending data between Android and an Arduino over bluetooth.

i get
"Out of bounds error. Array length = 150, Index = 65535"

Just my luck its something simple.

to send the data from the Android device i'm using

"ast.Write(ser.ConvertArrayToBytes(Array("Test1", "Test2", 1701)))"

and to receive on the arduino I've done multiple things including copying and pasting from the example.

Any help would be appreciated.

Thank you all for your time.
 

Dan Davis

Member
Licensed User
Just figured it out. Baud rate on the Bluetooth didn't match the baud rate set in the Arduino. One of those face to the palm moments I guess.
 

Erel

Administrator
Staff member
Licensed User
B4A_Client example was updated. The example is now based on AsyncStreams in prefix mode. AsyncStreams in prefix mode + B4RSerializator is the recommended method for low level communication.
 

Humberto

Active Member
Licensed User
I´m trying this example but in this line
B4X:
astream.InitializePrefix(socket.InputStream, False, socket.OutputStream, "Astream")
I get this error
java.lang.OutOfMemoryError
at anywheresoftware.b4a.randomaccessfile.AsyncStreams$AIN.run(AsyncStreams.java:261)
at java.lang.Thread.run(Thread.java:841)
And the program crash
 

Humberto

Active Member
Licensed User
It use "initializeprefix" because the esp8266 expect this initialization mode to receive the message
 

Erel

Administrator
Staff member
Licensed User
Make sure that the ES8266 code also uses AsyncStreams in prefix mode.
 

maleche

Member
Licensed User
Is the serializer a good library to communicate with arduino and b4j?
I need to send x and y coordinates from arduino to b4j.
Just need to understand the new wait for instructions to ensure good data.
Thank you all!
 
Status
Not open for further replies.
Top