Have a look at the code below; everything's in arrays (eg the button pin number, its associated led pin number, whether or not that button has been pressed, and the states.)
The score per button is in an array, I made them different to make it easy to see they work; just make them all the same if they should all be say 1 or 10.
All I did for the sound effect now was to play a buzzer tone high or low along with the delay()-less random blink of the leds.
I kept the total running after the 5 buttons have been pressed; I'm sure you'll see in the code where to reset it back to 0 if that's supposed to happen.
And there's a delay()-less blink on pin 13's led so you can see that nothing's blocked.
// https://forum.arduino.cc/index.php?topic=679079
// state change detect on a button struct array
// 21 april 2020
/*
I [xcg584] would need a program that when 5 buttons(later replalced with sensors)
are pressed, leds are turned on respectedly. When all 5 leds are on,
a sound effect is triggered and the leds blink a few times with random
blink from 50 to 250 ms and then turn off. Buttons should be debounced
because of a score counter for each time a button is activated.
*/
/*
BASED ON State change detection (edge detection) changed for INPUT PULLUP
and with a struct array
delay()-less millis()-based pulse pin 13
*/
// the buttons
struct buttons
{
byte pin;
byte led;
bool state;
bool prevState;
byte score;
byte pressed;
};
const byte buttonPins[] = {15, 16, 17, 18 , 19};
const byte numberOfButtons = sizeof(buttonPins) / sizeof(buttonPins[0]);
buttons mybuttons[numberOfButtons];
const byte ledPins[] = {2, 3, 4, 5, 6};
const byte scores[] = {10, 20, 30, 40, 50};
int runningTotal;
byte numberOfButtonsPressed = 0;
//the pulse led
int pulseLedInterval = 500;
unsigned long previousMillisPulse;
bool pulseState = false;
//the effect led
int effectLedInterval;
int effectLedIntervalMax = 250;
int effectLedIntervalMin = 50;
unsigned long previousMillisEffect;
bool effectState;
bool doEffect = false;
//the buzzer
byte buzzer = 9;
void setup()
{
// initialize serial communication:
Serial.begin(9600);
Serial.println("setup() ... ");
Serial.println("** 679079 **");
Serial.print("Compiler: ");
Serial.print(__VERSION__);
Serial.print(", Arduino IDE: ");
Serial.println(ARDUINO);
Serial.print("Created: ");
Serial.print(__TIME__);
Serial.print(", ");
Serial.println(__DATE__);
Serial.println(__FILE__);
// initialize the button pins as input with pullup so active low
// make sure the button is from pin to ground
Serial.println(" ");
Serial.print("Initialising "); Serial.print(numberOfButtons); Serial.println(" buttons");
for (int i = 0; i < numberOfButtons; i++)
{
mybuttons[i].pin = buttonPins[i];
pinMode(mybuttons[i].pin, INPUT_PULLUP);
mybuttons[i].led = ledPins[i];
pinMode(mybuttons[i].led, OUTPUT);
mybuttons[i].state = digitalRead(mybuttons[i].pin);
mybuttons[i].prevState = mybuttons[i].state;
mybuttons[i].score = scores[i];
mybuttons[i].pressed = 0;
Serial.print("Button: "); Serial.print(i);
Serial.print(", Pin: "); Serial.print(mybuttons[i].pin);
Serial.print(", Led: "); Serial.print(mybuttons[i].led);
Serial.print(", Score: "); Serial.print(mybuttons[i].score);
Serial.print(", Pressed: "); Serial.print(mybuttons[i].pressed);
Serial.print(", State: "); Serial.print(mybuttons[i].state);
Serial.print(", Prev state: "); Serial.println(mybuttons[i].prevState);
}
//initialise pulse led
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, pulseState);
Serial.println(" ");
Serial.println("setup() done");
Serial.println("Press a button....");
Serial.println(" ");
}
void loop()
{
doPulse();
checkForButtonStateChange();
if (doEffect) blinkLedsAndMakeANoise();
} //loop
void checkForButtonStateChange()
{
for (int i = 0; i < numberOfButtons; i++)
{
mybuttons[i].state = digitalRead(mybuttons[i].pin);
// compare the buttonState to its previous state
if (mybuttons[i].state != mybuttons[i].prevState) // means it changed... but which way?
{
if (mybuttons[i].state == LOW) // changed to pressed
{
Serial.print(i);
Serial.print(" newly pressed");
if (mybuttons[i].pressed == 0)
{
mybuttons[i].pressed = 1;
numberOfButtonsPressed++;
Serial.print(", Unique buttons pressed "); Serial.print(numberOfButtonsPressed);
}
digitalWrite(mybuttons[i].led, HIGH);
runningTotal = runningTotal + mybuttons[i].score;
Serial.print(", Score "); Serial.println(runningTotal);
}
// poor man's de-bounce
delay(50);
}
// save the current state as the last state, for next time through the loop
mybuttons[i].prevState = mybuttons[i].state;
}
if (numberOfButtonsPressed == 5)
{
Serial.print("All leds on, score "); Serial.println(runningTotal);
for (int i = 0; i < numberOfButtons; i++)
{
mybuttons[i].pressed = 0;
}
doEffect = true;
numberOfButtonsPressed = 0;
}
} // checkForButtonStateChange()
void blinkLedsAndMakeANoise()
{
static byte numberOfEffects = 0;
if (millis() - previousMillisEffect >= effectLedInterval)
{
effectLedInterval = random(effectLedIntervalMin, effectLedIntervalMax);
previousMillisEffect = millis();
effectState = !effectState;
for (int i = 0; i < numberOfButtons; i++)
{
digitalWrite(mybuttons[i].led, effectState);
if (effectState) tone(buzzer, 1000); else tone(buzzer, 500);
}
numberOfEffects++;
}
if (numberOfEffects == 10)
{
doEffect = false;
numberOfEffects = 0;
for (int i = 0; i < numberOfButtons; i++)
{
digitalWrite(mybuttons[i].led, LOW);
}
noTone(buzzer);
}
}
void doPulse()
{
if (millis() - previousMillisPulse >= pulseLedInterval)
{
previousMillisPulse = millis();
pulseState = !pulseState;
digitalWrite(LED_BUILTIN, pulseState);
}
} //doPulse
I think it does what you want.