Универсальный класс кнопки
- Войдите на сайт для отправки комментариев
Чт, 02/01/2014 - 01:26
Несмотря на то, что я в очередной раз изобретаю велосипед, и подобные классы уже наверняка есть, в большинстве местных тем кнопки обрабатываются вручную. Предлагаю на обсуждение класс, который проверяет клики, даблклики и удержания кнопок. Подразумевается, что в свободном состоянии на входе 1, в нажатом состоянии 0, что в общем довольно стандартно с учётом встроенных подтягивающих резисторов.
class Button {
byte pin, prev_state;
bool _clicked, _pressed, _held, _dblclicked;
unsigned long pressed_time, uct, clct;
static const unsigned int jtime = 10;
static const unsigned int htime = 100;
static const unsigned int dbltime = 300;
public:
void process_button() {
byte val = digitalReadFast(pin);
_clicked = false;
_dblclicked = false;
if (val == 0 && prev_state == 1) {
_pressed = true;
if (pressed_time == 0)
pressed_time = millis();
if (millis() > pressed_time + jtime) {
uct = 0;
prev_state = val;
_clicked = true;
if (clct != 0 && millis() < clct + dbltime) {
_dblclicked = true;
}
clct = millis();
}
} else if (val == 1 && prev_state == 0) {
_pressed = false;
if (uct == 0)
uct = millis();
if (millis() > uct + jtime) {
pressed_time = 0;
prev_state = val;
_held = false;
uct = millis();
}
}
if (val == 0 && prev_state == 0 && millis() > clct + htime) {
_held = true;
} else {
_held = false;
}
}
Button(byte _pin) :
pin(_pin) {
prev_state = 1;
_dblclicked = _held = _pressed = _clicked = false;
clct = uct = pressed_time = 0;
}
bool is_clicked() {
return _clicked;
}
unsigned long held_time() {
if(_held)
return millis() - clct;
return 0;
}
bool is_dblclicked() {
return _held;
}
};
Пример использования:
Button b_next(next_button);
Button b_prev(prev_button);
byte current_alg = 2;
void loop() {
b_next.process_button();
b_prev.process_button();
if (b_next.is_clicked()) {
++current_alg;
shift_out(latchpin, clockpin, datapin, 0);
}
if (b_prev.is_clicked()) {
--current_alg;
shift_out(latchpin, clockpin, datapin, 0);
}
if (b_prev.is_dblclicked()) {
current_alg = random(8);
shift_out(latchpin, clockpin, datapin, 0);
}
if (b_next.is_dblclicked()) {
current_alg = random(8);
shift_out(latchpin, clockpin, datapin, 0);
}
current_alg &= 7;
// ....... последующий код.....
}
Последняя версия. Исправлена ошибка, убрано лишнее. Думаю, что я на этом тему для себя закончил.
class Button { byte pin, prev_state; bool _clicked, _held, _dblclicked; unsigned long pressed_time, uct, clct; static const unsigned int jtime = 10; static const unsigned int htime = 100; static const unsigned int dbltime = 300; public: void process_button() { byte val = digitalReadFast(pin); _clicked = false; _dblclicked = false; if (val == 0 && prev_state == 1) { uct = 0; unsigned long now = millis(); if (pressed_time == 0) pressed_time = now; if (now > pressed_time + jtime) { prev_state = val; _clicked = true; if (clct != 0 && now < clct + dbltime) { _dblclicked = true; } clct = pressed_time; } } else if (val == 1 && prev_state == 0) { pressed_time = 0; if (uct == 0) uct = millis(); if (millis() > uct + jtime) { prev_state = val; _held = false; uct = millis(); } } if (val == 0 && prev_state == 0 && millis() > clct + htime) { _held = true; } else { _held = false; } } Button(byte _pin) : pin(_pin) { prev_state = 1; _dblclicked = _held = _clicked = false; clct = uct = pressed_time = 0; } bool is_clicked() { return _clicked; } unsigned long held_time() { if (_held) return millis() - clct; return 0; } bool is_dblclicked() { return _dblclicked; } };A как чайнику воспользоваться данной конструкцией. Например кнопка включает разные режимы светодиода.
A как чайнику воспользоваться данной конструкцией. Например кнопка включает разные режимы светодиода.
Скопировать этот класс себе, заменить digitalReadFast на digitalRead, создать экземпляр класса инициализировав его номером пина, к которому подключена кнопка и опрашивать в loop метод экземпляра is_clicked. Пример использования с разными программами со сдвиговым регистром есть в другой моей теме: http://arduino.ru/forum/programmirovanie/pyatoe-uprazhnenie-po-arduino-shift-out-click-button-digitalreadwritefast