Zac
Zac

Reputation: 2279

Arduino : Check byte array for chars one at a time

I communicate with Arduino via Serial using a program that sends a series of bytes.

In order for the Arduino to realize it is receiving a message rather than junk, I have tagged the start of my byte array with the chars 'S' 'T' 'A' 'R' 'T'. After this will eventually follow a series of bytes that will be assigned to internal variables (not yet implemented).

The Arduino must read each byte sequentially and compare it to the byte array and if all are present in the correct order it will continue with the next part of the program, otherwise it will should discard current byte and wait for more bytes to arrive.

I am trying to implement it in the most efficient and readable way rather than using a series of nested if statements.

So far I have got:

byte inByte = 0;
byte handShake[] = {'S','T','A','R','T'};

void setup() {
  Serial.begin(9600);

}

void loop() 
{
  while (Serial.available()) 
{
  for (int x =0; x < sizeof(handShake) ; x++)
    {
    inByte = Serial.read();
    Serial.println(x);
    if (inByte == handShake[x]) 
     {
        if (x == (sizeof(handShake)-1)) {setArduino();}  
      }
       else break;
   }
  }
}


void setArduino () {
  Serial.println("Ready To Set Parameters");
}

This however doesn't seem to get past the second byte and I'm not sure why.

Upvotes: 0

Views: 7205

Answers (3)

Martynas
Martynas

Reputation: 627

You could try to calculate your message. CRC is old and good solution. I use it and it works perfect for me. I am not sure what kind of device are you communicating with.

//define
const uint32_t Polynomial = 0xEDB88320;
const uint16_t NumBytes = 256;
uint8_t data[NumBytes];

/// compute CRC32
uint32_t crc32_bitwise(const void* data, uint16_t length, uint32_t previousCrc32 = 0)
{
  uint32_t crc = ~previousCrc32; // same as previousCrc32 ^ 0xFFFFFFFF
  uint8_t* current = (uint8_t*) data;

  while (length--)
  {
    crc ^= *current++;
    for (uint8_t j = 0; j < 8; j++)
    {
      uint8_t lowestBit = crc & 1;
      crc >>= 1;
      if (lowestBit)
        crc ^= Polynomial;
    }
  }
  return ~crc; // same as crc ^ 0xFFFFFFFF
}
void setup() {
  // put your setup code here, to run once:    
}

void loop() {
  // put your main code here, to run repeatedly:    
}

when you need to calculate CRC

uint32_t crc = crc32_bitwise(data_bytes, sizeof(data_bytes));

data_bytes is byte array.

Then you can get all settings or message in byte data[x] and calculate CRC. Then you can add CRC to the message and send message byte data[x+sizeof(CRC)]

P.S. Use byte instead of int. For ex. for(byte x =0; x<sizeof(handShake); x++)

Upvotes: 0

Zac
Zac

Reputation: 2279

Better answer : This allows the rest of the loop to iterate while waiting for the message to finish and if the full handshake message isn't received the counter will reset.

byte inByte = 0;
char handShake[] = {'S','T','A','R','T'};
int messageIndex = 0;

void setup() {
  Serial.begin(9600);

}

void loop() 
{
  while (Serial.available()) 
  {
    inByte = Serial.read();
    Serial.println(messageIndex);
    if (inByte == handShake[messageIndex]) 
      {
        messageIndex++;
        if (messageIndex == sizeof(handShake)) {messageIndex = 0; setArduino();}  
      }
       else {messageIndex=0;}
  }
// Other code while waiting for message to finish
Serial.println("tick");
}


void setArduino () {
  Serial.println("Ready To Set Parameters");
}

Upvotes: 1

Zac
Zac

Reputation: 2279

Worked it out :

Here is the answer:

byte inByte = 0;
char handShake[] = {'S','T','A','R','T'};

void setup() {
  Serial.begin(9600);

}

void loop() 
{
  while (Serial.available()) 
  {
  for (int x =0; x < sizeof(handShake) ; x++)
    {
    inByte = Serial.read();
    Serial.println(x);
    if (inByte == handShake[x]) 
      {
       if (x == (sizeof(handShake)-1)) {setArduino();}  
       while(!Serial.available()) {delay(1);}
      }
       else {break;}
    }
  }
}


void setArduino () {
  Serial.println("Ready To Set Parameters");
}

This may not be the most efficient way perhaps, but I can't see a problem with it currently.

Upvotes: 1

Related Questions