Here's the code. It's a bingo machine with 25 holes. When a ball drops in a hole the switch is closed and the lights light. I'm trying to detect when the switched is pressed and released. it works most of the time, but then it starts outputting things like:
#16 pin 9 was just pressed
#17 pin 4 was just pressed
#18 pin 14 was just pressed
#19 pin 22 was just pressed
#21 pin 26 was just pressed
#22 pin 6 was just pressed
#23 pin 11 was just pressed
#19 pin 22 was just released
#21 pin 26 was just released
#23 pin 11 was just released
#19 pin 22 was just pressed
#21 pin 26 was just pressed
#23 pin 11 was just pressed
Like something's bouncing. I have each Arduino input pin declared as INPUT_PULLUP.
const byte NUMBERS_IN_GAME = 25;
const byte NUM_MATCHES = 5;
const unsigned long DEBOUNCE = 200;
const byte RELAY_PIN = 17;
const byte MAX_SCORE_PIN = 8;
// Map bingo numbers to input pins on the Arduino.
byte PinMap[] = { 0,
/* 1-5 */ 49, 46, 47, 44, 45,
/* 6-10 */ 42, 40, 38, 36, 34,
/* 11-15 */ 52, 53, 50, 51, 48,
/* 16-19 */ 9, 4, 14, 22,
/* 20-23 */ 18, 26, 6, 11,
/* 24-25 */ 16, 43 /* 15 is a spare */
};
const byte NUM_CARDS = 6;
byte LastNumBallsDetected;
// Track if number is currently lit.
byte NumberState[NUMBERS_IN_GAME + 1], NumberIsLit[NUMBERS_IN_GAME + 1];
bool JustPressed[NUMBERS_IN_GAME + 1], JustReleased[NUMBERS_IN_GAME + 1];
// This function checks all the number inputs for any changes. The routine is called eacch loop in order
// to debounce the switches.
void checkNumbers()
{
static byte _previousstate[NUMBERS_IN_GAME + 1];
static byte _currentstate[NUMBERS_IN_GAME + 1];
static byte _statecount[NUMBERS_IN_GAME + 1];
static unsigned long _lasttime;
byte index;
if (millis() < _lasttime)
{
_lasttime = millis(); // we wrapped around, lets just try again
}
if ((_lasttime + DEBOUNCE) > millis())
{
return; // Not enough time has passed to debounce
}
// We have waited DEBOUNCE milliseconds, lets reset the timer
_lasttime = millis();
for (index = 1; index <= NUMBERS_IN_GAME; index++)
{
// Clear out the "just" indicators
JustPressed[index] = false;
JustReleased[index] = false;
_currentstate[index] = digitalRead(PinMap[index]); // read the button
if (_currentstate[index] == _previousstate[index])
{
if (_statecount[index] < NUM_MATCHES)
{
_statecount[index]++;
}
else
{
if ((NumberState[index] == LOW) && (_currentstate[index] == LOW))
{
JustPressed[index] = true;
Serial.println(String("") + "#" + index + " pin " + PinMap[index] + " was just pressed");
NumberIsLit[index] = 1;
}
else if ((NumberState[index] == HIGH) && (_currentstate[index] == HIGH))
{
JustReleased[index] = 1;
Serial.println(String("") + "#" + index + " pin " + PinMap[index] + " was just released");
NumberIsLit[index] = 0;
}
NumberState[index] = !_currentstate[index]; // remember, digital HIGH means NOT lit
}
}
else _statecount[index] = 0;
_previousstate[index] = _currentstate[index]; // keep a running tally of the switches
}
}
byte searchForNumbers()
{
byte numNumbersLit = 0;
for (byte i = 1; i <= NUMBERS_IN_GAME; i++)
{
if (NumberIsLit[i] != 0) numNumbersLit++;
}
return numNumbersLit;
}
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
Serial.println("Starting");
for (byte i = 1; i <= NUMBERS_IN_GAME; i++)
{
pinMode(PinMap[i], INPUT_PULLUP);
NumberIsLit[i] = 0;
}
pinMode(RELAY_PIN, OUTPUT);
pinMode(MAX_SCORE_PIN, INPUT_PULLUP);
// See how many numbers are lit. Have to wait until they debounce.
for (byte i = 0; i <= NUM_MATCHES; i++)
{
checkNumbers();
delay(DEBOUNCE);
}
LastNumBallsDetected = searchForNumbers();
}
void loop() {
// put your main code here, to run repeatedly:
checkNumbers(); // This will keep the NumberIsLit array up-to-date.
}