AceButton  1.2
An adjustable, compact, event-driven (ACE) 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 
30 // TODO: Verify if this is actually needed. The program size seems to be
31 // identical with or without it on the Arduino IDE (which uses gcc).
32 #define ACE_BUTTON_INLINE __attribute__((always_inline))
33 
34 namespace ace_button {
35 
36 class AceButton;
37 class TimingStats;
38 
69 class ButtonConfig {
70  public:
71  // Various timing constants, in milliseconds.
72  //
73  // Note that the timing constants are stored as uint16_t (2
74  // bytes) instead of unsigned long (4 bytes) which is the type returned by
75  // the millis() system method. It turns out that we can store and perform
76  // all timing calculations using uint16_t without ill effect, as long as the
77  // polling of AceButton::check() happens more frequently than the rollover
78  // time of a uint16_t (i.e. 65.536 seconds) and certain precautions (e.g.
79  // AceButton::checkOrphanedClick()) are taken before a uint16_t rollover
80  // happens. In theory, these additional precautions would be needed even if
81  // an 'unsigned long' is used but almost no one does them because they
82  // assume that their code won't be running continuously for the rollover
83  // time of an 'unsigned long' (i.e. 49.7 days).
84 
86  static const uint16_t kDebounceDelay = 50;
87 
89  static const uint16_t kClickDelay = 200;
90 
92  static const uint16_t kDoubleClickDelay = 400;
93 
95  static const uint16_t kLongPressDelay = 1000;
96 
98  static const uint16_t kRepeatPressDelay = 1000;
99 
101  static const uint16_t kRepeatPressInterval = 200;
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 
159  static const FeatureFlagType kFeatureSuppressAll =
160  (kFeatureSuppressAfterClick |
161  kFeatureSuppressAfterDoubleClick |
162  kFeatureSuppressAfterLongPress |
163  kFeatureSuppressAfterRepeatPress |
165 
173  typedef void (*EventHandler)(AceButton* button, uint8_t eventType,
174  uint8_t buttonState);
175 
177  ButtonConfig();
178 
179  // These configuration methods are virtual so that they can be overriddden.
180  // Subclasses can override at the class-level by defining a new virtual
181  // function in the subclass, or by defining an instance variable and storing
182  // the parameter with each instance of this class.
183 
185  virtual uint16_t getDebounceDelay() { return kDebounceDelay; }
186 
188  virtual uint16_t getClickDelay() { return kClickDelay; }
189 
194  virtual uint16_t getDoubleClickDelay() {
195  return kDoubleClickDelay;
196  }
197 
199  virtual uint16_t getLongPressDelay() {
200  return kLongPressDelay;
201  }
202 
209  virtual uint16_t getRepeatPressDelay() {
210  return kRepeatPressDelay;
211  }
212 
216  virtual uint16_t getRepeatPressInterval() {
217  return kRepeatPressInterval;
218  }
219 
220  // The getClock() and readButton() are external dependencies that normally
221  // would be injected using separate classes, but in the interest of saving
222  // RAM in an embedded environment, we expose them in this class instead.
223 
229  virtual unsigned long getClock() { return millis(); }
230 
235  virtual unsigned long getClockMicros() { return micros(); }
236 
242  virtual int readButton(uint8_t pin) {
243  return digitalRead(pin);
244  }
245 
246  // These methods return the various feature flags that control the
247  // functionality of the AceButton.
248 
250  bool isFeature(FeatureFlagType features) ACE_BUTTON_INLINE {
251  return mFeatureFlags & features;
252  }
253 
255  void setFeature(FeatureFlagType features) ACE_BUTTON_INLINE {
256  mFeatureFlags |= features;
257  }
258 
260  void clearFeature(FeatureFlagType features) ACE_BUTTON_INLINE {
261  mFeatureFlags &= ~features;
262  }
263 
264  // EventHandler
265 
267  EventHandler getEventHandler() ACE_BUTTON_INLINE {
268  return mEventHandler;
269  }
270 
275  void setEventHandler(EventHandler eventHandler) ACE_BUTTON_INLINE {
276  mEventHandler = eventHandler;
277  }
278 
279  // TimingStats
280 
282  void setTimingStats(TimingStats* timingStats) {
283  mTimingStats = timingStats;
284  }
285 
287  TimingStats* getTimingStats() { return mTimingStats; }
288 
293  static ButtonConfig* getSystemButtonConfig() ACE_BUTTON_INLINE {
294  return &sSystemButtonConfig;
295  }
296 
297  protected:
302  virtual void init() {
303  mFeatureFlags = 0;
304  mTimingStats = nullptr;
305  }
306 
307  private:
308  // Disable copy-constructor and assignment operator
309  ButtonConfig(const ButtonConfig&) = delete;
310  ButtonConfig& operator=(const ButtonConfig&) = delete;
311 
313  EventHandler mEventHandler;
314 
316  FeatureFlagType mFeatureFlags;
317 
319  TimingStats* mTimingStats;
320 
325  static ButtonConfig sSystemButtonConfig;
326 };
327 
328 }
329 #endif
static const uint16_t kRepeatPressInterval
Default value returned by getRepeatPressInterval().
Definition: ButtonConfig.h:101
static const uint16_t kDebounceDelay
Default value returned by getDebounceDelay().
Definition: ButtonConfig.h:86
virtual uint16_t getDoubleClickDelay()
Milliseconds between the first and second click to register as a double-click.
Definition: ButtonConfig.h:194
virtual void init()
Initialize to its pristine state, except for the EventHandler which is unchanged. ...
Definition: ButtonConfig.h:302
virtual uint16_t getRepeatPressDelay()
Milliseconds that a button needs to be Pressed down before the start of the sequence of RepeatPressed...
Definition: ButtonConfig.h:209
static const FeatureFlagType kFeatureClick
Flag to activate the AceButton::kEventClicked event.
Definition: ButtonConfig.h:113
ButtonConfig()
Constructor.
EventHandler getEventHandler() ACE_BUTTON_INLINE
Return the eventHandler.
Definition: ButtonConfig.h:267
TimingStats * getTimingStats()
Get the timing stats.
Definition: ButtonConfig.h:287
void clearFeature(FeatureFlagType features) ACE_BUTTON_INLINE
Disable the given features.
Definition: ButtonConfig.h:260
void setEventHandler(EventHandler eventHandler) ACE_BUTTON_INLINE
Install the event handler.
Definition: ButtonConfig.h:275
void setTimingStats(TimingStats *timingStats)
Set the timing stats object.
Definition: ButtonConfig.h:282
virtual uint16_t getClickDelay()
Milliseconds to wait for a possible click.
Definition: ButtonConfig.h:188
static const FeatureFlagType kFeatureDoubleClick
Flag to activate the AceButton::kEventDoubleClicked event.
Definition: ButtonConfig.h:120
bool isFeature(FeatureFlagType features) ACE_BUTTON_INLINE
Check if the given features are enabled.
Definition: ButtonConfig.h:250
virtual int readButton(uint8_t pin)
Return the HIGH or LOW state of the button.
Definition: ButtonConfig.h:242
static const FeatureFlagType kFeatureRepeatPress
Flag to activate the AceButton::kEventRepeatPressed event.
Definition: ButtonConfig.h:126
uint16_t FeatureFlagType
Type of the feature flag.
Definition: ButtonConfig.h:110
virtual uint16_t getLongPressDelay()
Milliseconds for a long press event.
Definition: ButtonConfig.h:199
static const FeatureFlagType kFeatureSuppressAll
Convenience flag to suppress all suppressions.
Definition: ButtonConfig.h:159
Class that defines the timing parameters and event handler of an AceButton or a group of AceButton in...
Definition: ButtonConfig.h:69
virtual uint16_t getRepeatPressInterval()
Milliseconds between two successive RepeatPressed events.
Definition: ButtonConfig.h:216
static ButtonConfig * getSystemButtonConfig() ACE_BUTTON_INLINE
Return a pointer to the singleton instance of the ButtonConfig which is attached to all AceButton ins...
Definition: ButtonConfig.h:293
static const FeatureFlagType kFeatureLongPress
Flag to activate the AceButton::kEventLongPress event.
Definition: ButtonConfig.h:123
void(* EventHandler)(AceButton *button, uint8_t eventType, uint8_t buttonState)
The event handler signature.
Definition: ButtonConfig.h:173
static const FeatureFlagType kFeatureSuppressClickBeforeDoubleClick
Flag to suppress kEventClicked before a kEventDoubleClicked.
Definition: ButtonConfig.h:150
static const uint16_t kDoubleClickDelay
Default value returned by getDoubleClickDelay().
Definition: ButtonConfig.h:92
static const uint16_t kClickDelay
Default value returned by getClickDelay().
Definition: ButtonConfig.h:89
static const FeatureFlagType kFeatureSuppressAfterLongPress
Flag to suppress kEventReleased after a kEventLongPressed.
Definition: ButtonConfig.h:139
static const uint16_t kRepeatPressDelay
Default value returned by getRepeatPressDelay().
Definition: ButtonConfig.h:98
virtual uint16_t getDebounceDelay()
Milliseconds to wait for debouncing.
Definition: ButtonConfig.h:185
static const uint16_t kLongPressDelay
Default value returned by getLongPressDelay().
Definition: ButtonConfig.h:95
An Adjustable Compact Event-driven (ACE) Button library that debounces and dispatches button events t...
Definition: AceButton.h:50
void setFeature(FeatureFlagType features) ACE_BUTTON_INLINE
Enable the given features.
Definition: ButtonConfig.h:255
virtual unsigned long getClockMicros()
Return the microseconds of the internal clock.
Definition: ButtonConfig.h:235
static const FeatureFlagType kFeatureSuppressAfterDoubleClick
Flag to suppress kEventReleased after a kEventDoubleClicked.
Definition: ButtonConfig.h:136
static const FeatureFlagType kFeatureSuppressAfterClick
Flag to suppress kEventReleased after a kEventClicked.
Definition: ButtonConfig.h:129
virtual unsigned long getClock()
Return the milliseconds of the internal clock.
Definition: ButtonConfig.h:229
static const FeatureFlagType kFeatureSuppressAfterRepeatPress
Flag to suppress kEventReleased after a kEventRepeatPressed.
Definition: ButtonConfig.h:142