My arduino program for automotive use will receive a fixed size packet over serial at a fixed interval (maybe every 100 ms). It will always have the same size and format:
Packet:
< byte 1, byte 2, byte 3, byte 4 >
byte 1 = pedal % (0 to 100)
byte 2 & 3 = engine RPM (0 to 10000)
byte 4 = gear (1-15)
My question is, how should a fixed size packet be constructed to be sent over serial? Or more specifically, how do you read the contents of a single packet without getting mixed up between the start/end markers and packet data of the same value?
For example, say a struct packet is being sent from a visual C# interface to the arduino:
struct controllerPacket {
char startMarker;
uint8_t pedalPos;
uint16_t engRPM;
uint8_t gear;
char endMarker;
};
controllerPacket packet = { '<', 62, 4500, 3, '>' };
// hex conversion = { 3C, 3E, 11, 94, 03, 3E }
So as you read bytes from incoming serial you find the start marker, '<' (hex 3C), but then find the end marker '>' (hex 3E) as the next byte, even though the hex 3E is really part of the data and signifies 62% pedal. My first thought was to do:
if (Serial.available >= 6) // take 6 bytes as a packet, check for start/end markers and process data
My issue with that is what if a byte gets lost or missed and the 6 byte packet you read no longer lines up with the data and then you lose data from the packet:
{ 3C, 3E, 11, 94, 03, 3E } missed byte, take another 6 bytes ---> { OLDBYTE, 3C, 3E, 11, 94, 03} **lost end marker
Even if you are just reading bytes waiting for '<' and then counting until 6 bytes have filled your packet, how would you prevent reading a '<' in the data and have a bad starting byte position?