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

Status
Not open for further replies.
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

  • B4RSerializator.bas
    4.9 KB · Views: 3,290
  • B4R_Server.zip
    1.1 KB · Views: 3,267
  • B4A_Client.zip
    10 KB · Views: 3,311
Last edited:

Mostez

Well-Known Member
Licensed User
Longtime User
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

Well-Known Member
Licensed User
Longtime User
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
 

Mostez

Well-Known Member
Licensed User
Longtime User
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

B4X founder
Staff member
Licensed User
Longtime 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
Longtime 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
Longtime 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.
 

ma7tin

Member
Licensed User
How to check after receiving data if object into array is a String ?
 

Humberto

Active Member
Licensed User
Longtime 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
Longtime User
It use "initializeprefix" because the esp8266 expect this initialization mode to receive the message
 

maleche

Active Member
Licensed User
Longtime 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