25 #include "AceButton.h"
27 namespace ace_button {
34 #define CONCAT_(x, y) x##y
35 #define CONCAT(x,y) CONCAT_(x,y)
36 #define COMPILE_TIME_ASSERT(cond, msg) \
37 extern char CONCAT(compile_time_assert, __LINE__)[(cond) ? 1 : -1];
41 COMPILE_TIME_ASSERT(HIGH == 1,
"HIGH must be 1")
42 COMPILE_TIME_ASSERT(LOW == 0, "LOW must be 0")
46 #if ARDUINO_API_VERSION >= 10000
53 "kButtonStateUnknown conflicts with PinStatus enum")
58 static const char sEventPressed[] PROGMEM =
"Pressed";
59 static const char sEventReleased[] PROGMEM =
"Released";
60 static const char sEventClicked[] PROGMEM =
"Clicked";
61 static const char sEventDoubleClicked[] PROGMEM =
"DoubleClicked";
62 static const char sEventLongPressed[] PROGMEM =
"LongPressed";
63 static const char sEventRepeatPressed[] PROGMEM =
"RepeatPressed";
64 static const char sEventLongReleased[] PROGMEM =
"LongReleased";
65 static const char sEventHeartBeat[] PROGMEM =
"HeartBeat";
66 static const char sEventUnknown[] PROGMEM =
"(unknown)";
68 static const char*
const sEventNames[] PROGMEM = {
80 const char* name = (
event >=
sizeof(sEventNames) /
sizeof(
const char*))
82 : (
const char*) pgm_read_ptr(sEventNames + event);
83 return (__FlashStringHelper*) name;
93 setDefaultReleasedState(defaultReleasedState);
97 uint8_t defaultReleasedState, uint8_t
id) {
98 mButtonConfig = buttonConfig;
99 init(pin, defaultReleasedState,
id);
102 void AceButton::setDefaultReleasedState(uint8_t state) {
104 mFlags |= kFlagDefaultReleasedState;
106 mFlags &= ~kFlagDefaultReleasedState;
111 return (mFlags & kFlagDefaultReleasedState) ? HIGH : LOW;
117 uint8_t buttonState = mButtonConfig->
readButton(mPin);
126 uint16_t now = mButtonConfig->
getClock();
134 if (checkDebounced(now, buttonState)) {
136 if (checkInitialized(buttonState)) {
137 checkEvent(now, buttonState);
142 void AceButton::checkEvent(uint16_t now, uint8_t buttonState) {
156 checkPostponedClick(now);
157 checkOrphanedClick(now);
161 checkLongPress(now, buttonState);
164 checkRepeatPress(now, buttonState);
167 checkChanged(now, buttonState);
171 bool AceButton::checkDebounced(uint16_t now, uint8_t buttonState) {
172 if (isFlag(kFlagDebouncing)) {
183 uint16_t elapsedTime = now - mLastDebounceTime;
185 bool isDebouncingTimeOver =
188 if (isDebouncingTimeOver) {
189 clearFlag(kFlagDebouncing);
203 setFlag(kFlagDebouncing);
204 mLastDebounceTime = now;
209 bool AceButton::checkInitialized(uint16_t buttonState) {
220 mLastButtonState = buttonState;
224 void AceButton::checkLongPress(uint16_t now, uint8_t buttonState) {
229 if (isFlag(kFlagPressed) && !isFlag(kFlagLongPressed)) {
230 uint16_t elapsedTime = now - mLastPressTime;
232 setFlag(kFlagLongPressed);
238 void AceButton::checkRepeatPress(uint16_t now, uint8_t buttonState) {
243 if (isFlag(kFlagPressed)) {
244 if (isFlag(kFlagRepeatPressed)) {
245 uint16_t elapsedTime = now - mLastRepeatPressTime;
248 mLastRepeatPressTime = now;
251 uint16_t elapsedTime = now - mLastPressTime;
253 setFlag(kFlagRepeatPressed);
257 mLastRepeatPressTime = now;
263 void AceButton::checkChanged(uint16_t now, uint8_t buttonState) {
264 mLastButtonState = buttonState;
265 checkPressed(now, buttonState);
266 checkReleased(now, buttonState);
269 void AceButton::checkPressed(uint16_t now, uint8_t buttonState) {
275 mLastPressTime = now;
276 setFlag(kFlagPressed);
280 void AceButton::checkReleased(uint16_t now, uint8_t buttonState) {
293 bool wasLongPressed = isFlag(kFlagLongPressed);
297 ((isFlag(kFlagLongPressed) &&
300 (isFlag(kFlagRepeatPressed) &&
303 (isFlag(kFlagClicked) &&
305 (isFlag(kFlagDoubleClicked) &&
313 clearFlag(kFlagPressed);
314 clearFlag(kFlagDoubleClicked);
315 clearFlag(kFlagLongPressed);
316 clearFlag(kFlagRepeatPressed);
321 if (wasLongPressed) {
329 void AceButton::checkClicked(uint16_t now) {
330 if (!isFlag(kFlagPressed)) {
335 clearFlag(kFlagClicked);
338 uint16_t elapsedTime = now - mLastPressTime;
340 clearFlag(kFlagClicked);
346 checkDoubleClicked(now);
352 if (isFlag(kFlagDoubleClicked)) {
353 clearFlag(kFlagClicked);
358 mLastClickTime = now;
359 setFlag(kFlagClicked);
362 setFlag(kFlagClickPostponed);
368 void AceButton::checkDoubleClicked(uint16_t now) {
369 if (!isFlag(kFlagClicked)) {
370 clearFlag(kFlagDoubleClicked);
374 uint16_t elapsedTime = now - mLastClickTime;
376 clearFlag(kFlagDoubleClicked);
386 if (isFlag(kFlagClickPostponed)) {
387 clearFlag(kFlagClickPostponed);
389 setFlag(kFlagDoubleClicked);
393 void AceButton::checkOrphanedClick(uint16_t now) {
404 uint16_t elapsedTime = now - mLastClickTime;
405 if (isFlag(kFlagClicked) && (elapsedTime >= orphanedClickDelay)) {
406 clearFlag(kFlagClicked);
410 void AceButton::checkPostponedClick(uint16_t now) {
412 uint16_t elapsedTime = now - mLastClickTime;
413 if (isFlag(kFlagClickPostponed) && elapsedTime >= postponedClickDelay) {
415 clearFlag(kFlagClickPostponed);
419 void AceButton::checkHeartBeat(uint16_t now) {
423 if (! isFlag(kFlagHeartRunning)) {
424 setFlag(kFlagHeartRunning);
425 mLastHeartBeatTime = now;
429 uint16_t elapsedTime = now - mLastHeartBeatTime;
435 mLastHeartBeatTime = now;
439 void AceButton::handleEvent(uint8_t eventType) {