Serial.read() and for loop problems

Hi,

I am still struggling to parse chars from the serial buffer into a couple of char arrays.

The principle is to find a fixed length packet of characters in the serial buffer contained within unique headers and footers (in the case ‘q’ and ‘w’ to help me decode using a keyboard). If i find a packet that fits these constraints i strip the first 3 bytes out to an array called cmd and the next 4 bytes out to an array called data.

The code spots the packet in the buffer, i then want to see the contents of each array on the serial monitor to cross check the results. Here i find that cmd is 9 bytes long and contains all of the packet plus some garbled extras and data is 6 bytes long and contains the data part of the packet and some garbled extras. Cmd and data array sizes have both been declared as 3 and 4 bytes wide respectively.

Help much appreciated, i have been struggling with this for quite some time :-/, there must be something fundamental in my code. I have tried this in many different ways using strncpy, atoi, not in a for loop etc etc with the same/similar result.

Full code:

//Character arrays
char cmd[3], data[4];

//Chip Setup
void setup(){
  Serial.begin(9600);
  while(!Serial);
}

void loop(){
  
  if(serialEvent()){    
    if(cmd=="OPM"){
      Serial.println("Yay");
      Serial.print("data=");
      Serial.println(data);
    }
    else{
      Serial.println("Nay");
      Serial.print("cmd=");
      Serial.println(cmd);
      Serial.print("data=");
      Serial.println(data);
    }
  }
  else{
    Serial.println("No data or corrupt packet");
  }  
  delay(2000);
  
}

boolean serialEvent(){

 boolean msg_ok=false;
  
  if(Serial.available()){                       
    if(Serial.find("q")){
      for(int i=0; i<8; i++){
          if(i<3){
            cmd[i]=Serial.read();
          }
          else if(i>=3 && i<7){
            data[i-3]=Serial.read();
          }
          else if(i==7){
              if(Serial.read()=='w'){
                msg_ok=true;
              }
              else{
                msg_ok=false;
              }
          }
        }
      }
    }
  return msg_ok;
}

The results on the monitor when sending “qOPM0001w” and “qSTS1234w”:

No data or corrupt packet
No data or corrupt packet
Nay
cmd=OPM0001|(
data=0001|(
No data or corrupt packet
No data or corrupt packet
No data or corrupt packet
Nay
cmd=STS1234G
data=1234G
No data or corrupt packet
No data or corrupt packet

You're printing a not-null-terminated C-string, which results in printing any of the following bytes in memory until it reaches a null bytes by chance. Extend your string size by one byte and insert a null byte there, it will probably work.

If you know the length of the array you can use Serial.write(data, len) and you won't need to add null bytes.

...R

Simple serial code that may have some of the operations you are looking for.

//zoomkat 3-5-12 simple delimited ',' string parse 
//from serial port input (via serial monitor)
//and print result out serial port
//send on, or off, from the serial monitor to operate LED

int ledPin = 13;
String readString;

void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT); 
  Serial.println("serial LED on/off test with , delimiter"); // so I can keep track
}

void loop() {

  if (Serial.available())  {
    char c = Serial.read();  //gets one byte from serial buffer
    if (c == ',') {
      Serial.println(readString); //prints string to serial port out
      //do stuff with the captured readString
      if(readString.indexOf("on") >=0)
      {
        digitalWrite(ledPin, HIGH);
        Serial.println("LED ON");
      }
      if(readString.indexOf("off") >=0)
      {
        digitalWrite(ledPin, LOW);
        Serial.println("LED OFF");
      }       
      readString=""; //clears variable for new input
    }  
    else {     
      readString += c; //makes the string readString
    }
  }
}
    if(cmd=="OPM"){

The address of an array will NEVER equal that string literal.

strcmp() suggests itself...

Thanks everyone for your replies. So, I'm assuming that for an array of characters to be treated properly as a string in c it must have '\0' in the last element. Without this string functions will not return the expected results.

Paul, you are infering that the value of cmd is the memory address of the first element of the array, correct?

On a related note, I am used to working in VHDL where you can address a parts of an array, for example an array 8 bits wide, parts of the array can be referenced in the following way array[7 downto 4] for example looking at the first four bits of the array.

How is this done in c?

So, I'm assuming that for an array of characters to be treated properly as a string in c it must have '\0' in the last element. Without this string functions will not return the expected results.

Correct.

Paul, you are infering that the value of cmd is the memory address of the first element of the array, correct?

No. I inferred nothing. I stated, as a fact, something. The array name, as you are using it, refers to the memory location where the data is stored. In that context, the array name is a pointer. The address that it points to can never be "OPM".

for example an array 8 bits wide

The smallest memory unit on the Arduino is a byte, which is 8 bits wide. You can not have bit-sized arrays in C.

PaulS:

So, I’m assuming that for an array of characters to be treated properly as a string in c it must have ‘\0’ in the last element. Without this string functions will not return the expected results.

Correct.

Paul, you are infering that the value of cmd is the memory address of the first element of the array, correct?

No. I inferred nothing. I stated, as a fact, something. The array name, as you are using it, refers to the memory location where the data is stored. In that context, the array name is a pointer. The address that it points to can never be “OPM”.

for example an array 8 bits wide

The smallest memory unit on the Arduino is a byte, which is 8 bits wide. You can not have bit-sized arrays in C.

Paul, do you mean to come across as an obnoxious arrogant individual?

You obviously have some expertise, delivering it in a manner that doesn’t infer idiocy in the person you are trying to help is something you should consider.

If you suffer from aspergers, please take this as constructive criticism.