This function implements software debouncing for a two-state button. It responds to a short press and a long press and identifies between the two examples. This information is returned encoded in an integer, whereby 0 means no activity, 1 means a short press has been detected and 2 indicates a long press has occurred.
The press times are defined as constants in the beginning of the function. as the time to debounce and for a quick press is 50ms or more. The time for a long press is 2 seconds. These values are easily changed to fine tune for your hardware/situation.
External to the function, the only requirements are that the button pin be defined. In addition, a second Pin is defined as a ground pin, usually adjacent to the button pin, to allow both wires to the button to run side by side. This first pin should be defined as "INPUT_ONLY". The second pin should be defined as an "OUTPUT", and a digital write should set the pin LOW.
It has been written so that there are no intrinsic timing loops. This means your sketch can continue processing while the button function continues to pause for debouncing or waiting for a long press.
#define buttonPin 12
#define groundPin 11
void setup() {
// put your setup code here, to run once:
Serial.begin(57600);
pinMode(buttonPin,INPUT_PULLUP);
pinMode(groundPin,OUTPUT);
digitalWrite(groundPin,LOW);
}
void loop() {
while (true) {
switch (checkButton()) {
case 0:
break;
case 1:
Serial.println();Serial.println("Short press");
break;
case 2:
Serial.println();Serial.println("L-o-n-g press");
break;
}
}
}
int checkButton() {
const int stateNormal=0; // no button activity
const int stateShort=1; // short button press
const int stateLong=2; // long button press
const long longDelta=2000; // hold 2 seconds for a long press
const long debounceDelta=50; // debounce time of 50ms
static int lastButtonStatus=HIGH; // HIGH indicates the button is NOT pressed
static long longTime=0, shortTime=0; // future times to determine is button has been poressed a short or long time
int buttonStatus; // button state Pressed/LOW; Open/HIGH
boolean Released=true, Transition=false; // various button states
boolean timeoutShort=false, timeoutLong=false; // flags for the state of the presses
buttonStatus=digitalRead(buttonPin); // read the button state on the pin "buttonPin"
timeoutShort=(millis()>shortTime); // calculate the current time states for the button presses
timeoutLong =(millis()>longTime);
if (buttonStatus != lastButtonStatus) { // reset the timeouts if the button state changed
longTime =millis()+longDelta;
shortTime=millis()+debounceDelta;
}
Transition=(buttonStatus != lastButtonStatus);
Released = (Transition && (buttonStatus == HIGH)); // for input pullup circuit
lastButtonStatus = buttonStatus; // save the button status
if ( ! Transition) return stateNormal; // if there has not been a transition, return the normal state
if (timeoutLong && Released) { // long timeout has occurred and the button was just released
return stateLong;
} else if (timeoutShort && Released){ // short timeout has occurred (and not long timeout) and button ws just released
return stateShort;
} else { // else there is no change in status, return the normal state
return stateNormal;
}
}