Files
gunner47-GyverLamp/libraries/GyverButton/GyverButton.cpp

189 lines
4.8 KiB
C++

#include "GyverButton.h"
#include <Arduino.h>
GButton::GButton(uint8_t pin) {
_PIN = pin;
GButton::init();
}
GButton::GButton(uint8_t pin, boolean type, boolean dir) {
_PIN = pin;
GButton::init();
GButton::setType(type);
flags.inv_state = dir;
}
void GButton::init() {
_debounce = 60;
_timeout = 500;
_step_timeout = 400;
_click_timeout = 300;
flags.inv_state = NORM_OPEN;
flags.mode = false;
flags.type = false;
flags.tickMode = false;
GButton::setType(HIGH_PULL);
}
void GButton::setDebounce(uint16_t debounce) {
_debounce = debounce;
}
void GButton::setTimeout(uint16_t timeout) {
_timeout = timeout;
}
void GButton::setClickTimeout(uint16_t timeout) {
_click_timeout = timeout;
}
void GButton::setStepTimeout(uint16_t step_timeout) {
_step_timeout = step_timeout;
}
void GButton::setType(boolean type) {
flags.type = type;
if (type) pinMode(_PIN, INPUT);
else pinMode(_PIN, INPUT_PULLUP);
}
void GButton::setDirection(boolean dir) {
flags.inv_state = dir;
}
void GButton::setTickMode(boolean tickMode) {
flags.tickMode = tickMode;
}
boolean GButton::isPress() {
if (flags.tickMode) GButton::tick();
if (flags.isPress_f) {
flags.isPress_f = false;
return true;
} else return false;
}
boolean GButton::isRelease() {
if (flags.tickMode) GButton::tick();
if (flags.isRelease_f) {
flags.isRelease_f = false;
return true;
} else return false;
}
boolean GButton::isClick() {
if (flags.tickMode) GButton::tick();
if (flags.isOne_f) {
flags.isOne_f = false;
return true;
} else return false;
}
boolean GButton::isHolded() {
if (flags.tickMode) GButton::tick();
if (flags.isHolded_f) {
flags.isHolded_f = false;
return true;
} else return false;
}
boolean GButton::isHold() {
if (flags.tickMode) GButton::tick();
if (flags.step_flag) return true;
else return false;
}
boolean GButton::state() {
if (flags.tickMode) GButton::tick();
return flags.btn_state;
}
boolean GButton::isSingle() {
if (flags.tickMode) GButton::tick();
if (flags.counter_flag && last_counter == 1) {
flags.counter_flag = false;
return true;
} else return false;
}
boolean GButton::isDouble() {
if (flags.tickMode) GButton::tick();
if (flags.counter_flag && last_counter == 2) {
flags.counter_flag = false;
return true;
} else return false;
}
boolean GButton::isTriple() {
if (flags.tickMode) GButton::tick();
if (flags.counter_flag && last_counter == 3) {
flags.counter_flag = false;
return true;
} else return false;
}
boolean GButton::hasClicks() {
if (flags.tickMode) GButton::tick();
if (flags.counter_flag) {
flags.counter_flag = false;
return true;
} else return false;
}
uint8_t GButton::getClicks() {
return last_counter;
}
boolean GButton::isStep() {
if (flags.tickMode) GButton::tick();
if (flags.step_flag && (millis() - btn_timer >= _step_timeout)) {
btn_timer = millis();
return true;
}
else return false;
}
uint8_t GButton::getHoldClicks() {
if (flags.tickMode) GButton::tick();
return flags.hold_flag ? last_hold_counter : 0;
}
void GButton::tick(boolean state) {
flags.mode = true;
flags.btn_state = state ^ flags.inv_state;
GButton::tick();
flags.mode = false;
}
void GButton::tick() {
// читаем пин
if (!flags.mode) flags.btn_state = !digitalRead(_PIN) ^ (flags.inv_state ^ flags.type);
// нажатие
if (flags.btn_state && !flags.btn_flag) {
if (!flags.btn_deb) {
flags.btn_deb = true;
btn_timer = millis();
} else {
if (millis() - btn_timer >= _debounce) {
flags.btn_flag = true;
flags.isPress_f = true;
flags.oneClick_f = true;
}
}
} else {
flags.btn_deb = false;
}
// отпускание
if (!flags.btn_state && flags.btn_flag) {
flags.btn_flag = false;
if (!flags.hold_flag) btn_counter++;
flags.hold_flag = false;
flags.isRelease_f = true;
btn_timer = millis();
flags.step_flag = false;
if (flags.oneClick_f) {
flags.oneClick_f = false;
flags.isOne_f = true;
}
}
// кнопка удерживается
if (flags.btn_flag && flags.btn_state && (millis() - btn_timer >= _timeout) && !flags.hold_flag) {
flags.hold_flag = true;
last_hold_counter = btn_counter;
btn_counter = 0;
last_counter = 0;
flags.isHolded_f = true;
flags.step_flag = true;
flags.oneClick_f = false;
btn_timer = millis();
}
// обработка накликивания
if ((millis() - btn_timer >= _click_timeout) && (btn_counter != 0)) {
last_counter = btn_counter;
btn_counter = 0;
flags.counter_flag = true;
}
}