Example Arduino code for debouncing and long pressing buttons

I’ve recently been playing around with Arduino, and put together a code snippet that I am running on an ESP8266 WiFi module.

It’s very basic, and just registers button presses of more than 50ms, but less than 5000ms as a normal/short press, and anything over 5000ms as a long press.

This can be handy when you have a limited number of buttons (e.g. only one) and you want to provide different options for using that button (short press and long press) and also want to ensure that the button is debounced (electrical “noise” is filtered out to avoid spurious button presses being registered).

Below is the code, which can be adapted to suit your purpose.

const int buttonPin = 0; // input button pin number
const unsigned long longPressThreshold = 5000; // the threshold (in milliseconds) before a long press is detected
const unsigned long debounceThreshold = 50; // the threshold (in milliseconds) for a button press to be confirmed (i.e. not "noise")

unsigned long buttonTimer = 0; // stores the time that the button was pressed (relative to boot time)
unsigned long buttonPressDuration = 0; // stores the duration (in milliseconds) that the button was pressed/held down for

boolean buttonActive = false; // indicates if the button is active/pressed
boolean longPressActive = false; // indicate if the button has been long-pressed

void setup() {
pinMode(buttonPin, INPUT); // set the button pin as an input

// Start serial debugging
Serial.begin(115200);
Serial.println();
Serial.println("Serial debugging started");
}

void loop() {

// if the button pin reads LOW, the button is pressed (negative/ground switch)
if (digitalRead(buttonPin) == LOW)
{
// mark the button as active, and start the timer
if (buttonActive == false)
{
buttonActive = true;
buttonTimer = millis();
}

// calculate the button press duration by subtracting the button time from the boot time
buttonPressDuration = millis() - buttonTimer;

// mark the button as long-pressed if the button press duration exceeds the long press threshold
if ((buttonPressDuration > longPressThreshold) && (longPressActive == false))
{
longPressActive = true;
Serial.print("Long press detected: ");
Serial.println(buttonPressDuration);
}
}

// button either hasn't been pressed, or has been released
else
{
// if the button was marked as active, it was recently pressed
if (buttonActive == true)
{
// reset the long press active state
if (longPressActive == true)
{
longPressActive = false;
}

// we either need to debounce the press (noise) or register a normal/short press
else
{
// if the button press duration exceeds our bounce threshold, then we register a short press
if (buttonPressDuration > debounceThreshold)
{
Serial.print("Short press detected: ");
Serial.println(buttonPressDuration);
}

// if the button press is less than our bounce threshold, we debounce (i.e. ignore as noise)
else
{
Serial.print("Debounced: ");
Serial.println(buttonPressDuration);
}
}

// reset the button active status
buttonActive = false;
}
}
}