Serial.available() and Serial.read() to control LED

does anyone can help me with my code?
i want to control a LED by sending a character ‘5’ from the serial monitor to turn it on flashing light, until i send another character different than ‘5’ to turn it off.
But when i send the data the code go into while loop execute once and imediatly break the loop without sendign another character i dont know why is happening that. could someone help pleasee.

char val;
const int led = 5;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(led, OUTPUT);
}
void loop() {
if(Serial.available() > 0) {
val = Serial.read();
delay(200);
if(val == ‘5’){
while(val == ‘5’) {
digitalWrite(led, HIGH);
delay(300);
digitalWrite(led, LOW);
delay(300);
if(Serial.available()){
val = Serial.read();
delay(300);
}
}
}
}
}

this is the code that i use :frowning:

sketch_oct03c.ino (513 Bytes)

In the future, post you code here using code tags (the </> sign). And regarding the code itself, maybe try something like this. I can’t guarantee you that it’s working, because I don’t have Arduino at this moment :slight_smile: Let me know if it’s working

void loop() {
  if(Serial.available() > 0) {
    val = Serial.read();
    delay(200);
    if(val == '5') {
      while(Serial.read() == '5') {
        digitalWrite(led, HIGH);
        delay(300);
        digitalWrite(led, LOW);
        delay(300);
      }
    }
  }
}

What have you got the line ending set to in the Serial monitor. Your code requires it to be set to No line ending otherwise the line ending character(s) will be available after the '5'

Have a look at the examples in Serial Input Basics - simple reliable ways to receive data.

...R

One problem I spotted, is in the following part:

if(val == '5') {
      while(Serial.read() == '5') {
        digitalWrite(led, HIGH);
        delay(300);
        digitalWrite(led, LOW);
        delay(300);
      }
    }

You never leave the while-loop because nowhere in it are you reading the serial input again.
the code just gets stuck in the loop. on the other hand it would be sufficent to just leave the while-loop out.
In that case the code checks in every loop-iteration if something was sent. If there was a 5 it writes it into val and blinks one time.
If afterwards nothing was sent you blink again because val is still 5.
As soon as someting other than 5 is read the new value is stored and insimply doesn't execute the blink-code.

itwasntme967:
One problem I spotted, is in the following part:

if(val == '5') {

while(Serial.read() == '5') {
        digitalWrite(led, HIGH);
        delay(300);
        digitalWrite(led, LOW);
        delay(300);
      }
    }




You never leave the while-loop because nowhere in it are you reading the serial input again.

It gets checked every time the WHILE line is executed.

IMHO the problem is the opposite - when the 5 was read into the variable val it was removed from the serial input buffer so it won't be there when the WHILE goes looking for it.

...R

I am willing to bet that the OP has a line ending turned on in the Serial monitor.

The program reads a '5', turns the LED on then off and because Serial data is still available it reads the line ending so val no longer equals '5' and the LED does not flash again.

@OP

I could not solve your problem being only in the loop() function. I have to take the help of the void serialEvent() function. I have used the built-in LED (L) for test purpose.

char val;
const int led = 13;//5;  //builit-in LED (L) of NANO/UNO
bool flag1 = LOW;

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

void loop()
{
  if (flag1 == HIGH)
  {
    digitalWrite(13, !digitalRead(13));
    delay(300);
  }
}

void serialEvent()
{
  val = Serial.read();
  //  delay(200);
  if (val == '5')
  {
    flag1 = HIGH;
  }
  if(val != '5')
  {
    digitalWrite(13, LOW);
    flag1 = LOW;
  }
}

I could not solve your problem being only in the loop() function. I have to take the help of the void serialEvent() function

The original code does just what the OP says he wants as long as the Line ending is set to No line ending in the Serial monitor.

The serialEvent() function is a waste of space and just serves to confuse things

UKHeliBob:
The serialEvent() function is a waste of space and just serves to confuse things

Adan54:
i want to control a LED by sending a character '5' from the serial monitor to turn it on flashing light, until i send another character different than '5' to turn it off.

But, it solves the problem in a way the OP wants; the post could be treated as a source of alternative arrangement. We should welcome all kinds of entries in an objective way.

it solves the problem in a way the OP wants;

What problem are you trying to solve ?

Your code does not work if a line ending is specified in the Serial monitor, which I still think is the original problem that the OP had.

UKHeliBob:
What problem are you trying to solve ?

Your code does not work if a line ending is specified in the Serial monitor, which I still think is the original problem that the OP had.

The OP said that he wanted to send only the character 5; if so, why should he/I be including any other character (NL, CR or NL&CR) directly or indirectly with 5?

why should he/I be including any other character (NL, CR or NL&CR) directly or indirectly with 5?

That's the point. He shouldn't, but he may well have the Line ending turned on which prevents his (and your) code doing what is intended.

Does you program work if you turn on a line ending in the Serial monitor ?

UKHeliBob:
Does you program work if you turn on a line ending in the Serial monitor ?

The program should not work! I was not really contented with the OP's program logic that he included everything in the loop() and finally he forgot to turn OFF the Newline option/button in the Serial Monitor at the time of program execution. I had no attention to look into it; but, @UKHeliBob meticulously noticed it for which he deserves credit.