Serial Communication Problem from Arduino Serial Port Monitor

Hi,
I try to communication via Arduino Serial Port to receive and send data. When it comes to Arduino codes, I used to "if / else if" commands to compare data. When I run the program and send data from Serial port for example: "PS,0,0*" or "X,0,0*" , It works for just one time and sends message like "PS" or "X".
When I send the second message from Serial port, It doesn't answer the message and write anything, something like "PS" or "X". Why it may not be running the if loop in the second message? Could you please help me. My codes:

String readString; 
String Header = ""; //data header
int M_Header = 0;//data Mod Header

String data1;
String data2;

int ind1;
int ind2;
int ind3;
int ind4;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

}

void loop() {
  // put your main code here, to run repeatedly:
  if (Serial.available()) {
    M_Header = 0;

    char c = Serial.read();
    if (c == '*')
    {

      ind1 = readString.indexOf(',');  //first index location
      Header = readString.substring(0, ind1);   //captures first data String
      ind2 = readString.indexOf(',', ind1 + 1 ); //finds location of second ,
      data1 = readString.substring(ind1 + 1, ind2 + 1); //captures second data String
      ind3 = readString.indexOf(',', ind2 + 1 );
      data2 = readString.substring(ind2 + 1);

      if (Header == "PS") {
        M_Header = 1;
        Serial.println(Header);
      }
      else if (Header == "S") {
        M_Header = 3;
        Serial.println(Header);
      }
      else if (Header == "X") {
        M_Header = 2;
        Serial.println(Header);
      }


      readString = ""; //clears variable for new input
      data1 = "";
      data2 = "";
      Header = "";
    }
    else
    {
      readString += c; //makes the string readString
    }
  }
}

I would suggest to study Serial Input Basics to understand how to deal with the Serial communication and possibly handle this

Use the methods in Robin2's serial input basics tutorial (linked by @J-M-L ) to read the whole line of serial input then parse the values that you want. Here is a demo using the receive with end marker example. The end marker is changed to '*'. The serial input basics tutorial uses strings so as to avoid the potential memory problems that the String class can cause (see the evils of Strings). Comparison is done with the strcmp() function and parsing is done with the strtok() function.

const byte numChars = 32;
char receivedChars[numChars];   // an array to store the received data

boolean newData = false;

char header[4];
int data_1 = 0;
int data_2 = 0;
int M_Header = 0;

void setup()
{
   Serial.begin(115200);
   Serial.println("<Arduino is ready>  Enter letter header plus 2 integers");
   Serial.println("separated by commas and terminated with a '*', like PS,1,3*");   
}

void loop()
{
   recvWithEndMarker();
   //showNewData();
   if (newData)
   {
      parseData();
   }
}

void recvWithEndMarker()
{
   static byte ndx = 0;
   char endMarker = '*';
   char rc;

   while (Serial.available() > 0 && newData == false)
   {
      rc = Serial.read();
      if(rc == '\r') // ignore carruage return
      {
         return;
      }
      if (rc != endMarker)
      {
         receivedChars[ndx] = rc;
         ndx++;
         if (ndx >= numChars)
         {
            ndx = numChars - 1;
         }
      }
      else
      {
         receivedChars[ndx] = '\0'; // terminate the string
         ndx = 0;
         newData = true;
      }
   }
}

void showNewData()
{
   if (newData == true)
   {
      Serial.print("This just in ... ");
      Serial.println(receivedChars);
      //newData = false;
   }
}

void parseData()
{
   char *strings[3]; // an array of pointers to the pieces of the above array after strtok()
   char *ptr = NULL; byte index = 0;
   ptr = strtok(receivedChars, ",");  // delimiters, comma
   while (ptr != NULL)
   {
      strings[index] = ptr;
      index++;
      ptr = strtok(NULL, ",");
   }
   /*
   //Serial.println(index);
   // print all the parts
   Serial.print("the number of pieces received = ");
   Serial.println(index);
   Serial.println("The Pieces separated by strtok()");
   for (int n = 0; n < index; n++)
   {
      Serial.print("piece ");
      Serial.print(n);
      Serial.print(" = ");
      Serial.println(strings[n]);
   }
   */
   // convert string data to numbers
   strcpy(header, strings[0]);
   data_1 = atoi(strings[1]);
   data_2 = atoi(strings[2]);
   
   Serial.print("header = ");
   Serial.print(header);
   Serial.print("   data_1 = ");
   Serial.print(data_1);
   Serial.print("   data_2 = ");
   Serial.println(data_2);

   if(strcmp(header, "PS") == 0)
   {
      M_Header = 1;
   }
   else if(strcmp(header, "S") == 0)
   {
      M_Header = 3;
   }
   else if(strcmp(header, "X") == 0)
   {
      M_Header = 2;
   }
   else
   {
      Serial.print("invalid input");
      M_Header = 999;
   }
   Serial.print("M_Header = ");
   Serial.println(M_Header);
   Serial.println(); // blank line
   newData = false;
}

Thanks for your reply @J-M-L @groundFungus.
You have explained clearly. I try to run your codes, but I have same problem again as you can see this image from serial port monitor. It can't read the second data and gives the "invalid input".

I think the problem may be because of another something, not because of software. But I don't have any idea for now.

Don’t send the new line (yeni satir) in the serial monitor settings.
Choose "none" as your star is the end marker

Dear @J-M-L thank you so much, I didn't relaize this detail :frowning:
Now it is Okay :ok_hand: