Add libraries dir

This commit is contained in:
2022-03-12 03:50:28 +08:00
parent 816f0bb3a5
commit 7572125fcb
256 changed files with 41193 additions and 0 deletions
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021 Alex
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+171
View File
@@ -0,0 +1,171 @@
![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)
![author](https://img.shields.io/badge/author-AlexGyver-informational.svg)
# GyverButton
Библиотека для многофункциональной отработки нажатия кнопки
**ВНИМАНИЕ, БИБЛИОТЕКА УСТАРЕЛА! ИСПОЛЬЗУЙ БИБЛИОТЕКУ [EncButton](https://github.com/GyverLibs/EncButton)**
- Работа с нормально замкнутыми и нормально разомкнутыми кнопками
- Работа с подключением PULL_UP и PULL_DOWN
- Опрос кнопки с программным антидребезгом контактов (настраиваемое время)
- Отработка нажатия, удерживания, отпускания, клика по кнопке (+ настройка таймаутов)
- Отработка одиночного, двойного и тройного нажатия (вынесено отдельно)
- Отработка любого количества нажатий кнопки (функция возвращает количество нажатий)
- Функция изменения значения переменной с заданным шагом и заданным интервалом по времени
- Возможность работы с "виртуальными" кнопками (все возможности библиотеки используются для матричных и резистивных клавиатур)
### Совместимость
Совместима со всеми Arduino платформами (используются Arduino-функции)
### Документация
К библиотеке есть [расширенная документация](https://alexgyver.ru/GyverButton/)
## Содержание
- [Установка](#install)
- [Инициализация](#init)
- [Использование](#usage)
- [Пример](#example)
- [Версии](#versions)
- [Баги и обратная связь](#feedback)
<a id="install"></a>
## Установка
- Библиотеку можно найти по названию **GyverButton** и установить через менеджер библиотек в:
- Arduino IDE
- Arduino IDE v2
- PlatformIO
- [Скачать библиотеку](https://github.com/GyverLibs/GyverButton/archive/refs/heads/main.zip) .zip архивом для ручной установки:
- Распаковать и положить в *C:\Program Files (x86)\Arduino\libraries* (Windows x64)
- Распаковать и положить в *C:\Program Files\Arduino\libraries* (Windows x32)
- Распаковать и положить в *Документы/Arduino/libraries/*
- (Arduino IDE) автоматическая установка из .zip: *Скетч/Подключить библиотеку/Добавить .ZIP библиотеку…* и указать скачанный архив
- Читай более подробную инструкцию по установке библиотек [здесь](https://alexgyver.ru/arduino-first/#%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B1%D0%B8%D0%B1%D0%BB%D0%B8%D0%BE%D1%82%D0%B5%D0%BA)
<a id="init"></a>
## Инициализация
```cpp
GButton btn; // без привязки к пину (виртуальная кнопка) и без указания типа (по умолч. HIGH_PULL и NORM_OPEN)
GButton btn(пин); // с привязкой к пину и без указания типа (по умолч. HIGH_PULL и NORM_OPEN)
GButton btn(пин, тип подключ.); // с привязкой к пину и указанием типа подключения (HIGH_PULL / LOW_PULL) и без указания типа кнопки (по умолч. NORM_OPEN)
GButton btn(пин, тип подключ., тип кнопки); // с привязкой к пину и указанием типа подключения (HIGH_PULL / LOW_PULL) и типа кнопки (NORM_OPEN / NORM_CLOSE)
GButton btn(BTN_NO_PIN, тип подключ., тип кнопки); // без привязки к пину и указанием типа подключения (HIGH_PULL / LOW_PULL) и типа кнопки (NORM_OPEN / NORM_CLOSE)
```
<a id="usage"></a>
## Использование
```cpp
void setDebounce(uint16_t debounce); // установка времени антидребезга (по умолчанию 80 мс)
void setTimeout(uint16_t timeout); // установка таймаута удержания (по умолчанию 300 мс)
void setClickTimeout(uint16_t timeout); // установка таймаута между кликами (по умолчанию 500 мс)
void setStepTimeout(uint16_t step_timeout); // установка таймаута между инкрементами (по умолчанию 400 мс)
void setType(uint8_t type); // установка типа кнопки (HIGH_PULL - подтянута к питанию, LOW_PULL - к gnd)
void setDirection(uint8_t dir); // установка направления (разомкнута/замкнута по умолчанию - NORM_OPEN, NORM_CLOSE)
void setTickMode(uint8_t tickMode); // (MANUAL / AUTO) ручной или автоматический опрос кнопки функцией tick()
// MANUAL - нужно вызывать функцию tick() вручную
// AUTO - tick() входит во все остальные функции и опрашивается сама
void tick(); // опрос кнопки
void tick(boolean state); // опрос внешнего значения (0 нажато, 1 не нажато) (для матричных, резистивных клавиатур и джойстиков)
boolean isPress(); // возвращает true при нажатии на кнопку. Сбрасывается после вызова
boolean isRelease(); // возвращает true при отпускании кнопки. Сбрасывается после вызова
boolean isClick(); // возвращает true при клике. Сбрасывается после вызова
boolean isHolded(); // возвращает true при удержании дольше timeout. Сбрасывается после вызова
boolean isHold(); // возвращает true при нажатой кнопке, не сбрасывается
boolean state(); // возвращает состояние кнопки
boolean isSingle(); // возвращает true при одиночном клике. Сбрасывается после вызова
boolean isDouble(); // возвращает true при двойном клике. Сбрасывается после вызова
boolean isTriple(); // возвращает true при тройном клике. Сбрасывается после вызова
boolean hasClicks(); // проверка на наличие кликов. Сбрасывается после вызова
uint8_t getClicks(); // вернуть количество кликов
uint8_t getHoldClicks();// вернуть количество кликов, предшествующее удерживанию
boolean isStep(); // возвращает true по таймеру setStepTimeout, смотри пример
void resetStates(); // сбрасывает все is-флаги и счётчики
```
<a id="example"></a>
## Пример
Остальные примеры смотри в **examples**!
```cpp
// Пример использования библиотеки GyverButton, все возможности в одном скетче.
#define BTN_PIN 3 // кнопка подключена сюда (BTN_PIN --- КНОПКА --- GND)
#include "GyverButton.h"
GButton butt1(BTN_PIN);
// Варианты инициализации:
// GButton btn; // без привязки к пину (виртуальная кнопка) и без указания типа (по умолч. HIGH_PULL и NORM_OPEN)
// GButton btn(пин); // с привязкой к пину и без указания типа (по умолч. HIGH_PULL и NORM_OPEN)
// GButton btn(пин, тип подключ.); // с привязкой к пину и указанием типа подключения (HIGH_PULL / LOW_PULL) и без указания типа кнопки (по умолч. NORM_OPEN)
// GButton btn(пин, тип подключ., тип кнопки); // с привязкой к пину и указанием типа подключения (HIGH_PULL / LOW_PULL) и типа кнопки (NORM_OPEN / NORM_CLOSE)
// GButton btn(BTN_NO_BTN_PIN, тип подключ., тип кнопки); // без привязки к пину и указанием типа подключения (HIGH_PULL / LOW_PULL) и типа кнопки (NORM_OPEN / NORM_CLOSE)
int value = 0;
void setup() {
Serial.begin(9600);
butt1.setDebounce(50); // настройка антидребезга (по умолчанию 80 мс)
butt1.setTimeout(300); // настройка таймаута на удержание (по умолчанию 500 мс)
butt1.setClickTimeout(600); // настройка таймаута между кликами (по умолчанию 300 мс)
// HIGH_PULL - кнопка подключена к GND, пин подтянут к VCC (BTN_PIN --- КНОПКА --- GND)
// LOW_PULL - кнопка подключена к VCC, пин подтянут к GND
// по умолчанию стоит HIGH_PULL
butt1.setType(HIGH_PULL);
// NORM_OPEN - нормально-разомкнутая кнопка
// NORM_CLOSE - нормально-замкнутая кнопка
// по умолчанию стоит NORM_OPEN
butt1.setDirection(NORM_OPEN);
}
void loop() {
butt1.tick(); // обязательная функция отработки. Должна постоянно опрашиваться
if (butt1.isClick()) Serial.println("Click"); // проверка на один клик
if (butt1.isSingle()) Serial.println("Single"); // проверка на один клик
if (butt1.isDouble()) Serial.println("Double"); // проверка на двойной клик
if (butt1.isTriple()) Serial.println("Triple"); // проверка на тройной клик
if (butt1.hasClicks()) // проверка на наличие нажатий
Serial.println(butt1.getClicks()); // получить (и вывести) число нажатий
if (butt1.isPress()) Serial.println("Press"); // нажатие на кнопку (+ дебаунс)
if (butt1.isRelease()) Serial.println("Release"); // отпускание кнопки (+ дебаунс)
if (butt1.isHold()) { // если кнопка удерживается
Serial.print("Holding "); // выводим пока удерживается
Serial.println(butt1.getHoldClicks()); // можно вывести количество кликов перед удержанием!
}
if (butt1.isHold()) Serial.println("Holding"); // проверка на удержание
//if (butt1.state()) Serial.println("Hold"); // возвращает состояние кнопки
if (butt1.isStep()) { // если кнопка была удержана (это для инкремента)
value++; // увеличивать/уменьшать переменную value с шагом и интервалом
Serial.println(value); // для примера выведем в порт
}
}
```
<a id="versions"></a>
## Версии
- v2.15: Добавлена возможность объявить кнопку без привязки к пину
- v3.0: Ускорен и оптимизирован код, переделана инициализация, дополнены примеры
- v3.1: isStep может принимать количество кликов, сделанных перед ним (см. пример clicks_step)
- v3.2: Добавлен метод getHoldClicks() - вернуть количество кликов, предшествующее удерживанию
- v3.3: Мелкие исправления
- v3.4: Добавлен метод resetStates(), сбрасывающий состояния и счётчики
- v3.5: увелична производительность для AVR Arduino
- v3.6: добавлен отдельный класс для работы с аналоговыми клавиатурами, см пример analogKeyboardG
- v3.7: исправления от Dryundel:
- Любой таймаут удержания
- Single, Double и Triple теперь не мешают hasClicks и getClicks и работают совместно
- isStep() тоже теперь ничего не мешает и он работает более корректно
- v3.8: исправления от Dryundel
<a id="feedback"></a>
## Баги и обратная связь
При нахождении багов создавайте **Issue**, а лучше сразу пишите на почту [alex@alexgyver.ru](mailto:alex@alexgyver.ru)
Библиотека открыта для доработки и ваших **Pull Request**'ов!
@@ -0,0 +1,59 @@
// Пример использования библиотеки GyverButton, все возможности в одном скетче.
#define BTN_PIN 3 // кнопка подключена сюда (BTN_PIN --- КНОПКА --- GND)
#include "GyverButton.h"
GButton butt1(BTN_PIN);
// Варианты инициализации:
// GButton btn; // без привязки к пину (виртуальная кнопка) и без указания типа (по умолч. HIGH_PULL и NORM_OPEN)
// GButton btn(пин); // с привязкой к пину и без указания типа (по умолч. HIGH_PULL и NORM_OPEN)
// GButton btn(пин, тип подключ.); // с привязкой к пину и указанием типа подключения (HIGH_PULL / LOW_PULL) и без указания типа кнопки (по умолч. NORM_OPEN)
// GButton btn(пин, тип подключ., тип кнопки); // с привязкой к пину и указанием типа подключения (HIGH_PULL / LOW_PULL) и типа кнопки (NORM_OPEN / NORM_CLOSE)
// GButton btn(BTN_NO_BTN_PIN, тип подключ., тип кнопки); // без привязки к пину и указанием типа подключения (HIGH_PULL / LOW_PULL) и типа кнопки (NORM_OPEN / NORM_CLOSE)
int value = 0;
void setup() {
Serial.begin(9600);
butt1.setDebounce(50); // настройка антидребезга (по умолчанию 80 мс)
butt1.setTimeout(300); // настройка таймаута на удержание (по умолчанию 500 мс)
butt1.setClickTimeout(600); // настройка таймаута между кликами (по умолчанию 300 мс)
// HIGH_PULL - кнопка подключена к GND, пин подтянут к VCC (BTN_PIN --- КНОПКА --- GND)
// LOW_PULL - кнопка подключена к VCC, пин подтянут к GND
// по умолчанию стоит HIGH_PULL
butt1.setType(HIGH_PULL);
// NORM_OPEN - нормально-разомкнутая кнопка
// NORM_CLOSE - нормально-замкнутая кнопка
// по умолчанию стоит NORM_OPEN
butt1.setDirection(NORM_OPEN);
}
void loop() {
butt1.tick(); // обязательная функция отработки. Должна постоянно опрашиваться
if (butt1.isClick()) Serial.println("Click"); // проверка на один клик
if (butt1.isSingle()) Serial.println("Single"); // проверка на один клик
if (butt1.isDouble()) Serial.println("Double"); // проверка на двойной клик
if (butt1.isTriple()) Serial.println("Triple"); // проверка на тройной клик
if (butt1.hasClicks()) // проверка на наличие нажатий
Serial.println(butt1.getClicks()); // получить (и вывести) число нажатий
if (butt1.isPress()) Serial.println("Press"); // нажатие на кнопку (+ дебаунс)
if (butt1.isRelease()) Serial.println("Release"); // отпускание кнопки (+ дебаунс)
if (butt1.isHold()) { // если кнопка удерживается
Serial.print("Holding "); // выводим пока удерживается
Serial.println(butt1.getHoldClicks()); // можно вывести количество кликов перед удержанием!
}
if (butt1.isHold()) Serial.println("Holding"); // проверка на удержание
//if (butt1.state()) Serial.println("Hold"); // возвращает состояние кнопки
if (butt1.isStep()) { // если кнопка была удержана (это для инкремента)
value++; // увеличивать/уменьшать переменную value с шагом и интервалом
Serial.println(value); // для примера выведем в порт
}
}
@@ -0,0 +1,50 @@
/*
Пример использования библиотеки GyverButton, все возможности в одном скетче.
*/
#define PIN 3 // кнопка подключена сюда (PIN --- КНОПКА --- GND)
#include "GyverButton.h"
GButton butt1(PIN);
// GButton butt1(PIN, HIGH_PULL, NORM_OPEN); // можно инициализировать так
int value = 0;
void setup() {
Serial.begin(9600);
butt1.setDebounce(50); // настройка антидребезга (по умолчанию 80 мс)
butt1.setTimeout(300); // настройка таймаута на удержание (по умолчанию 500 мс)
butt1.setClickTimeout(600); // настройка таймаута между кликами (по умолчанию 300 мс)
// HIGH_PULL - кнопка подключена к GND, пин подтянут к VCC (PIN --- КНОПКА --- GND)
// LOW_PULL - кнопка подключена к VCC, пин подтянут к GND
butt1.setType(HIGH_PULL);
// NORM_OPEN - нормально-разомкнутая кнопка
// NORM_CLOSE - нормально-замкнутая кнопка
butt1.setDirection(NORM_OPEN);
}
void loop() {
butt1.tick(); // обязательная функция отработки. Должна постоянно опрашиваться
if (butt1.isClick()) Serial.println("Click"); // проверка на один клик
if (butt1.isSingle()) Serial.println("Single"); // проверка на один клик
if (butt1.isDouble()) Serial.println("Double"); // проверка на двойной клик
if (butt1.isTriple()) Serial.println("Triple"); // проверка на тройной клик
if (butt1.hasClicks()) // проверка на наличие нажатий
Serial.println(butt1.getClicks()); // получить (и вывести) число нажатий
if (butt1.isPress()) Serial.println("Press"); // нажатие на кнопку (+ дебаунс)
if (butt1.isRelease()) Serial.println("Release"); // отпускание кнопки (+ дебаунс)
if (butt1.isHolded()) Serial.println("Holded"); // проверка на удержание
if (butt1.isHold()) Serial.println("Holding"); // проверка на удержание
//if (butt1.state()) Serial.println("Hold"); // возвращает состояние кнопки
if (butt1.isStep()) { // если кнопка была удержана (это для инкремента)
value++; // увеличивать/уменьшать переменную value с шагом и интервалом
Serial.println(value); // для примера выведем в порт
}
}
@@ -0,0 +1,54 @@
// Пример использования библиотеки GyverButton, все возможности в одном скетче.
// автоматический тик
#define BTN_PIN 3 // кнопка подключена сюда (BTN_PIN --- КНОПКА --- GND)
#include "GyverButton.h"
GButton butt1(BTN_PIN);
// GButton butt1(BTN_PIN, HIGH_PULL, NORM_OPEN); // можно инициализировать так
int value = 0;
void setup() {
Serial.begin(9600);
butt1.setDebounce(90); // настройка антидребезга (по умолчанию 80 мс)
butt1.setTimeout(300); // настройка таймаута на удержание (по умолчанию 500 мс)
// HIGH_PULL - кнопка подключена к GND, пин подтянут к VCC (BTN_PIN --- КНОПКА --- GND)
// LOW_PULL - кнопка подключена к VCC, пин подтянут к GND
// по умолчанию стоит HIGH_PULL
butt1.setType(HIGH_PULL);
// NORM_OPEN - нормально-разомкнутая кнопка
// NORM_CLOSE - нормально-замкнутая кнопка
// по умолчанию стоит NORM_OPEN
butt1.setDirection(NORM_OPEN);
// MANUAL - нужно вызывать функцию tick() вручную
// AUTO - tick() входит во все остальные функции и опрашивается сама!
butt1.setTickMode(AUTO);
}
void loop() {
// butt1.tick(); // НЕ НУЖНА, в этом режиме (AUTO) она входит в каждую функцию
if (butt1.isClick()) Serial.println("Click"); // проверка на один клик
if (butt1.isSingle()) Serial.println("Single"); // проверка на один клик
if (butt1.isDouble()) Serial.println("Double"); // проверка на двойной клик
if (butt1.isTriple()) Serial.println("Triple"); // проверка на тройной клик
if (butt1.hasClicks()) // проверка на наличие нажатий
Serial.println(butt1.getClicks()); // получить (и вывести) число нажатий
if (butt1.isPress()) Serial.println("Press"); // нажатие на кнопку (+ дебаунс)
if (butt1.isRelease()) Serial.println("Release"); // отпускание кнопки (+ дебаунс)
if (butt1.isHolded()) Serial.println("Holded"); // проверка на удержание
if (butt1.isHold()) Serial.println("Holding"); // проверка на удержание
//if (butt1.state()) Serial.println("Hold"); // возвращает состояние кнопки
if (butt1.isStep()) { // если кнопка была удержана (это для инкремента)
value++; // увеличивать/уменьшать переменную value с шагом и интервалом
Serial.println(value); // для примера выведем в порт
}
}
@@ -0,0 +1,42 @@
// Пример использования библиотеки GyverButton, все возможности в одном скетче.
// Дополнительный опрос по аппаратному прерыванию
#define BTN_PIN 3 // кнопка подключена сюда (BTN_PIN --- КНОПКА --- GND)
#include "GyverButton.h"
GButton butt1(BTN_PIN);
int value = 0;
void setup() {
Serial.begin(9600);
attachInterrupt(1, isr, CHANGE);
butt1.setDebounce(80); // настройка антидребезга (по умолчанию 80 мс)
butt1.setTimeout(300); // настройка таймаута на удержание (по умолчанию 500 мс)
}
void isr() {
butt1.tick(); // опрашиваем в прерывании, чтобы поймать нажатие в любом случае
}
void loop() {
butt1.tick(); // опрашиваем в скетче, иначе не будут работать проверки по времени!
if (butt1.isClick()) Serial.println("Click"); // проверка на один клик
if (butt1.isSingle()) Serial.println("Single"); // проверка на один клик
if (butt1.isDouble()) Serial.println("Double"); // проверка на двойной клик
if (butt1.isTriple()) Serial.println("Triple"); // проверка на тройной клик
if (butt1.hasClicks()) // проверка на наличие нажатий
Serial.println(butt1.getClicks()); // получить (и вывести) число нажатий
if (butt1.isPress()) Serial.println("Press"); // нажатие на кнопку (+ дебаунс)
if (butt1.isRelease()) Serial.println("Release"); // отпускание кнопки (+ дебаунс)
if (butt1.isHolded()) Serial.println("Holded"); // проверка на удержание
//if (butt1.isHold()) Serial.println("Hold"); // возвращает состояние кнопки
if (butt1.isStep()) { // если кнопка была удержана (это для инкремента)
value++; // увеличивать/уменьшать переменную value с шагом и интервалом
Serial.println(value); // для примера выведем в порт
}
}
@@ -0,0 +1,44 @@
/*
Пример использования библиотеки GyverButton, все возможности в одном скетче
Данный скетч показывает, как быть в сложном "не сквозном" коде с кучей delay и замкнутых циклов
Здесь кнопка опрашивается каждые 10 миллисекунд независимо от того, что происходит у вас в коде
Используется библиотека TimerOne https://github.com/PaulStoffregen/TimerOne
*/
#define BTN_PIN 3 // кнопка подключена сюда (BTN_PIN --- КНОПКА --- GND)
#include "GyverButton.h"
#include "TimerOne.h"
GButton butt1(BTN_PIN);
int value = 0;
void setup() {
Serial.begin(9600);
Timer1.initialize(10000); // установка таймера на каждые 10000 микросекунд (== 10 мс)
Timer1.attachInterrupt(timerIsr); // запуск таймера
}
void timerIsr() { // прерывание таймера
butt1.tick(); // отработка теперь находится здесь
}
void loop() {
if (butt1.isClick()) Serial.println("Click"); // проверка на один клик
if (butt1.isSingle()) Serial.println("Single"); // проверка на один клик
if (butt1.isDouble()) Serial.println("Double"); // проверка на двойной клик
if (butt1.isTriple()) Serial.println("Triple"); // проверка на тройной клик
if (butt1.hasClicks()) // проверка на наличие нажатий
Serial.println(butt1.getClicks()); // получить (и вывести) число нажатий
if (butt1.isPress()) Serial.println("Press"); // нажатие на кнопку (+ дебаунс)
if (butt1.isRelease()) Serial.println("Release"); // отпускание кнопки (+ дебаунс)
if (butt1.isHolded()) Serial.println("Holded"); // проверка на удержание
//if (butt1.isHold()) Serial.println("Hold"); // возвращает состояние кнопки
if (butt1.isStep()) { // если кнопка была удержана (это для инкремента)
value++; // увеличивать/уменьшать переменную value с шагом и интервалом
Serial.println(value); // для примера выведем в порт
}
}
@@ -0,0 +1,18 @@
// Пример использования библиотеки GyverButton, 1- 2- 3- нажатие
#define BTN_PIN 3 // кнопка подключена сюда (BTN_PIN --- КНОПКА --- GND)
#include "GyverButton.h"
GButton butt1(BTN_PIN);
void setup() {
Serial.begin(9600);
}
void loop() {
butt1.tick(); // обязательная функция отработки. Должна постоянно опрашиваться
if (butt1.isSingle()) Serial.println("Single"); // проверка на один клик
if (butt1.isDouble()) Serial.println("Double"); // проверка на двойной клик
if (butt1.isTriple()) Serial.println("Triple"); // проверка на тройной клик
}
@@ -0,0 +1,36 @@
// Пример использования библиотеки GyverButton
// опрос 5 кнопок в ручном режиме
// кнопки подключены к земле (PIN --- КНОПКА --- GND)
#define BTN1 3
#define BTN2 4
#define BTN3 5
#define BTN4 6
#define BTN5 7
#include "GyverButton.h"
GButton butt1(BTN1);
GButton butt2(BTN2);
GButton butt3(BTN3);
GButton butt4(BTN4);
GButton butt5(BTN5);
void setup() {
Serial.begin(9600);
}
void loop() {
// тик в ручном режиме
butt1.tick();
butt2.tick();
butt3.tick();
butt4.tick();
butt5.tick();
// проверяем одиночный клик
if (butt1.isClick()) Serial.println("Button 1");
if (butt2.isClick()) Serial.println("Button 2");
if (butt3.isClick()) Serial.println("Button 3");
if (butt4.isClick()) Serial.println("Button 4");
if (butt5.isClick()) Serial.println("Button 5");
}
@@ -0,0 +1,37 @@
// Пример использования библиотеки GyverButton
// опрос 5 кнопок в автоматическом режиме
// кнопки подключены к земле (PIN --- КНОПКА --- GND)
#define BTN1 3
#define BTN2 4
#define BTN3 5
#define BTN4 6
#define BTN5 7
#include "GyverButton.h"
GButton butt1(BTN1);
GButton butt2(BTN2);
GButton butt3(BTN3);
GButton butt4(BTN4);
GButton butt5(BTN5);
void setup() {
Serial.begin(9600);
// устанавливаем опрос на автоматический
butt1.setTickMode(AUTO);
butt2.setTickMode(AUTO);
butt3.setTickMode(AUTO);
butt4.setTickMode(AUTO);
butt5.setTickMode(AUTO);
}
void loop() {
// проверяем одиночный клик
// tick уже сидит внутри опроса
if (butt1.isClick()) Serial.println("Button 1");
if (butt2.isClick()) Serial.println("Button 2");
if (butt3.isClick()) Serial.println("Button 3");
if (butt4.isClick()) Serial.println("Button 4");
if (butt5.isClick()) Serial.println("Button 5");
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

@@ -0,0 +1,45 @@
// Пример использования библиотеки GyverButton с аналоговой клавиатурой
// аналоговая клавиатура подключена на А7
// Схему смотри на странице библиотеки https://alexgyver.ru/gyverbutton/
// также она есть в папке с примером
#include "GyverButton.h"
// создаём кнопки без привязки к пину
GButton myButt1;
GButton myButt2;
GButton myButt3;
void setup() {
Serial.begin(9600);
// меняем тип на LOW_PULL, потому что по умолчанию стоит HIGH_PULL
myButt1.setType(LOW_PULL);
myButt2.setType(LOW_PULL);
myButt3.setType(LOW_PULL);
}
void loop() {
// читаем значение
int analog = analogRead(7);
// для начала нужно вывести и запомнить значение для каждой кнопки
//Serial.println(analog);
// проверяем у каждой кнопки свой диапазон (+- 20 от полученного значения)
myButt1.tick(analog < 860 && analog > 820);
myButt2.tick(analog < 740 && analog > 700);
myButt3.tick(analog < 650 && analog > 600);
// проверка на удержание, например
if (myButt1.isHolded()) {
Serial.println("hold 1");
}
if (myButt2.isHolded()) {
Serial.println("hold 2");
}
if (myButt3.isHolded()) {
Serial.println("hold 3");
}
delay(10); // задержка тут не нужна, чисто для вывода
}
@@ -0,0 +1,49 @@
// новый пример работы с аналоговой клавиатурой
/*
Сигналы кнопок
1023
927
856
783
671
632
590
560
504
480
455
440
399
319
255
230
*/
#include "AnalogKey.h"
// указываем пин и количество кнопок
AnalogKey<A0, 3> keys;
#include <GyverButton.h>
GButton btn1, btn2, btn3;
void setup() {
Serial.begin(9600);
// указываем сигналы кнопок аналоговой клавы
keys.attach(0, 1023);
keys.attach(1, 927);
keys.attach(2, 856);
}
void loop() {
// тикаем кнопки как статусы аналоговых
btn1.tick(keys.status(0));
btn2.tick(keys.status(1));
btn3.tick(keys.status(2));
if (btn1.isClick()) Serial.println("click 0");
if (btn2.isClick()) Serial.println("click 1");
if (btn3.isClick()) Serial.println("click 2");
if (btn1.isHolded()) Serial.println("click 0");
if (btn2.isHolded()) Serial.println("hold 1");
if (btn3.isHolded()) Serial.println("hold 2");
}
@@ -0,0 +1,57 @@
// пример с прерываниями pinChangeInterrupt (прерывания на любом пине)
// только для ATmega328 (UNO, Nano, Pro Mini)
#define BTN_PIN 3
#include "GyverButton.h"
GButton butt1(BTN_PIN);
void setup() {
Serial.begin(9600);
// настроить PCINT
attachPCINT(BTN_PIN);
}
void loop() {
butt1.tick(); // обязательно нужен отработчик ещё и в loop, чтобы работали таймауты
if (butt1.isClick()) Serial.println("Click"); // проверка на один клик
if (butt1.isSingle()) Serial.println("Single"); // проверка на один клик
if (butt1.isDouble()) Serial.println("Double"); // проверка на двойной клик
if (butt1.isTriple()) Serial.println("Triple"); // проверка на тройной клик
}
// функция для настройки PCINT для ATmega328 (UNO, Nano, Pro Mini)
uint8_t attachPCINT(uint8_t pin) {
if (pin < 8) { // D0-D7 // PCINT2
PCICR |= (1 << PCIE2);
PCMSK2 |= (1 << pin);
return 2;
}
else if (pin > 13) { //A0-A5 // PCINT1
PCICR |= (1 << PCIE1);
PCMSK1 |= (1 << pin - 14);
return 1;
}
else { // D8-D13 // PCINT0
PCICR |= (1 << PCIE0);
PCMSK0 |= (1 << pin - 8);
return 0;
}
}
// Векторы PCINT, нужно кинуть сюда тики
// не обязательно в каждый вектор, достаточно в тот, который задействован
// пины 0-7: PCINT2
// пины 8-13: PCINT0
// пины A0-A5: PCINT1
ISR(PCINT0_vect) {
//butt1.tick();
}
ISR(PCINT1_vect) {
//butt1.tick();
}
ISR(PCINT2_vect) {
butt1.tick();
}
@@ -0,0 +1,27 @@
// ловим степ с накликиванием
#define BTN_PIN 0 // кнопка подключена сюда (BTN_PIN --- КНОПКА --- GND)
#include "GyverButton.h"
GButton butt1(BTN_PIN);
void setup() {
Serial.begin(9600);
}
void loop() {
butt1.tick();
// удержание
if (butt1.isStep()) {
Serial.println("0x");
}
// один клик + удержание
if (butt1.isStep(1)) {
Serial.println("1x");
}
// два клика + удержание
if (butt1.isStep(2)) {
Serial.println("2x");
}
}
@@ -0,0 +1,41 @@
/*
Пример использования библиотеки GyverButton, управляем переменной value при помощи двух кнопок
Конструкция с isIncr делает увеличение/уменьшение переменной при нажатой кнопке с шагом по времени
*/
#define BTN1 2 // кнопка подключена сюда (PIN --- КНОПКА --- GND)
#define BTN2 3 // кнопка подключена сюда (PIN --- КНОПКА --- GND)
#include "GyverButton.h"
GButton butt1(BTN1);
GButton butt2(BTN2);
int value = 0;
void setup() {
Serial.begin(9600);
}
void loop() {
butt1.tick(); // обязательная функция отработки. Должна постоянно опрашиваться
butt2.tick(); // обязательная функция отработки. Должна постоянно опрашиваться
if (butt1.isClick()) { // одиночное нажатие
value++; // инкремент
Serial.println(value); // для примера выведем в порт
}
if (butt2.isClick()) { // одиночное нажатие
value--; // декремент
Serial.println(value); // для примера выведем в порт
}
if (butt1.isStep()) { // обработчик удержания с шагами
value++; // увеличивать/уменьшать переменную value с шагом и интервалом!
Serial.println(value); // для примера выведем в порт
}
if (butt2.isStep()) { // обработчик удержания с шагами
value--; // увеличивать/уменьшать переменную value с шагом и интервалом!
Serial.println(value); // для примера выведем в порт
}
}
@@ -0,0 +1,19 @@
/*
Пример использования библиотеки GyverButton, отработка любого количества нажатий
*/
#define BTN_PIN 3 // кнопка подключена сюда (BTN_PIN --- КНОПКА --- GND)
#include "GyverButton.h"
GButton butt1(BTN_PIN);
void setup() {
Serial.begin(9600);
butt1.setTimeout(400); // настройка таймаута на удержание и второй клик (по умолчанию 500 мс)
}
void loop() {
butt1.tick(); // обязательная функция отработки. Должна постоянно опрашиваться
if (butt1.hasClicks()) // проверка на наличие нажатий
Serial.println(butt1.getClicks()); // получить (и вывести) число нажатий
}
+51
View File
@@ -0,0 +1,51 @@
#######################################
# Syntax Coloring Map For GyverButton
#######################################
#######################################
# Datatypes (KEYWORD1)
#######################################
GButton KEYWORD1
GyverButton KEYWORD1
#######################################
# Methods and Functions (KEYWORD2)
#######################################
setDebounce KEYWORD2
setTimeout KEYWORD2
setStepTimeout KEYWORD2
setClickTimeout KEYWORD2
setType KEYWORD2
setDirection KEYWORD2
setTickMode KEYWORD2
tick KEYWORD2
isPress KEYWORD2
isRelease KEYWORD2
isClick KEYWORD2
isHolded KEYWORD2
isHold KEYWORD2
state KEYWORD2
hasClicks KEYWORD2
getClicks KEYWORD2
getHoldClicks KEYWORD2
isSingle KEYWORD2
isDouble KEYWORD2
isTriple KEYWORD2
isStep KEYWORD2
resetStates KEYWORD2
#######################################
# Constants (LITERAL1)
#######################################
HIGH_PULL LITERAL1
LOW_PULL LITERAL1
NORM_OPEN LITERAL1
NORM_CLOSE LITERAL1
MANUAL LITERAL1
AUTO LITERAL1
+9
View File
@@ -0,0 +1,9 @@
name=GyverButton
version=3.8
author=AlexGyver <alex@alexgyver.ru>
maintainer=AlexGyver <alex@alexgyver.ru>
sentence=Advanced button control library
paragraph=Advanced button control library
category=Sensors
url=https://github.com/GyverLibs/GyverButton
architectures=*
+64
View File
@@ -0,0 +1,64 @@
#ifndef AnalogKey_h
#define AnalogKey_h
/*
Мини класс для работы с аналоговой клавиатурой
GitHub: https://github.com/GyverLibs/AnalogKey
- Встроенный простенький дебаунс
- Оптимальный опрос пина по таймеру
- Проверка конкретной кнопки или вывод номера нажатой
AlexGyver, alex@alexgyver.ru
https://alexgyver.ru/
MIT License
*/
#define _AKEY_PERIOD 50 // период опроса в мс
template <byte PIN, byte AMOUNT>
class AnalogKey {
public:
// подключает кнопку на указанное значение
void attach(byte num, int value) {
if (num >= AMOUNT) return;
signals[num] = value;
}
// устанавливает окно сигнала (умолч. 20)
void setWindow(int window) {
_window = window;
}
// возвращает статус указанной кнопки
bool status(byte num) {
if (millis() - tmr > _AKEY_PERIOD) {
tmr = millis();
int thisRead = analogRead(PIN);
if (abs(thisRead - _lastRead) < _window) _ready = true;
else _ready = false;
_lastRead = thisRead;
}
if (_ready &&
_lastRead > signals[num] - _window &&
_lastRead < signals[num] + _window) return true;
else return false;
}
// выводит номер нажатой кнопки или -1, если нажатых кнопок нет
int pressed() {
status(0); // вызываем опрос
for (byte i = 0; i < AMOUNT; i++) {
if (_ready &&
_lastRead > signals[i] - _window &&
_lastRead < signals[i] + _window) return i;
}
return -1;
}
private:
int signals[AMOUNT];
int _lastRead = 0;
int _window = 20;
bool _ready = false;
uint32_t tmr;
};
#endif
+224
View File
@@ -0,0 +1,224 @@
#include "GyverButton.h"
// ==================== CONSTRUCTOR ====================
GButton::GButton(int8_t pin, bool type, bool dir) {
if (pin != BTN_NO_PIN) {
_PIN = (uint8_t)pin;
flags.noPin = false;
} else {
flags.noPin = true;
}
setType(type);
flags.mode = false;
flags.tickMode = false;
flags.inv_state = dir;
}
// ==================== SET ====================
void GButton::setDebounce(uint16_t debounce) {
_debounce = debounce;
}
void GButton::setTimeout(uint16_t new_timeout) {
_timeout = new_timeout;
}
void GButton::setClickTimeout(uint16_t new_timeout) {
_click_timeout = new_timeout;
}
void GButton::setStepTimeout(uint16_t step_timeout) {
_step_timeout = step_timeout;
}
void GButton::setType(bool type) {
flags.type = type;
if (!flags.noPin) {
if (type) pinMode(_PIN, INPUT);
else pinMode(_PIN, INPUT_PULLUP);
#if defined(__AVR__)
_pin_reg = portInputRegister(digitalPinToPort(_PIN));
_bit_mask = digitalPinToBitMask(_PIN);
#endif
}
}
void GButton::setDirection(bool dir) {
flags.inv_state = dir;
}
void GButton::setTickMode(bool tickMode) {
flags.tickMode = tickMode;
}
// ==================== IS ====================
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 btn_state;
}
boolean GButton::isSingle() {
if (flags.tickMode) GButton::tick();
if (flags.counter_flag && last_counter == 1) {
// last_counter = 0;
// flags.counter_flag = false;
flags.counter_reset = true;
return true;
} else return false;
}
boolean GButton::isDouble() {
if (flags.tickMode) GButton::tick();
if (flags.counter_flag && last_counter == 2) {
// flags.counter_flag = false;
// last_counter = 0;
flags.counter_reset = true;
return true;
} else return false;
}
boolean GButton::isTriple() {
if (flags.tickMode) GButton::tick();
if (flags.counter_flag && last_counter == 3) {
// flags.counter_flag = false;
// last_counter = 0;
flags.counter_reset = true;
return true;
} else return false;
}
boolean GButton::hasClicks() {
if (flags.tickMode) GButton::tick();
if (flags.counter_flag) {
// flags.counter_flag = false;
flags.counter_reset = true;
return true;
} else return false;
}
uint8_t GButton::getClicks() {
// byte thisCount = last_counter; // Исключено 14.01.2021
// last_counter = 0;
flags.counter_reset = true;
return last_counter; // return thisCount; (замена) 14.01.2021
}
uint8_t GButton::getHoldClicks() {
if (flags.tickMode) GButton::tick();
return last_hold_counter; //return flags.hold_flag ? last_hold_counter : 0; (Замена) 14.01.2021
}
boolean GButton::isStep(byte clicks) {
if (flags.tickMode) GButton::tick();
if (btn_counter == clicks && flags.step_flag && (millis() - btn_timer >= _step_timeout)) {
btn_timer = millis();
return true;
}
else return false;
}
void GButton::resetStates() {
flags.isPress_f = false;
flags.isRelease_f = false;
flags.isOne_f = false;
flags.isHolded_f = false;
flags.step_flag = false;
flags.counter_flag = false;
last_hold_counter = 0;
last_counter = 0;
}
// ==================== TICK ====================
void GButton::tick(boolean state) {
flags.mode = true;
btn_state = state ^ flags.inv_state;
GButton::tick();
flags.mode = false;
}
void GButton::tick() {
// читаем пин
if (!flags.mode && !flags.noPin) btn_state = !_buttonRead() ^ (flags.inv_state ^ flags.type);
uint32_t thisMls = millis();
// нажатие
if (btn_state && !btn_flag) {
if (!flags.btn_deb) {
flags.btn_deb = true;
btn_timer = thisMls;
} else {
if (thisMls - btn_timer >= _debounce) {
btn_flag = true;
flags.isPress_f = true;
flags.oneClick_f = true;
}
}
} else {
flags.btn_deb = false;
}
// отпускание
if (!btn_state && btn_flag) {
btn_flag = false;
if (!flags.hold_flag) btn_counter++;
flags.hold_flag = false;
flags.isRelease_f = true;
btn_timer = thisMls;
if (flags.step_flag) {
last_counter = 0;
btn_counter = 0;
flags.step_flag = false;
}
if (flags.oneClick_f) {
flags.oneClick_f = false;
flags.isOne_f = true;
}
}
// кнопка удерживается
if (btn_flag && btn_state && (thisMls - 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 = thisMls;
}
// обработка накликивания
if ((thisMls - btn_timer >= _click_timeout) && (btn_counter != 0) && !btn_state) { //И здесь еще добавлен !btn_state
last_counter = btn_counter;
btn_counter = 0;
flags.counter_flag = true;
}
// сброс накликивания //Добавлено
if (flags.counter_reset) {
last_counter = 0;
flags.counter_flag = false;
flags.counter_reset = false;
}
}
+134
View File
@@ -0,0 +1,134 @@
/*
GyverButton - библиотека для многофункциональной отработки нажатия кнопки
ВНИМАНИЕ, БИБЛИОТЕКА УСТАРЕЛА! ИСПОЛЬЗУЙ БИБЛИОТЕКУ EncButton https://github.com/GyverLibs/EncButton
GitHub: https://github.com/GyverLibs/GyverButton
Документация: https://alexgyver.ru/gyverbutton/
Возможности:
- Работа с нормально замкнутыми и нормально разомкнутыми кнопками
- Работа с подключением PULL_UP и PULL_DOWN
- Опрос кнопки с программным антидребезгом контактов (настраиваемое время)
- Отработка нажатия, удерживания, отпускания, клика по кнопке (+ настройка таймаутов)
- Отработка одиночного, двойного и тройного нажатия (вынесено отдельно)
- Отработка любого количества нажатий кнопки (функция возвращает количество нажатий)
- Функция изменения значения переменной с заданным шагом и заданным интервалом по времени
- Возможность работы с "виртуальными" кнопками (все возможности библиотеки используются для матричных и резистивных клавиатур)
Версии:
v2.15: Добавлена возможность объявить кнопку без привязки к пину
v3.0: Ускорен и оптимизирован код, переделана инициализация, дополнены примеры
v3.1: isStep может принимать количество кликов, сделанных перед ним (см. пример clicks_step)
v3.2: Добавлен метод getHoldClicks() - вернуть количество кликов, предшествующее удерживанию
v3.3: Мелкие исправления
v3.4: Добавлен метод resetStates(), сбрасывающий состояния и счётчики
v3.5: увелична производительность для AVR Arduino
v3.6: добавлен отдельный класс для работы с аналоговыми клавиатурами, см пример analogKeyboardG
v3.7: исправления от Dryundel:
- Любой таймаут удержания
- Single, Double и Triple теперь не мешают hasClicks и getClicks и работают совместно
- isStep() тоже теперь ничего не мешает и он работает более корректно
v3.8: исправления от Dryundel:
*/
#ifndef GyverButton_h
#define GyverButton_h
#include <Arduino.h>
#if defined(__AVR__)
#define _buttonRead() bool(*_pin_reg & _bit_mask)
#else
#define _buttonRead() digitalRead(_PIN)
#endif
#pragma pack(push,1)
typedef struct {
bool btn_deb: 1;
bool hold_flag: 1;
bool counter_flag: 1;
bool isHolded_f: 1;
bool isRelease_f: 1;
bool isPress_f: 1;
bool step_flag: 1;
bool oneClick_f: 1;
bool isOne_f: 1;
bool inv_state: 1;
bool mode: 1;
bool type: 1;
bool tickMode: 1;
bool noPin: 1;
bool counter_reset: 1; //Добавлен
} GyverButtonFlags;
#pragma pack(pop)
#define BTN_NO_PIN -1
#define HIGH_PULL 0
#define LOW_PULL 1
#define NORM_OPEN 0
#define NORM_CLOSE 1
#define MANUAL 0
#define AUTO 1
// Варианты инициализации:
// GButton btn; // без привязки к пину (виртуальная кнопка) и без указания типа (по умолч. LOW_PULL и NORM_OPEN)
// GButton btn(пин); // с привязкой к пину и без указания типа (по умолч. HIGH_PULL и NORM_OPEN)
// GButton btn(пин, тип подключ.); // с привязкой к пину и указанием типа подключения (HIGH_PULL / LOW_PULL) и без указания типа кнопки (по умолч. NORM_OPEN)
// GButton btn(пин, тип подключ., тип кнопки); // с привязкой к пину и указанием типа подключения (HIGH_PULL / LOW_PULL) и типа кнопки (NORM_OPEN / NORM_CLOSE)
// GButton btn(BTN_NO_PIN, тип подключ., тип кнопки); // без привязки к пину и указанием типа подключения (HIGH_PULL / LOW_PULL) и типа кнопки (NORM_OPEN / NORM_CLOSE)
class GButton {
public:
GButton(int8_t pin = BTN_NO_PIN, bool type = HIGH_PULL, bool dir = NORM_OPEN); // конструктор кнопки, принимает PIN пин, тип type (HIGH_PULL / LOW_PULL) и направление dir (NORM_OPEN / NORM_CLOSE)
// HIGH_PULL - кнопка подключена к GND, пин подтянут к VCC, pinMode - INPUT_PULLUP (по умолчанию)
// LOW_PULL - кнопка подключена к VCC, пин подтянут к GND, pinMode - INPUT
// NORM_OPEN - кнопка по умолчанию разомкнута (по умолчанию)
// NORM_CLOSE - кнопка по умолчанию замкнута
void setDebounce(uint16_t debounce); // установка времени антидребезга (по умолчанию 80 мс)
void setTimeout(uint16_t new_timeout); // установка таймаута удержания (по умолчанию 300 мс)
void setClickTimeout(uint16_t new_timeout); // установка таймаута между кликами (по умолчанию 500 мс)
void setStepTimeout(uint16_t step_timeout); // установка таймаута между инкрементами (по умолчанию 400 мс)
void setType(bool type); // установка типа кнопки (HIGH_PULL - подтянута к питанию, LOW_PULL - к gnd)
void setDirection(bool dir); // установка направления (разомкнута/замкнута по умолчанию - NORM_OPEN, NORM_CLOSE)
void setTickMode(bool tickMode); // (MANUAL / AUTO) ручной или автоматический опрос кнопки функцией tick()
// MANUAL - нужно вызывать функцию tick() вручную
// AUTO - tick() входит во все остальные функции и опрашивается сама
void tick(); // опрос кнопки
void tick(boolean state); // опрос внешнего значения (1 нажато, 0 не нажато) (для матричных, резистивных клавиатур и джойстиков)
boolean isPress(); // возвращает true при нажатии на кнопку. Сбрасывается после вызова
boolean isRelease(); // возвращает true при отпускании кнопки. Сбрасывается после вызова
boolean isClick(); // возвращает true при клике. Сбрасывается после вызова
boolean isHolded(); // возвращает true при удержании дольше timeout. Сбрасывается после вызова
boolean isHold(); // возвращает true при нажатой кнопке, не сбрасывается
boolean state(); // возвращает состояние кнопки
boolean isSingle(); // возвращает true при одиночном клике. Сбрасывается после вызова
boolean isDouble(); // возвращает true при двойном клике. Сбрасывается после вызова
boolean isTriple(); // возвращает true при тройном клике. Сбрасывается после вызова
boolean hasClicks(); // проверка на наличие кликов. Сбрасывается после вызова
uint8_t getClicks(); // вернуть количество кликов
uint8_t getHoldClicks();// вернуть количество кликов, предшествующее удерживанию
boolean isStep(byte clicks = 0); // возвращает true по таймеру setStepTimeout, смотри пример
void resetStates(); // сбрасывает все is-флаги и счётчики
private:
GyverButtonFlags flags;
uint8_t _PIN = 0;
uint16_t _debounce = 60;
uint16_t _timeout = 500;
uint16_t _click_timeout = 500;
uint16_t _step_timeout = 400;
uint8_t btn_counter = 0, last_counter = 0, last_hold_counter = 0;
uint32_t btn_timer = 0;
bool btn_state = false;
bool btn_flag = false;
#if defined(__AVR__)
volatile uint8_t *_pin_reg;
volatile uint8_t _bit_mask;
#endif
};
#endif