AceButton  1.3.3
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 
90  static const uint8_t kButtonStateUnknown = 2;
91 
124  explicit AceButton(uint8_t pin = 0, uint8_t defaultReleasedState = HIGH,
125  uint8_t id = 0);
126 
132  explicit AceButton(ButtonConfig* buttonConfig);
133 
139  void init(uint8_t pin = 0, uint8_t defaultReleasedState = HIGH,
140  uint8_t id = 0);
141 
143  ButtonConfig* getButtonConfig() ACE_BUTTON_INLINE {
144  return mButtonConfig;
145  }
146 
152  void setButtonConfig(ButtonConfig* buttonConfig) ACE_BUTTON_INLINE {
153  mButtonConfig = buttonConfig;
154  }
155 
166  ACE_BUTTON_INLINE {
167  mButtonConfig->setEventHandler(eventHandler);
168  }
169 
171  uint8_t getPin() ACE_BUTTON_INLINE { return mPin; }
172 
174  uint8_t getId() ACE_BUTTON_INLINE { return mId; }
175 
177  uint8_t getDefaultReleasedState();
178 
192  uint8_t getLastButtonState() ACE_BUTTON_INLINE {
193  return mLastButtonState;
194  }
195 
203  void check();
204 
220  bool isReleased(uint8_t buttonState) ACE_BUTTON_INLINE {
221  return buttonState == getDefaultReleasedState();
222  }
223 
231  bool isPressedRaw() ACE_BUTTON_INLINE {
232  return !isReleased(mButtonConfig->readButton(mPin));
233  }
234 
235  // Some of these private methods may be useful to the calling client but I
236  // don't want to release them to the public because I want to keep the API as
237  // small as possible for easier long term maintenance. (Once a method is
238  // released to the public, it must be supported forever to ensure backwards
239  // compatibility with older client code.)
240 
241  private:
242  // Disable copy-constructor and assignment operator
243  AceButton(const AceButton&) = delete;
244  AceButton& operator=(const AceButton&) = delete;
245 
247  void setPin(uint8_t pin) ACE_BUTTON_INLINE { mPin = pin; }
248 
256  void setDefaultReleasedState(uint8_t state);
257 
259  void setId(uint8_t id) ACE_BUTTON_INLINE { mId = id; }
260 
261  // Various bit masks to store a boolean flag in the 'mFlags' field.
262  // We use bit masks to save static RAM. If we had used a 'bool' type, each
263  // of these would consume one byte.
264  static const uint8_t kFlagDefaultReleasedState = 0x01;
265  static const uint8_t kFlagDebouncing = 0x02;
266  static const uint8_t kFlagPressed = 0x04;
267  static const uint8_t kFlagClicked = 0x08;
268  static const uint8_t kFlagDoubleClicked = 0x10;
269  static const uint8_t kFlagLongPressed = 0x20;
270  static const uint8_t kFlagRepeatPressed = 0x40;
271  static const uint8_t kFlagClickPostponed = 0x80;
272 
273  // Methods for accessing the button's internal states.
274  // I don't expect these to be useful to the outside world.
275 
276  // If this is set, then mLastDebounceTime is valid.
277  bool isDebouncing() ACE_BUTTON_INLINE {
278  return mFlags & kFlagDebouncing;
279  }
280 
281  void setDebouncing() ACE_BUTTON_INLINE {
282  mFlags |= kFlagDebouncing;
283  }
284 
285  void clearDebouncing() ACE_BUTTON_INLINE {
286  mFlags &= ~kFlagDebouncing;
287  }
288 
289  // If this is set, then mLastPressTime is valid.
290  bool isPressed() ACE_BUTTON_INLINE {
291  return mFlags & kFlagPressed;
292  }
293 
294  void setPressed() ACE_BUTTON_INLINE {
295  mFlags |= kFlagPressed;
296  }
297 
298  void clearPressed() ACE_BUTTON_INLINE {
299  mFlags &= ~kFlagPressed;
300  }
301 
302  // If this is set, then mLastClickTime is valid.
303  bool isClicked() ACE_BUTTON_INLINE {
304  return mFlags & kFlagClicked;
305  }
306 
307  void setClicked() ACE_BUTTON_INLINE {
308  mFlags |= kFlagClicked;
309  }
310 
311  void clearClicked() ACE_BUTTON_INLINE {
312  mFlags &= ~kFlagClicked;
313  }
314 
315  // A double click was detected. No need to store the last double-clicked
316  // time because we don't support a triple-click event (yet).
317  bool isDoubleClicked() ACE_BUTTON_INLINE {
318  return mFlags & kFlagDoubleClicked;
319  }
320 
321  void setDoubleClicked() ACE_BUTTON_INLINE {
322  mFlags |= kFlagDoubleClicked;
323  }
324 
325  void clearDoubleClicked() ACE_BUTTON_INLINE {
326  mFlags &= ~kFlagDoubleClicked;
327  }
328 
329  // If this is set, then mLastPressTime can be treated as the start
330  // of a long press.
331  bool isLongPressed() ACE_BUTTON_INLINE {
332  return mFlags & kFlagLongPressed;
333  }
334 
335  void setLongPressed() ACE_BUTTON_INLINE {
336  mFlags |= kFlagLongPressed;
337  }
338 
339  void clearLongPressed() ACE_BUTTON_INLINE {
340  mFlags &= ~kFlagLongPressed;
341  }
342 
343  // If this is set, then mLastRepeatPressTime is valid.
344  bool isRepeatPressed() ACE_BUTTON_INLINE {
345  return mFlags & kFlagRepeatPressed;
346  }
347 
348  void setRepeatPressed() ACE_BUTTON_INLINE {
349  mFlags |= kFlagRepeatPressed;
350  }
351 
352  void clearRepeatPressed() ACE_BUTTON_INLINE {
353  mFlags &= ~kFlagRepeatPressed;
354  }
355 
356  bool isClickPostponed() ACE_BUTTON_INLINE {
357  return mFlags & kFlagClickPostponed;
358  }
359 
360  void setClickPostponed() ACE_BUTTON_INLINE {
361  mFlags |= kFlagClickPostponed;
362  }
363 
364  void clearClickPostponed() ACE_BUTTON_INLINE {
365  mFlags &= ~kFlagClickPostponed;
366  }
367 
373  bool checkDebounced(uint16_t now, uint8_t buttonState);
374 
381  bool checkInitialized(uint16_t buttonState);
382 
384  void checkEvent(uint16_t now, uint8_t buttonState);
385 
387  void checkLongPress(uint16_t now, uint8_t buttonState);
388 
390  void checkRepeatPress(uint16_t now, uint8_t buttonState);
391 
393  void checkChanged(uint16_t now, uint8_t buttonState);
394 
399  void checkReleased(uint16_t now, uint8_t buttonState);
400 
402  void checkPressed(uint16_t now, uint8_t buttonState);
403 
405  void checkClicked(uint16_t now);
406 
411  void checkDoubleClicked(uint16_t now);
412 
421  void checkOrphanedClick(uint16_t now);
422 
427  void checkPostponedClick(uint16_t now);
428 
475  void handleEvent(uint8_t eventType);
476 
477  uint8_t mPin; // button pin number
478  uint8_t mId; // identifier, e.g. an index into an array
479 
480  // Internal states of the button debouncing and event handling.
481  // NOTE: We don't keep track of the lastDoubleClickTime, because we
482  // don't support a TripleClicked event. That may change in the future.
483  uint16_t mLastDebounceTime; // ms
484  uint16_t mLastClickTime; // ms
485  uint16_t mLastPressTime; // ms
486  uint16_t mLastRepeatPressTime; // ms
487 
489  uint8_t mFlags;
490 
495  uint8_t mLastButtonState;
496 
498  ButtonConfig* mButtonConfig;
499 };
500 
501 }
502 #endif
void setEventHandler(ButtonConfig::EventHandler eventHandler) ACE_BUTTON_INLINE
Convenience method to set the event handler.
Definition: AceButton.h:165
void setButtonConfig(ButtonConfig *buttonConfig) ACE_BUTTON_INLINE
Set the ButtonConfig associated with this Button.
Definition: AceButton.h:152
uint8_t getDefaultReleasedState()
Get the initial released state of the button, HIGH or LOW.
Definition: AceButton.cpp:67
bool isReleased(uint8_t buttonState) ACE_BUTTON_INLINE
Returns true if the given buttonState represents a &#39;Released&#39; state for the button.
Definition: AceButton.h:220
bool isPressedRaw() ACE_BUTTON_INLINE
Read the button state directly using ButtonConfig and return true if the button is in the Pressed sta...
Definition: AceButton.h:231
uint8_t getLastButtonState() ACE_BUTTON_INLINE
Return the button state that was last valid.
Definition: AceButton.h:192
static const uint8_t kEventRepeatPressed
Button was held down and auto generated multiple presses.
Definition: AceButton.h:84
void setEventHandler(EventHandler eventHandler) ACE_BUTTON_INLINE
Install the event handler.
Definition: ButtonConfig.h:296
static const uint8_t kButtonStateUnknown
Button state is unknown.
Definition: AceButton.h:90
virtual int readButton(uint8_t pin)
Return the HIGH or LOW state of the button.
Definition: ButtonConfig.h:263
ButtonConfig * getButtonConfig() ACE_BUTTON_INLINE
Get the ButtonConfig associated with this Button.
Definition: AceButton.h:143
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:49
Class that defines the timing parameters and event handler of an AceButton or a group of AceButton in...
Definition: ButtonConfig.h:60
static const uint8_t kEventDoubleClicked
Button was double-clicked.
Definition: AceButton.h:70
static const uint8_t kEventLongPressed
Button was held down for longer than ButtonConfig::getLongPressDelay()).
Definition: AceButton.h:76
uint8_t getId() ACE_BUTTON_INLINE
Get the custom identifier of the button.
Definition: AceButton.h:174
void(* EventHandler)(AceButton *button, uint8_t eventType, uint8_t buttonState)
The event handler signature.
Definition: ButtonConfig.h:164
uint8_t getPin() ACE_BUTTON_INLINE
Get the button&#39;s pin number.
Definition: AceButton.h:171
void check()
Check state of button and trigger event processing.
Definition: AceButton.cpp:73
An Adjustable Compact Event-driven (ACE) Button library that debounces and dispatches button events t...
Definition: AceButton.h:50
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:39
static const uint8_t kEventReleased
Button was released.
Definition: AceButton.h:58
static const uint8_t kEventPressed
Button was pressed.
Definition: AceButton.h:55
static const uint8_t kEventClicked
Button was clicked (Pressed and Released within ButtonConfig::getClickDelay()).
Definition: AceButton.h:64