Switches that need debounce before and after pull up

if you're going to use millis() why not check the timeout first before even reading the button? may need a flag indicating the timer is active

here's a different approach

// check multiple buttons and toggle LEDs

enum { Off = HIGH, On = LOW };

byte pinsLed [] = { 10, 11, 12 };
byte pinsBut [] = { A1, A2, A3 };
#define N_BUT   sizeof(pinsBut)

byte butState [N_BUT];

// -----------------------------------------------------------------------------
int
chkButtons ()
{
    for (unsigned n = 0; n < sizeof(pinsBut); n++)  {
        byte but = digitalRead (pinsBut [n]);

        if (butState [n] != but)  {
            butState [n] = but;

            delay (10);     // debounce

            if (On == but)
                return n;
        }
    }
    return -1;
}

// -----------------------------------------------------------------------------
void
loop ()
{
    switch (chkButtons ())  {
    case 2:
        digitalWrite (pinsLed [2], ! digitalRead (pinsLed [2]));
        break;

    case 1:
        digitalWrite (pinsLed [1], ! digitalRead (pinsLed [1]));
        break;

    case 0:
        digitalWrite (pinsLed [0], ! digitalRead (pinsLed [0]));
        break;
    }
}

// -----------------------------------------------------------------------------
void
setup ()
{
    Serial.begin (9600);

    for (unsigned n = 0; n < sizeof(pinsBut); n++)  {
        pinMode (pinsBut [n], INPUT_PULLUP);
        butState [n] = digitalRead (pinsBut [n]);
    }

    for (unsigned n = 0; n < sizeof(pinsLed); n++)  {
        digitalWrite (pinsLed [n], Off);
        pinMode      (pinsLed [n], OUTPUT);
    }
}

Using ezButton library could simplify your code a lot. The below is an example of using multiple buttons in an array:

#include <ezButton.h>

const int BUTTON_NUM = 5;

const int BUTTON_1_PIN = 2;
const int BUTTON_2_PIN = 3;
const int BUTTON_3_PIN = 4;
const int BUTTON_4_PIN = 5;
const int BUTTON_5_PIN = 6;

ezButton buttonArray[] = {
  ezButton(BUTTON_1_PIN),
  ezButton(BUTTON_2_PIN),
  ezButton(BUTTON_3_PIN),
  ezButton(BUTTON_4_PIN),
  ezButton(BUTTON_5_PIN)
};

void setup() {
  Serial.begin(9600);

  for (byte i = 0; i < BUTTON_NUM; i++) {
    buttonArray[i].setDebounceTime(50); // set debounce time to 50 milliseconds
  }
}

void loop() {
  for (byte i = 0; i < BUTTON_NUM; i++)
    buttonArray[i].loop(); // MUST call the loop() function first

  for (byte i = 0; i < BUTTON_NUM; i++) {
    if (buttonArray[i].isPressed()) {
      Serial.print("The button ");
      Serial.print(i + 1);
      Serial.println(" is pressed");
    }

    if (buttonArray[i].isReleased()) {
      Serial.print("The button ");
      Serial.print(i + 1);
      Serial.println(" is released");
    }
  }
}

I may do that OR wait for a second row to be all knocked down before resetting one row. I believe that is what the one in the arcade does from what I can tell.

Per the conversation in post #4 of this discussion, I elected NOT to use a library like eZbutton despite the fact I had already started down that path. At the point of post #1, I was using typical debouncing code taken from working examples to monitor the switches of each of the clown targets. However, this approach did not address a bunch of false positives I was receiving when the game shook or when a target teetered even the slightest amount no matter the reason. The code in the sketch was specifically written to monitor every break in the normally closed circuit to distinguish between static and a clown target actually being knocked over. Is it clumsy? Yes but it works and as said in that post...

1 Like

I'm going to flag the solution and close this forum discussion. Thanks again to all who contributed ideas. The final "Down the Clown" arcade project can be seen in this forum link: Forum Discussion on Completed Down the Clown Arcade Project