Read Serial hex data into an array

This is not my first post, but could not log in with previous email.

I have searched everywhere and tried umpteen variations of my code. I assume I have a fundamental misunderstanding of arrays, as I can't even print what I am expecting. I have tried using char and byte

I am receiving a string of 5 bytes in hex and I simply want to do something. Different strings of 5 bytes will evoke different functions in code. Usually just the last byte changes, but not always.

I simply want to check for the arrival of a sting in my main loop and if received, go do something, clear the buffer. Another command, do other task, clear the buffer.

I've been allocating myself an hour or 2 per day and also setting a 'goal'. I research as much as I can leading up my one or two hours. Once reaching my goal, I walk away and - for the most part - it's been working really well. But this one has me stumped.

Any help greatly appreciated.

void setup() {
  // put your setup code here, to run once:
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(19200);
};
byte DataStream [5] ;
byte StartCode[5] = {
  0x32,
  0x29,
  0x86,
  0x15,
  0x15,
};
byte StopCode[5] = {
  0x32,
  0x29,
  0x86,
  0x15,
  0x1A,
};
void loop() {

  while (Serial.available () < 5)
  {}
  for (byte i = 0 ; i < 5 ; i++)
    DataStream[i] = Serial.read(); 

Serial.println(DataStream[5]);

//if (DataStream[5]=StartCode[5]){
//  TurnOnLED();}

//if (DataStream[5]=StopCode[5]){
//  TurnOffLED();}

void TurnOnLED(){
digitalWrite(LED_BUILTIN, HIGH); //I want to do something here
// DataStream="";
}

void TurnOffLED(){
digitalWrite(LED_BUILTIN, LOW); //I want to do something here
// DataStream="";
}

The memcmp function?

I know you've commented this code out, but if you are comparing values, then it's == rather than =.

You should also have a read of the serial input basics tutorial here in the forums. It might help you in retrieving data from the serial port. Your code as it stands can easily get out of sync with the sender.

Oh, and take note of what @anon56112670 just said below.

...and a five element array does not have an element with the index 5.

Thank you - nothing else seemed to work - I tried 0 through to 4

Inline with your first suggestion I added;

 if (memcmp(DataStream, StartCode, sizeof(DataStream)) == 0) {
    Serial.println("Arrays are equal");
  }

and changed "StartCode" to
0x01
0x02
0x03
0x04
0x05
It compiled, but did not print the output when that string received

Also with no index, it will not compile.

"Compilation error: no matching function for call to 'println(byte [5])'"

With any other index - 0,1,2,3,4 it also will not compile.

Hi Mark, and thank you. I have done a thorough read of the serial input basics a couple of times and just feel I am even deeper down the hole. No matter what I try - I can't even 'print' my variables to try to ascertain where I am going wrong.

Are you saying you can't print a single element of an array?
Can you show a concrete example?

I am saying that I accept what you are saying that I can not have [5] indexing an array of 5, but absolutely nothing else works. The concrete example was the code above.

Tried a completely different approach and still can not get anywhere. I am changing from ascii to hex and back again and

const unsigned int MAX_MESSAGE = 5;

void setup() {
  // put your setup code here, to run once:
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(19200);
};
byte DataStream[5];
byte StartCode[5] = {
  1,
  2,
  3,
  4,
  5,
};
byte StopCode[5] = {
  0x01,
  0x02,
  0x02,
  0x11,
  0x1A,
};
void loop() { 
static char message[MAX_MESSAGE];
   static unsigned int message_pos = 0;
  //Check to see if anything is available in the serial receive buffer
 while (Serial.available() > 0 && message_pos <= MAX_MESSAGE)
 {
   //Create a place to hold the incoming message
   //Read the next available byte in the serial receive buffer
   char inByte = Serial.read();
   //Message coming in (check not terminating character) and guard for over message size
   if ((message_pos <= MAX_MESSAGE - 1) )
   {
     //Add the incoming byte to our message
     message[message_pos] = inByte;
     message_pos++;
   }
   //Full message received...
   else
   {
     //Add null character to string
     //message[message_pos] = '\n';

     //Print the message (or do other things)
     Serial.println(message);

     if (message == '12345'){
       digitalWrite(LED_BUILTIN, HIGH);
     }

     //Reset for the next message
     message_pos = 0;
   }

    if (memcmp(message, StartCode, sizeof(message)) == 0) {
    Serial.println("Arrays are equal");
    }

  if (DataStream==StartCode){
  digitalWrite(LED_BUILTIN, LOW);
  }

  if (DataStream == StopCode){
digitalWrite(LED_BUILTIN, LOW);
  }
}
}

That's not what you think it is
Forget you ever saw such a thing.

Yeah - just clutching at straws now.

Perhaps start with the basics. I assume that those byte are in ASCII hex such that the decimal value 17 is sent as the ASCII characters '1' & '1'. What separates each value? Is it a space, a comma, nothing etc. What terminates the string of bytes? Is it carriage return / line feed? Is the first byte always the same value?

Perhaps knowing about the format of the data you are trying to read in would help to provide a direction to head in and/or a solution.

When viewed with a Salae logic analyzer I see packets of 0x01 0x02 0x02 0x11 0x1A (for example) @ 19200, 8N1, no commas, no spaces, no line feed. I have successfully written code to simulate the transmitting device, but as I type this to you now, I suddenly realise that is 5 words and not 5 bytes? - noobie error :frowning:

NO, that's five bytes alright. That information would have been so useful in post#1, now we should be able to get somewhere.
However, stick with the logic analyzer for a minute. Is that the complete transmission? Does the source go silent then for a period of time? Can you tell if, across many such emissions, either a lead or trailing byte is consistent? That might establish a framing.

I guess, your intention was something like

for( const byte& b: DataStream ) { // with all bytes of DataStream 
  Serial.print(b, HEX); Serial.write(' ');
} Serial.println();

Actually - it was there in my first post in the form of one of two arrays I had setup to 'compare' to. See below. I was changing the bytes around later to 0x01 etc. to experiment with.

That is the complete transmission and I can reliably repeat it. I have more testing to do, but so far the first byte is consistent, but the last byte is changing. There can't be more than a handful of commands, so my assumption is they are sending 5 bytes as a kind of 'insurance' from a false trigger - ie; we have to have 5 bytes for a good command, now what is the last one?

Getting late here, but I will setup the circuit again tomorrow and try to sniff out any other commands, but for now I am happy to assume 5 bytes with the first remaining consistent.

Hi Michael,

I will try this tomorrow - Thank you!

No. That is start and end of transmission. The device sends a 'start' signal and then a 'stop' signal.

No. That is start and end of transmission. The device sends a 'start' signal and then a 'stop' signal.

That is conflicting information. If you have a start and end signal, then you have complete control over the interpretation of the five bytes, no need for guessing about start and end bytes.