#define button1B 3 // пин кнопки button1
boolean button1S; // храним состояния кнопок (S - State)
boolean button1F; // флажки кнопок (F - Flag)
boolean button1R; // флажки кнопок на отпускание (R - Release)
boolean button1P; // флажки кнопок на нажатие (P - Press)
boolean button1H; // флажки кнопок на удержание (многократный вызов) (H - Hold)
boolean button1HO; // флажки кнопок на удержание (один вызов при нажатии) (HO - Hold Once)
boolean button1D; // флажки кнопок на двойное нажатие (D - Double)
boolean button1DP; // флажки кнопок на двойное нажатие и отпускание (D - Double Pressed)
#define DOUBLE_TIMER 500 // время (мс), отведённое на второе нажатие
#define HOLD 2000 // время (мс), после которого кнопка считается зажатой
#define DEBOUNCE 50 // (мс), антидребезг
unsigned long button1_timer; // таймер последнего нажатия кнопки
unsigned long button1_double; // таймер двойного нажатия кнопки
unsigned long _millis;
void setup() {
Serial.begin(9600);
pinMode(button1B, INPUT_PULLUP);
}
void loop() {
button1S = !digitalRead(button1B);
_millis = millis();
uint8_t btn = buttons(); //отработка кнопок
if (3 == btn) {
Serial.println("pressed");
}
if (5 == btn) {
Serial.println("double");
}
if (7 == btn) {
Serial.println("hold once");
}
}
uint8_t buttons(void)
{
uint8_t bt1=0; // Будем возвращать результат в этой переменной
// if (BitIsClear(BUT1_PIN,BUT1)) button1S=1;
// else button1S=0; // Состояние кнопки
// нажали (с антидребезгом)
if (button1S && !button1F && _millis - button1_timer > DEBOUNCE)
{
button1F = 1; // Установим флаг кнопки
button1HO = 1; // флаг на удержание
button1_timer = _millis; // таймер последнего нажатия кнопки
bt1=1;
}
// если отпустили до hold, считать отпущенной
if (!button1S && button1F && !button1R && !button1DP && _millis - button1_timer < HOLD)
{
button1R = 1; // флаг на отпускание
button1F = 0; //флаг кнопки
bt1=2;
button1_double = _millis; // Таймер двойного нажатия кнопки
}
// если отпустили и прошло больше double_timer, считать 1 нажатием
if (button1R && !button1DP && _millis - button1_double > DOUBLE_TIMER)
{
button1R = 0;
button1P = 1;
bt1=3;
}
// если отпустили и прошло меньше double_timer и нажата снова, считать что нажата 2 разa
if (button1F && !button1DP && button1R && _millis - button1_double < DOUBLE_TIMER)
{
button1F = 0;
button1R = 0;
button1DP = 1;
bt1=4;
}
// если была нажата 2 разa и отпущена, считать что была нажата 2 раза
if (button1DP && _millis - button1_timer < HOLD)
{
button1DP = 0;
button1D = 1;
button1_timer = _millis;
bt1=5;
}
// Если удерживается более hold, то считать удержанием
if (button1F && !button1D && !button1H && millis - button1_timer > HOLD)
{
button1H = 1;
bt1=6;
}
// Если отпущена после hold, то считать, что была удержана
if (!button1S && button1F && millis - button1_timer > HOLD)
{
button1F = 0;
button1H = 0;
button1_timer = millis;
bt1=7;
}
// отработка режимов (опускание флага обязательно!)
if (button1P) button1P = 0;
if (button1D) button1D = 0;
if (button1H && button1HO) button1HO = 0;
if (button1H) button1H = 0;
return bt1;
}