Button2: click handlers for one push button
Button2 by Lennart Hennigs reads a button and calls a function you register for each kind of press: a click, a double click, a triple click, a long click, or simply pressed and released. It is popular on the ESP32 boards with a built-in button, such as the TTGO T-Display, but works the same way on an Uno.
Built in on Mokxi: #include <Button2.h> and it builds, with nothing to install. Free, and no account needed.
What Button2 does
Each handler receives the button itself, as Button2 &, so one function can serve several buttons and ask which one called it with getPin() or how long it was held with wasPressedFor(). Calls to button.loop() on every pass of loop() do the reading; the handlers then run from inside loop(), never from an interrupt.
The timing is what decides which handler fires. A press shorter than the long-click time (200 ms by default) counts as a click, and the library waits out the double-click time (300 ms) to see whether another press follows before it reports a click, double or triple click. A long click is reported when the button is released. In Mokxi the handlers must be plain functions: a lambda that captures variables does not build.
| Library Manager name | Button2 |
|---|---|
| Author | Lennart Hennigs |
| Include | #include <Button2.h> |
| Boards | every board Mokxi compiles for |
| In the simulator | Simulated: it runs against the part the way it does on the bench. |
| Parts it drives | Pushbutton |
Install it
It builds on every board Mokxi compiles for.
In Mokxi it is built in: #include <Button2.h> and the sketch compiles, with no download, no zip and no Library Manager.
On a real board, install "Button2" by Lennart Hennigs from the Arduino IDE’s Library Manager (Sketch, Include Library, Manage Libraries), or add Button2 to lib_deps in PlatformIO. Mokxi follows the calls of release 2.7.0, so a sketch written here builds there too.
What to know in the simulator: Handlers are plain functions; a lambda that captures variables (a std::function upstream on the ESP32) does not build.
- ESP32-C3
- Arduino Uno
- Arduino Nano
- Arduino Mega 2560
- Arduino Leonardo
- SparkFun Pro Micro
- Arduino Micro
- ESP32-C6
- WCH CH32V003
- ATtiny85
- Raspberry Pi Pico
- Raspberry Pi Pico W
- Seeed XIAO SAMD21
- STM32
- STM32 Nucleo-F411RE
- STM32 Blue Pill
- micro:bit V2
- Arduino Uno R4
- ESP32 DevKit
- ESP32-S3-DevKitC-1
- ESP8266 NodeMCU
- Arduino Pro Mini 3.3 V
- Seeed XIAO ESP32-C3
- ESP32-C3 SuperMini
- Seeed XIAO ESP32-C6
- ESP32-DevKitC V4
- LOLIN32 Lite
- Wemos D1 R32
- Cheap Yellow Display
- TTGO T-Display
- Seeed XIAO ESP32-S3
- Arduino Nano ESP32
- Arduino Nano RP2040 Connect
- Seeed XIAO RP2040
- Waveshare RP2040-Zero
- Arduino Uno R4 WiFi
The calls you will use
In the order a sketch meets them.
Button2 button
Declares a button. Its pin is given to begin().
button.begin(2)
Uses pin 2 with the internal pull-up, so pressed reads LOW. Wire the button between the pin and GND.
button.setClickHandler(click)
Runs void click(Button2 &btn) after a single short press, once the double-click time has passed with no second press.
button.setDoubleClickHandler(doubleClick)
Runs a function after two quick presses. setTripleClickHandler() does the same for three.
button.setLongClickHandler(longClick)
Runs a function when a press longer than the long-click time is released.
void longClick(Button2 &btn) {
Serial.print("held ");
Serial.println(btn.wasPressedFor());
}button.setLongClickDetectedHandler(holding)
Runs as soon as the long-click time is reached, while the button is still down, for feedback before release.
button.setLongClickTime(1000)
Changes the long-click threshold in ms. setDoubleClickTime() and setDebounceTime() change the others.
button.loop()
Reads the pin and runs any handler that is due. Call it on every pass of loop().
Example: Click, double click and long click
On the Arduino Uno R3. It runs in the browser exactly as printed.
#include "Button2.h"
Button2 button;
void click(Button2 &) { Serial.println("click"); }
void doubleClick(Button2 &) { Serial.println("double click"); }
void longClick(Button2 &btn) {
Serial.print("long click (");
Serial.print(btn.wasPressedFor());
Serial.println(" ms)");
}
void setup() {
Serial.begin(9600);
button.begin(2);
button.setClickHandler(click);
button.setDoubleClickHandler(doubleClick);
button.setLongClickHandler(longClick);
Serial.println("Button Demo");
}
void loop() {
button.loop();
}Wiring
- Arduino Uno R3 2 to Pushbutton 1a
- Arduino Uno R3 GND to Pushbutton 2a
Common errors and how to fix them
Every quick press is reported as a long click
The default long-click time is only 200 ms. Raise it with setLongClickTime(800) or so, which suits most people’s idea of a long press.
A single click takes a moment to be reported
The library is waiting the double-click time in case a second press follows. Shorten it with setDoubleClickTime(200), or use setPressedHandler() when you need an instant response.
no matching function for call to setClickHandler with a lambda
In Mokxi the handlers are plain function pointers, so a lambda that captures variables cannot convert. Write a normal function that takes Button2 & and reads globals instead.
Try Button2 without installing anything
Open the example, change the sketch, and keep your version in a free account.