AceButton  1.9.1
An adjustable, compact, event-driven button library for Arduino.
AceButton.h
1 /*
2 MIT License
3 
4 Copyright (c) 2018 Brian T. Park
5 
6 Permission is hereby granted, free of charge, to any person obtaining a copy
7 of this software and associated documentation files (the "Software"), to deal
8 in the Software without restriction, including without limitation the rights
9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 copies of the Software, and to permit persons to whom the Software is
11 furnished to do so, subject to the following conditions:
12 
13 The above copyright notice and this permission notice shall be included in all
14 copies or substantial portions of the Software.
15 
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 SOFTWARE.
23 */
24 
25 #ifndef ACE_BUTTON_ACE_BUTTON_H
26 #define ACE_BUTTON_ACE_BUTTON_H
27 
28 #include <Arduino.h>
29 #include "ButtonConfig.h"
30 
31 namespace ace_button {
32 
51 class AceButton {
52  public:
53  // The supported event types.
54 
56  static const uint8_t kEventPressed = 0;
57 
59  static const uint8_t kEventReleased = 1;
60 
65  static const uint8_t kEventClicked = 2;
66 
71  static const uint8_t kEventDoubleClicked = 3;
72 
77  static const uint8_t kEventLongPressed = 4;
78 
85  static const uint8_t kEventRepeatPressed = 5;
86 
96  static const uint8_t kEventLongReleased = 6;
97 
104  static const uint8_t kButtonStateUnknown = 127;
105 
138  explicit AceButton(
139  uint8_t pin = 0,
140  uint8_t defaultReleasedState = HIGH,
141  uint8_t id = 0
142  ) :
143  mButtonConfig(ButtonConfig::getSystemButtonConfig()) {
144  init(pin, defaultReleasedState, id);
145  }
146 
170  explicit AceButton(
171  ButtonConfig* buttonConfig,
172  uint8_t pin = 0,
173  uint8_t defaultReleasedState = HIGH,
174  uint8_t id = 0) {
175  init(buttonConfig, pin, defaultReleasedState, id);
176  }
177 
183  void init(
184  uint8_t pin = 0,
185  uint8_t defaultReleasedState = HIGH,
186  uint8_t id = 0);
187 
194  void init(
195  ButtonConfig* buttonConfig,
196  uint8_t pin = 0,
197  uint8_t defaultReleasedState = HIGH,
198  uint8_t id = 0);
199 
202  return mButtonConfig;
203  }
204 
210  void setButtonConfig(ButtonConfig* buttonConfig) {
211  mButtonConfig = buttonConfig;
212  }
213 
245  mButtonConfig->setEventHandler(eventHandler);
246  }
247 
249  uint8_t getPin() const { return mPin; }
250 
252  uint8_t getId() const { return mId; }
253 
255  uint8_t getDefaultReleasedState() const;
256 
270  uint8_t getLastButtonState() const {
271  return mLastButtonState;
272  }
273 
281  void check();
282 
287  void checkState(uint8_t buttonState);
288 
304  bool isReleased(uint8_t buttonState) const {
305  return buttonState == getDefaultReleasedState();
306  }
307 
315  bool isPressedRaw() const {
316  return !isReleased(mButtonConfig->readButton(mPin));
317  }
318 
319  // Some of these private methods may be useful to the calling client but I
320  // don't want to release them to the public because I want to keep the API as
321  // small as possible for easier long term maintenance. (Once a method is
322  // released to the public, it must be supported forever to ensure backwards
323  // compatibility with older client code.)
324 
325  private:
326  // Disable copy-constructor and assignment operator
327  AceButton(const AceButton&) = delete;
328  AceButton& operator=(const AceButton&) = delete;
329 
331  void setPin(uint8_t pin) { mPin = pin; }
332 
340  void setDefaultReleasedState(uint8_t state);
341 
343  void setId(uint8_t id) { mId = id; }
344 
345  // Various bit masks to store a boolean flag in the 'mFlags' field.
346  // We use bit masks to save static RAM. If we had used a 'bool' type, each
347  // of these would consume one byte.
348  static const uint8_t kFlagDefaultReleasedState = 0x01;
349  static const uint8_t kFlagDebouncing = 0x02;
350  static const uint8_t kFlagPressed = 0x04;
351  static const uint8_t kFlagClicked = 0x08;
352  static const uint8_t kFlagDoubleClicked = 0x10;
353  static const uint8_t kFlagLongPressed = 0x20;
354  static const uint8_t kFlagRepeatPressed = 0x40;
355  static const uint8_t kFlagClickPostponed = 0x80;
356 
357  // Methods for accessing the button's internal states.
358  // I don't expect these to be useful to the outside world.
359 
360  // If this is set, then mLastDebounceTime is valid.
361  bool isDebouncing() const {
362  return mFlags & kFlagDebouncing;
363  }
364 
365  void setDebouncing() {
366  mFlags |= kFlagDebouncing;
367  }
368 
369  void clearDebouncing() {
370  mFlags &= ~kFlagDebouncing;
371  }
372 
373  // If this is set, then mLastPressTime is valid.
374  bool isPressed() const {
375  return mFlags & kFlagPressed;
376  }
377 
378  void setPressed() {
379  mFlags |= kFlagPressed;
380  }
381 
382  void clearPressed() {
383  mFlags &= ~kFlagPressed;
384  }
385 
386  // If this is set, then mLastClickTime is valid.
387  bool isClicked() const {
388  return mFlags & kFlagClicked;
389  }
390 
391  void setClicked() {
392  mFlags |= kFlagClicked;
393  }
394 
395  void clearClicked() {
396  mFlags &= ~kFlagClicked;
397  }
398 
399  // A double click was detected. No need to store the last double-clicked
400  // time because we don't support a triple-click event (yet).
401  bool isDoubleClicked() const {
402  return mFlags & kFlagDoubleClicked;
403  }
404 
405  void setDoubleClicked() {
406  mFlags |= kFlagDoubleClicked;
407  }
408 
409  void clearDoubleClicked() {
410  mFlags &= ~kFlagDoubleClicked;
411  }
412 
413  // If this is set, then mLastPressTime can be treated as the start
414  // of a long press.
415  bool isLongPressed() const {
416  return mFlags & kFlagLongPressed;
417  }
418 
419  void setLongPressed() {
420  mFlags |= kFlagLongPressed;
421  }
422 
423  void clearLongPressed() {
424  mFlags &= ~kFlagLongPressed;
425  }
426 
427  // If this is set, then mLastRepeatPressTime is valid.
428  bool isRepeatPressed() const {
429  return mFlags & kFlagRepeatPressed;
430  }
431 
432  void setRepeatPressed() {
433  mFlags |= kFlagRepeatPressed;
434  }
435 
436  void clearRepeatPressed() {
437  mFlags &= ~kFlagRepeatPressed;
438  }
439 
440  bool isClickPostponed() const {
441  return mFlags & kFlagClickPostponed;
442  }
443 
444  void setClickPostponed() {
445  mFlags |= kFlagClickPostponed;
446  }
447 
448  void clearClickPostponed() {
449  mFlags &= ~kFlagClickPostponed;
450  }
451 
457  bool checkDebounced(uint16_t now, uint8_t buttonState);
458 
465  bool checkInitialized(uint16_t buttonState);
466 
468  void checkEvent(uint16_t now, uint8_t buttonState);
469 
471  void checkLongPress(uint16_t now, uint8_t buttonState);
472 
474  void checkRepeatPress(uint16_t now, uint8_t buttonState);
475 
477  void checkChanged(uint16_t now, uint8_t buttonState);
478 
483  void checkReleased(uint16_t now, uint8_t buttonState);
484 
486  void checkPressed(uint16_t now, uint8_t buttonState);
487 
489  void checkClicked(uint16_t now);
490 
495  void checkDoubleClicked(uint16_t now);
496 
505  void checkOrphanedClick(uint16_t now);
506 
511  void checkPostponedClick(uint16_t now);
512 
565  void handleEvent(uint8_t eventType);
566 
568  ButtonConfig* mButtonConfig;
569 
571  uint8_t mPin;
572 
574  uint8_t mId;
575 
577  uint8_t mFlags;
578 
583  uint8_t mLastButtonState;
584 
585  // Internal states of the button debouncing and event handling.
586  // NOTE: We don't keep track of the lastDoubleClickTime, because we
587  // don't support a TripleClicked event. That may change in the future.
588  uint16_t mLastDebounceTime; // ms
589  uint16_t mLastClickTime; // ms
590  uint16_t mLastPressTime; // ms
591  uint16_t mLastRepeatPressTime; // ms
592 };
593 
594 }
595 #endif
ace_button::AceButton::check
void check()
Check state of button and trigger event processing.
Definition: AceButton.cpp:84
ace_button::AceButton::kEventRepeatPressed
static const uint8_t kEventRepeatPressed
Button was held down and auto generated multiple presses.
Definition: AceButton.h:85
ace_button::AceButton::isPressedRaw
bool isPressedRaw() const
Read the button state directly using ButtonConfig and return true if the button is in the Pressed sta...
Definition: AceButton.h:315
ace_button::AceButton::kEventLongReleased
static const uint8_t kEventLongReleased
Button was released after a long press.
Definition: AceButton.h:96
ace_button::AceButton::AceButton
AceButton(uint8_t pin=0, uint8_t defaultReleasedState=HIGH, uint8_t id=0)
Constructor defines parameters of the button that changes from button to button.
Definition: AceButton.h:138
ace_button::AceButton::getId
uint8_t getId() const
Get the custom identifier of the button.
Definition: AceButton.h:252
ace_button::AceButton::kEventReleased
static const uint8_t kEventReleased
Button was released.
Definition: AceButton.h:59
ace_button::AceButton::getPin
uint8_t getPin() const
Get the button's pin number.
Definition: AceButton.h:249
ace_button::AceButton::getDefaultReleasedState
uint8_t getDefaultReleasedState() const
Get the initial released state of the button, HIGH or LOW.
Definition: AceButton.cpp:78
ace_button::AceButton::getButtonConfig
ButtonConfig * getButtonConfig() const
Get the ButtonConfig associated with this Button.
Definition: AceButton.h:201
ace_button::ButtonConfig::setEventHandler
void setEventHandler(EventHandler eventHandler)
Install the EventHandler function pointer.
Definition: ButtonConfig.h:376
ace_button::AceButton
An Adjustable Compact Event-driven (ACE) Button library that debounces and dispatches button events t...
Definition: AceButton.h:51
ace_button::ButtonConfig
Class that defines the timing parameters and event handler of an AceButton or a group of AceButton in...
Definition: ButtonConfig.h:66
ace_button::ButtonConfig::EventHandler
void(* EventHandler)(AceButton *button, uint8_t eventType, uint8_t buttonState)
The event handler signature.
Definition: ButtonConfig.h:176
ace_button::AceButton::kEventLongPressed
static const uint8_t kEventLongPressed
Button was held down for longer than ButtonConfig::getLongPressDelay()).
Definition: AceButton.h:77
ace_button::AceButton::AceButton
AceButton(ButtonConfig *buttonConfig, uint8_t pin=0, uint8_t defaultReleasedState=HIGH, uint8_t id=0)
Constructor that accepts a ButtonConfig as a dependency.
Definition: AceButton.h:170
ace_button::AceButton::isReleased
bool isReleased(uint8_t buttonState) const
Returns true if the given buttonState represents a 'Released' state for the button.
Definition: AceButton.h:304
ace_button::AceButton::kEventClicked
static const uint8_t kEventClicked
Button was clicked (Pressed and Released within ButtonConfig::getClickDelay()).
Definition: AceButton.h:65
ace_button::AceButton::setButtonConfig
void setButtonConfig(ButtonConfig *buttonConfig)
Set the ButtonConfig associated with this Button.
Definition: AceButton.h:210
ace_button::AceButton::kEventPressed
static const uint8_t kEventPressed
Button was pressed.
Definition: AceButton.h:56
ace_button::AceButton::kButtonStateUnknown
static const uint8_t kButtonStateUnknown
Button state is unknown.
Definition: AceButton.h:104
ace_button::AceButton::getLastButtonState
uint8_t getLastButtonState() const
Return the button state that was last valid.
Definition: AceButton.h:270
ace_button::AceButton::checkState
void checkState(uint8_t buttonState)
Version of check() used by EncodedButtonConfig.
Definition: AceButton.cpp:89
ace_button::AceButton::init
void init(uint8_t pin=0, uint8_t defaultReleasedState=HIGH, uint8_t id=0)
Reset the button to the initial constructed state.
Definition: AceButton.cpp:54
ace_button::AceButton::kEventDoubleClicked
static const uint8_t kEventDoubleClicked
Button was double-clicked.
Definition: AceButton.h:71
ace_button::AceButton::setEventHandler
void setEventHandler(ButtonConfig::EventHandler eventHandler)
Convenience method to set the event handler.
Definition: AceButton.h:244
ace_button::ButtonConfig::readButton
virtual int readButton(uint8_t pin)
Return the HIGH or LOW state of the button.
Definition: ButtonConfig.h:303