Odd if condition behavior

Hi, I am still new to the Arduino programming language, I have encounter some odd behavior in the following code that I can't understand why it functions in this way, and was hoping someone would be able to clear things out for me.

void setup()
 {
  Serial.begin(9600); // setting the serial port speed to 9600
  pinMode(13, OUTPUT); // declaring pin 13 as an output
 }

 char letter;
 
 void loop()
 {
   if(Serial.available()>0)
   {
     letter = Serial.read();
   }
     if(letter == 'a')
     {
       digitalWrite(13, HIGH);
     }
   else if (letter == 'b')
   {
     digitalWrite(13, HIGH);
     delay(500);
     digitalWrite(13, LOW);
     delay(500);
   }
   else 
   {
     digitalWrite(13, LOW);
   }
   
 }

so in the previous code when you press 'a', the LED turn ON and if you press any other letter except b
the LED keeps being ON. While if you press 'b' , the LED will blink and if you press any letter except 'a' the LED will turn OFF.

I don't understand why the LED keeps its condition in case of 'a' when pressing any other letter but doesn't keep its condition in 'b' when pressing any other key.

My advice is to add some Serial.println() to your code and then watch the output in Serial Monitor so you can understand what is happening.

   if(Serial.available()>0)
   {
     letter = Serial.read();
   }

You close the if() too soon

Menna_Ali:
so in the previous code when you press 'a', the LED turn ON and if you press any other letter except b
the LED keeps being ON. While if you press 'b' , the LED will blink and if you press any letter except 'a' the LED will turn OFF.

Are you sure? That's not how it works for me. Using SerialMonitor with line ending set to "No line ending" I get this behavior:
send 'a': light turns on
send 'b': light starts blinking and continues to blink
send any other character: light turns off
That is what the sketch is telling it to do and that is what it does on my Arduino UNO.

If the line ending is set to Newline, 'a' turns the light on very briefly and 'b' blinks once. Because Newline is neither 'a' nor 'b' it turns the light off when it is received.

johnwasser:
Are you sure? That's not how it works for me. Using SerialMonitor with line ending set to "No line ending" I get this behavior:
send 'a': light turns on
send 'b': light starts blinking and continues to blink
send any other character: light turns off
That is what the sketch is telling it to do and that is what it does on my Arduino UNO.

If the line ending is set to Newline, 'a' turns the light on very briefly and 'b' blinks once. Because Newline is neither 'a' nor 'b' it turns the light off when it is received.

yes, but let me simplify more the behavior I am talking about, if you write the following code:

void setup()
 {
  Serial.begin(9600); // setting the serial port speed to 9600
  pinMode(13, OUTPUT); // declaring pin 13 as an output
 }

 char letter;
 
 void loop()
 {
   if(Serial.available()>0)
   {
     letter = Serial.read();
   }
     if(letter == 'a')
     {
       digitalWrite(13, HIGH);
     }
   
 }

the LED turns ON when you send 'a', and if you press any other letter it won't turn OFF, it will still be ON.
but if you write the following code:

void setup()
 {
  Serial.begin(9600); // setting the serial port speed to 9600
  pinMode(13, OUTPUT); // declaring pin 13 as an output
 }

 char letter;
 
 void loop()
 {
   if(Serial.available()>0)
   {
     letter = Serial.read();
   }
     if(letter == 'a')
     {
       digitalWrite(13, HIGH);
       delay(500);
       digitalWrite(13, LOW);
       delay(500);
     }
   
 }

when you send 'a' it will blink the LED, but if you send any other letter it will stop blinking. which is unlike the first code where sending any other letter does nothing.

Also, can you explain to me what you mean by " No line ending" I am still new to the arduino and didn't
understand it.

and thank you for time.

In your sketches you read a character into ‘letter’ whenever a character is available. IF NO CHARACTER IS AVAILABLE YOU ACT ON THE LAST LETTER STORED IN ‘letter’.

If ‘letter’ contains ‘a’, the first sketch turns the LED on and the second sketch turns the LED on for a time and then off for a time. As long as the last character received was ‘a’ the first sketch with repeat turning the LED on and the second sketch will repeat turning the LED on for a time and then off for a time.

If the last character received is no longer ‘a’, the first sketch stops turning the LED on but there is nothing to turn it off so it stays on. The second sketch stops turning the LED on for a time and then off for a time and since the last thing done to the LED is ‘off for a time’, it stays off.

The Serial Monitor has a menu at the bottom for selecting line ending. The line ending is an optional special character (or characters) that let the receiver know that you have pressed the Return/Enter key. Since those special characters are not ‘a’ or ‘b’ they fall into the ‘any other character’ case.

Menna_Ali:
when you send 'a' it will blink the LED, but if you send any other letter it will stop blinking. which is unlike the first code where sending any other letter does nothing.

It's the expected behavior of your code.

You didn't fix the problem pointed by arduino_new in reply #2

johnwasser:
In your sketches you read a character into ‘letter’ whenever a character is available. IF NO CHARACTER IS AVAILABLE YOU ACT ON THE LAST LETTER STORED IN ‘letter’.

If ‘letter’ contains ‘a’, the first sketch turns the LED on and the second sketch turns the LED on for a time and then off for a time. As long as the last character received was ‘a’ the first sketch with repeat turning the LED on and the second sketch will repeat turning the LED on for a time and then off for a time.

If the last character received is no longer ‘a’, the first sketch stops turning the LED on but there is nothing to turn it off so it stays on. The second sketch stops turning the LED on for a time and then off for a time and since the last thing done to the LED is ‘off for a time’, it stays off.

The Serial Monitor has a menu at the bottom for selecting line ending. The line ending is an optional special character (or characters) that let the receiver know that you have pressed the Return/Enter key. Since those special characters are not ‘a’ or ‘b’ they fall into the ‘any other character’ case.

Thank you sir so much, according to what I understood from you, the code keeps its last state in both codes when other letter than ‘a’ is sent. So I added digitalWrite(13,HIGH) in the second code as the last line in the if statement and when I sent any other letter than ‘a’, the LED stayed ON.

Menna_Ali:

Quote from: Menna_AliI added digitalWrite(13,HIGH) in the second code as the last line in the if statement and when I sent any other letter than 'a', the LED stayed ON.

Yes, turning the LED on (HIGH) tends to make the LED stay on. Perhaps you wanted to turn it OFF/LOW instead?:

     if(letter == 'a')
     {
       digitalWrite(13, HIGH);
     }
     else
     {
        digitalWrite(13, LOW);
      }

I think what you are missing is that loop() keeps repeating again and again no matter if there is a character available at the serial port or not.

You only read a character if one is available, then the rest of loop() runs no matter what. The formatting of the code might be throwing you off, with the if statement indented it might seem like that line only executes if a character is read. Select Tools => Auto Format in the IDE and you will see it change.

Maybe some code with comments and print statements would help?

void loop()
{
  // if there is a new letter availabe
  if (Serial.available() > 0)
  {
    // store it
    letter = Serial.read();
  }

  // if stored letter is 'a'
  if (letter == 'a')
  {
    Serial.println("stored letter is a");

    // turn LED ON
    digitalWrite(13, HIGH);
  }

}

Run the above and look at the serial monitor. Assuming the serial monitor is set to "No line ending", if you enter 'a' it should print "stored letter is a" over and over

void loop()
{
  // if there is a new letter availabe
  if (Serial.available() > 0)
  {
    // store it
    letter = Serial.read();

    // if stored letter is 'a'
    if (letter == 'a')
    {
      Serial.println("stored letter is a");

      // turn LED ON
      digitalWrite(13, HIGH);

    } else {

      // turn LED off
      digitalWrite(13, LOW);

    }
  }

}

Run this version and you should only see output on the serial monitor when an 'a' is entered.