acid-drop

- Hacking the planet from a LilyGo T-Deck using custom firmware
git clone git://git.acid.vegas/acid-drop.git
Log | Files | Refs | Archive | README | LICENSE

README.md (40586B)

      1 # AceButton
      2 
      3 An adjustable, compact, event-driven button library for Arduino platforms.
      4 
      5 Version: 1.3.3 (2019-03-10)
      6 
      7 [![AUniter Jenkins Badge](https://us-central1-xparks2018.cloudfunctions.net/badge?project=AceButton)](https://github.com/bxparks/AUniter)
      8 
      9 ## Summary
     10 
     11 This library provides classes which accept inputs from a mechanical button
     12 connected to a digital input pin on the Arduino. The library should be able to
     13 handle momentary buttons, maintained buttons, and switches, but it was designed
     14 primarily for momentary buttons.
     15 
     16 The library is called the ACE Button Library (or AceButton Library) because:
     17 
     18 * many configurations of the button are **adjustable**, either at compile-time
     19   or run-time
     20 * the library is optimized to create **compact** objects which take up
     21   a minimal amount of static memory
     22 * the library detects changes in the button state and sends **events** to
     23   a user-defined `EventHandler` callback function
     24 
     25 Most of the features of the library can be accessed through 2 classes and
     26 1 callback function:
     27 
     28 * `AceButton` (class)
     29 * `ButtonConfig` (class)
     30 * `EventHandler` (typedef)
     31 
     32 The `AceButton` class contains the logic for debouncing and determining if a
     33 particular event has occurred. The `ButtonConfig` class holds various timing
     34 parameters, the event handler, code for reading the button, and code for
     35 getting the internal clock. The `EventHandler` is a user-defined callback
     36 function with a specific signature which is registered with the `ButtonConfig`
     37 object. When the library detects interesting events, the callback function is
     38 called by the library, allowing the client code to handle the event.
     39 
     40 The supported events are:
     41 
     42 * `AceButton::kEventPressed`
     43 * `AceButton::kEventReleased`
     44 * `AceButton::kEventClicked`
     45 * `AceButton::kEventDoubleClicked`
     46 * `AceButton::kEventLongPressed`
     47 * `AceButton::kEventRepeatPressed`
     48 
     49 (TripleClicked is not supported but can be easily added to the library if
     50 requested.)
     51 
     52 ### Features
     53 
     54 Here are the high-level features of the AceButton library:
     55 
     56 * debounces the mechanical contact
     57 * supports both pull-up and pull-down wiring
     58 * event-driven through a user-defined `EventHandler` callback funcition
     59 * supports 6 event types:
     60     * Pressed
     61     * Released
     62     * Clicked
     63     * DoubleClicked
     64     * LongPressed
     65     * RepeatPressed
     66 * can distinguish between Clicked and DoubleClicked
     67 * adjustable configurations at runtime or compile-time
     68     * timing parameters
     69     * `digitalRead()` button read function can be overridden
     70     * `millis()` clock function can be overridden
     71 * small memory footprint
     72     * each `AceButton` consumes 14 bytes
     73     * each `ButtonConfig` consumes 20 bytes
     74     * one System `ButtonConfig` instance created automatically by the library
     75 * thoroughly unit tested using [AUnit](https://github.com/bxparks/AUnit)
     76 * properly handles reboots while the button is pressed
     77 * properly handles orphaned clicks, to prevent spurious double-clicks
     78 * only 13-15 microseconds (on 16MHz ATmega328P) per polling call to `AceButton::check()`
     79 * can be instrumented to extract profiling numbers
     80 * tested on Arduino AVR (UNO, Nano, etc), Teensy ARM (LC
     81   and 3.2), ESP8266 and ESP32 platforms
     82 
     83 Compared to other Arduino button libraries, I think the unique or exceptional
     84 features of the AceButton library are:
     85 
     86 * many supported event types (e.g. LongPressed and RepeatPressed)
     87 * able to distinguish between Clicked and DoubleClicked
     88 * small memory usage
     89 * thorough unit testing
     90 * proper handling of orphaned clicks
     91 * proper handling of a reboot while button is pressed
     92 
     93 ### Non-goals
     94 
     95 An Arduino UNO or Nano has 16 times more flash memory (32KB) than static memory
     96 (2KB), so the library is optimized to minimize the static memory usage. The
     97 AceButton library is not optimized to create a small program size (i.e. flash
     98 memory), or for small CPU cycles (i.e. high execution speed). I assumed that if
     99 you are seriously optimizing for program size or CPU cycles, you will probably
    100 want to write everything yourself from scratch.
    101 
    102 That said, the [examples/AutoBenchmark](examples/AutoBenchmark) program
    103 shows that `AceButton::check()` takes between 13-15 microseconds on a 16MHz
    104 ATmega328P chip on average. Hopefully that is fast enough for the vast
    105 majority of people.
    106 
    107 ### HelloButton
    108 
    109 Here is a simple program (see `examples/HelloButton.ino`) which controls
    110 the builtin LED on the Arduino board using a momentary button connected
    111 to PIN 2.
    112 
    113 ```C++
    114 #include <AceButton.h>
    115 using namespace ace_button;
    116 
    117 const int BUTTON_PIN = 2;
    118 const int LED_ON = HIGH;
    119 const int LED_OFF = LOW;
    120 
    121 AceButton button(BUTTON_PIN);
    122 
    123 void handleEvent(AceButton*, uint8_t, uint8_t);
    124 
    125 void setup() {
    126   pinMode(LED_BUILTIN, OUTPUT);
    127   pinMode(BUTTON_PIN, INPUT_PULLUP);
    128   button.setEventHandler(handleEvent);
    129 }
    130 
    131 void loop() {
    132   button.check();
    133 }
    134 
    135 void handleEvent(AceButton* /* button */, uint8_t eventType,
    136     uint8_t /* buttonState */) {
    137   switch (eventType) {
    138     case AceButton::kEventPressed:
    139       digitalWrite(LED_BUILTIN, LED_ON);
    140       break;
    141     case AceButton::kEventReleased:
    142       digitalWrite(LED_BUILTIN, LED_OFF);
    143       break;
    144   }
    145 }
    146 ```
    147 
    148 (The `button` and `buttonState` parameters are commented out to avoid an `unused
    149 parameter` warning from the compiler. We can't remove the parameters completely
    150 because the method signature is defined by the `EventHandler` typedef.)
    151 
    152 ## Installation
    153 
    154 The latest stable release is available in the Arduino IDE Library Manager.
    155 Search for "AceButton". Click install.
    156 
    157 The development version can be installed by cloning the
    158 [GitHub repository](https://github.com/bxparks/AceButton), checking out the
    159 `develop` branch, then manually copying over the contents to the `./libraries`
    160 directory used by the Arduino IDE. (The result is a directory named
    161 `./libraries/AceButton`.) The `master` branch contains the stable release.
    162 
    163 ### Source Code
    164 
    165 The source files are organized as follows:
    166 * `src/AceButton.h` - main header file
    167 * `src/ace_button/` - all implementation files
    168 * `src/ace_button/testing/` - internal testing files
    169 * `tests/` - unit tests which require [AUnit](https://github.com/bxparks/AUnit)
    170 * `examples/` - example sketches
    171 
    172 ### Docs
    173 
    174 Besides this README.md file, the [docs/](docs/) directory contains the
    175 [Doxygen docs published on GitHub Pages](https://bxparks.github.io/AceButton/html/).
    176 It can help you navigate an unfamiliar code base.
    177 
    178 ### Examples
    179 
    180 The following example sketches are provided:
    181 
    182 * [HelloButton.ino](examples/HelloButton)
    183     * minimal program that reads a switch and control the built-in LED
    184 * [SingleButton.ino](examples/SingleButton)
    185     * controls a single button wired with a pull-up resistor
    186     * prints out a status line for every supported event
    187 * [SingleButtonPullDown.ino](examples/SingleButtonPullDown)
    188     * same as SingleButton.ino but with an external pull-down resistor
    189 * [Stopwatch.ino](examples/Stopwatch)
    190     * measures the speed of `AceButton:check()` with a start/stop/reset button
    191     * uses `kFeatureLongPress`
    192 * [TunerButtons.ino](examples/TunerButtons)
    193     * implements 5 radio buttons (tune-up, tune-down, and 3 presets)
    194     * shows multiple `ButtonConfig` instances
    195     * shows multiple `EventHandler`s
    196     * shows an example of how to use `getId()`
    197     * uses `kFeatureLongPress`, `kFeatureRepeatPress`,
    198       `kFeatureSuppressAfterLongPress`, and `kFeatureSuppressAfterRepeatPress`
    199 * [ClickVersusDoubleClickUsingReleased.ino](examples/ClickVersusDoubleClickUsingReleased)
    200     * a way to distinguish between a `kEventClicked` from a
    201       `kEventDoubleClicked` using a `kEventReleased` instead
    202 * [ClickVersusDoubleClickUsingSuppression.ino](examples/ClickVersusDoubleClickUsingSuppression)
    203     * another way to dstinguish between a `kEventClicked` from a
    204       `kEventDoubleClicked` using the `kFeatureSuppressClickBeforeDoubleClick`
    205       flag at the cost of increasing the response time of the `kEventClicked`
    206       event
    207 * [ClickVersusDoubleClickUsingBoth.ino](examples/ClickVersusDoubleClickUsingBoth)
    208     * an example that combines both the "UsingPressed" and "UsingSuppression"
    209       techniques
    210 * [CapacitiveButton](examples/CapacitiveButton)
    211     * reads a capacitive button using the
    212       [CapacitiveSensor](https://github.com/PaulStoffregen/CapacitiveSensor)
    213       library
    214 * [AutoBenchmark.ino](examples/AutoBenchmark)
    215     * generates the timing stats (min/average/max) for the `AceButton::check()`
    216       method for various types of events (idle, press/release, click,
    217       double-click, and long-press)
    218 
    219 ## Usage
    220 
    221 There are 2 classes and one typedef that a user will normally interact with:
    222 
    223 * `AceButton` (class)
    224 * `ButtonConfig` (class)
    225 * `EventHandler` (typedef)
    226 
    227 We explain how to use these below.
    228 
    229 ### Include Header and Use Namespace
    230 
    231 Only a single header file `AceButton.h` is required to use this library.
    232 To prevent name clashes with other libraries that the calling code may use, all
    233 classes are defined in the `ace_button` namespace. To use the code without
    234 prepending the `ace_button::` prefix, use the `using` directive:
    235 
    236 ```C++
    237 #include <AceButton.h>
    238 using namespace ace_button;
    239 ```
    240 
    241 If you are dependent on just `AceButton`, the following might be sufficient:
    242 
    243 ```C++
    244 #include <AceButton.h>
    245 using ace_button::AceButton;
    246 ```
    247 
    248 ### Pin Wiring and Initialization
    249 
    250 An Arduino microcontroller pin can be in an `OUTPUT` mode, an `INPUT` mode, or
    251 an `INPUT_PULLUP` mode. This mode is controlled by the `pinMode()` method.
    252 
    253 By default upon boot, the pin is set to the `INPUT` mode. However, this `INPUT`
    254 mode puts the pin into a high impedance state, which means that if there is no
    255 wire connected to the pin, the voltage on the pin is indeterminant. When the
    256 input pin is read (using `digitalRead()`), the boolean value will be a random
    257 value. If you are using the pin in `INPUT` mode, you *must* connect an external
    258 pull-up resistor (connected to Vcc) or pull-down resistor (connected to ground)
    259 so that the voltage level of the pin is defined when there is nothing connected
    260 to the pin (i.e. when the button is not pressed).
    261 
    262 The `INPUT_PULLUP` mode is a special `INPUT` mode which tells the
    263 microcontroller to connect an internal pull-up resistor to the pin. It is
    264 activated by calling `pintMode(pin, INPUT_PULLUP)` on the given `pin`. This mode
    265 is very convenient because it eliminates the external resistor, making the
    266 wiring simpler.
    267 
    268 The AceButton library itself does *not* call the `pinMode()` function. The
    269 calling application is responsible for calling `pinMode()`. Normally, this
    270 happens in the global `setup()` method but the call can happen somewhere else if
    271 the application requires it. The reason for decoupling the hardware
    272 configuration from the AceButton library is mostly because the library does not
    273 actually care about the specific hardware wiring of the button. It does not care
    274 whether an external resistor is used, or the internal resistor is used. It only
    275 cares about whether the resistor is a pull-up or a pull-down.
    276 
    277 See https://www.arduino.cc/en/Tutorial/DigitalPins for additional information
    278 about the I/O pins on an Arduino.
    279 
    280 ### AceButton Class
    281 
    282 Each physical button will be handled by an instance of `AceButton`. At a
    283 minimum, the instance needs to be told the pin number of the button. This can
    284 be done through the constructor:
    285 
    286 ```C++
    287 const uint8_t BUTTON_PIN = 2;
    288 
    289 AceButton button(BUTTON_PIN);
    290 
    291 void setup() {
    292   pinMode(BUTTON_PIN, INPUT_PULLUP);
    293   ...
    294 }
    295 ```
    296 
    297 Or we can use the `init()` method in the `setup()`:
    298 
    299 ```C++
    300 AceButton button;
    301 
    302 void setup() {
    303   pinMode(BUTTON_PIN, INPUT_PULLUP);
    304   button.init(BUTTON_PIN);
    305   ...
    306 }
    307 ```
    308 
    309 Both the constructor and the `init()` function take 3 optional parameters:
    310 ```C++
    311 AceButton(uint8_t pin = 0, uint8_t defaultReleasedState = HIGH, uint8_t id = 0);
    312 
    313 void init(uint8_t pin = 0, uint8_t defaultReleasedState = HIGH, uint8_t id = 0);
    314 ```
    315 
    316 * `pin`: the I/O pin number assigned to the button
    317 * `defaultReleasedState`: the logical value of the button when it is in its
    318   default "released" state (`HIGH` using a pull-up resistor,
    319   `LOW` for a pull-down pull-down resistor)
    320 * `id`: an optional, user-defined identifier for the the button,
    321   for example, an index into an array with additional information
    322 
    323 The `pin` must be defined either through the constructor or the `init()` method.
    324 But the other two parameters may be optional in many cases.
    325 
    326 Finally, the `AceButton::check()` method should be called from the `loop()`
    327 method periodically. Roughly speaking, this should be about 4 times faster than
    328 the value of `getDebounceDelay()` so that the various event detection logic can
    329 work properly. (If the debounce delay is 20 ms, `AceButton::check()` should be
    330 called every 5 ms or faster.)
    331 
    332 ```C++
    333 void loop() {
    334   ...
    335   button.check();
    336   ...
    337 }
    338 ```
    339 
    340 ### ButtonConfig Class
    341 
    342 The core concept of the AceButton library is the separation of the
    343 button (`AceButton`) from its configuration (`ButtonConfig`).
    344 
    345 * The `AceButton` class has the logic for debouncing and detecting the various
    346   events (Pressed, Released, etc), and the various bookkeeping variables
    347   needed to implement the logic. These variables are associated with the
    348   specific instance of that `AceButton`.
    349 * The `ButtonConfig` class has the various timing parameters which control
    350   how much time is needed to detect certain events. This class also has the
    351   ability to override the default methods for reading the pin (`readButton()`)
    352   and the clock (`getClock()`). This ability allows unit tests to be written.
    353 
    354 The `ButtonConfig` can be created and assigned to one or more `AceButton`
    355 instances using dependency injection through the `AceButton(ButtonConfig*)`
    356 constructor. If this constructor is used, then the `AceButton::init()` method
    357 must be used to set the pin number of the button. For example:
    358 
    359 ```C++
    360 const uint8_t PIN1 = 2;
    361 const uint8_t PIN2 = 4;
    362 
    363 ButtonConfig buttonConfig;
    364 AceButton button1(&buttonConfig);
    365 AceButton button2(&buttonConfig);
    366 
    367 void setup() {
    368   pinMode(PIN1, INPUT_PULLUP);
    369   button1.init(PIN1);
    370 
    371   pinMode(PIN2, INPUT_PULLUP);
    372   button2.init(PIN2);
    373   ...
    374 }
    375 ```
    376 
    377 Another way to inject the `ButtonConfig` dependency is to use the
    378 `AceButton::setButtonConfig()` method but it is recommended that you use the
    379 constructor instead because the dependency is easier to follow.
    380 
    381 #### System ButtonConfig
    382 
    383 A single instance of `ButtonConfig` called the "System ButtonConfig" is
    384 automatically created by the library at startup. By default, all instances of
    385 `AceButton` are automatically assigned to this singleton instance. We explain in
    386 the _Single Button Simplifications_ section below how this simplifies the code
    387 needed to handle a single button.
    388 
    389 #### Configuring the EventHandler
    390 
    391 The `ButtonConfig` class provides a number of methods which are mostly
    392 used internally by the `AceButton` class. The one method which is expected
    393 to be used by the calling client code is `setEventHandler()` which
    394 assigns the user-defined `EventHandler` callback function to the `ButtonConfig`
    395 instance. This is explained in more detail below in the
    396 _EventHandler Callback_ section.
    397 
    398 #### Timing Parameters
    399 
    400 Here are the methods to retrieve the timing parameters:
    401 
    402 * `uint16_t getDebounceDelay();` (default: 20 ms)
    403 * `uint16_t getClickDelay();` (default: 200 ms)
    404 * `uint16_t getDoubleClickDelay();` (default: 400 ms)
    405 * `uint16_t getLongPressDelay();` (default: 1000 ms)
    406 * `uint16_t getRepeatPressDelay();` (default: 1000 ms)
    407 * `uint16_t getRepeatPressInterval();` (default: 200 ms)
    408 
    409 The default values of each timing parameter can be changed at run-time using
    410 the following methods:
    411 
    412 * `void setDebounceDelay(uint16_t debounceDelay);`
    413 * `void setClickDelay(uint16_t clickDelay);`
    414 * `void setDoubleClickDelay(uint16_t doubleClickDelay);`
    415 * `void setLongPressDelay(uint16_t longPressDelay);`
    416 * `void setRepeatPressDelay(uint16_t repeatPressDelay);`
    417 * `void setRepeatPressInterval(uint16_t repeatPressInterval);`
    418 
    419 #### Hardware Dependencies
    420 
    421 The `ButtonConfig` class has 2 methods which provide hooks to its external
    422 hardware dependencies:
    423 
    424 * `virtual unsigned long getClock();`
    425 * `virtual int readButton(uint8_t pin);`
    426 
    427 By default these are mapped to the underlying Arduino system functions respectively:
    428 
    429 * `millis()`
    430 * `digitalRead()`
    431 
    432 Unit tests are possible because these methods are `virtual` and the hardware
    433 dependencies can be swapped out with fake ones.
    434 
    435 #### Multiple ButtonConfig Instances
    436 
    437 We have assumed that there is a 1-to-many relationship between a `ButtonConfig`
    438 and the `AceButton`. In other words, multiple buttons will normally be
    439 associated with a single configuration. Each `AceButton` has a pointer to an
    440 instance of `ButtonConfig`. So the cost of separating the `ButtonConfig` from
    441 `AceButton` is 2 bytes in each instance of `AceButton`. Note that this is
    442 equivalent to adding virtual methods to `AceButton` (which would add 2 bytes),
    443 so in terms of static RAM size, this is a wash.
    444 
    445 The library is designed to handle multiple buttons, and it assumes that the
    446 buttons are normally grouped together into a handful of types. For example,
    447 consider the buttons of a car radio. It has several types of buttons:
    448 
    449 * the tuner buttons (2, up and down)
    450 * the preset buttons (6)
    451 * the AM/FM band button (1)
    452 
    453 In this example, there are 9 buttons, but only 3 instances of `ButtonConfig`
    454 would be needed.
    455 
    456 ### EventHandler
    457 
    458 The event handler is a callback function that gets called when the `AceButton`
    459 class determines that an interesting event happened on the button. The
    460 advantage of this mechanism is that all the complicated logic of determining
    461 the various events happens inside the `AceButton` class, and the user will
    462 normally not need to worry about the details.
    463 
    464 #### EventHandler Signature
    465 
    466 The event handler has the following signature:
    467 
    468 ```C++
    469 typedef void (*EventHandler)(AceButton* button, uint8_t eventType,
    470     uint8_t buttonState);
    471 ```
    472 
    473 The event handler is registered with the `ButtonConfig` object, not with the
    474 `AceButton` object, although the convenience method
    475 `AceButton::setEventHandler()` is provided as a pass-through to the underlying
    476 `ButtonConfig` (see the _Single Button Simplifications_ section below):
    477 
    478 ```C++
    479 ButtonConfig buttonConfig;
    480 
    481 void handleEvent(AceButton* button, uint8_t eventType, uint8_t buttonState) {
    482   ...
    483 }
    484 
    485 void setup() {
    486   ...
    487   buttonConfig.setEventHandler(handleEvent);
    488   ...
    489 }
    490 ```
    491 
    492 The motivation for this design is to save static memory. If multiple buttons
    493 are associated with a single `ButtonConfig`, then it is not necessary for every
    494 button of that type to hold the same pointer to the `EventHandler` function. It
    495 is only necessary to save that information once, in the `ButtonConfig` object.
    496 
    497 **Pro Tip**: Comment out the unused parameter(s) in the `handleEvent()` method
    498 to avoid the `unused parameter` compiler warning:
    499 ```C++
    500 void handleEvent(AceButton* /* button */, uint8_t eventType,
    501     uint8_t /* buttonState */) {
    502   ...
    503 }
    504 ```
    505 The Arduino sketch compiler can get confused with the parameters commented out,
    506 so you may need to add a forward declaration for the `handleEvent()` method
    507 before the `setup()` method:
    508 ```C++
    509 void handleEvent(AceButton*, uint8_t, uint8_t);
    510 ```
    511 
    512 #### EventHandler Parameters
    513 
    514 The `EventHandler` function receives 3 parameters from the `AceButton`:
    515 
    516 * `aceButton`
    517     * pointer to the `AceButton` instance that generated this event
    518     * can be used to retrieve the `getPin()` or the `getId()`
    519 * `eventType`
    520     * the type of this event given by the various `AceButton::kEventXxx`
    521       constants
    522 * `buttonState`
    523     * the `HIGH` or `LOW` button state that generated this event
    524 
    525 The `aceButton` pointer should be used only to extract information about the
    526 button that triggered the event. It should **not** be used to modify the
    527 button's internal variables in any way within the eventHandler. The logic in
    528 `AceButton::check()` assumes that those internal variable are held constant,
    529 and if they are changed by the eventHandler, unpredictable results may occur.
    530 (I was tempted to make the `aceButton` a pointer to a `const AceButton`
    531 but this cause too many viral changes to the code which seemed to increase
    532 the complexity without too much benefit.)
    533 
    534 If you are using only a single button, then you should need to check
    535 only the `eventType`.
    536 
    537 It is not expected that `buttonState` will be needed very often. It should be
    538 sufficient to examine just the `eventType` to determine the action that needs
    539 to be performed. Part of the difficulty with this parameter is that it has the
    540 value of `LOW` or `HIGH`, but the physical interpretation of those values depends
    541 on whether the button was wired with a pull-up or pull-down resistor. The helper
    542 function `AceButton::isReleased(uint8_t buttonState)` is provided to make this
    543 determination if you need it.
    544 
    545 #### One EventHandler
    546 
    547 Only a single `EventHandler` per `ButtonConfig` is supported. An alternative
    548 would have been to register a separate event handler for each of the 6
    549 `kEventXxx` events. But each callback function requires 2 bytes of memory, and
    550 it was assumed that in most cases, the calling client code would be interested
    551 in only a few of these event types, so it seemed wasteful to allocate 12 bytes
    552 when most of these would be unused. If the client code really wanted separate
    553 event handlers, it can be easily emulated by invoking them through the main
    554 event handler:
    555 
    556 ```C++
    557 void handleEvent(AceButton* button, uint8_t eventType, uint8_t buttonState) {
    558   switch (eventType) {
    559     case AceButton:kEventPressed:
    560       handleEventPressed(button, eventType, buttonState);
    561       break;
    562     case AceButton::kEventReleased:
    563       handleEventReleased(button, eventType, buttonState);
    564       break;
    565     ...
    566   }
    567 }
    568 ```
    569 
    570 #### EventHandler Tips
    571 
    572 The Arduino runtime environment is single-threaded, so the `EventHandler` is
    573 called in the middle of the `AceButton::check()` method, in the same thread as
    574 the `check()` method. It is therefore important to write the `EventHandler`
    575 code to run somewhat quickly, so that the delay doesn't negatively impact the
    576 logic of the `AceButton::check()` algorithm. Since `AceButton::check()` should
    577 run approximately every 5 ms, the user-provided `EventHandler` should run
    578 somewhat faster than 5 ms. Given a choice, it is probably better to use the
    579 `EventHandler` to set some flags or variables and return quickly, then do
    580 additional processing from the `loop()` method.
    581 
    582 Speaking of threads, the API of the AceButton Library was designed to work in a
    583 multi-threaded environment, if that situation were to occur in the Arduino
    584 world.
    585 
    586 ### Event Types
    587 
    588 The supported events are defined by a list of constants in `AceButton`:
    589 
    590 * `AceButton::kEventPressed` (always enabled)
    591 * `AceButton::kEventReleased` (conditionally enabled)
    592 * `AceButton::kEventClicked` (default: disabled)
    593 * `AceButton::kEventDoubleClicked` (default: disabled)
    594 * `AceButton::kEventLongPressed` (default: disabled)
    595 * `AceButton::kEventRepeatPressed` (default: disabled)
    596 
    597 These values are sent to the `EventHandler` in the `eventType` parameter.
    598 
    599 Two of the events are enabled by default, four are disabled by default but can
    600 be enabled by using a Feature flag described below.
    601 
    602 ### ButtonConfig Feature Flags
    603 
    604 There are 9 flags defined in `ButtonConfig` which can
    605 control the behavior of `AceButton` event handling:
    606 
    607 * `ButtonConfig::kFeatureClick`
    608 * `ButtonConfig::kFeatureDoubleClick`
    609 * `ButtonConfig::kFeatureLongPress`
    610 * `ButtonConfig::kFeatureRepeatPress`
    611 * `ButtonConfig::kFeatureSuppressAfterClick`
    612 * `ButtonConfig::kFeatureSuppressAfterDoubleClick`
    613 * `ButtonConfig::kFeatureSuppressAfterLongPress`
    614 * `ButtonConfig::kFeatureSuppressAfterRepeatPress`
    615 * `ButtonConfig::kFeatureSuppressClickBeforeDoubleClick`
    616 * `ButtonConfig::kFeatureSuppressAll`
    617 
    618 These constants are used to set or clear the given flag:
    619 
    620 ```C++
    621 ButtonConfig* config = button.getButtonConfig();
    622 
    623 config->setFeature(ButtonConfig::kFeatureLongPress);
    624 
    625 config->clearFeature(ButtonConfig::kFeatureLongPress);
    626 
    627 if (config->isFeature(ButtonConfig::kFeatureLongPress)) {
    628   ...
    629 }
    630 ```
    631 
    632 The meaning of these flags are described below.
    633 
    634 #### Event Activation
    635 
    636 Of the 6 event types, 4 are disabled by default:
    637 
    638 * `AceButton::kEventClicked`
    639 * `AceButton::kEventDoubleClicked`
    640 * `AceButton::kEventLongPressed`
    641 * `AceButton::kEventRepeatPressed`
    642 
    643 To receive these events, call `ButtonConfig::setFeature()` with the following
    644 flags respectively:
    645 
    646 * `ButtonConfig::kFeatureClick`
    647 * `ButtonConfig::kFeatureDoubleClick`
    648 * `ButtonConfig::kFeatureLongPress`
    649 * `ButtonConfig::kFeatureRepeatPress`
    650 
    651 To disable these events, call `ButtonConfig::clearFeature()` with one of these
    652 flags.
    653 
    654 Enabling `kFeatureDoubleClick` automatically enables `kFeatureClick`, because we
    655 need to have a Clicked event before a DoubleClicked event can be detected.
    656 
    657 It seems unlikely that both `LongPress` and `RepeatPress` events would be
    658 useful at the same time, but both event types can be activated if you need it.
    659 
    660 #### Event Suppression
    661 
    662 Event types can be considered to be built up in layers, starting with the
    663 lowest level primitive events: Pressed and Released. Higher level events are
    664 built on top of the lower level events through various timing delays. When a
    665 higher level event is detected, it is sometimes useful to suppress the lower
    666 level event that was used to detect the higher level event.
    667 
    668 For example, a Clicked event requires a Pressed event followed by a Released
    669 event within a `ButtonConfig::getClickDelay()` milliseconds (200 ms by
    670 default). The Pressed event is always generated. If a Clicked event is
    671 detected, we could choose to generate both a Released event and a Clicked
    672 event, and this is the default behavior.
    673 
    674 However, many times, it is useful to suppress the Released event if the Clicked
    675 event is detected. The `ButtonConfig` can be configured to suppress these lower
    676 level events. Call the `setFeature(feature)` method passing the various
    677 `kFeatureSuppressXxx` constants:
    678 
    679 * `ButtonConfig::kFeatureSuppressAfterClick`
    680     * suppresses the Released event after a Clicked event is detected
    681     * also suppresses the Released event from the *first* Clicked of a
    682       DoubleClicked, since `kFeatureDoubleClick` automatically enables
    683       `kFeatureClick`
    684 * `ButtonConfig::kFeatureSuppressAfterDoubleClick`
    685     * suppresses the Released event and the *second* Clicked event if a
    686       DoubleClicked event is detected
    687 * `ButtonConfig::kFeatureSuppressAfterLongPress`
    688     * suppresses the Released event if a LongPressed event is detected
    689 * `ButtonConfig::kFeatureSuppressAfterRepeatPress`
    690     * suppresses the Released event after the last RepeatPressed event
    691 * `ButtonConfig::kFeatureSuppressAll`
    692     * a convenience parameter that is the equivalent of suppressing all of the
    693       previous events
    694 * `ButtonConfig::kFeatureSuppressClickBeforeDoubleClick`
    695     * The *first* Clicked event is postponed by `getDoubleClickDelay()`
    696       millis until the code can determine if a DoubleClick has occurred. If so,
    697       then the postponed Clicked message to the `EventHandler` is suppressed.
    698     * See the section ___Distinguishing Between a Clicked and DoubleClicked___
    699       for more info.
    700 
    701 By default, no suppression is performed.
    702 
    703 As an example, to suppress the `Released` event after a `LongPressed` event
    704 (this is actually often the case), you would do this:
    705 
    706 ```C++
    707 ButtonConfig* config = button.getButtonConfig();
    708 config->setFeature(ButtonConfig::kFeatureSuppressAfterLongPress);
    709 ```
    710 
    711 The special convenient constant `kFeatureSuppressAll` is equivalent of using all
    712 suppression constants:
    713 
    714 ```C++
    715 ButtonConfig* config = button.getButtonConfig();
    716 config->setFeature(ButtonConfig::kFeatureSuppressAll);
    717 ```
    718 
    719 All suppressions can be cleared by using:
    720 ```C++
    721 ButtonConfig* config = button.getButtonConfig();
    722 config->clearFeature(ButtonConfig::kFeatureSuppressAll);
    723 ```
    724 
    725 Note, however, that the `isFeature(ButtonConfig::kFeatureSuppressAll)` currently
    726 means "isAnyFeature() implemented?" not "areAllFeatures() implemented?" We don't
    727 expect `isFeature()` to be used often (or at all) for `kFeatureSuppressAll`.
    728 
    729 ### Distinguishing Between a Clicked and DoubleClicked
    730 
    731 On a project using only a small number of buttons (due to physical limits or the
    732 limited availability of pins), it may be desirable to distinguish between a
    733 single Clicked event and a DoubleClicked event from a single button. This is a
    734 challenging problem to solve because fundamentally, a DoubleClicked event *must
    735 always* generate a Clicked event, because a Clicked event must happen before it
    736 can become a DoubleClicked event.
    737 
    738 Notice that on a desktop computer (running Windows, MacOS or Linux), a
    739 double-click on a mouse always generates both a Clicked and a DoubleClicked. The
    740 first Click selects the given desktop object (e.g. an icon or a window), and
    741 the DoubleClick performs some action on the selected object (e.g. open the
    742 icon, or resize the window).
    743 
    744 The AceButton Library provides 3 solutions which may work for some projects:
    745 
    746 **Method 1:** The `kFeatureSuppressClickBeforeDoubleClick` flag causes the first
    747 Clicked event to be detected, but the posting of the event message (i.e. the
    748 call to the `EventHandler`) is postponed until the state of the DoubleClicked
    749 can be determined. If the DoubleClicked happens, then the first Clicked event
    750 message is suppressed. If DoubleClicked does not occur, the long delayed
    751 Clicked message is sent via the `EventHandler`.
    752 
    753 There are two noticeable disadvantages of this method. First, the response time
    754 of all Clicked events is delayed by about 600 ms (`kClickDelay +
    755 kDoubleClickDelay`) whether or not the DoubleClicked event happens. Second, the
    756 user may not be able to accurately produce a Clicked event (due to the physical
    757 characteristics of the button, or the user's dexterity).
    758 
    759 It may also be worth noting that only the Clicked event is postponed.
    760 The accompanying Released event of the Clicked event is not postponed. So a
    761 single click action (without a DoubleClick) produces the following sequence of
    762 events to the EventHandler:
    763 
    764 1. `kEventPressed` - at time 0ms
    765 1. `kEventReleased` - at time 200ms
    766 1. `kEventClicked` - at time 600ms (200ms + 400ms)
    767 
    768 The `ButtonConfig` configuration looks like this:
    769 ```C++
    770 ButtonConfig* buttonConfig = button.getButtonConfig();
    771 buttonConfig->setFeature(ButtonConfig::kFeatureDoubleClick);
    772 buttonConfig->setFeature(
    773     ButtonConfig::kFeatureSuppressClickBeforeDoubleClick);
    774 ```
    775 
    776 See the example code at
    777 `examples/ClickVersusDoubleClickUsingSuppression/`.
    778 
    779 **Method 2:** A viable alternative is to use the Released event instead of the
    780 Clicked event to distinguish it from the DoubleClicked. For this method to work,
    781 we need to suppress the Released event after both Clicked and DoubleClicked.
    782 
    783 The advantage of using this method is that there is no response time lag in the
    784 handling of the Released event. To the user, there is almost no difference
    785 between triggering on the Released event, versus triggering on the Clicked
    786 event.
    787 
    788 The disadvantage of this method is that the Clicked event must be be ignored
    789 (because of the spurious Clicked event generated by the DoubleClicked). If the
    790 user accidentally presses and releases the button to quickly, it generates a
    791 Clicked event, which will cause the program to do nothing.
    792 
    793 The `ButtonConfig` configuration looks like this:
    794 ```C++
    795 ButtonConfig* buttonConfig = button.getButtonConfig();
    796 buttonConfig->setEventHandler(handleEvent);
    797 buttonConfig->setFeature(ButtonConfig::kFeatureDoubleClick);
    798 buttonConfig->setFeature(ButtonConfig::kFeatureSuppressAfterClick);
    799 buttonConfig->setFeature(ButtonConfig::kFeatureSuppressAfterDoubleClick);
    800 ```
    801 
    802 See the example code at
    803 `examples/ClickVersusDoubleClickUsingReleased/`.
    804 
    805 **Method 3:** We could actually combine both Methods 1 and 2 so that either
    806 Released or a delayed Click is considered to be a "Click". This may be the best
    807 of both worlds.
    808 
    809 The `ButtonConfig` configuration looks like this:
    810 ```C++
    811 ButtonConfig* buttonConfig = button.getButtonConfig();
    812 buttonConfig->setEventHandler(handleEvent);
    813 buttonConfig->setFeature(ButtonConfig::kFeatureDoubleClick);
    814 buttonConfig->setFeature(
    815     ButtonConfig::kFeatureSuppressClickBeforeDoubleClick);
    816 buttonConfig->setFeature(ButtonConfig::kFeatureSuppressAfterClick);
    817 buttonConfig->setFeature(ButtonConfig::kFeatureSuppressAfterDoubleClick);
    818 ```
    819 
    820 See the example code at
    821 `examples/ClickVersusDoubleClickUsingBoth/`.
    822 
    823 ### Single Button Simplifications
    824 
    825 Although the AceButton library is designed to shine for multiple buttons, you
    826 may want to use it to handle just one button. The library provides some features
    827 to make this simple case easy.
    828 
    829 1. The library automatically creates one instance of `ButtonConfig`
    830    called a "System ButtonConfig". This System ButtonConfig can be retrieved
    831    using the class static method `ButtonConfig::getSystemButtonConfig()`.
    832 1. Every instance of `AceButton` is assigned an instance of the System
    833    ButtonConfig by default (which can be overridden manually).
    834 1. A convenience method allows the `EventHandler` for the System
    835    ButtonConfig to be set easily through `AceButton` itself, instead of having
    836    to get the System ButtonConfig first, then set the event handler. In other
    837    words, `button.setEventHandler(handleEvent)` is a synonym for
    838    `button.getButtonConfig()->setEventHandler(handleEvent)`.
    839 
    840 These simplifying features allow a single button to be configured and used like
    841 this:
    842 
    843 ```C++
    844 AceButton button(BUTTON_PIN);
    845 
    846 void setup() {
    847   pinMode(BUTTON_PIN, INPUT_PULLUP);
    848   button.setEventHandler(handleEvent);
    849   ...
    850 }
    851 
    852 void loop() {
    853   button.check();
    854 }
    855 
    856 void handleEvent(AceButton* button, uint8_t eventType, uint8_t buttonState) {
    857   ...
    858 }
    859 ```
    860 
    861 To configure the System ButtonConfig, you may need to add something like
    862 this to the `setup()` section:
    863 
    864 ```C++
    865   button.getButtonConfig()->setFeature(ButtonConfig::kFeatureLongPress);
    866 ```
    867 
    868 ### Multiple Buttons
    869 
    870 When transitioning from a single button to multiple buttons, it's important to
    871 remember what's happening underneath the convenience methods. The single
    872 `AceButton` button is assigned to the System ButtonConfig that was created
    873 automatically. When an `EventHandler` is assigned to the button, it is actually
    874 assigned to the System ButtonConfig. All subsequent instances of `AceButton`
    875 will also be associated with this event handler, unless another `ButtonConfig`
    876 is explicitly assigned.
    877 
    878 See the example sketch `TunerButtons.ino` to see how to use multiple
    879 `ButtonConfig` instances with multiple `AceButton` instances.
    880 
    881 ### Events After Reboot
    882 
    883 A number of edge cases occur when the microcontroller is rebooted:
    884 
    885 * if the button is held down, should the Pressed event be triggered?
    886 * if the button is in its natural Released state, should the Released event
    887   happen?
    888 * if the button is Pressed down, and `ButtonConfig` is configured to
    889   support RepeatPress events, should the `kEventRepeatPressed` events
    890   be triggered initially?
    891 
    892 I think most users would expect that in all these cases, the answer is no, the
    893 microcontroller should not trigger an event until the button undergoes a
    894 human-initiated change in state. The AceButton library implements this logic.
    895 (It might be useful to make this configurable using a `ButtonConfig` feature
    896 flag but that is not implemented.)
    897 
    898 On the other hand, it is sometimes useful to perform some special action if a
    899 button is pressed while the device is rebooted. To support this use-case, call
    900 the `AceButton::isPressedRaw()` in the global `setup()` method (after the
    901 button is configured). It will directly call the `digitalRead()` method
    902 associated with the button pin and return `true` if the button is in the
    903 Pressed state.
    904 
    905 ### Orphaned Clicks
    906 
    907 When a Clicked event is generated, the `AceButton` class looks for a
    908 second Clicked event within a certain time delay (default 400 ms) to
    909 determine if the second Clicked event is actually a DoubleClicked event.
    910 
    911 All internal timestamps in `AceButton` are stored as `uint16_t`
    912 (i.e. an unsigned integer of 16 bits) in millisecond units. A 16-bit
    913 unsigned counter rolls over after 65536 iterations. Therefore, if the second
    914 Clicked event happens between (65.636 seconds, 66.036 seconds) after the first
    915 Clicked event, a naive-logic would erroneously consider the (long-delayed)
    916 second click as a double-click.
    917 
    918 The `AceButton` contains code that prevents this from happening.
    919 
    920 Note that even if the `AceButton` class uses an `unsigned long` type (a 32-bit
    921 integer on the Arduino), the overflow problem would still occur after `2^32`
    922 milliseconds (i.e. 49.7 days). To be strictly correct, the `AceButton` class
    923 would still need logic to take care of orphaned Clicked events.
    924 
    925 ## Resource Consumption
    926 
    927 Here are the sizes of the various classes on the 8-bit AVR microcontrollers
    928 (Arduino Uno, Nano, etc):
    929 
    930 * sizeof(AceButton): 14
    931 * sizeof(ButtonConfig): 20
    932 
    933 (An early version of `AceButton`, with only half of the functionality, consumed
    934 40 bytes. It got down to 11 bytes before additional functionality increased it
    935 to 14.)
    936 
    937 **Program size:**
    938 
    939 [LibrarySizeBenchmark](examples/LibrarySizeBenchmark/) was used to determine
    940 the size of the library. For a single button, the library consumed:
    941 * flash memory: 1100-1330 bytes
    942 * static memory: 14-28 bytes
    943 
    944 depending on the target board. See the README.md in the above link for more
    945 details.
    946 
    947 **CPU cycles:**
    948 
    949 The profiling numbers for `AceButton::check()` can be found in
    950 [examples/AutoBenchmark](examples/AutoBenchmark).
    951 
    952 In summary, the average numbers for various boards are:
    953 * Arduino Nano: 13-15 microsesconds
    954 * Teensy 3.2: 3 microseconds
    955 * ESP8266: 8-9 microseconds
    956 * ESP32: 2-3 microseconds
    957 
    958 ## System Requirements
    959 
    960 This library was developed and tested using:
    961 * [Arduino IDE 1.8.5 - 1.8.7](https://www.arduino.cc/en/Main/Software)
    962 * [Teensyduino 1.41](https://www.pjrc.com/teensy/td_download.html)
    963 * [ESP8266 Arduino Core 2.4.1 - 2.4.2](https://arduino-esp8266.readthedocs.io/en/2.4.2/)
    964 * [arduino-esp32](https://github.com/espressif/arduino-esp32)
    965 
    966 I used MacOS 10.13.3 and Ubuntu Linux 17.10 for most of my development.
    967 
    968 The library has been verified to work on the following hardware:
    969 
    970 * Arduino Nano clone (16 MHz ATmega328P)
    971 * Arduino UNO R3 clone (16 MHz ATmega328P)
    972 * Arduino Pro Micro clone (16 MHz ATmega32U4)
    973 * Teensy LC (48 MHz ARM Cortex-M0+)
    974 * Teensy 3.2 (72 MHz ARM Cortex-M4)
    975 * NodeMCU 1.0 clone (ESP-12E module, 80MHz ESP8266)
    976 * ESP32 Dev Module (ESP-WROOM-32 module, 240MHz dual core Tensilica LX6)
    977 
    978 ## Background Motivation
    979 
    980 There are numerous "button" libraries out there for the Arduino. Why write
    981 another one? I wanted to add a button to an addressable strip LED controller,
    982 which was being refreshed at 120 Hz. I had a number of requirements:
    983 
    984 * the button needed to support a LongPress event, in addition to the simple
    985   Press and Release events
    986 * the button code must not interfere with the LED refresh code which was
    987   updating the LEDs at 120 Hz
    988 * well-tested, I didn't want to be hunting down random and  obscure bugs
    989 
    990 Since the LED refresh code needed to run while the button code was waiting for
    991 a "LongPress" delay, it seemed that the cleanest API for a button library
    992 would use an event handler callback mechanism. This reduced the number of
    993 candidate libraries to a handful. Of these, only a few of them supported a
    994 LongPress event. I did not find the remaining ones flexible enough for my
    995 button needs in the future. Finally, I knew that it was tricky to write correct
    996 code for debouncing and detecting various events (e.g. DoubleClick, LongPress,
    997 RepeatPress). I looked for a library that contained unit tests, and I found
    998 none.
    999 
   1000 I decided to write my own and use the opportunity to learn how to create and
   1001 publish an Arduino library.
   1002 
   1003 ## Changelog
   1004 
   1005 See [CHANGELOG.md](CHANGELOG.md).
   1006 
   1007 ## License
   1008 
   1009 * Versions 1.0 to 1.0.6: [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0)
   1010 * Versions 1.1 and above: [MIT License](https://opensource.org/licenses/MIT)
   1011 
   1012 I changed to the MIT License starting with version 1.1 because the MIT License
   1013 is so simple to understand. I could not be sure that I understood what the
   1014 Apache License 2.0 meant.
   1015 
   1016 ## Feedback and Support
   1017 
   1018 If you have any questions, comments, bug reports, or feature requests, please
   1019 file a GitHub ticket or send me an email. I'd love to hear about how this
   1020 software and its documentation can be improved. Instead of forking the
   1021 repository to modify or add a feature for your own projects, let me have a
   1022 chance to incorporate the change into the main repository so that your external
   1023 dependencies are simpler and so that others can benefit. I can't promise that I
   1024 will incorporate everything, but I will give your ideas serious consideration.
   1025 
   1026 ## Author
   1027 
   1028 Created by Brian T. Park (brian@xparks.net).