Push button - detect the sequence (push1, push2, push3 and push4)

Hi folks,

I'm having trouble testing a sketch with the utilization of a push button.
The goal down the road is to use this sketch with a LED strip that will light up in 4 different colors depending of the sequence of a push on the button.
e.g.
1st push: 'color1', 2nd push: 'color2', 3rd push color3,, 4th push color4. one more push color1 again.

At this moment I'm just testing the push sequence.

/*
 * copied from https://www.instructables.com/Arduino-Push-Button-Counter-With-LED-Indication/
 * ... improved version
 *  
 ***********************/

constexpr boolean LEDS = false;         // [true] if LED's are attached to the circuit

int count=0;
int newcount;

// ***************************************
void setup() {
  Serial.begin(9600);  
  pinMode(5,INPUT);         // button
  if (LEDS==true) {
    // only when using LED's
    pinMode(6,OUTPUT);        // LED's
    pinMode(7,OUTPUT);
    pinMode(8,OUTPUT);
    pinMode(9,OUTPUT);      
  }
} 

// **************************************
void loop() {  

int val = digitalRead(5);
//digitalRead(5)==LOW;
//digitalRead(5);
//if(digitalRead(5)==HIGH) {
if (val==HIGH) {
  newcount=count+1;
  if(newcount!=count) { 
    delay(500);
    switch (newcount) {
      case 1: 
        if (LEDS==true) { digitalWrite(6,HIGH); }
        Serial.println("this is case #1");
        break;               
      case 2: 
        if (LEDS==true) { digitalWrite(7,HIGH); }
        Serial.println("this is case #2");
        break;
      case 3: 
        if (LEDS==true) { digitalWrite(8,HIGH); }
        Serial.println("this is case #3");        
        break;         
      case 4: 
        if (LEDS==true) { digitalWrite(9,HIGH); }
        Serial.println("this is case #4");
        count = newcount=0;
        break;         
      default:  
        if (LEDS==true) {
          digitalWrite(6,LOW);
          digitalWrite(7,LOW);
          digitalWrite(8,LOW);
          digitalWrite(9,LOW);
        }
        Serial.println("this is default case (case #5)");
        //newcount=0;
        break;
       }
      count=newcount;
    }
    delay(500);
  }
  delay(500);
} 

At the moment, when running the sketch, it shows a delayed print of the Serial.print(...) and after 4 times, it's printing all output lines w/o any push of the button.

I think I'm missing some of the logic (of the digitalRead() functionality.
Perhaps someone can point out to me what I'm doing wrong in this sketch.
Any help is much appreciated.
TIA

The drawing looks like you have the button pin floating (not tied to ground or Vcc). Floating pin will make val HI many times, and make all the Serial.print(); you are seeing.

Here is how Arduino wires their buttons.
https://docs.arduino.cc/built-in-examples/digital/Button/

I don't think this is the cause of your problem, but the 'if' statement will always evaluate to true. The line immediately before the 'if' ensures that newcount will not be eual to count. What was your rationale for including that 'if' statement?

Hello domify80

Check this sketch:

// https://forum.arduino.cc/t/push-button-detect-the-sequence-push1-push2-push3-and-push4/1379625
// make names
enum Button {Select};
enum Colour {Colour1, Colour2, Colour3, Colour4, MaxColour};
enum OnOff {Off,On};
enum ButtonState {Pressed};
// make variables
constexpr uint8_t Input[] {A0};
constexpr uint8_t Output[] {9, 10, 11, 12};
uint8_t colour = Colour1;
void setup()
{
  Serial.begin(115200);
  for (auto i : Input) pinMode(i, INPUT_PULLUP); // [PIN] --- [input] --- [GND]
  for (auto o : Output) pinMode(o, OUTPUT);   // [PIN] --- [output] --- [+5V]
  Serial.println("and here we go .... ");
}
void loop()
{
  static uint8_t buttonOld = digitalRead(Input[Select]);
  uint8_t buttonNew = digitalRead(Input[Select]);
  if (buttonOld != buttonNew)
  {
    delay(100); // quick debounce
    buttonOld = buttonNew;
    if (buttonNew == Pressed)
    {
      for (auto o:Output) digitalWrite(o,Off);
      digitalWrite(Output[colour],On);
      switch (colour)
      {
        case Colour1:
          Serial.println("this is Colour1");
          break;
        case Colour2:
          Serial.println("this is Colour2");
          break;
        case Colour3:
          Serial.println("this is Colour3");
          break;
        case Colour4:
          Serial.println("this is Colour4");
          break;
      }
      colour = (colour + 1) % MaxColour;
    }
  }
}

I think you are right.
It was a short circuit in my brain.
It's corrected. Testing continues.
Thanks

Thank you.
I made the corrections on the circuit.
But it's still not responding the way as I expect.
It's still running through the loop without having the button pressed.
I will continue to tinker.
Thanks, xfpd

Just to confirm, the build in examples works fine. What other to expect?

Finally I have success. :smiley:

For completion, here is the sketch that is running fine now.

/*
 * copied from https://www.instructables.com/Arduino-Push-Button-Counter-With-LED-Indication/
 * ... improved version
 * see also here: https://docs.arduino.cc/built-in-examples/digital/Button/
 * 
 * New 06-May-2025
 * 
 * Setup:
 *  arduino (5V) -- push button(A1)
 *  arduino (D2) -- push button(B1)
 *  arduino (D6, D7, D8, D9) -- Resistor(150ohm) -- LED's (positive terminal)
 *  arduino(GND) -- LED(negative terminal)
 *  arduino(GND) -- Resistor(10K) -- push button(B2)
 *  
 * Tested in pio on Uno
 *  
 */

#include <Arduino.h>
constexpr boolean LEDS = false;
constexpr int TIMEDELAY = 200;
int count=0;
int newcount;

// variables will change: (for loop #2)
byte buttonState;  // variable for reading the pushbutton status
byte lastButtonState = 1;
constexpr int buttonPin = 2;  // the number of the pushbutton pin

// forward declaration
void resetLEDS();

// **********************************************************
void setup() {
  Serial.begin(9600);  
  pinMode(buttonPin,INPUT);         // button
  if (LEDS==true) {
    // only when using LED's
    pinMode(6,OUTPUT);        // LED's
    pinMode(7,OUTPUT);
    pinMode(8,OUTPUT);
    pinMode(9,OUTPUT);      
  }
  Serial.println("setup() completed");
} 


// **************************************
void loop() {  

int val = digitalRead(buttonPin);
delay(100);
if (val==HIGH) {
  newcount=count+1;
  switch (newcount) {
    case 1: 
      if (LEDS==true) { 
        resetLEDS();
        digitalWrite(6,HIGH); }
      Serial.println("this is case #1");
      break;               
    case 2: 
      if (LEDS==true) { digitalWrite(7,HIGH); }
      Serial.println("this is case #2");
      break;
    case 3: 
      if (LEDS==true) { digitalWrite(8,HIGH); }
      Serial.println("this is case #3");        
      break;         
    case 4: 
      if (LEDS==true) { digitalWrite(9,HIGH); }
      Serial.println("this is case #4");
      count = newcount=0;
      break;         
    default:  
      // never to be reached
      Serial.println("this is default case (case #5)");
      break;        
    }                // *** switch
    // Serial.println(newcount);
    count=newcount;
  }                   // *** if(val==HIGH
  val = LOW;
  delay(TIMEDELAY);
}                       // *** loop()


// ***********************************************
void resetLEDS () {
  if (LEDS==true) {
    digitalWrite(6,LOW);
    digitalWrite(7,LOW);
    digitalWrite(8,LOW);
    digitalWrite(9,LOW);
  }
}

The only thing I've noticed is that the button action is a little bit finicky (?!)
Sometimes is not recognizing the push, sometime it's over reactive (1, 2 in a row).
I will play a little bit more with the delay in the loop delay(TIMEDELAY); so see what the result will be.
Thanks for all responses and inspirations.

The finicky-ness is the button reading using delay() as a debounce mechanism alone. To accurately read a button press-and-release, the button state must go from "pressed" to "not pressed" and remain "not pressed" for a length of time, using millis() to keep track of time.

Here is an example simulation of your button read (Button 3) and the state-change-and-timing button read (Button 2):

Search for "arduino button press state change millis"