I am trying to replicate what I believe is the simplest type of code and setup you’d need to have it so that one push button can turn on a traffic light of LEDs in sequence, starting with the Red, then yellow, then Green, then all off, and then repeat from the top.
In short, where each button press indicates the next switchcase.
This does work to a degree, but each press of the button does not automatically mean the next switchcase is chosen. In practice I have to either hammer the button awfully fast for it to register, or press once, wait, then press again X seconds later, its sporadic and unreliable.
Here is the code
// using combo of arduino example codes for debounce (https://docs.arduino.cc/built-in-examples/digital/Debounce/)
// and edge detection (https://docs.arduino.cc/built-in-examples/digital/StateChangeDetection/)
// and then switch cases for good measure
const int ButtonPin = 2;
const int RedLEDPin = 11;
const int YellowLEDPin = 9;
const int GreenLEDPin = 5;
int RedLEDState = LOW;
int YellowLEDState = LOW;
int GreenLEDState = LOW;
int ButtonState = LOW;
int lastButtonState = LOW;
int ButtonPushCounter = 0;
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 100;
void setup() {
pinMode(ButtonPin, INPUT);
pinMode(RedLEDPin, OUTPUT);
pinMode(YellowLEDPin, OUTPUT);
pinMode(GreenLEDPin, OUTPUT);
Serial.begin(9600);
}
void loop() { // start by pulling from the debounce script,
int reading = digitalRead(ButtonPin); // read the state of the switch into a local variable, check the see if the button is pressed
if (reading != lastButtonState) { //compare the buttonstate to its previous, if the switch is changed due to noise or pressing:
lastDebounceTime = millis(); // reset the debounce timer.
}
if ((millis() - lastDebounceTime) > debounceDelay) { // whatever the reading is at, it has been there for longer than the debounce delay, so take it as the actual current state
if (reading != ButtonState) { // if the button state has changed
ButtonState = reading; // change it back to the reading.
}
ButtonState = digitalRead(ButtonPin); // assuming debounce is cleared, read the button input pin again
if (ButtonState != lastButtonState) { // compare it to its previous state
if (ButtonState == HIGH) { // if it has changed, increment the counter
ButtonPushCounter++;
Serial.println("On");
Serial.print("Number of Button Presses ");
Serial.println(ButtonPushCounter);
Serial.print(millis() - lastDebounceTime);
Serial.println(" Last Debounce Time");
if (ButtonPushCounter >= 4) { //try to get it to reset the counter so it loops back to 0 then 1 2 and 3 again
ButtonPushCounter = 0;
} else {
Serial.println("Off");
}
}
}
}
lastButtonState = ButtonState; // save the current sate as the last state, for next time through the loop.
switch (ButtonPushCounter) {
case 1:
digitalWrite(RedLEDPin, HIGH);
digitalWrite(YellowLEDPin, LOW);
digitalWrite(GreenLEDPin, LOW);
break;
case 2:
digitalWrite(RedLEDPin, LOW);
digitalWrite(YellowLEDPin, HIGH);
digitalWrite(GreenLEDPin, LOW);
break;
case 3:
digitalWrite(RedLEDPin, LOW);
digitalWrite(YellowLEDPin, LOW);
digitalWrite(GreenLEDPin, HIGH);
case 4:
digitalWrite(RedLEDPin, LOW);
digitalWrite(YellowLEDPin, LOW);
digitalWrite(GreenLEDPin, LOW);
break;
}
}
I initially thought the debounceDelay was the cause of the problem, but adjusting it between 25, 50, 100 and more millis didn’t produce reliable results.
This is my schematic
An example of the Serial Monitor output
14:56:46.412 -> On
14:56:46.412 -> Number of Button Presses 1
14:56:46.412 -> 550 Last Debounce Time
14:56:46.447 -> Off
14:56:51.403 -> On
14:56:51.403 -> Number of Button Presses 2
14:56:51.436 -> 162 Last Debounce Time
14:56:51.473 -> Off
14:56:52.488 -> On
14:56:52.488 -> Number of Button Presses 3
14:56:52.488 -> 124 Last Debounce Time
14:56:52.521 -> Off
14:58:29.881 -> On
14:58:29.881 -> Number of Button Presses 4
14:58:29.917 -> 140 Last Debounce Time
14:58:34.560 -> On
14:58:34.560 -> Number of Button Presses 1
14:58:34.593 -> 4819 Last Debounce Time
14:58:34.628 -> Off
14:58:39.713 -> On
14:58:39.754 -> Number of Button Presses 2
14:58:39.754 -> 1074 Last Debounce Time
14:58:39.787 -> Off
14:58:47.385 -> On
14:58:47.385 -> Number of Button Presses 3
14:58:47.428 -> 227 Last Debounce Time
14:58:47.428 -> Off
15:03:59.520 -> On
15:03:59.563 -> Number of Button Presses 4
15:03:59.591 -> 195 Last Debounce Time
I’ll also include a physical picture of the setup, as I’m not against the idea that perhaps somewhere in construction I’ve enabled a completely garbled signal between push button and the arduino, in which case I’d shoot off to Hardware.




