AceButton  1.6
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 
50 class AceButton {
51  public:
52  // The supported event types.
53 
55  static const uint8_t kEventPressed = 0;
56 
58  static const uint8_t kEventReleased = 1;
59 
64  static const uint8_t kEventClicked = 2;
65 
70  static const uint8_t kEventDoubleClicked = 3;
71 
76  static const uint8_t kEventLongPressed = 4;
77 
84  static const uint8_t kEventRepeatPressed = 5;
85 
92  static const uint8_t kButtonStateUnknown = 127;
93 
126  explicit AceButton(uint8_t pin = 0, uint8_t defaultReleasedState = HIGH,
127  uint8_t id = 0);
128 
138  explicit AceButton(ButtonConfig* buttonConfig, uint8_t pin = 0,
139  uint8_t defaultReleasedState = HIGH, uint8_t id = 0);
140 
146  void init(uint8_t pin = 0, uint8_t defaultReleasedState = HIGH,
147  uint8_t id = 0);
148 
155  void init(ButtonConfig* buttonConfig, uint8_t pin = 0,
156  uint8_t defaultReleasedState = HIGH, uint8_t id = 0);
157 
160  return mButtonConfig;
161  }
162 
168  void setButtonConfig(ButtonConfig* buttonConfig) {
169  mButtonConfig = buttonConfig;
170  }
171 
203  mButtonConfig->setEventHandler(eventHandler);
204  }
205 
207  uint8_t getPin() const { return mPin; }
208 
210  uint8_t getId() const { return mId; }
211 
213  uint8_t getDefaultReleasedState() const;
214 
228  uint8_t getLastButtonState() const {
229  return mLastButtonState;
230  }
231 
239  void check();
240 
245  void checkState(uint8_t buttonState);
246 
262  bool isReleased(uint8_t buttonState) const {
263  return buttonState == getDefaultReleasedState();
264  }
265 
273  bool isPressedRaw() const {
274  return !isReleased(mButtonConfig->readButton(mPin));
275  }
276 
277  // Some of these private methods may be useful to the calling client but I
278  // don't want to release them to the public because I want to keep the API as
279  // small as possible for easier long term maintenance. (Once a method is
280  // released to the public, it must be supported forever to ensure backwards
281  // compatibility with older client code.)
282 
283  private:
284  // Disable copy-constructor and assignment operator
285  AceButton(const AceButton&) = delete;
286  AceButton& operator=(const AceButton&) = delete;
287 
289  void setPin(uint8_t pin) { mPin = pin; }
290 
298  void setDefaultReleasedState(uint8_t state);
299 
301  void setId(uint8_t id) { mId = id; }
302 
303  // Various bit masks to store a boolean flag in the 'mFlags' field.
304  // We use bit masks to save static RAM. If we had used a 'bool' type, each
305  // of these would consume one byte.
306  static const uint8_t kFlagDefaultReleasedState = 0x01;
307  static const uint8_t kFlagDebouncing = 0x02;
308  static const uint8_t kFlagPressed = 0x04;
309  static const uint8_t kFlagClicked = 0x08;
310  static const uint8_t kFlagDoubleClicked = 0x10;
311  static const uint8_t kFlagLongPressed = 0x20;
312  static const uint8_t kFlagRepeatPressed = 0x40;
313  static const uint8_t kFlagClickPostponed = 0x80;
314 
315  // Methods for accessing the button's internal states.
316  // I don't expect these to be useful to the outside world.
317 
318  // If this is set, then mLastDebounceTime is valid.
319  bool isDebouncing() const {
320  return mFlags & kFlagDebouncing;
321  }
322 
323  void setDebouncing() {
324  mFlags |= kFlagDebouncing;
325  }
326 
327  void clearDebouncing() {
328  mFlags &= ~kFlagDebouncing;
329  }
330 
331  // If this is set, then mLastPressTime is valid.
332  bool isPressed() const {
333  return mFlags & kFlagPressed;
334  }
335 
336  void setPressed() {
337  mFlags |= kFlagPressed;
338  }
339 
340  void clearPressed() {
341  mFlags &= ~kFlagPressed;
342  }
343 
344  // If this is set, then mLastClickTime is valid.
345  bool isClicked() const {
346  return mFlags & kFlagClicked;
347  }
348 
349  void setClicked() {
350  mFlags |= kFlagClicked;
351  }
352 
353  void clearClicked() {
354  mFlags &= ~kFlagClicked;
355  }
356 
357  // A double click was detected. No need to store the last double-clicked
358  // time because we don't support a triple-click event (yet).
359  bool isDoubleClicked() const {
360  return mFlags & kFlagDoubleClicked;
361  }
362 
363  void setDoubleClicked() {
364  mFlags |= kFlagDoubleClicked;
365  }
366 
367  void clearDoubleClicked() {
368  mFlags &= ~kFlagDoubleClicked;
369  }
370 
371  // If this is set, then mLastPressTime can be treated as the start
372  // of a long press.
373  bool isLongPressed() const {
374  return mFlags & kFlagLongPressed;
375  }
376 
377  void setLongPressed() {
378  mFlags |= kFlagLongPressed;
379  }
380 
381  void clearLongPressed() {
382  mFlags &= ~kFlagLongPressed;
383  }
384 
385  // If this is set, then mLastRepeatPressTime is valid.
386  bool isRepeatPressed() const {
387  return mFlags & kFlagRepeatPressed;
388  }
389 
390  void setRepeatPressed() {
391  mFlags |= kFlagRepeatPressed;
392  }
393 
394  void clearRepeatPressed() {
395  mFlags &= ~kFlagRepeatPressed;
396  }
397 
398  bool isClickPostponed() const {
399  return mFlags & kFlagClickPostponed;
400  }
401 
402  void setClickPostponed() {
403  mFlags |= kFlagClickPostponed;
404  }
405 
406  void clearClickPostponed() {
407  mFlags &= ~kFlagClickPostponed;
408  }
409 
415  bool checkDebounced(uint16_t now, uint8_t buttonState);
416 
423  bool checkInitialized(uint16_t buttonState);
424 
426  void checkEvent(uint16_t now, uint8_t buttonState);
427 
429  void checkLongPress(uint16_t now, uint8_t buttonState);
430 
432  void checkRepeatPress(uint16_t now, uint8_t buttonState);
433 
435  void checkChanged(uint16_t now, uint8_t buttonState);
436 
441  void checkReleased(uint16_t now, uint8_t buttonState);
442 
444  void checkPressed(uint16_t now, uint8_t buttonState);
445 
447  void checkClicked(uint16_t now);
448 
453  void checkDoubleClicked(uint16_t now);
454 
463  void checkOrphanedClick(uint16_t now);
464 
469  void checkPostponedClick(uint16_t now);
470 
523  void handleEvent(uint8_t eventType);
524 
526  ButtonConfig* mButtonConfig;
527 
529  uint8_t mPin;
530 
532  uint8_t mId;
533 
535  uint8_t mFlags;
536 
541  uint8_t mLastButtonState;
542 
543  // Internal states of the button debouncing and event handling.
544  // NOTE: We don't keep track of the lastDoubleClickTime, because we
545  // don't support a TripleClicked event. That may change in the future.
546  uint16_t mLastDebounceTime; // ms
547  uint16_t mLastClickTime; // ms
548  uint16_t mLastPressTime; // ms
549  uint16_t mLastRepeatPressTime; // ms
550 };
551 
552 }
553 #endif
ace_button::AceButton::check
void check()
Check state of button and trigger event processing.
Definition: AceButton.cpp:94
ace_button::AceButton::kEventRepeatPressed
static const uint8_t kEventRepeatPressed
Button was held down and auto generated multiple presses.
Definition: AceButton.h:84
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:273
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.cpp:54
ace_button::AceButton::getId
uint8_t getId() const
Get the custom identifier of the button.
Definition: AceButton.h:210
ace_button::AceButton::kEventReleased
static const uint8_t kEventReleased
Button was released.
Definition: AceButton.h:58
ace_button::AceButton::getPin
uint8_t getPin() const
Get the button's pin number.
Definition: AceButton.h:207
ace_button::AceButton::getDefaultReleasedState
uint8_t getDefaultReleasedState() const
Get the initial released state of the button, HIGH or LOW.
Definition: AceButton.cpp:88
ace_button::AceButton::getButtonConfig
ButtonConfig * getButtonConfig() const
Get the ButtonConfig associated with this Button.
Definition: AceButton.h:159
ace_button::ButtonConfig::setEventHandler
void setEventHandler(EventHandler eventHandler)
Install the EventHandler function pointer.
Definition: ButtonConfig.h:359
ace_button::AceButton
An Adjustable Compact Event-driven (ACE) Button library that debounces and dispatches button events t...
Definition: AceButton.h:50
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:76
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:262
ace_button::AceButton::kEventClicked
static const uint8_t kEventClicked
Button was clicked (Pressed and Released within ButtonConfig::getClickDelay()).
Definition: AceButton.h:64
ace_button::AceButton::setButtonConfig
void setButtonConfig(ButtonConfig *buttonConfig)
Set the ButtonConfig associated with this Button.
Definition: AceButton.h:168
ace_button::AceButton::kEventPressed
static const uint8_t kEventPressed
Button was pressed.
Definition: AceButton.h:55
ace_button::AceButton::kButtonStateUnknown
static const uint8_t kButtonStateUnknown
Button state is unknown.
Definition: AceButton.h:92
ace_button::AceButton::getLastButtonState
uint8_t getLastButtonState() const
Return the button state that was last valid.
Definition: AceButton.h:228
ace_button::AceButton::checkState
void checkState(uint8_t buttonState)
Version of check() used by EncodedButtonConfig.
Definition: AceButton.cpp:99
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:64
ace_button::AceButton::kEventDoubleClicked
static const uint8_t kEventDoubleClicked
Button was double-clicked.
Definition: AceButton.h:70
ace_button::AceButton::setEventHandler
void setEventHandler(ButtonConfig::EventHandler eventHandler)
Convenience method to set the event handler.
Definition: AceButton.h:202
ace_button::ButtonConfig::readButton
virtual int readButton(uint8_t pin)
Return the HIGH or LOW state of the button.
Definition: ButtonConfig.h:286