Compare string of the serial interface using strcmp and Serial.read()

Hello

I wrote a little Arduino code which should switch on a LED by a text typed in the serial console. I have a bug in my code but I can’t find the problem.

Here is my code:

#include <stdio.h>
#include <stddef.h>

void loop() 
{ 
  char inSerial[5];   
  int i=0; 
  delay(1000);
  
  if (Serial.available() > 0) 
  {             
       while (Serial.available() > 0) {
         inSerial[i]=Serial.read(); //read data  
         i++;      
       }
       inSerial[i]='\0';
      Check_Protocol(inSerial);
    }    
};


void Check_Protocol(char inStr[])
{   
  Serial.print("Command: ");
  Serial.println(inStr);
       
  Serial.println("Check_Protocol");
  if(!strcmp(inStr,"ON")) digitalWrite(13,HIGH);
  if(!strcmp(inStr,"OFF")) digitalWrite(13,LOW);
}

But if I type ON in the serial console, it is not detected as equal to ON. The same with OFF. Does anybody see the programming failure?

Thank you in advance.

Felix

Where do you reset i?

What option do you have selected in the Serial Monitor? Are you sending a carriage return and line feed, too? If so, those are stored in inSerial, too.

You also seem to expect that the serial data arrives instantly. It does not. The loop() function can run several hundred thousand times between the time the O arrives and the time the linefeed arrives. Even if you are not sending CR/LF, the loop() function can run several hundred thousand times between the time the O arrives and the time the N arrives.

You need some kind of end-of-packet marker (the CR/LF are fine for this), and you read and store data until the marker arrives. Do not store the marker.

Only test the data in the array when the end marker arrives, then reset the array and index.

Dear Paul

Thank you for your reply. I also found your post about this topic: Arduino Forum

But also your code will not work for me. You asked me, if I am sending \r or \n too. Sorry, but I don't know. Sorry for this question, but is the little menu at the bottom of the Arduino serial monitor to way to decided if I am sending \r and \n? I tested all four possibilities, but your code will not work for me.

Any hint?

I have tried your code, I only changed it to print a message instead of digitalWrite, added setup(), and removed useless includes:

void setup()
{
  Serial.begin(9600);
}

void loop() 
{ 
  char inSerial[5];   
  int i=0; 
  delay(1000);
  
  if (Serial.available() > 0) 
  {             
       while (Serial.available() > 0) {
         inSerial[i]=Serial.read(); //read data  
         i++;      
       }
       inSerial[i]='\0';
      Check_Protocol(inSerial);
    }    
};


void Check_Protocol(char inStr[])
{   
  Serial.print("Command: ");
  Serial.println(inStr);
       
  Serial.println("Check_Protocol");
  if(!strcmp(inStr,"ON")) Serial.println("on");
  if(!strcmp(inStr,"OFF")) Serial.println("off");
}

It's working :slight_smile:

Great.
My fault was, that I send a carriage return with every input text. Now everything is fine.

I hope this code, will also help some other guys.

Thank you so much.

how to modify this to work with carriage return and newline \r\n ?

how to modify this to work with carriage return and newline \r\n ?

Use a text editor. Or post "this".

sorry...
is this correct way ?
i dont have access to arduino at the moment.

if (Serial1.available() > 0) 
  {             
       while (Serial1.available() > 0) {
         inSerial[i]=Serial1.read(); //read data  
         i++;      
       }
       if(inSerial[i]=='\r\n'){  
          Check_Protocol(inSerial);
       }else{
       inSerial[i]='\0';
      Check_Protocol(inSerial);
      }
    }
       if(inSerial[i]=='\r\n'){

SerialRead() only reads one character at a time so inSerial[i] will never contain two characters. You need to test the two consecutive characters to spot them. Something like this

if (inSerial[i] == '\n')
{   
  if (inSerial[i-1] == '\r')
  {
    Check_Protocol(inSerial);
  }
}

Be careful if you try to use use

if (inSerial[i] == '\n' && inSerial[i-1] == '\r')

because on the first iteration inSerial[i-1] will be outside the bounds of the array, but you could use it if you skip the test when i == 0

thanks UKHeliBob
i will try this on tuesday :slight_smile: