AceButton  1.10.0
An adjustable, compact, event-driven button library for Arduino.
ButtonConfig.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_BUTTON_CONFIG_H
26 #define ACE_BUTTON_BUTTON_CONFIG_H
27 
28 #include <Arduino.h>
29 #include "IEventHandler.h"
30 
31 // https://stackoverflow.com/questions/295120
32 #if defined(__GNUC__) || defined(__clang__)
33  #define ACE_BUTTON_DEPRECATED __attribute__((deprecated))
34 #elif defined(_MSC_VER)
35  #define ACE_BUTTON_DEPRECATED __declspec(deprecated)
36 #else
37  #pragma message("WARNING: Implement ACE_BUTTON_DEPRECATED for this compiler")
38  #define ACE_BUTTON_DEPRECATED
39 #endif
40 
41 namespace ace_button {
42 
43 class AceButton;
44 
66 class ButtonConfig {
67  public:
68  // Various timing constants, in milliseconds.
69  //
70  // Note that the timing constants are stored as uint16_t (2
71  // bytes) instead of unsigned long (4 bytes) which is the type returned by
72  // the millis() system method. It turns out that we can store and perform
73  // all timing calculations using uint16_t without ill effect, as long as the
74  // polling of AceButton::check() happens more frequently than the rollover
75  // time of a uint16_t (i.e. 65.536 seconds) and certain precautions (e.g.
76  // AceButton::checkOrphanedClick()) are taken before a uint16_t rollover
77  // happens. In theory, these additional precautions would be needed even if
78  // an 'unsigned long' is used but almost no one does them because they
79  // assume that their code won't be running continuously for the rollover
80  // time of an 'unsigned long' (i.e. 49.7 days).
81 
83  static const uint16_t kDebounceDelay = 20;
84 
86  static const uint16_t kClickDelay = 200;
87 
89  static const uint16_t kDoubleClickDelay = 400;
90 
92  static const uint16_t kLongPressDelay = 1000;
93 
95  static const uint16_t kRepeatPressDelay = 1000;
96 
98  static const uint16_t kRepeatPressInterval = 200;
99 
101  static const uint16_t kHeartBeatInterval = 5000;
102 
103  // Various features controlled by feature flags.
104 
110  typedef uint16_t FeatureFlagType;
111 
113  static const FeatureFlagType kFeatureClick = 0x01;
114 
121 
123  static const FeatureFlagType kFeatureLongPress = 0x04;
124 
127 
130 
137 
140 
143 
151 
153  static const FeatureFlagType kFeatureHeartBeat = 0x200;
154 
160 
174 
182  typedef void (*EventHandler)(AceButton* button, uint8_t eventType,
183  uint8_t buttonState);
184 
186  ButtonConfig() = default;
187 
188  #if ! defined(ARDUINO_ARCH_AVR)
218  virtual ~ButtonConfig() = default;
219  #endif
220 
222  uint16_t getDebounceDelay() const { return mDebounceDelay; }
223 
225  uint16_t getClickDelay() const { return mClickDelay; }
226 
231  uint16_t getDoubleClickDelay() const {
232  return mDoubleClickDelay;
233  }
234 
236  uint16_t getLongPressDelay() const {
237  return mLongPressDelay;
238  }
239 
246  uint16_t getRepeatPressDelay() const {
247  return mRepeatPressDelay;
248  }
249 
251  uint16_t getRepeatPressInterval() const {
252  return mRepeatPressInterval;
253  }
254 
256  uint16_t getHeartBeatInterval() const {
257  return mHeartBeatInterval;
258  }
259 
261  void setDebounceDelay(uint16_t debounceDelay) {
262  mDebounceDelay = debounceDelay;
263  }
264 
266  void setClickDelay(uint16_t clickDelay) {
267  mClickDelay = clickDelay;
268  }
269 
271  void setDoubleClickDelay(uint16_t doubleClickDelay) {
272  mDoubleClickDelay = doubleClickDelay;
273  }
274 
276  void setLongPressDelay(uint16_t longPressDelay) {
277  mLongPressDelay = longPressDelay;
278  }
279 
281  void setRepeatPressDelay(uint16_t repeatPressDelay) {
282  mRepeatPressDelay = repeatPressDelay;
283  }
284 
286  void setRepeatPressInterval(uint16_t repeatPressInterval) {
287  mRepeatPressInterval = repeatPressInterval;
288  }
289 
291  void setHeartBeatInterval(uint16_t heartBeatInterval) {
292  mHeartBeatInterval = heartBeatInterval;
293  }
294 
295  // The getClock() and readButton() are external dependencies that normally
296  // would be injected using separate classes, but in the interest of saving
297  // RAM in an embedded environment, we expose them in this class instead.
298 
307  virtual unsigned long getClock() { return millis(); }
308 
317  virtual int readButton(uint8_t pin) {
318  return digitalRead(pin);
319  }
320 
321  // These methods provide access to various feature flags that control the
322  // functionality of the AceButton.
323 
325  bool isFeature(FeatureFlagType features) const {
326  return mFeatureFlags & features;
327  }
328 
330  void setFeature(FeatureFlagType features) {
331  mFeatureFlags |= features;
332  }
333 
335  void clearFeature(FeatureFlagType features) {
336  mFeatureFlags &= ~features;
337  }
338 
344  void resetFeatures() {
345  // NOTE: If any additional kInternalFeatureXxx flag is added, it must be
346  // added here like this:
347  // mFeatureFlags &= (kInternalFeatureIEventHandler | kInternalFeatureXxx)
348  mFeatureFlags &= kInternalFeatureIEventHandler;
349  }
350 
351  // EventHandler
352 
362  EventHandler getEventHandler() const ACE_BUTTON_DEPRECATED {
363  return reinterpret_cast<EventHandler>(mEventHandler);
364  }
365 
370  void dispatchEvent(AceButton* button, uint8_t eventType,
371  uint8_t buttonState) const {
372 
373  if (! mEventHandler) return;
374 
376  IEventHandler* eventHandler =
377  reinterpret_cast<IEventHandler*>(mEventHandler);
378  eventHandler->handleEvent(button, eventType, buttonState);
379  } else {
380  EventHandler eventHandler =
381  reinterpret_cast<EventHandler>(mEventHandler);
382  eventHandler(button, eventType, buttonState);
383  }
384  }
385 
390  void setEventHandler(EventHandler eventHandler) {
391  mEventHandler = reinterpret_cast<void*>(eventHandler);
393  }
394 
399  void setIEventHandler(IEventHandler* eventHandler) {
400  mEventHandler = eventHandler;
402  }
403 
409  return &sSystemButtonConfig;
410  }
411 
412  private:
417  static ButtonConfig sSystemButtonConfig;
418 
419  // Disable copy-constructor and assignment operator
420  ButtonConfig(const ButtonConfig&) = delete;
421  ButtonConfig& operator=(const ButtonConfig&) = delete;
422 
428  void* mEventHandler = nullptr;
429 
431  FeatureFlagType mFeatureFlags = 0;
432 
433  uint16_t mDebounceDelay = kDebounceDelay;
434  uint16_t mClickDelay = kClickDelay;
435  uint16_t mDoubleClickDelay = kDoubleClickDelay;
436  uint16_t mLongPressDelay = kLongPressDelay;
437  uint16_t mRepeatPressDelay = kRepeatPressDelay;
438  uint16_t mRepeatPressInterval = kRepeatPressInterval;
439  uint16_t mHeartBeatInterval = kHeartBeatInterval;
440 };
441 
442 }
443 #endif
An Adjustable Compact Event-driven (ACE) Button library that debounces and dispatches button events t...
Definition: AceButton.h:54
Class that defines the timing parameters and event handler of an AceButton or a group of AceButton in...
Definition: ButtonConfig.h:66
uint16_t getDoubleClickDelay() const
Milliseconds between the first and second click to register as a double-click.
Definition: ButtonConfig.h:231
EventHandler getEventHandler() const ACE_BUTTON_DEPRECATED
Return the eventHandler function pointer.
Definition: ButtonConfig.h:362
void setHeartBeatInterval(uint16_t heartBeatInterval)
Set the heartBeatInterval milliseconds.
Definition: ButtonConfig.h:291
static const FeatureFlagType kFeatureSuppressAfterLongPress
Flag to suppress kEventReleased after a kEventLongPressed.
Definition: ButtonConfig.h:139
uint16_t FeatureFlagType
Type of the feature flag.
Definition: ButtonConfig.h:110
static const uint16_t kRepeatPressInterval
Default milliseconds returned by getRepeatPressInterval().
Definition: ButtonConfig.h:98
uint16_t getDebounceDelay() const
Milliseconds to wait for debouncing.
Definition: ButtonConfig.h:222
uint16_t getClickDelay() const
Milliseconds to wait for a possible click.
Definition: ButtonConfig.h:225
void clearFeature(FeatureFlagType features)
Disable the given features.
Definition: ButtonConfig.h:335
void setDoubleClickDelay(uint16_t doubleClickDelay)
Set the doubleClickDelay milliseconds.
Definition: ButtonConfig.h:271
static const uint16_t kRepeatPressDelay
Default milliseconds returned by getRepeatPressDelay().
Definition: ButtonConfig.h:95
uint16_t getLongPressDelay() const
Milliseconds for a long press event.
Definition: ButtonConfig.h:236
virtual unsigned long getClock()
Return the milliseconds of the internal clock.
Definition: ButtonConfig.h:307
static const FeatureFlagType kFeatureLongPress
Flag to activate the AceButton::kEventLongPress event.
Definition: ButtonConfig.h:123
static const uint16_t kClickDelay
Default milliseconds returned by getClickDelay().
Definition: ButtonConfig.h:86
static const FeatureFlagType kFeatureSuppressAfterClick
Flag to suppress kEventReleased after a kEventClicked.
Definition: ButtonConfig.h:129
static ButtonConfig * getSystemButtonConfig()
Return a pointer to the singleton instance of the ButtonConfig which is attached to all AceButton ins...
Definition: ButtonConfig.h:408
uint16_t getRepeatPressInterval() const
Milliseconds between two successive RepeatPressed events.
Definition: ButtonConfig.h:251
virtual int readButton(uint8_t pin)
Return the HIGH or LOW state of the button.
Definition: ButtonConfig.h:317
static const uint16_t kLongPressDelay
Default milliseconds returned by getLongPressDelay().
Definition: ButtonConfig.h:92
static const FeatureFlagType kFeatureDoubleClick
Flag to activate the AceButton::kEventDoubleClicked event.
Definition: ButtonConfig.h:120
static const FeatureFlagType kFeatureSuppressAfterRepeatPress
Flag to suppress kEventReleased after a kEventRepeatPressed.
Definition: ButtonConfig.h:142
void(* EventHandler)(AceButton *button, uint8_t eventType, uint8_t buttonState)
The event handler signature.
Definition: ButtonConfig.h:182
void setIEventHandler(IEventHandler *eventHandler)
Install the IEventHandler object pointer.
Definition: ButtonConfig.h:399
static const FeatureFlagType kFeatureSuppressAfterDoubleClick
Flag to suppress kEventReleased after a kEventDoubleClicked.
Definition: ButtonConfig.h:136
void setLongPressDelay(uint16_t longPressDelay)
Set the longPressDelay milliseconds.
Definition: ButtonConfig.h:276
static const FeatureFlagType kFeatureSuppressClickBeforeDoubleClick
Flag to suppress kEventClicked before a kEventDoubleClicked.
Definition: ButtonConfig.h:150
static const uint16_t kDebounceDelay
Default milliseconds returned by getDebounceDelay().
Definition: ButtonConfig.h:83
static const uint16_t kHeartBeatInterval
Default milliseconds returned by getHeartBeatInterval().
Definition: ButtonConfig.h:101
void setDebounceDelay(uint16_t debounceDelay)
Set the debounceDelay milliseconds.
Definition: ButtonConfig.h:261
virtual ~ButtonConfig()=default
If the ButtonConfig is created and deleted on the heap, a virtual destructor is technically required ...
void setRepeatPressInterval(uint16_t repeatPressInterval)
Set the repeatPressInterval milliseconds.
Definition: ButtonConfig.h:286
ButtonConfig()=default
Constructor.
void dispatchEvent(AceButton *button, uint8_t eventType, uint8_t buttonState) const
Dispatch the event to the handler.
Definition: ButtonConfig.h:370
static const FeatureFlagType kFeatureSuppressAll
Convenience flag to suppress all suppressions.
Definition: ButtonConfig.h:168
static const FeatureFlagType kInternalFeatureIEventHandler
Internal flag to indicate that mEventHandler is an IEventHandler object pointer instead of an EventHa...
Definition: ButtonConfig.h:159
static const FeatureFlagType kFeatureClick
Flag to activate the AceButton::kEventClicked event.
Definition: ButtonConfig.h:113
static const FeatureFlagType kFeatureRepeatPress
Flag to activate the AceButton::kEventRepeatPressed event.
Definition: ButtonConfig.h:126
void setFeature(FeatureFlagType features)
Enable the given features.
Definition: ButtonConfig.h:330
bool isFeature(FeatureFlagType features) const
Check if the given features are enabled.
Definition: ButtonConfig.h:325
uint16_t getRepeatPressDelay() const
Milliseconds that a button needs to be Pressed down before the start of the sequence of RepeatPressed...
Definition: ButtonConfig.h:246
void setClickDelay(uint16_t clickDelay)
Set the clickDelay milliseconds.
Definition: ButtonConfig.h:266
static const uint16_t kDoubleClickDelay
Default milliseconds returned by getDoubleClickDelay().
Definition: ButtonConfig.h:89
static const FeatureFlagType kFeatureHeartBeat
Flag to enable periodic kEventHeartBeat.
Definition: ButtonConfig.h:153
void setRepeatPressDelay(uint16_t repeatPressDelay)
Set the repeatPressDelay milliseconds.
Definition: ButtonConfig.h:281
void setEventHandler(EventHandler eventHandler)
Install the EventHandler function pointer.
Definition: ButtonConfig.h:390
void resetFeatures()
Disable all (externally visible) features.
Definition: ButtonConfig.h:344
uint16_t getHeartBeatInterval() const
Milliseconds between two successive HeartBeat events.
Definition: ButtonConfig.h:256
Interface of the class that will handle the button event.
Definition: IEventHandler.h:39
virtual void handleEvent(AceButton *button, uint8_t eventType, uint8_t buttonState)=0
Handle the button event.