yellow LED not turning off in traffic light simulation

I wanted to make a simulation of a traffic light, and since I don’t have any sensors I used a button to change between the different states (red/stop and green/drive). When the states are changing I wanted to have a short yellow blink- just like normal traffic lights work. But in the first state(green), yellow doesn’t turn off. In the second the same problem occurs, but if I press the button, that I connected to GPIO pin 2, the LED turns off. It makes no sense to me, as the switch sentence turn off the yellow LED before powering the others (in both cases). In addition, I can’t wrap my head around the fact that the yellow LED turns off after I press the button once more, as I only have two cases in the switch sentence, but it now seems like there is three.

here’s the code(included the whole thing, but I think the switch sentence is most relevant):

// Include button library
#include <Button.h>

// Create button object for GPIO pin 2
Button switchLedBtn(2);

// Declare ledPins to initiate outputs 
const byte ledPins[3] = {11, 10, 9};

// Declare i variable
int colour = 0;

void setup() {
  
  // Use GPIO pin 9, 10 and 11 as output
  for(int i = 0; i <= 2; i++) {
    pinMode(ledPins[i], OUTPUT);
  }

  // Begin button
  switchLedBtn.begin();
}

void loop() {
  // Turn the green led on (GPIO PIN 11) if button pressed once. If button is pressed again switch to yellow then to red.
  if(switchLedBtn.pressed()) {
    colour = colour + 1;
    if(colour > 3) {
      colour = 1;
    }
  }
  
  switch(colour) {

    // Turn off red, turn on yellow in half a second, then power green (green(0), yellow(1) and red(2))
    case 1: digitalWrite(ledPins[2], LOW); digitalWrite(ledPins[1], HIGH); delay(500); digitalWrite(ledPins[1], LOW); digitalWrite(ledPins[0], HIGH); 
            break;

    // Turn green off, turn yellow on for a second, then power red
    case 2: digitalWrite(ledPins[0], LOW); digitalWrite(ledPins[1], HIGH); delay(1000); digitalWrite(ledPins[1], LOW); digitalWrite(ledPins[2], HIGH);
            break;
  }             
}

Try to put your "switch(colour)" statement inside the "if (isButtonPressed)" brackets in order to make the light only change upon button press and not every loop. You may also want to change "if (colour > 3)" to "if (colour > 2)"

I suggest that you serial.print the value of colour before the switch to ensure that your button class is actually debouncing adequately.

Also, multiple statements on one line makes your code hard to read - some judicious use of the enter key would help.

I put the switch statement into the “if(ButtonIsPressed)” brackets, as you suggested Danois, and it worked. Thanks a lot :slight_smile: However, I still don’t understand what makes it work can you (or someone else) explain to me what the issue was? I also separated the commands in the switch statement to make it easier to read.

// Include button library
#include <Button.h>

// Create button object for GPIO pin 2
Button switchLedBtn(2);

// Declare ledPins to initiate outputs 
const byte ledPins[3] = {11, 10, 9};

// Declare i variable
int colour = 0;

void setup() {
  
  // Use GPIO pin 9, 10 and 11 as output
  for(int i = 0; i <= 2; i++) {
    pinMode(ledPins[i], OUTPUT);
  }

  // Begin button
  switchLedBtn.begin();
}

void loop() {
  // Turn the green led on (GPIO PIN 11) if button pressed once. If button is pressed again switch to yellow then to red.
  if(switchLedBtn.pressed()) {
    colour = colour + 1;
    if(colour > 2) {
      colour = 1;
    }
  switch(colour) {

    // Turn off red, turn on yellow in half a second, then power green (green(0), yellow(1) and red(2))
    case 1: digitalWrite(ledPins[2], LOW); 
            digitalWrite(ledPins[1], HIGH); 
            delay(500); 
            digitalWrite(ledPins[1], LOW); 
            digitalWrite(ledPins[0], HIGH); 
            break;

    // Turn green off, turn yellow on for a second, then power red
    case 2: digitalWrite(ledPins[0], LOW); 
            digitalWrite(ledPins[1], HIGH); 
            delay(1000); 
            digitalWrite(ledPins[1], LOW); 
            digitalWrite(ledPins[2], HIGH);
            break;
    }             
  }    
}

Yes, it is quite simple. When you do the "green" sequence, the LED's go: red off, yellow on, delay, yellow off, green on. In your first attempt this sequence was repeated over and over and since green is already on and red is already off yellow will turn on for 500 ms and then be turned off aigain until next loop where this will repeat. You will not be able to see the brief off state of the LED, causing it to be on all the time.