Ищу библиотеку для работы с кнопками
- Войдите на сайт для отправки комментариев
Чт, 25/09/2014 - 10:31
Может кто сталкивался, или знает где найти толковую библиотеку для работы с кнопками, такую с помощью которой можно было бы легко отслеживать одинарные, двойные, тройные и т.д. с удержанием или без него. Чтоб на каждую комбинацию можно было повесить свою функцию и т.д.
Ну или подскажите мне идею, как организовать лучше историю нажатий кнопки (клик, двойно клик, двойной клик с удержанием)
Напишите сами, это интереснее.
Нагляднее всего хранить историю нажатий в текстовой строке, приплюсовывая для каждого нового нажатия в зависимсти от его длительности определённый символ (в принципе так даже коротки и длинный клик можно различать). Соотетственно сбрасить строку если состояние "кнопка отпущена" превысил некий разумный интервал времени, предварительно проанализировав. И при привышении длительности нажатия аналогично сбросить строку после анализа на совпадение с заданным жестом оканчивающимся на "удержание".
Для понимания идеи такой алгоритм нагляднее всего и его даже можно иногда реально использовать в устройствах. Если при этом опрашивать состояние клавишь не чаще раза в 10мс, то и дополнительных антидребезговых алгоритмов не нужно.
Вот мое решение:
// Объявляем переменные и константы const int buttonPin = 2; // Пин с кнопкой int currentButtonStatus = 0; // 0 - Кнопка не нажата // 1 - Кнопка нажата первый раз // 2 - Кнопка отжата после нажатия // 3 - Кнопка нажата во второй раз unsigned long currentButtonStatusStart1; // Кол-во милисекунд от начала работы программы, когда начался статус 1 unsigned long currentButtonStatusStart2; // Кол-во милисекунд от начала работы программы, когда начался статус 2 unsigned long currentButtonStatusStart3; // Кол-во милисекунд от начала работы программы, когда начался статус 3 const int delayFalse = 10; // Длительность, меньше которой не регистрируется единоразовый клик const int delayLongSingleClick = 1000; // Длительность зажатия кнопки для выхода в режим увеличения громкости const int delayDeltaDoubleClick = 800; // Длительность между кликами, когда будет зафиксирован двойной клик void setup() { // Прописываем пины pinMode(buttonPin, INPUT); // Вывод Serial.begin(9600); } void loop() { // Определяем текущий статус кнопки int event = changeButtonStatus(); if(event > 0) { // Если поменялся статус Serial.print("status change: "); Serial.println(event); } } /** * Смена текущего статуса * @return = 0 - ничего не произошло * 1 - простой клик * 2 - двойнок клик * 3 - зажата кнопка * 4 - отжата кнопка после долгого зажатия */ int changeButtonStatus() { // Событие int event = 0; // Текущее состояние кнопки int currentButtonClick = digitalRead(buttonPin); // Текущее время unsigned long timeButton = millis(); switch(currentButtonStatus) { case 0: // В настоящий момент кнопка не нажималась if(currentButtonClick) { // Зафиксировали нажатие кнопки currentButtonStatus = 1; currentButtonStatusStart1 = millis(); } else { // Кнопка не нажата // Ничего не происходит } break; case 1: // В настоящий момент кнопка на этапе первого нажатия if(currentButtonClick) { // Кнопка все еще нажата if(timeButton - currentButtonStatusStart1 >= delayLongSingleClick) { // Кнопка в нажатом состоянии уже дольше времени, после которого фиксируем длительное одинарное нажатие на кнопку // Событие длительного давления на кнопку - продолжаем давить event = 3; } } else { // Кнопку отжали обратно if(timeButton - currentButtonStatusStart1 < delayFalse) { // Время, которое была кнопка нажата, меньше минимального времени регистрации клика по кнопке // Скорее всего это были какие то флюктуации // Отменяем нажатие currentButtonStatus = 0; event = 0; } else if(timeButton - currentButtonStatusStart1 < delayLongSingleClick) { // Время, которое была кнопка нажата, меньше времени фиксации долгого нажатия на кнопку // Значит это первое одноразовое нажатие // Дальше будем ожидать второго нажатия currentButtonStatus = 2; currentButtonStatusStart2 = millis(); } else { // Время, которое была нажата кнопка, больше времени фиксации долгого единоразового нажатия // Значит это завершение длительного нажатия currentButtonStatus = 0; event = 4; } } break; case 2: // Мы находимся в фазе отжатой кнопки в ожидании повторного ее нажатия для фиксации двойного нажатия // или, если не дождемся - значит зафиксируем единичное нажатие if(currentButtonClick) { // Если кнопку снова нажали // Проверяем, сколько времени кнопка находилась в отжатом состоянии if(timeButton - currentButtonStatusStart2 < delayFalse) { // Кнопка была в отжатом состоянии слишком мало времени // Скорее всего это была какая то флюктуация дребезга кнопки // Возвращаем обратно состояние на первичное нажатие кнопки currentButtonStatus = 1; } else { // Кнопка была достаточно долго отжата, чтобы зафиксировать начало второго нажатия // Фиксируем currentButtonStatus = 3; currentButtonStatusStart3 = millis(); } } else { // Если кнопка все еще отжата // Проверяем, не достаточно ли она уже отжата, чтобы зафиксировать разовый клик if(timeButton - currentButtonStatusStart2 > delayDeltaDoubleClick) { // Кнопка в отжатом состоянии слишком долго // Фиксируем одинарный клие currentButtonStatus = 0; event = 1; } } break; case 3: // Мы на этапе второго нажатия // Для подтверждения факта двойного нажатия if(currentButtonClick) { // Кнопка все еще зажата // Ничего не происходит, ждем, когда отожмут } else { // Кнопку отжали // Проверям, действительно ли отжали, или это дребезг кнопки if(timeButton - currentButtonStatusStart3 < delayFalse) { // Кнопку отжали слишком рано // Скорре всего это дребезг // Гинорируем его } else { // Кнопка была в нажатом состоянии уже достаточно длительное время // Это завершение цикла фиксации двойного нажатия // Сообщаем такое событие event = 2; currentButtonStatus = 0; } } break; } return event; }Еще один адепт церкви Идеальной Кнопки.
Еще один адепт церкви Идеальной Кнопки.
а, чего мне нравится - смешные комменты в коде
102// Скорее всего это были какие то флюктуации103// Отменяем нажатиеЧерт! А я их фильтром отсеивал. :(
Черт! А я их фильтром отсеивал. :(
фильтровать - это полдела, а вот отменять нажатие...