Troubles with serial monitor

Hi everyone, I have a problem with my code using Serial monitor.
My goal is to achieve to communicate with traffic lights from my computer (in this case the traffic lights represent leds (green, red and orange).

So far I can let the leds go on as it should be (it furst turns red, then green and then orange). It works in a loop so it never stops (like real traffic lights). The serial monitor prints which led is on at the very moment.

Anyhow my next goal is to sent a value (1) which means the traffic lights have to operate normally (first red, then green and then orange; just like described above). So I just added this to my code:

while (Serial.available() == 0);
int val = Serial.read() - '0';
if (val == 1)

The problem is when I enter the value '1' only the red led goes on, if I enter '1' again the green led goes on. In other words it doesn't switch automatically.

I think it's because my switch(state) doesnt work properly but I don't know what to do.
Can anyone help me?

Here is my code:

void loop() {
while (Serial.available() == 0);
int val = Serial.read() - '0';
if (val == 1)
{
switch(state)
{
case red:
digitalWrite(ledred,HIGH);
Serial.println("red light is on");
digitalWrite(ledorange,LOW);
digitalWrite(ledgreen,LOW);
delay(6000);
state=green;
break;

case orange:
digitalWrite(ledred,LOW);
digitalWrite(ledorange,HIGH);
Serial.println("orange light is on");
digitalWrite(ledgreen,LOW);
state=red;
break;

case green:
digitalWrite(ledred,LOW);
digitalWrite(ledorange,LOW);
digitalWrite(ledgreen,HIGH);
Serial.println("green light is on");
delay(4000);
state=orange;
break;
}
delay(2000);
}

}

Thank you for the help!! :slight_smile:

Hi

After you type in '1', the switch statement gets executed just once before you loop round to this statement:

 while (Serial.available() == 0);

That statement will loop there until you type in the next command. So the lights never move from the first state.

Assuming you want the lights to cycle continuously after typing the command to start them, try this ...

Change the start of your loop code to:

void loop()
{
  static int val = 0;
  if (Serial.available())
  {
    val = Serial.read() - '0';
  }
  if (val == 1)
  {
    etc

If you type a second command that is not '1', that should stop the lights in the current position in the cycle. But the command will only be recognised at a gap between the various delay statements you are using. If you want to improve the program, especially if you want to add extra features, you should use the "BlinkWithoutDelay" approach and drop the delays.

Regards

Ray

This is the example from the documentation of Serial.read()

int incomingByte = 0;   // for incoming serial data

void setup() {
   Serial.begin(115200);     // opens serial port, sets data rate to 9600 bps
}//setup()

void loop() {
  // send data only when you receive data:
  if (Serial.available() > 0) {
    // read the incoming byte:
    incomingByte = Serial.read();

    // say what you got:
    Serial.print("I received: ");
    Serial.println(incomingByte, DEC);
  }//if()
}//loop()

Run it and see what happens and think about how your code will react

Thank you Ray, it works! I'm just wondering why the led stops when I put an unknown value?

Thank you Ray, it works! I'm just wondering why the led stops when I put an unknown value?

You modified your code in some mysterious way, and it does something you don't expect. And, you want us to explain why? Perhaps next time...

Thank you Ray, it works! I'm just wondering why the led stops when I put an unknown value?

When you type in '1', your code sets val to 1, so the if statement condition is true and the switch statement gets executed.

If you type in '2', for example, val gets set to 2, so the if statement condition is false, and the switch statement is not executed, so the light sequence stops.