Get specific bytes from serial port and the receive 12 bytes more

hi,
At my project I want to receive 4 byte from serial and then start to receive 12byte at the buffer
the bytes that I want to recognize are 02 00 03 00

at the serial port comes any byte but only if these bytes comes then start to receive the 12 bytes more at the BUFFER
then I wait to receive again 02 00 03 00 to start over

thank
kalarakis

Use a 4 byte (circular or just shifting upon reception) buffer to keep getting the incoming bytes. Once the 4 bytes match 02 00 03 00 you know you got the header and can store the next 12 bytes in your payload.

yes,
but how I do that in code?

I would start by programing one Aduino to send a single byte repeatadly with a delay in between.

Then program the receiving Arduino to read bytes from a serial port and print the byte value out in the IDE serial monitor.

give it a try.

I would suggest to study Serial Input Basics to get a good understanding on how to listen asynchronously to the Serial port.

here is a high level structure that would work, I let you write the code to handle the header

const uint8_t payloadLength = 12;
uint8_t payload[payloadLength];

bool getPayload(uint8_t pl[payloadLength]) {
  enum tState : uint8_t {HEADER, PAYLOAD};
  static tState state = HEADER;
  const uint8_t startMarker[] =  {0x02, 0x00, 0x03, 0x00};
  const uint8_t startMarkerLength = sizeof startMarker;
  static uint8_t marker[startMarkerLength] = {0xFF, 0xFF, 0xFF, 0xFF};

  static uint8_t payloadPos = 0;
  bool payloadComplete = false;

  int r = Serial.read();

  if (r == -1) return false;

  switch (state) {
    case HEADER:
      => shift marker[] array left to make space for the new byte at the end
      => insert (uint8_t) (r & 0xFF) at the end of marker array (marker[startMarkerLength - 1] )
      => compare the marker memory with startMarker on startMarkerLength bytes (use memcmp)
      => if match, reset the marker array for next time using memset, set payloadPos at the start of the buffer (payloadPos = 0;) and  change the state (state = PAYLOAD;)
      break;

    case PAYLOAD:
      pl[payloadPos++] = (uint8_t) (r & 0xFF);  // store the new byte
      payloadComplete = (payloadPos >= payloadLength);
      if (payloadComplete) state = HEADER;
      break;
  }
  return payloadComplete;
}

void setup() {
  Serial.begin(115200); Serial.println();
  Serial.println(F("I'm ready!"));
}

void loop() {
  if (getPayload(payload)) {
    Serial.print("Got payload : ");
    for (uint8_t i = 0; i < payloadLength; i++) {
      Serial.print(payload[i], HEX);
      if (isalnum(payload[i])) {
        Serial.write('(');
        Serial.write((char) payload[i]);
        Serial.write(')');
      }
      Serial.write(' ');
    }
    Serial.println();
  }
}

to test this in the Serial monitor, change

  const uint8_t startMarker[] =  {0x02, 0x00, 0x03, 0x00};

into

  const uint8_t startMarker[] =  {'W', 'X', 'Y', 'Z'};

open the Serial monitor at 115200 bauds, set it so that it does not send any end marker and type

GarbageWXYZ0123456789ABGarbageWWWWXYZ0123456789ABenter

and you should see the payload being printed by the loop

I'm ready!
Got payload : 30(0) 31(1) 32(2) 33(3) 34(4) 35(5) 36(6) 37(7) 38(8) 39(9) 41(A) 42(B) 
Got payload : 30(0) 31(1) 32(2) 33(3) 34(4) 35(5) 36(6) 37(7) 38(8) 39(9) 41(A) 42(B) 

Your topic was MOVED to its current forum category as it is more suitable than the original

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