Checking sequential bytes in Serial

Please Help!!

I am working with an external serial device that sends out a data packet every 200m secs. The data packet consists of 5 bytes : 0x02, 0x88, 0x31 , 0x00, 0x00 and 0x04.

Byte 0, byte 1 and byte 4 are always the same. In order for me to send this external device a command, I have to replace bytes 3 and 4 and resend the entire 5 byte packet timed about 60 msecs after the device sends a packet.

All seems to be working on my Mega using Serial1 but I found that line noise every now and then gets my receive data out of sequence (out of sync) so I came up with the following code.

I am a beginner and it seems that I am most likely not doing this in the most efficient or fastest manner. Any advice would be greatly appreciated.

void loop (){
  if ((Serial1.available () > 4))  // data packet with 5 bytes sent once every 200 msecs
  {
      receivePacket[0] = Serial1.read();  // check if first two bytes in correct sequence
      if (receivePacket[0]  == 0x02)
      {
        // Get next byte
        receivePacket[1] = Serial1.read();  // check if first two bytes in correct sequence
        if (receivePacket[1]  == 0x88)
        {
          // in sync so get last 3 bytes
          for (int i=2; i < 5; i++)
            {
              receivePacket[i] = Serial1.read();
             }
        }
      }
    
      // FINAL CHECK MAKE SURE THE LAST BYTE == 0X04
      if (receivePacket [4] == 0x04)
      {
        SendToSerial();  // this is where i deal with the commands I want to send back
       }   
    }
  }

There isn't really anything wrong with what you are doing. But, that's not how I'd do it. I'd start storing the data when the 0x02 arrived, and stop storing it after 6 bytes (you can't count, can you?) had been saved. Then, I'd check that the appropriate bytes contained the right data. If not, I'd ignore the whole packet. If so, I'd replace the appropriate bytes and resend.

if (receivePacket [4] == 0x04)

Needs to be

if (receivePacket [5] == 0x04)

Since there are 6 bytes, 0 - 5

Sorry all, it is 5 bytes not 6. I wrote this up too quickly and tried to remember to refer to them starting as byte 0. The 5 bytes are 0x02, 0x88, 0x31 , 0x00, and 0x04. I have to replace the 3rd and 4th (0x31, 0x00) with a two byte "command".

So, your advice is to read in the whole packet first and then check the if the 1st, 2nd and last byte are correct as I am now doing? IS there a faster method to check the entire received array against what is expected, ie. compare two arrays routine? What is the fastest (fewest clock cycles) as I am also looping to check other sensors via I2C.

thanks jerry

IS there a faster method to check the entire received array against what is expected, ie. compare two arrays routine?

memcmp(), IF the two arrays really do contain the same data. For checking 5 elements, you are not going to gain any time, though, as memcmp() still needs to iterate through the array.

You can look for the 1st byte, 0x02. If OK then look for the 2nd byte 0x88. If OK then get the last 3 bytes. like you are doing. Only put it in a function, so you can flag it if it’s OK or not.
Here is an wireless example.

void GetPacket()
{
   Address = 0;
   Command = 0;
   data_in = 0;
   CRC = 0;
   do{
    data_incoming();
   if (data_in > 47 && data_in < 58)  // wait for number 0 - 9
   {Address = data_in;}
      } while(Address == 0);
      
   data_in = 0;

   do{
    data_incoming();
   if (data_in > 64 && data_in <91) // wait for Command A - Z
   {Command = data_in;}   
      } while(Command == 0);

// then get the last 3 bytes      
}

Waits till the 1st two bytes are good. In this example, the first byte MUST be a number 0 -9
The 2nd byte MUST be a letter A - Z
This example will Hang till it’s good, as correct data is better then no data.

Thanks for the code example. Since I am also checking other sensor data in my main Loop, I don't want to have anything hang too long and block. I guess I could either put in a timer or a number of iterations (10?) where if the correct sequence doesnt appear I could 'break' and then flush the serial1 buffer and start within the main Loop() again. Does that sound reasonable?

k1jos: Thanks for the code example. Since I am also checking other sensor data in my main Loop, I don't want to have anything hang too long and block. I guess I could either put in a timer or a number of iterations (10?) where if the correct sequence doesnt appear I could 'break' and then flush the serial1 buffer and start within the main Loop() again. Does that sound reasonable?

or just read a byte each loop() execution if available and process when you have number_of_bytes equal to size_of_yourPacket

Look at Reply#11 in this post: http://forum.arduino.cc/index.php?topic=262658.new;topicseen#new

That's what I am doing in the first line of my Loop() (see first post). However I find that after some period of time all it takes is one bit (no pun) of noise and the sequence gets messed up.

void loop (){
  if ((Serial1.available () > 4))  // data packet with 5 bytes sent once every 200 msecs
  {
   ...
   ...
}

Perhaps a really dumb question but is there any advantage to placing my packet of 5 bytes into a data structure like:

typedef struct {        
  byte Byte0
  byte Byte1
  byte Byte2
  byte Byte3
  byte Byte4
}

Is there a library function that facilitates manipulating and testing the bytes with the structure? I have seen something like this used in the some wireless libraries.

Have you tried the one byte per turn approach? you may have your solution already.

Perhaps a really dumb question but is there any advantage to placing my packet of 5 bytes into a data structure like:

It's not, and no there isn't.

Now, an array would be a different story, but you are already doing that.

Is there a library function that facilitates manipulating and testing the bytes with the structure? I have seen something like this used in the some wireless libraries.

No.