Below is some sample code that I found in the forum that was originally written to monitor one button which I've modified to monitor 10 switches. Normal game play creates a lot of "false" status changes when reading switch statuses. My question is this... is there a better approach or Library (e.g. ezButton) that would simplify this code?
I am using a Mega Arduino with most of the pins being used for other items not shown here.
In my arcade game application, I have 10 targets that rest against individual switches that are in the "closed" position when the target has NOT been knocked down. When the status of the switch is read, LOW returns when the target is still standing (normal state) and HIGH returns when the target has been knocked over. During normal play, vibrations give "false" readings and tell the circuit the target has been knocked down when in fact the target may have teetered but not fallen. I'm going to need to essentially debounce the input pullup at the first potential status change to filter out the noise and again at the end for typical switch debouncing needs.
/*
Debounce
Each time the input pin goes from LOW to HIGH , need to check to see if it is just "noise" or if Target is really down
press),. There's a minimum delay between toggles to debounce the circuit (i.e. to ignore noise).
- switches on 10 targets.
- switch is mechanically in "closed" position in at rest.
- switch reads "HIGH" when Target is knocked down
- Each time the input pin goes from LOW to HIGH , need to check to see if it is just "noise" or if Target is really down
- If target is really down, then need to debounce the circuit
*/
const int switchPin[] = {23, 24, 25, 26, 27, 28, 29, 30, 31}; // the number of the pushswitch pin
// Variables
int switchState[] = {LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW}; // the current reading from the input pin
int lastSwitchState[] = {LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW} ; // the previous reading from the input pin
int reading[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
// 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, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // the last time the output pin was toggled
unsigned long debounceDelay = 50; // the debounce time; increase if the output flickers
void setup() {
pinMode(switchPin[1], INPUT_PULLUP); // NC Switch for Target01
pinMode(switchPin[2], INPUT_PULLUP); // NC Switch for Target02
pinMode(switchPin[3], INPUT_PULLUP); // NC Switch for Target03
pinMode(switchPin[4], INPUT_PULLUP); // NC Switch for Target04
pinMode(switchPin[5], INPUT_PULLUP); // NC Switch for Target05
pinMode(switchPin[6], INPUT_PULLUP); // NC Switch for Target06
pinMode(switchPin[7], INPUT_PULLUP); // NC Switch for Target07
pinMode(switchPin[8], INPUT_PULLUP); // NC Switch for Target08
pinMode(switchPin[9], INPUT_PULLUP); // NC Switch for Target09
pinMode(switchPin[10], INPUT_PULLUP); // NC Switch for Target10
}
void loop() {
// read the state of the switch into a local variable:
for (int i = 1; i < 11; i++) {
reading[i] = digitalRead(switchPin[i]);
// If the switch changed, due to noise or pressing:
if (reading != lastSwitchState[i]) {
// reset the debouncing timer
lastDebounceTime[i] = millis();
}
if ((millis() - lastDebounceTime[i]) > 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 switch state has changed:
if (reading != switchState[i]) {
switchState[i] = reading;
// only perform the following code if the new switch state is HIGH
if (switchState[i] == HIGH) {
// Add to score, etc.
}
}
}
}
// save the reading. Next time through the loop, it'll be the lastSwitchState[i]:
for (int i = 1; i < 11; i++) {
lastSwitchState[i] = reading[i];
}
}