Detect String in a XBEE frame

Hello,

I'm working with 2 XBEEs : one master and one slave.
Master send a frame which is read by slave.

With the master, i send a frame with XCTU.
This frame construction is detailed in attachments : "Frame_XCTU".

In this frame i send, there is a "Strt" which has to be detected by the other XBEE module (slave).

I store all the frame received in a String and then search for "Strt" with the indexOf function.

When I print the frame received, i see that "Strt" is read. But the result of indexOf is "-1", so it can't find the word in the frame received ...
You can also find the printed results in attachment : "Serial_Results".

Could it be linked to the format of the frame ?
I feel like it could be due to the "RF Data" part in my frame construction ... (cf Frame_XCTU)

Here is my code :

#include <SoftwareSerial.h> 

#define RXPIN 0 // Arduino Pin for Reception
#define TXPIN 1   // Arduino Pin for Transmission

SoftwareSerial xbee(RXPIN,TXPIN);  // link virtual serial between xbee and arduino


/* Communication */
int i,found ;
String frame = ""; //sent to the other XBEE
String state_start=""; //for start
String received=""; //received from the other XBEE
char c; //byte received

void setup() {
  
  Serial.begin(9600); //opening serial with 9600 baud
  
  /* XBee Initialisation */
  while(!Serial)
  { ; } //waiting for Serial Port
  xbee.begin(9600); // opening serial xbee with 9600 baud
  
  Serial.println("Arduino is ready"); //serial link activated
}

void loop() {

//Waiting for the Start of Pi
if(state_start=="Strt"){

   Serial.println("Start received ! ");
   Serial.println("Data ready to be sent !");

}
   
else {
    state_start="";
    received="";

    xbee.flush(); //clear out
    c=xbee.read();
    
    //Start Delimiter Detected
    if (c==0x7E) {
       received.concat(c);
       for (i=0;i<16;i++) {
        c=xbee.read();
        Serial.println(c);
        Serial.println(c,HEX);
        received.concat(c); 
       }
   
    Serial.println(received);
    
    found = received.indexOf("Strt"); //detect "Send" and return index

    Serial.print("With indexOf : ");
    Serial.println(found);
    
    if (found != -1) { 
      state_start="Strt"; }

    }
} }

#define RXPIN 0 // Arduino Pin for Reception
#define TXPIN 1   // Arduino Pin for Transmission

SoftwareSerial xbee(RXPIN,TXPIN);  // link virtual serial between xbee and arduino

Pretty silly to be doing software serial on the hardware serial pins.

  Serial.begin(9600); //opening serial with 9600 baud

Pretty stupid to think you can do it at the same time you are doing hardware serial on those pins.

    xbee.flush(); //clear out

The flush() method blocks until the outgoing buffer is empty. How is THAT useful?

    //Start Delimiter Detected
    if (c==0x7E) {
       received.concat(c);
       for (i=0;i<16;i++) {

Just because the start delimiter has arrived does NOT mean that there are 16 more bytes in the buffer to be read.

You MUST make sure you actually read something USEFUL before adding it to the String.

    found = received.indexOf("Strt"); //detect "Send" and return index

That is NOT what that code does.

You really should NOT be using Strings.

Thank you for your answer !

If SoftwareSerial isn't not ok for XBEE, shall i just use Serial ?

Just because the start delimiter has arrived does NOT mean that there are 16 more bytes in the buffer to be read.

I actually send 13 bytes. And when i display what is received, i see the whole frame.

You really should NOT be using Strings.

Can Arrays be appropriated to store bytes from the frame ?

If SoftwareSerial isn't not ok for XBEE, shall i just use Serial ?

SoftwareSerial IS OK. You just can't do software serial on the same pins you are doing hardware serial on, any more than you can put two feet in one shoe.

I actually send 13 bytes.

Oh. Well, that explains why you think you can read 16 bytes, without ever checking that there IS anything to read.

Can Arrays be appropriated to store bytes from the frame ?

Yes.

I don't know if it matters but i'm using an XBEE shield with a switch USB/XBEE to avoid trouble with pins 0 and 1.

I change the code in order to check IF there IS anything to read.
Also I use an array to store data : char res[13].

But I still have trouble to find the word "Strt" in the data received ...

void loop() {

if(state_start=="Strt"){

   Serial.println("Start received ! ");
   Serial.println("Data ready to be sent !");

}
   
else {
    state_start="";

    if (xbee.available()>0) {
      c=xbee.read();
    
      //Start Delimiter Detected
      if (c==0x7E) {
       res[0]=c;
       for (i=1;i<13;i++) { 
        c=xbee.read();
        Serial.println(c,HEX);
        res[i]=c;
       }
      }

      for(i=0;i<13;i++) {
        Serial.print(res[i]);
      }
      
     Serial.println("");

     found = StrContains(res,"Strt");
     Serial.print("Found ? ");
     Serial.println(found);
     // 0 not found
     // 1 found
    
     if (found ==1) {
      state_start="Strt";
      }
    }

   else { Serial.println("Not available"); }
    
  }

}

The function StrContains is :

char StrContains(char *str, char *sfind)
{
    char found = 0;
    char index = 0;
    char len;

    len = strlen(str);
    
    if (strlen(sfind) > len) {
        return 0;
    }
    while (index < len) {
        if (str[index] == sfind[found]) {
            found++;
            if (strlen(sfind) == found) {
                return 1;
            }
        }
        else {
            found = 0;
        }
        index++;
    }

    return 0;
}
      //Start Delimiter Detected
      if (c==0x7E) {
       res[0]=c;
       for (i=1;i<13;i++) {
        c=xbee.read();
        Serial.println(c,HEX);
        res[i]=c;
       }

If the byte that you happened to read is the start marker, you STILL read 13 bytes, EVEN IF THERE IS NO DATA TO READ.

When you stop doing that, you will have a chance of having parse-able data.

Apparently the problem came from the 0 (option field before my data) which is a delimiter of end chain. When using "indexOf" the function is searching characters before the 0.

So I split the entire frame stored in String in two parts.
The first 8 characters in one part and the rest in another part.
Then I apply the indexOf function on the second part and now i detect properly the word i wanna find.