25 #include "TimingStats.h" 26 #include "AceButton.h" 33 #define CONCAT_(x, y) x##y 34 #define CONCAT(x,y) CONCAT_(x,y) 35 #define COMPILE_TIME_ASSERT(cond, msg) \ 36 extern char CONCAT(compile_time_assert, __LINE__)[(cond) ? 1 : -1]; 40 COMPILE_TIME_ASSERT(HIGH == 1,
"HIGH must be 1")
41 COMPILE_TIME_ASSERT(LOW == 0, "LOW must be 0")
45 #if ARDUINO_API_VERSION >= 10000 52 "kButtonStateUnknown conflicts with PinStatus enum")
57 init(pin, defaultReleasedState,
id);
61 uint8_t defaultReleasedState, uint8_t
id) {
62 init(buttonConfig, pin, defaultReleasedState,
id);
70 mLastDebounceTime = 0;
72 setDefaultReleasedState(defaultReleasedState);
76 uint8_t defaultReleasedState, uint8_t
id) {
77 mButtonConfig = buttonConfig;
78 init(pin, defaultReleasedState,
id);
81 void AceButton::setDefaultReleasedState(uint8_t state) {
83 mFlags |= kFlagDefaultReleasedState;
85 mFlags &= ~kFlagDefaultReleasedState;
90 return (mFlags & kFlagDefaultReleasedState) ? HIGH : LOW;
103 uint16_t now = mButtonConfig->
getClock();
105 uint8_t buttonState = mButtonConfig->
readButton(mPin);
108 if (checkDebounced(now, buttonState)) {
110 if (checkInitialized(buttonState)) {
111 checkEvent(now, buttonState);
116 if (stats !=
nullptr) {
117 uint16_t elapsedMicros = mButtonConfig->
getClockMicros() - nowMicros;
118 stats->update(elapsedMicros);
122 void AceButton::checkEvent(uint16_t now, uint8_t buttonState) {
136 checkPostponedClick(now);
137 checkOrphanedClick(now);
141 checkLongPress(now, buttonState);
144 checkRepeatPress(now, buttonState);
147 checkChanged(now, buttonState);
151 bool AceButton::checkDebounced(uint16_t now, uint8_t buttonState) {
152 if (isDebouncing()) {
163 uint16_t elapsedTime = now - mLastDebounceTime;
165 bool isDebouncingTimeOver =
168 if (isDebouncingTimeOver) {
184 mLastDebounceTime = now;
189 bool AceButton::checkInitialized(uint16_t buttonState) {
200 mLastButtonState = buttonState;
204 void AceButton::checkLongPress(uint16_t now, uint8_t buttonState) {
209 if (isPressed() && !isLongPressed()) {
210 uint16_t elapsedTime = now - mLastPressTime;
218 void AceButton::checkRepeatPress(uint16_t now, uint8_t buttonState) {
224 if (isRepeatPressed()) {
225 uint16_t elapsedTime = now - mLastRepeatPressTime;
228 mLastRepeatPressTime = now;
231 uint16_t elapsedTime = now - mLastPressTime;
237 mLastRepeatPressTime = now;
243 void AceButton::checkChanged(uint16_t now, uint8_t buttonState) {
244 mLastButtonState = buttonState;
245 checkPressed(now, buttonState);
246 checkReleased(now, buttonState);
249 void AceButton::checkPressed(uint16_t now, uint8_t buttonState) {
255 mLastPressTime = now;
260 void AceButton::checkReleased(uint16_t now, uint8_t buttonState) {
277 (isRepeatPressed() &&
282 (isDoubleClicked() &&
288 clearDoubleClicked();
290 clearRepeatPressed();
297 void AceButton::checkClicked(uint16_t now) {
306 uint16_t elapsedTime = now - mLastPressTime;
314 checkDoubleClicked(now);
320 if (isDoubleClicked()) {
326 mLastClickTime = now;
336 void AceButton::checkDoubleClicked(uint16_t now) {
338 clearDoubleClicked();
342 uint16_t elapsedTime = now - mLastClickTime;
344 clearDoubleClicked();
354 if (isClickPostponed()) {
355 clearClickPostponed();
361 void AceButton::checkOrphanedClick(uint16_t now) {
372 uint16_t elapsedTime = now - mLastClickTime;
373 if (isClicked() && (elapsedTime >= orphanedClickDelay)) {
378 void AceButton::checkPostponedClick(uint16_t now) {
380 uint16_t elapsedTime = now - mLastClickTime;
381 if (isClickPostponed() && elapsedTime >= postponedClickDelay) {
383 clearClickPostponed();
387 void AceButton::handleEvent(uint8_t eventType) {