AceButton
An adjustable, compact, event-driven button library for Arduino that debounces and dispatches events to a user-defined event handler.
Install / Use
/learn @bxparks/AceButtonREADME
AceButton
An adjustable, compact, event-driven button library for Arduino platforms.
This library provides classes which accept inputs from a mechanical button connected to a digital input pin on the Arduino. The library should be able to handle momentary buttons, maintained buttons, and switches, but it was designed primarily for momentary (aka push) buttons.
The library is named "AceButton" because:
- many configurations of the button are adjustable, either at compile-time or run-time
- the library is optimized to create compact objects which take up a minimal amount of static memory
- the library detects changes in the button state and sends events to
a user-defined
EventHandlercallback function
Most of the features of the library can be accessed through 2 classes, using either a callback function or an interface:
AceButton(class)ButtonConfig(class)EventHandler(typedef for callback function)IEventHandler(interface)
The AceButton class contains the logic for debouncing and determining if a
particular event has occurred.
The ButtonConfig class holds various timing parameters, the event handler,
code for reading the button, and code for getting the internal clock.
The EventHandler is a user-defined callback function with a specific signature
which is registered with the ButtonConfig object. When the library detects
interesting events, the callback function is called by the library, allowing the
client code to handle the event.
The IEventHandler is an interface (pure abstract class) that provides an
alternative to the EventHandler. Instead of using a callback function, an
object of type IEventHandler can be used to handle the button events.
The supported events are:
AceButton::kEventPressedAceButton::kEventReleasedAceButton::kEventClickedAceButton::kEventDoubleClickedAceButton::kEventLongPressedAceButton::kEventRepeatPressedAceButton::kEventLongReleased(v1.8)AceButton::kEventHeartBeat(v1.10)
The basic ButtonConfig class assumes that each button is connected to a single
digital input pin. In some situations, the number of buttons that we want is
greater than the number of input pins available. This library provides
2 subclasses of ButtonConfig which may be useful:
EncodedButtonConfig- Supports binary encoded buttons, to read
2^N - 1buttons usingNpins (e.g. 7 buttons using 3 digital pins).
- Supports binary encoded buttons, to read
LadderButtonConfig- Supports 1-8 buttons (maybe more) on a single analog pin through a
resistor ladder. The
analogRead()method is used to read the different voltage levels corresponding to each button.
- Supports 1-8 buttons (maybe more) on a single analog pin through a
resistor ladder. The
Both EncodedButtonConfig and LadderButtonConfig support all events listed
above (e.g. kEventClicked and kEventDoubleClicked).
Version: 1.10.1 (2023-05-25)
Changelog: CHANGELOG.md
Table of Contents
- Features
- HelloButton
- Installation
- Documentation
- Usage
- Advanced Topics
- Resource Consumption
- System Requirements
- Background Motivation
- Bugs and Limitations
- License
- Feedback and Support
- Author
<a name="Features"></a>
Features
Here are the high-level features of the AceButton library:
- debounces the mechanical contact
- supports both pull-up and pull-down wiring
- event-driven through a user-defined
EventHandlercallback function - event-driven through an object-based
IEventHandler(>= v1.6) - supports the following event types:
kEventPressedkEventReleasedkEventClickedkEventDoubleClickedkEventLongPressedkEventRepeatPressedkEventLongReleasedkEventHeartBeat
- adjustable configurations at runtime or compile-time
- timing parameters
digitalRead()button read function can be overriddenmillis()clock function can be overridden
- small memory footprint
- each
AceButtonconsumes 17 bytes (8-bit) or 20 bytes (32-bit) - each
ButtonConfigconsumes 20 bytes (8-bit) or 24 bytes (32-bit) - one System
ButtonConfiginstance created automatically by the library - 970-2180 bytes of flash memory for the simple case of 1 AceButton and 1 ButtonConfig, depending on 8-bit or 32-bit processors
- each
- supports multiple buttons on shared pins using various circuits
- Binary Encoded buttons (e.g. 7 buttons using 3 pins)
- Resistor Ladder buttons (e.g. 5 buttons on a single analog pin)
- only 13-15 microseconds (on 16MHz ATmega328P) per polling call to
AceButton::check() - extensive testing
- thoroughly unit tested using AUnit
- Tier 1 support includes: Arduino AVR (UNO, Nano, Micro etc), SAMD21 (Seeed XIAO M0), STM32 (Blue Pill), SAMD51 (Adafruit ItsyBitsy M4), ESP8266, and ESP32
Compared to other Arduino button libraries, I think the unique or exceptional features of the AceButton library are:
- many supported event types (e.g. LongPressed and RepeatPressed)
- able to distinguish between Clicked and DoubleClicked
- small memory usage
- thorough unit testing
- support for multiple buttons using Binary Encoding or a Resistor Ladder
<a name="HelloButton"></a>
HelloButton
Here is a simple program (see examples/HelloButton) which controls the builtin LED on the Arduino board using a momentary button connected to PIN 2.
#include <AceButton.h>
using namespace ace_button;
const int BUTTON_PIN = 2;
const int LED_ON = HIGH;
const int LED_OFF = LOW;
AceButton button(BUTTON_PIN);
void handleEvent(AceButton*, uint8_t, uint8_t);
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
pinMode(BUTTON_PIN, INPUT_PULLUP);
button.setEventHandler(handleEvent);
}
void loop() {
button.check();
}
void handleEvent(AceButton* /*button*/, uint8_t eventType,
uint8_t /*buttonState*/) {
switch (eventType) {
case AceButton::kEventPressed:
digitalWrite(LED_BUILTIN, LED_ON);
break;
case AceButton::kEventReleased:
digitalWrite(LED_BUILTIN, LED_OFF);
break;
}
}
(The button and buttonState parameters are commented out to avoid an unused parameter warning from the compiler. We can't remove the parameters completely
because the method signature is defined by the EventHandler typedef.)
<a name="Installation"></a>
Installation
The latest stable release is available in the Arduino IDE Library Manager. Search for "AceButton". Click install.
The development version can be installed by cloning the
GitHub repository (https://github.com/bxparks/AceButton), checking out the
develop branch, then manually copying over the contents to the ./libraries
directory used by the Arduino IDE. (The result is a directory named
./libraries/AceButton.)
The master branch contains the tagged stable releases.
<a name="ExternalDependencies"></a>
External Dependencies
The core of the library is self-contained and has no external dependencies.
The some programs in examples/ may depend on:
- AceCommon (https://github.com/bxparks/AceCommon)
The unit tests under tests depend on:
- AUnit (https://github.com/bxparks/AUnit)
<a name="SourceCode"></a>
Source Code
The source files are organized as follows:
src/AceButton.h- main header filesrc/ace_button/- all implementation filessrc/ace_button/testing/- internal testing filestests/- unit tests which re
