Button with a counter - Sometimes works, sometimes misses #2

Starting off with a basic button and counter, then plan to add WS2812 LED for my kids bookshelf.

However, There are a few things that I’m not able to get working. Likely oversight but i’m unable to pinpoint my issue.

Basically, push the button, cycle the counter. The counter is compared to a switch case and i’ll change the color of the LED’s based on that.

Using an Arduino Nano, when I monitor the outout, I push the button and sometimes get a 1. If I push it again, I get 3…

#define PIN 8
#define PINpushbutton 10

// Variables //
int IntButtonPushCounter = 0;    //Start the button count at 0
int IntButtonState = 0;          // current state of the button
int IntLastButtonState = 0;     // previous state of the button

void setup() {
  Serial.begin(9600);
  pinMode(PINpushbutton, INPUT);    // declare pushbutton as input
}

void loop() {
  // Some example procedures showing how to display to the pixels:
  Serial.println("About to read pin");
  IntButtonState = digitalRead(PINpushbutton);  // read input value
  Serial.println(IntButtonState);
  if (IntButtonState != IntLastButtonState) {   // Comparing current state to last state
     Serial.println("Entering case");
     Serial.print("IntButtonState is ");
     Serial.println(IntButtonState);
     Serial.print("before case switch ");
     Serial.println("");
     if (IntButtonPushCounter < 3) {
      }
       if (IntButtonState == HIGH) {
          switch (IntButtonPushCounter) {
            case 1:
             // colorWipe(strip.Color(64, 0, 0), 50); //Red
               Serial.println("case 1");
             break;
            case 2:
            // colorWipe(strip.Color(0, 64, 0), 50); //Green
               Serial.println("case 2");
             break;
             case 3: 
            // colorWipe(strip.Color(0, 0, 64), 50); // Blue
               Serial.println("case 3");
             break;
  } // End Switchcase

   } //end of ButtonState IF
    IntButtonPushCounter++;
    IntLastButtonState = IntButtonState;
    
  }

 

    delay(50);  // Add .5 seconds delay at end
} // END of Loop


Pushbutton is connected to PIN 10 (and vcc / GND via 10k resistor)

If I’m reading your code correctly it looks like the if condition is entered on button down and button up because of this logic:

button down, IntButtonState = HIGH, IntLastButtonState = LOW
IntButtonState != IntLastButtonState) == true
IntLastButtonState = HIGH

button up, IntButtonState = LOW, IntLastButtonState = HIGH
IntButtonState != IntLastButtonState) == true
IntLastButtonState = LOW

button down, IntButtonState = HIGH, IntLastButtonState = LOW
IntButtonState != IntLastButtonState) == true
IntLastButtonState = HIGH

BTW, I think you meant to reset the counter here:

     if (IntButtonPushCounter < 3) {
      }

You need to debounce the button. A single press or release can cause multiple transitions on your input pin.

   button down, IntButtonState = HIGH, IntLastButtonState = LOW
   IntButtonState != IntLastButtonState) == true

Which programming language are you using?

Thanks Blue. Yes, I hadn’t gotten all my cases proper as i had the bounce problem where it seems the button press was causing all sorts of weird issues.

In the code snippet you’ve highlighted, I wanted to count the current value up to a maximum of 3 (3 colors on LED strip) then reset it back to 0. Basically, button starts at 0 = black, 1 press = blue, 2nd press = red, 3rd press = green. Then back to 0

Any recommendations on that?

Here is the final working code for those that also need help

LED is onboard 13 Pin is 10 (with a 20k resistor to ground for pull-down)

/*
  Debounce - http://www.arduino.cc/en/Tutorial/Debounce
*/

// constants won't change. They're used here to set pin numbers:
const int PinButton = 10;    // the number of the pushbutton pin
const int PinLed = 13;      // the number of the LED pin

// Variables will change:
int ledState = LOW;         // the current state of the output pin
int buttonState;             // the current reading from the input pin
int lastButtonState = LOW;   // the previous reading from the input pin

// the following variables are unsigned longs because the time, measured in
// milliseconds, will quickly become a bigger number than can be stored in an int.
unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers

void setup() {
  Serial.begin(9600);
  pinMode(PinButton, INPUT);
  pinMode(PinLed, OUTPUT);

  // set initial LED state
  digitalWrite(PinLed, ledState);
}

void loop() {
  // read the state of the switch into a local variable:
  int reading = digitalRead(PinButton);

  // check to see if you just pressed the button
  // (i.e. the input went from LOW to HIGH), and you've waited long enough
  // since the last press to ignore any noise:

  // If the switch changed, due to noise or pressing:
  if (reading != lastButtonState) {
    lastDebounceTime = millis();      // reset the debouncing timer
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer than the debounce
    // delay, so take it as the actual current state:

    // if the button state has changed:
    if (reading != buttonState) {
      buttonState = reading;

      // only toggle the LED if the new button state is HIGH
      if (buttonState == HIGH) {
        // Will Enter this IF when the button is pressed //
        Serial.println("The Button has been pressed");
      }
    }
  }


  // save the reading. Next time through the loop, it'll be the lastButtonState:
  lastButtonState = reading;
}

What I need to figure out how is how to

Created a counter, starting at 0 that goes up to 3, then cycles back THe counter I can compare in a switchcase, each case will change the LED a certain color.