Sending raw binary data

Hello...

I have question how is best to send binary data (structure) over serial.
The data need to be packed as sending is as ascii is to long, and I need some kind of CRC.
So as data is packed there can be CR/LF in data so in that way I can't figure where frame start/end.
Usually I do byte stuffing if data contain CR/LF, but wish to know if Arduino allready have some special library for that.

say you have a struct in variable myStruct and its size fits on a byte

You need to decide your protocol:

if you want to start with two 0xFF bytes followed by the size of the struct

Serial.write(0xFF);
Serial.write(0xFF);
Serial.write(sizeof(myStruct)); // assuming it's less than 255

Then you just send the bytes of the structure Serial.write(&myStruct, sizeof(myStruct));

then it's a matter of adding a trailer to your protocol, if you have a CRC function working on the sum of he bytes on 1 byte, you can callSerial.write(ccc(&myStruct, sizeof myStruct) + sizeof myStruct);

your protocol is then

0xFF 0xFF SIZE_BYTE <PAYLOAD SIZE BYTES> CRC_BYTE

What are you sending the data to? Does the receiving device have a specification for how it expects the data to be formatted? Or is the receiving device a program you have written yourself, and are free to change?

One option is to reserve 3 bytes (say 253, 254 and 255) as special bytes. Use 254 and 255 for start and end markers and use 253 to denote that the next byte is a data byte rather than a marker-byte. For example to send 254 as data you would send 253 254.

Another option is only to send a message when requested by the receiving program. In effect, the request becomes the start marker as far as the receiving program is concerned. The the data could include a byte that identifies the length of the message or the receiving program could assume that the message will all be received within NN millisecs.

...R

Also, if sending binary you need to worry about what kind of architecture is on the other side. If they don't match you need to encode it in some way.

I use a system that uses what what Robin2 said (Master/slave). Mine sends a numBytes byte, then that number of raw data bytes. The master initiates communication and the slave can only reply. Both use the same message layout.

-jim ee

Hello...
Usually (in assembly) I was doing similar to Robin2 says.
I reserved 3 bytes as FrameESC, FrameStart, FrameEnd.
I start frame with FrameStart and end with FrameEnd. But if either of 3 bytes apear in data I exchange it with FrameEsc followed with byte Xored with 0xA5 (may be other)
As I'm new in arduino I just wonder if there are some library to do that or I need to parse each byte of struct and send byte by byte..
Master/Slave is not option as there is realtime data that need to be transfered.

As I'm new in arduino I just wonder if there are some library to do that or I need to parse each byte of struct and send byte by byte..

Parsing the struct byte by byte is literally less than 10 lines of code

byte* structPtr = &myStructure;
Serial.write(FrameStart);
for (size_t i=0; i < sizeof(myStructure); i++)
  if ((structPtr[i] == FrameStart) || (structPtr[i] == FrameEnd) || (structPtr[i] == FrameESC)) {
    Serial.write(FrameESC);
    Serial.write(structPtr[i] ^ 0xA5);
  } else Serial.write(structPtr[i]);
Serial.write(FrameEnd);

not sure it deserves a library..

Hello...
Fell stupid as I can't find how to proper make pointers to work.
(I'm fresh on C but have years on assembly)

struct Txf_struct  {
  uint16_t Voltage;
  uint16_t Zpos;
  uint16_t Zofs;
};

Txf_struct Txf;

const byte FrameStart=0xfa;
const byte FrameEnd=0xfb;
const byte FrameESC=0xfc;




void TxFrame(){
  byte* structPtr = &Txf_struct;
  //Serial.write(FrameStart);
  //Serial.write(FrameEnd);
}

Your struct variable name is Txf so you ask for the address of Txf with &

 byte* structPtr = &Txf;

J-M-L:
Your struct variable name is Txf so you ask for the address of Txf with &

 byte* structPtr = &Txf;

got

test:19:22: error: cannot convert 'Txf_struct*' to 'byte* {aka unsigned char*}' in initialization
byte* structPtr = &Txf;
^~~
exit status 1
cannot convert 'Txf_struct*' to 'byte* {aka unsigned char*}' in initialization

Typed too fast... try with byte* structPtr = (byte*) &Txf;

J-M-L:
Typed too fast... try with

 byte* structPtr = (byte*) &Txf;

That works. Thank you.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.