Длинное и короткое нажатие на Keypad.
- Войдите на сайт для отправки комментариев
Всем привет. Есть програмка, которая в зависимости от того какая клавиша нажата на клавиатуре - запускает разные фунции. что-то вроде такого. Заголовок, сетап-часть и прочее - опускаю за ненадобностью. Импортится Keypad.h модуль. Клава заведена столбцы - на 5-6-7 сам столбец подключен на 8 ногу. Т.е. для выполнения кейса 'a' - нужно чтобы соеденились 5 и 8 ноги, для 'b' - 6 и 8 и тп....
void loop() { char key = kpd.getKey(); if(key) // Check for a valid key. { switch (key) { case 'a': digitalWrite(13, !digitalRead(13)); //Инвертировать выход break; //прекратить выполнение программы. } { case 'b': digitalWrite(14, !digitalRead(14)); //Инвертировать выход break; //прекратить выполнение программы. } { case 'c': digitalWrite(15, !digitalRead(15)); //Инвертировать выход break; //прекратить выполнение программы. } } }
Воспрос - как мне заставить чтобы на длинное нажатие клавиши запускалась другая функция? т.е. чтобы при коротком соединении 5 и 8 ноги (case 'a') - я запускал одну функцию (включение/выключение ноги), а если выводы соеденены долго - то чтобы запускалась другая функция (запись в епром или еще что...)?
UPDATE:
был предложен вариант:
void loop() { char key = kpd.getKey(); static char savekey = 0; if(key) { static uint32_t startmillis = 0; if(!startmillis) { startmillis = millis(); savekey = key; } else if(millis()-startmillis > 500) { startmillis = 0; switch (key) { case 'a': ... // Делаем, то что надо break; //прекратить выполнение программы. case 'b': ... // Делаем, то что надо break; //прекратить выполнение программы. case 'c': ... // Делаем, то что надо break; //прекратить выполнение программы. } } key = 0; } else if(startmillis) { key = savekey; startmillis = 0; } if(key) // Check for a valid key. { switch (key) { case 'a': digitalWrite(13, !digitalRead(13)); //Инвертировать выход break; //прекратить выполнение программы. case 'b': digitalWrite(14, !digitalRead(14)); //Инвертировать выход break; //прекратить выполнение программы. case 'c': digitalWrite(15, !digitalRead(15)); //Инвертировать выход break; //прекратить выполнение программы. } } }
но он не заработал. Конкретно в таком виде компилятор ругался на 46 строку, а когда я вынес переменную глобально - смог прошить ардуинку. Но - на динное нажатие никакой реакции, на короткое - нужно было "попасть в цикл" - т.е. то реагировал на нажатие кнопки соединяющую 5 и 8 ноги - диод на 13 выводе включался-выключался произвольно, а если часто и быстро нажимать кнопку - можно было добится циклического мигания светодиода с равными интервалами...
Пока застопорился с дальнейшими идеями. Кто-то может что-то подсказать?
если кнопка нажата
{
фиксируем время1;
пока кнопка нажата ждем;
фиксируем время2;
вычисляем время зажатия = верямя2-время1.
}
в зависимости от времени зажатия выполняем команды
ну вот вроде выше так и сделано, но не работает. можно чуть в более ардуино-синтаксическом виде? )
Примерно так, но для аналоговой клавиатуры, другой нет. Переменные и условия для своих клавиш переделайте. Срабатывает по отпусканию кнопки. Дребезгом не занимался.
Вот так под ваши текстовые, только не знаю, что ваша функция возвращает, если не нажата ни одна клавиша. У себя в условие вбил пробел. У вас надо смотреть.
Так, если я правильно понимаю - то у вас получается что под разную длинну нажатий выводятся разные "клавиши".
Keypad работает чуток иначе - каждая клавиша - это соединение двух каких-то ног. например case 'a' - это соединение 5 и 8 ноги, case 'b' - 6 и 8 и тд.
Давайте для простоты попробуем в шапке все обозначить.
Т.е. сведем все до 1 кнопки/кейса.
Попробовал написать скетч, пользуясь вашим примером -
Работают только короткие нажатия. Длинне никак не реагируют.
Конкретно в таком виде компилятор ругался на 46 строку
В 46 строке компилятору не на что ругается.
он не заработал
Ну а если и сейчас не заработает длительное нажатие, то это означает, что с данной библиотекой в текущем варианте это невозможно.
С библиотекой Keypad.h должно работать так:
И замените в 33 строке RELEASED на HOLD, иначе нажатия будут срабатывать только через полсекунды.
Огромное спасибо!!! да, так работает. Извиняюсь за некоторую путанницу с кодами и прочим - я достаточно начинающий, поэтому бывают явные "глупости".
Так, если я правильно понимаю - то у вас получается что под разную длинну нажатий выводятся разные "клавиши".
Keypad работает чуток иначе - каждая клавиша - это соединение двух каких-то ног. например case 'a' - это соединение 5 и 8 ноги, case 'b' - 6 и 8 и тд.
Давайте для простоты попробуем в шапке все обозначить.
Т.е. сведем все до 1 кнопки/кейса.
Попробовал написать скетч, пользуясь вашим примером -
Работают только короткие нажатия. Длинне никак не реагируют.
Они у вас и не будут реагировать. Вы убрали защелку нажата-ненажата. Дальше логика уже не работает. Для корректной работы вам надо определить, что возвращает функция при ненажатой клавише. Пришел код - нет нажатых клавиш, начали отрабатывать условия. Возможно с этой библиотекой так и не выйдет.
Не, работает с Released. C HOLD - работает не корректно - длинные нажатия не отрабатывают, короткие отрабатывают через раз.
Всем спасибо. Финальный код выглядит так:
Все работает как надо.
Так работает или не работает с RELEASED ?
Работает имено с RELEASED. C HOLD - не работает.
Ну и более оптимально будет так
Кстати, а почему я не могу тут
else
if
(millis()-startmillis > 500)
указать больше чем 500? например если мне задержка нужна в 2500-3000? Если пробую указать даже 600 - то ничего не происходит по долгому нажатию.
Причем меньше чем 500 - установить могу, отрабатывает корректно. больше - просто перестают работать "долгие" нажатия.
Потому что setHoldTime по-умолчанию 500 после этого state меняется на hold а Вы ловите Pressed и Released.
В чём вообще прикол, используя библиотеку самому считать время, когда это уже реализовано в библиотеке?
Слушайте, а в чем фишка этой библиотеки? Может она и мне нужна?
Точно. Прописал в setup части - kbp.setHoldTime = 2500; и стало считать большие значения.
Я бы с радостью использовал все, что есть в библиотеке - но знаний пока не хватает.
Она по сути кейпад делает.
А 8 пинов на 16 клавиш, это не слишком щедро? Есть ведь варианты на 1 или 2
http://arduino.ru/forum/programmirovanie/rabota-s-knopkami-v-pomoshch-novichku?page=4#comment-86325
http://arduino.ru/forum/programmirovanie/podklyuchenie-matrichnoi-klaviatury-po-i2c
Сам правда не проверял, мне больше трех пока было не надо.
Потому что setHoldTime по-умолчанию 500 после этого state меняется на hold а Вы ловите Pressed и Released.
В чём вообще прикол, используя библиотеку самому считать время, когда это уже реализовано в библиотеке?
Все верно, просто нужно внимательнее читать описание библиотек.
Как-то у меня последний пример не заработал. короткие нажатия работают нормально, длинные нет. Может я что-то в сетап-части упустил?
Так. поскольку чуток в голове уже инфы появилось, перечитал еще раз документацию к библиотеке, и посмотрел в очередной раз примеры. И оказалось, что пример "EventKeypad" очень похож на то, что мне нужно (наконец-то я это смог увидеть).
Работает.