Files
mixly3-server/arduino-libs/arduino-cli/libraries/Button2/src/Button2.cpp

294 lines
8.2 KiB
C++

/////////////////////////////////////////////////////////////////
/*
Button2.cpp - Arduino Library to simplify working with buttons.
Created by Lennart Hennigs.
*/
/////////////////////////////////////////////////////////////////
#include "Button2.h"
/////////////////////////////////////////////////////////////////
Button2::Button2() {
pin = 255;
}
/////////////////////////////////////////////////////////////////
Button2::Button2(byte attachTo, byte buttonMode /* = INPUT_PULLUP */, boolean isCapacitive /* = false */, boolean activeLow /* = true */) {
begin(attachTo, buttonMode, isCapacitive, activeLow);
}
/////////////////////////////////////////////////////////////////
void Button2::begin(byte attachTo, byte buttonMode /* = INPUT_PULLUP */, boolean isCapacitive /* = false */, boolean activeLow /* = true */) {
pin = attachTo;
longclick_detected_retriggerable = false;
setDebounceTime(DEBOUNCE_MS);
setLongClickTime(LONGCLICK_MS);
setDoubleClickTime(DOUBLECLICK_MS);
pressed = activeLow ? LOW : HIGH;
state = activeLow ? HIGH : LOW;
if (!isCapacitive) {
pinMode(attachTo, buttonMode);
} else {
capacitive = true;
}
}
/////////////////////////////////////////////////////////////////
void Button2::setDebounceTime(unsigned int ms) {
debounce_time_ms = ms;
}
/////////////////////////////////////////////////////////////////
void Button2::setLongClickTime(unsigned int ms) {
longclick_time_ms = ms;
}
/////////////////////////////////////////////////////////////////
void Button2::setDoubleClickTime(unsigned int ms) {
doubleclick_time_ms = ms;
}
/////////////////////////////////////////////////////////////////
unsigned int Button2::getDebounceTime() const {
return debounce_time_ms;
}
/////////////////////////////////////////////////////////////////
unsigned int Button2::getLongClickTime() const {
return longclick_time_ms;
}
/////////////////////////////////////////////////////////////////
unsigned int Button2::getDoubleClickTime() const {
return doubleclick_time_ms;
}
/////////////////////////////////////////////////////////////////
byte Button2::getAttachPin() const {
return pin;
}
/////////////////////////////////////////////////////////////////
bool Button2::operator==(Button2 &rhs) {
return (this==&rhs);
}
/////////////////////////////////////////////////////////////////
void Button2::setLongClickDetectedRetriggerable(bool retriggerable) {
longclick_detected_retriggerable = retriggerable;
}
/////////////////////////////////////////////////////////////////
void Button2::setChangedHandler(CallbackFunction f)
{
change_cb = f;
}
/////////////////////////////////////////////////////////////////
void Button2::setPressedHandler(CallbackFunction f) {
pressed_cb = f;
}
/////////////////////////////////////////////////////////////////
void Button2::setReleasedHandler(CallbackFunction f) {
released_cb = f;
}
/////////////////////////////////////////////////////////////////
void Button2::setClickHandler(CallbackFunction f) {
click_cb = f;
}
/////////////////////////////////////////////////////////////////
void Button2::setTapHandler(CallbackFunction f) {
tap_cb = f;
}
/////////////////////////////////////////////////////////////////
void Button2::setLongClickHandler(CallbackFunction f) {
long_cb = f;
}
/////////////////////////////////////////////////////////////////
void Button2::setDoubleClickHandler(CallbackFunction f) {
double_cb = f;
}
/////////////////////////////////////////////////////////////////
void Button2::setTripleClickHandler(CallbackFunction f) {
triple_cb = f;
}
/////////////////////////////////////////////////////////////////
void Button2::setLongClickDetectedHandler(CallbackFunction f) {
longclick_detected_cb = f;
}
/////////////////////////////////////////////////////////////////
unsigned int Button2::wasPressedFor() const {
return down_time_ms;
}
/////////////////////////////////////////////////////////////////
boolean Button2::isPressed() const {
return (state == pressed);
}
/////////////////////////////////////////////////////////////////
boolean Button2::isPressedRaw() const {
return (digitalRead(pin) == pressed);
}
/////////////////////////////////////////////////////////////////
byte Button2::getNumberOfClicks() const {
return click_count;
}
/////////////////////////////////////////////////////////////////
byte Button2::getClickType() const {
return last_click_type;
}
/////////////////////////////////////////////////////////////////
void Button2::loop() {
if (pin != 255) {
prev_state = state;
unsigned long now = millis();
if (!capacitive) {
state = digitalRead(pin);
} else {
#if defined(ARDUINO_ARCH_ESP32)
int capa = touchRead(pin);
state = capa < CAPACITIVE_TOUCH_THRESHOLD ? LOW : HIGH;
#endif
}
// is button pressed?
if (state == pressed && prev_state != pressed) {
down_ms = now;
pressed_triggered = false;
click_ms = down_ms;
// trigger pressed event (after debounce has passed)
} else if (state == pressed && !pressed_triggered && (now - down_ms >= debounce_time_ms)) {
pressed_triggered = true;
click_count++;
if (change_cb != NULL) change_cb (*this);
if (pressed_cb != NULL) pressed_cb (*this);
// is the button released?
} else if (state != pressed && prev_state == pressed) {
down_time_ms = now - down_ms;
// is it beyond debounce time?
if (down_time_ms >= debounce_time_ms) {
// trigger release
if (change_cb != NULL) change_cb (*this);
if (released_cb != NULL) released_cb (*this);
// trigger tap
if (tap_cb != NULL) tap_cb (*this);
// was it a longclick? (preceeds single / double / triple clicks)
if (down_time_ms >= longclick_time_ms) {
longclick_detected = true;
}
}
// is the button released and the time has passed for multiple clicks?
} else if (state != pressed && now - click_ms > doubleclick_time_ms) {
// was there a longclick?
if (longclick_detected) {
// was it part of a combination?
if (click_count == 1) {
last_click_type = LONG_CLICK;
if (long_cb != NULL) long_cb (*this);
}
longclick_detected = false;
longclick_detected_reported = false;
longclick_detected_counter = 0;
// determine the number of single clicks
} else if (click_count > 0) {
switch (click_count) {
case 1:
last_click_type = SINGLE_CLICK;
if (click_cb != NULL) click_cb (*this);
break;
case 2:
last_click_type = DOUBLE_CLICK;
if (double_cb != NULL) double_cb (*this);
break;
case 3:
last_click_type = TRIPLE_CLICK;
if (triple_cb != NULL) triple_cb (*this);
break;
}
}
click_count = 0;
click_ms = 0;
}
bool longclick_period_detected = now - down_ms >= (longclick_time_ms * (longclick_detected_counter + 1));
// check to see that the longclick_ms period has been exceeded and call the appropriate callback
if (state == pressed && longclick_period_detected && !longclick_detected_reported) {
longclick_detected_reported = true;
longclick_detected = true;
if (longclick_detected_retriggerable) {
// if it's retriggerable then we bump the counter and reset the "reported" flag (as the counter will stop the false trigger)
longclick_detected_counter++;
longclick_detected_reported = false;
}
// longpress_detected_ms = now;
if (longclick_detected_cb != NULL)
longclick_detected_cb(*this);
}
}
}
/////////////////////////////////////////////////////////////////
void Button2::reset() {
pin = 255;
click_count = 0;
last_click_type = 0;
down_time_ms = 0;
pressed_triggered = false;
longclick_detected = false;
longclick_detected_reported = false;
pressed_cb = NULL;
released_cb = NULL;
change_cb = NULL;
tap_cb = NULL;
click_cb = NULL;
long_cb = NULL;
double_cb = NULL;
triple_cb = NULL;
longclick_detected_cb = NULL;
}
/////////////////////////////////////////////////////////////////