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
120 static const FeatureFlagType kFeatureDoubleClick = 0x02;
121
123 static const FeatureFlagType kFeatureLongPress = 0x04;
124
126 static const FeatureFlagType kFeatureRepeatPress = 0x08;
127
129 static const FeatureFlagType kFeatureSuppressAfterClick = 0x10;
130
136 static const FeatureFlagType kFeatureSuppressAfterDoubleClick = 0x20;
137
139 static const FeatureFlagType kFeatureSuppressAfterLongPress = 0x40;
140
142 static const FeatureFlagType kFeatureSuppressAfterRepeatPress = 0x80;
143
150 static const FeatureFlagType kFeatureSuppressClickBeforeDoubleClick = 0x100;
151
153 static const FeatureFlagType kFeatureHeartBeat = 0x200;
154
159 static const FeatureFlagType kInternalFeatureIEventHandler = 0x8000;
160
168 static const FeatureFlagType kFeatureSuppressAll = (
169 kFeatureSuppressAfterClick
170 | kFeatureSuppressAfterDoubleClick
171 | kFeatureSuppressAfterLongPress
172 | kFeatureSuppressAfterRepeatPress
173 | kFeatureSuppressClickBeforeDoubleClick);
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
375 if (isFeature(kInternalFeatureIEventHandler)) {
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);
392 clearFeature(kInternalFeatureIEventHandler);
393 }
394
399 void setIEventHandler(IEventHandler* eventHandler) {
400 mEventHandler = eventHandler;
401 setFeature(kInternalFeatureIEventHandler);
402 }
403
408 static ButtonConfig* getSystemButtonConfig() {
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
ace_button::AceButton
An Adjustable Compact Event-driven (ACE) Button library that debounces and dispatches button events t...
Definition: AceButton.h:54
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::getDoubleClickDelay
uint16_t getDoubleClickDelay() const
Milliseconds between the first and second click to register as a double-click.
Definition: ButtonConfig.h:231
ace_button::ButtonConfig::getEventHandler
EventHandler getEventHandler() const ACE_BUTTON_DEPRECATED
Return the eventHandler function pointer.
Definition: ButtonConfig.h:362
ace_button::ButtonConfig::setHeartBeatInterval
void setHeartBeatInterval(uint16_t heartBeatInterval)
Set the heartBeatInterval milliseconds.
Definition: ButtonConfig.h:291
ace_button::ButtonConfig::kFeatureSuppressAfterLongPress
static const FeatureFlagType kFeatureSuppressAfterLongPress
Flag to suppress kEventReleased after a kEventLongPressed.
Definition: ButtonConfig.h:139
ace_button::ButtonConfig::FeatureFlagType
uint16_t FeatureFlagType
Type of the feature flag.
Definition: ButtonConfig.h:110
ace_button::ButtonConfig::kRepeatPressInterval
static const uint16_t kRepeatPressInterval
Default milliseconds returned by getRepeatPressInterval().
Definition: ButtonConfig.h:98
ace_button::ButtonConfig::getDebounceDelay
uint16_t getDebounceDelay() const
Milliseconds to wait for debouncing.
Definition: ButtonConfig.h:222
ace_button::ButtonConfig::getClickDelay
uint16_t getClickDelay() const
Milliseconds to wait for a possible click.
Definition: ButtonConfig.h:225
ace_button::ButtonConfig::clearFeature
void clearFeature(FeatureFlagType features)
Disable the given features.
Definition: ButtonConfig.h:335
ace_button::ButtonConfig::setDoubleClickDelay
void setDoubleClickDelay(uint16_t doubleClickDelay)
Set the doubleClickDelay milliseconds.
Definition: ButtonConfig.h:271
ace_button::ButtonConfig::kRepeatPressDelay
static const uint16_t kRepeatPressDelay
Default milliseconds returned by getRepeatPressDelay().
Definition: ButtonConfig.h:95
ace_button::ButtonConfig::getLongPressDelay
uint16_t getLongPressDelay() const
Milliseconds for a long press event.
Definition: ButtonConfig.h:236
ace_button::ButtonConfig::getClock
virtual unsigned long getClock()
Return the milliseconds of the internal clock.
Definition: ButtonConfig.h:307
ace_button::ButtonConfig::kFeatureLongPress
static const FeatureFlagType kFeatureLongPress
Flag to activate the AceButton::kEventLongPress event.
Definition: ButtonConfig.h:123
ace_button::ButtonConfig::kClickDelay
static const uint16_t kClickDelay
Default milliseconds returned by getClickDelay().
Definition: ButtonConfig.h:86
ace_button::ButtonConfig::kFeatureSuppressAfterClick
static const FeatureFlagType kFeatureSuppressAfterClick
Flag to suppress kEventReleased after a kEventClicked.
Definition: ButtonConfig.h:129
ace_button::ButtonConfig::getSystemButtonConfig
static ButtonConfig * getSystemButtonConfig()
Return a pointer to the singleton instance of the ButtonConfig which is attached to all AceButton ins...
Definition: ButtonConfig.h:408
ace_button::ButtonConfig::getRepeatPressInterval
uint16_t getRepeatPressInterval() const
Milliseconds between two successive RepeatPressed events.
Definition: ButtonConfig.h:251
ace_button::ButtonConfig::readButton
virtual int readButton(uint8_t pin)
Return the HIGH or LOW state of the button.
Definition: ButtonConfig.h:317
ace_button::ButtonConfig::kLongPressDelay
static const uint16_t kLongPressDelay
Default milliseconds returned by getLongPressDelay().
Definition: ButtonConfig.h:92
ace_button::ButtonConfig::kFeatureDoubleClick
static const FeatureFlagType kFeatureDoubleClick
Flag to activate the AceButton::kEventDoubleClicked event.
Definition: ButtonConfig.h:120
ace_button::ButtonConfig::kFeatureSuppressAfterRepeatPress
static const FeatureFlagType kFeatureSuppressAfterRepeatPress
Flag to suppress kEventReleased after a kEventRepeatPressed.
Definition: ButtonConfig.h:142
ace_button::ButtonConfig::EventHandler
void(* EventHandler)(AceButton *button, uint8_t eventType, uint8_t buttonState)
The event handler signature.
Definition: ButtonConfig.h:182
ace_button::ButtonConfig::setIEventHandler
void setIEventHandler(IEventHandler *eventHandler)
Install the IEventHandler object pointer.
Definition: ButtonConfig.h:399
ace_button::ButtonConfig::kFeatureSuppressAfterDoubleClick
static const FeatureFlagType kFeatureSuppressAfterDoubleClick
Flag to suppress kEventReleased after a kEventDoubleClicked.
Definition: ButtonConfig.h:136
ace_button::ButtonConfig::setLongPressDelay
void setLongPressDelay(uint16_t longPressDelay)
Set the longPressDelay milliseconds.
Definition: ButtonConfig.h:276
ace_button::ButtonConfig::kFeatureSuppressClickBeforeDoubleClick
static const FeatureFlagType kFeatureSuppressClickBeforeDoubleClick
Flag to suppress kEventClicked before a kEventDoubleClicked.
Definition: ButtonConfig.h:150
ace_button::ButtonConfig::kDebounceDelay
static const uint16_t kDebounceDelay
Default milliseconds returned by getDebounceDelay().
Definition: ButtonConfig.h:83
ace_button::ButtonConfig::kHeartBeatInterval
static const uint16_t kHeartBeatInterval
Default milliseconds returned by getHeartBeatInterval().
Definition: ButtonConfig.h:101
ace_button::ButtonConfig::setDebounceDelay
void setDebounceDelay(uint16_t debounceDelay)
Set the debounceDelay milliseconds.
Definition: ButtonConfig.h:261
ace_button::ButtonConfig::~ButtonConfig
virtual ~ButtonConfig()=default
If the ButtonConfig is created and deleted on the heap, a virtual destructor is technically required ...
ace_button::ButtonConfig::setRepeatPressInterval
void setRepeatPressInterval(uint16_t repeatPressInterval)
Set the repeatPressInterval milliseconds.
Definition: ButtonConfig.h:286
ace_button::ButtonConfig::ButtonConfig
ButtonConfig()=default
Constructor.
ace_button::ButtonConfig::dispatchEvent
void dispatchEvent(AceButton *button, uint8_t eventType, uint8_t buttonState) const
Dispatch the event to the handler.
Definition: ButtonConfig.h:370
ace_button::ButtonConfig::kFeatureSuppressAll
static const FeatureFlagType kFeatureSuppressAll
Convenience flag to suppress all suppressions.
Definition: ButtonConfig.h:168
ace_button::ButtonConfig::kInternalFeatureIEventHandler
static const FeatureFlagType kInternalFeatureIEventHandler
Internal flag to indicate that mEventHandler is an IEventHandler object pointer instead of an EventHa...
Definition: ButtonConfig.h:159
ace_button::ButtonConfig::kFeatureClick
static const FeatureFlagType kFeatureClick
Flag to activate the AceButton::kEventClicked event.
Definition: ButtonConfig.h:113
ace_button::ButtonConfig::kFeatureRepeatPress
static const FeatureFlagType kFeatureRepeatPress
Flag to activate the AceButton::kEventRepeatPressed event.
Definition: ButtonConfig.h:126
ace_button::ButtonConfig::setFeature
void setFeature(FeatureFlagType features)
Enable the given features.
Definition: ButtonConfig.h:330
ace_button::ButtonConfig::isFeature
bool isFeature(FeatureFlagType features) const
Check if the given features are enabled.
Definition: ButtonConfig.h:325
ace_button::ButtonConfig::getRepeatPressDelay
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
ace_button::ButtonConfig::setClickDelay
void setClickDelay(uint16_t clickDelay)
Set the clickDelay milliseconds.
Definition: ButtonConfig.h:266
ace_button::ButtonConfig::kDoubleClickDelay
static const uint16_t kDoubleClickDelay
Default milliseconds returned by getDoubleClickDelay().
Definition: ButtonConfig.h:89
ace_button::ButtonConfig::kFeatureHeartBeat
static const FeatureFlagType kFeatureHeartBeat
Flag to enable periodic kEventHeartBeat.
Definition: ButtonConfig.h:153
ace_button::ButtonConfig::setRepeatPressDelay
void setRepeatPressDelay(uint16_t repeatPressDelay)
Set the repeatPressDelay milliseconds.
Definition: ButtonConfig.h:281
ace_button::ButtonConfig::setEventHandler
void setEventHandler(EventHandler eventHandler)
Install the EventHandler function pointer.
Definition: ButtonConfig.h:390
ace_button::ButtonConfig::resetFeatures
void resetFeatures()
Disable all (externally visible) features.
Definition: ButtonConfig.h:344
ace_button::ButtonConfig::getHeartBeatInterval
uint16_t getHeartBeatInterval() const
Milliseconds between two successive HeartBeat events.
Definition: ButtonConfig.h:256
ace_button::IEventHandler
Interface of the class that will handle the button event.
Definition: IEventHandler.h:39
ace_button::IEventHandler::handleEvent
virtual void handleEvent(AceButton *button, uint8_t eventType, uint8_t buttonState)=0
Handle the button event.