How to check if a string is on the serial port ??

OK ive got modem that will be outputing data to my arduino .

Example I want to turn an led on if “LED_ON” is sent over serial port. i also need the buffer to clear on every CR , so it will ignore incorrect strings and reset.
Because the messenger method works if you type some incorrect string in it seems to stop it working untill you reset . Im guessing is the buffer needs to be reset after each CR.

Ive found two way of doing this both with their problems , Can anyone help me to have a working one ?

Code 1 , I found this example of reading the data into a serial buffer , but i cant get it to check if the string is in the buffer .

#define STRLEN 16

char buffer[STRLEN];
int  bufferIndex = 0;

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

void loop()
{
  if( Serial.available())
  {
    char ch = Serial.read();
    if( ch == '\r')  // is this the terminating carriage return
    {
      buffer[ bufferIndex ] = 0; // terminate the string with a 0      bufferIndex = 0;  // reset the index ready for another string
      // do something with the string


if (buffer =="LED_ON"){               // THIS IS WHAT I PUT IN  IT DOESNT WORK!

  Serial.println("led on");
}



    }
    else
      buffer[ bufferIndex++ ] = ch; // add the character into the buffer
  }
}

Code 2

This a Messenger’s library checkString method , it work really well but if i send something other than the set commard say some random text it confuses it untill you reset it. It seems like it only clears the buffer after a match ect.

I need it to except other strings and only turn the led on when “on” is sent.

// This example demonstrates Messenger's checkString method
// It turns on the LED attached to pin 13 if it receives "on"
// It turns it off if it receives "off"


#include <Messenger.h>


// Instantiate Messenger object with the message function and the default separator 
// (the space character)
Messenger message = Messenger(); 


// Define messenger function
void messageCompleted() {
  // This loop will echo each element of the message separately
  while ( message.available() ) {
    if ( message.checkString("on") ) {
      digitalWrite(13,HIGH);
    } else if ( message.checkString("off") ) {
      digitalWrite(13,LOW);
    }
  }
  
  
}

void setup() {
  // Initiate Serial Communication
  Serial.begin(115200); 
  message.attach(messageCompleted);
  
  pinMode(13,OUTPUT);
  
}

void loop() {
  
  // The following line is the most effective way of 
  // feeding the serial data to Messenger
  while ( Serial.available() ) message.process( Serial.read() );


}

Any help or examples would be great , thanks for reading

Luke

In the first code, you are collecting the characters read from the serial port into an array, and properly NULL terminating the string. This is all good.

The problem is with the comparison. The == operator needs like objects, not arrays of objects, on either side.

To compare strings, the strings needs to be NULL terminated (as yours are), and you need to use the strcmp function:

if(strcmp(buffer, "LED_ON") == 0) // If strcmp returns 0, the strings match
{
   // Turn the LED on
}

cheers paul , ive just tried it and it works !

thanks for your help .

i can now operate things using commards

But im still getting the problem , that if i send "led_on" it works but if i send "DDDDDDFFHSH"...ect next time i type "led_on" it wont work .

Why is this ?

luke

Once you process the command, you need to reset the contents of buffer:

buffer[0] = '\0';

Otherwise, the new data just gets tacked onto the end of the string that was known to be a valid command.

I tried that didnt work too well , may have been something ive done.
but i got it working by looping the buffer . By no means this is the correct method of doing it but it kinda works.

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

void loop()
{
if( Serial.available())
{
char ch = Serial.read();
if( ch == ‘\r’) // is this the terminating carriage return
{
//buffer[ bufferIndex ] = 0; // terminate the string with a 0 bufferIndex = 0; // reset the index ready for another string
bufferIndex = 0;

/

if (strcmp (buffer,“LED_ON”) == 0) {
//perform relevant action here
Serial.println(“led on”);

// buffer[0] = ‘\0’;
}

for (i=0; i<=20; i++){

buffer = ‘\0’;

}

  • }*
  • else*
  • buffer[ bufferIndex++ ] = ch; // add the character into the buffer*
  • }*
    }

This is your code for what happens after the carriage return is received, cleaned up, properly indented:

if( ch == '\r')  // is this the terminating carriage return
{
   [glow]//[/glow]buffer[ bufferIndex ] = 0;
   bufferIndex = 0;

   if (strcmp (buffer,"LED_ON") == 0)
   {
     //perform relevant action here
     Serial.println("led on");

     // buffer[0] = '\0';
   }

   for (i=0; i<=20; i++)
   {
     buffer[i] = '\0';
   }
}

The commented out line to NULL-terminate the array needs to be un-commented. The array needs to be properly terminated in order for strcmp to work.

The (commented out) code to set buffer[0] to NULL is in the wrong place. That code is executed only if the string in buffer is “LED_ON”. The loop to set every position in buffer to NULL is unnecessary (but is where the code to set buffer[0] to NULL should be).

Suppose you send “LED_ON\r” to the serial port. The string is read, the \r is recognized and buffer contains LED_ON, so the LED is turned on, and buffer is “emptied”. Great.

Supposed you send “CAMERA_ON\r” to the serial port. The The string is read, the \r is recognized and buffer contains CAMERA_ON. This does not match any strcmp strings, so nothing happens, but the buffer is not “emptied”.

If you send LED_ON\r again, the string is read, the \r is recognized and buffer contains CAMERA_ONLED_ON. Now, this doesn’t match LED_ON.

It’s important to always “empty” the array (using buffer[0] = ‘\0’:wink: regardless of whether the contents of buffer were recognized, or not.

Thanks again paul for explaining it , kinda makes sense now .

starting to see reading serial port isnt as easy as it sounds.

i have one very last question now after looking at the modem using a serial sniffer software the commard i want would be received

LED_ON

Will my code need a complete redesign to make this work ?

Will my code need a complete redesign to make this work ?

No. Decide whether the trigger to perform the action will be the or the .

if( ch == '\r')  // is this the terminating line feed
{

or

if( ch == '\n')  // is this the terminating carriage return
{

Then, don’t store the other value in the array. Change:

   else
     buffer[ bufferIndex++ ] = ch; // add the character into the buffer

to:

   else
     if(ch != '\r' && ch != '\n')
       buffer[ bufferIndex++ ] = ch; // add the character into the buffer