Here's how I did it. It may give you some ideas. There's a state st_voting during which button presses are accepted. The pressed button puts its score into an array in the right slot. Once 4 buttons are pressed (I decided to force the user to explicitly press the 4th button. Scores start as 99 for not pressed, the get a 3,2,1 or 0 in sequence) it goes to state st_voted where you do whatever it is that needs to be done with the results. In that state, it accepts a 5th button to restart, when it sets the scores back to 99 and starts over with no buttons pressed.
The builtin led blinks without delay to prove nothing's blocking.
Here's some output:
It's time to vote! Press the buttons....
You voted for candidate 2, Score: 3
You voted for candidate 1, Score: 2
BZZZZZT! You already voted for candidate 2
You voted for candidate 0, Score: 1
BZZZZZT! You already voted for candidate 1
You voted for candidate 3, Score: 0
You have voted for all 4 candidates. Their scores are 1230
Press the restart button to vote again...
It's time to vote! Press the buttons....
// https://forum.arduino.cc/index.php?topic=686090
// 24 may 2020
// voting system
// built-in led blinks with no delay() to prove no blocking
// candidtaes' scores start at 99, you have to explicitly vote for the last candidate
// scores are in an array 3,2,1,0 so it's easy to change those to say 5,4,2,1 or whatever
// a led comes on for each voted-for candidate
// when all candidates have a vote, you can press restart, and reset to 99
//states
enum {st_voting, st_voted} votingState = st_voting;
// the buttons
struct buttons
{
byte pin;
bool state;
bool prevState;
byte led;
byte score;
};
const byte buttonPins[] = {2, 3, 4, 5};
const byte numberOfButtons = sizeof(buttonPins) / sizeof(buttonPins[0]);
buttons mybuttons[numberOfButtons];
const byte leds[] = {8, 9, 10, 11};
byte numberOfVotesCast = 0;
const byte scores[] = {3, 2, 1, 0};
//the pulse led
int pulseLedInterval = 500;
unsigned long previousMillisPulse;
bool pulseState = false;
const byte restartButton = 7;
void setup()
{
// initialize serial communication:
Serial.begin(9600);
Serial.println("setup() ... ");
Serial.println("** voting system **");
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(" pins");
for (int i = 0; i < numberOfButtons; i++)
{
mybuttons[i].pin = buttonPins[i];
pinMode(mybuttons[i].pin, INPUT_PULLUP);
mybuttons[i].state = digitalRead(mybuttons[i].pin);
mybuttons[i].prevState = mybuttons[i].state;
mybuttons[i].led = leds[i];
pinMode(mybuttons[i].led, OUTPUT);
mybuttons[i].score = 99; //shows not voted for
Serial.print("Candidate: "); Serial.print(i);
Serial.print(", Button: "); Serial.print(mybuttons[i].pin);
//Serial.print(", State: "); Serial.print(mybuttons[i].state);
//Serial.print(", Prev state: "); Serial.print(mybuttons[i].prevState);
Serial.print(", Led: "); Serial.print(mybuttons[i].led);
Serial.print(", Score: "); Serial.println(mybuttons[i].score);
}
//initialise pulse led
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, pulseState);
Serial.println(" ");
pinMode(restartButton, INPUT_PULLUP);
Serial.println("setup() done");
Serial.println("It's time to vote! Press the buttons....");
Serial.println(" ");
}
void loop()
{
manageVoting();
doPulse();
} //loop
void manageVoting()
{
switch (votingState) //st_voting, st_voted
{
case st_voting:
checkForButtonPress();
if (numberOfVotesCast == numberOfButtons)
{
votingState = st_voted;
Serial.print("You have voted for all ");
Serial.print(numberOfButtons);
Serial.print(" candidates. Their scores are ");
for (int i = 0; i < numberOfButtons; i++)
{
Serial.print(mybuttons[i].score);
}
Serial.println("");
Serial.println("Press the restart button to vote again...");
}
break;
case st_voted:
if (!digitalRead(restartButton))
{
for (int i = 0; i < numberOfButtons; i++)
{
mybuttons[i].score = 99;
digitalWrite(mybuttons[i].led, LOW);
}
Serial.println("It's time to vote! Press the buttons....");
votingState = st_voting;
numberOfVotesCast = 0;
}
break;
}//switch
}//manageVoting
void checkForButtonPress()
{
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
{
if (mybuttons[i].score == 99)
{
mybuttons[i].score = scores[numberOfVotesCast];
digitalWrite(mybuttons[i].led, HIGH);
Serial.print("You voted for candidate ");
Serial.print(i);
Serial.print(", Score: ");
Serial.println(mybuttons[i].score);
numberOfVotesCast++;
}
else
{
Serial.print(" BZZZZZT! You already voted for candidate ");
Serial.println(i);
}
}
// 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;
}
} // checkForButtonPress()
void doPulse()
{
if (millis() - previousMillisPulse >= (unsigned long) pulseLedInterval)
{
previousMillisPulse = millis();
pulseState = !pulseState;
digitalWrite(LED_BUILTIN, pulseState);
}
} //doPulse