Go Down

Topic: Compare string of the serial interface using strcmp and Serial.read() (Read 13522 times) previous topic - next topic

FelixGroup

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:
Code: [Select]


#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

PaulS

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.

FelixGroup

Dear Paul

Thank you for your reply. I also found your post about this topic: http://arduino.cc/forum/index.php/topic,45629.0.html

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?


guix

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

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 :)

FelixGroup

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.

psyazax

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

PaulS

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

Use a text editor. Or post "this".

psyazax

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

Code: [Select]


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);
      }
    }


UKHeliBob

Code: [Select]
       if(inSerial[i]=='\r\n'){ 
SerialRead() only reads one character at a time so
Code: [Select]
inSerial[i] will never contain two characters.  You need to test the two consecutive characters to spot them.  Something like this
Code: [Select]
if (inSerial[i] == '\n')
{   
  if (inSerial[i-1] == '\r')
  {
    Check_Protocol(inSerial);
  }
}


Be careful if you try to use use
Code: [Select]
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
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

psyazax


Go Up