Длительность и количество нажатий кнопки…???
- Войдите на сайт для отправки комментариев
Пнд, 01/12/2014 - 21:35
Подскажите, пожалуйста, как проще всего реализовать обработку нажатий кнопки по такому алгоритму:
- одно короткое (меньше 1 с.) – переключение первого выхода
- два коротких с интервалом до 500 мс - переключение второго
- один длинный (1 с или больше) - переключение третьего
- два длинных (1 с. или больше) с интервалом до 500 мс переключение четвертого
Знаю, что обработать несколько нажатий (без учета длительности) можно при помощи введения дополнительной переменной – об этом написано тут. А как обрабатывать с учетом длительности нажатия? Подскажите, пожалуйста, если не трудно! Заранее спасибо!
Считайте длительность нажатия кнопки и сравнивайте с эталоном (естественно плюс-минус не забудьте). Если длительность соответствует эталону, засчитываем нажатие как короткое или длинное и считаем паузу. Если пауза менее паузы завершения команды, считаем следующее нажатие и увеличиваем соответствующий счетчик. Потом опять паузу и так до тех пор пока пауза не превысит значение завершения команды.
Большое спасибо за подсказку!!! Код пока ещё не совтавил, но думаю, что понадобится использовать как минимум пять переменных!!!
Этого достаточно, или обязательно должна быть переменная задающая время обработки нажатий??? Если её не указать, с какой частотой плата Arduino будет сканировать кнопку???
Вы так над каждой переменной размышляете? Рано Вам еще. Делайте больше переменных, больше кода, потом исправляйте ошибки, анализируйте и упрощайте..
Отвлекитесь от "двух-длинных-двух-коротких", стремитесь к универсальности. Я бы, например, "ловил" все нажатия кнопки подряд, сохраняя нажатия, и "вдвигая" их в какую-нибудь переменную - "0" для короткого нажатия, "1" для длинного.
Вдвигание прекращаем, как только обнаружим слишком длинную паузу между нажатиями. После этого проверяем содержимое нашей переменной: если там одна из нужных нам комбинаций - переключаем соответствующий выход.
Только переменную лучше двигать начиная не с нулевого значения, а с 00000001b, иначе не получится отличить, например, одно короткое нажатие от нескольких.
Во, напридумывал. Интересно, понятно что-нибудь? :)
В моей, существующей пока только в моей голове, библиотеке по обработке кнопок кнопка это класс, в которой три главные вещи:
байт состояния и истории кнопки (сколько раз было нажато сколько отпущено);
время с последнего изменения ну и метод обрабатывающий текущее время (читаем millis()) и рещающее что же стало с этой кнопкой.
Отвлекитесь от "двух-длинных-двух-коротких", стремитесь к универсальности. Я бы, например, "ловил" все нажатия кнопки подряд, сохраняя нажатия, и "вдвигая" их в какую-нибудь переменную - "0" для короткого нажатия, "1" для длинного.
Большое спасибо Вам за идею! Попробовал написать следуя Вашему совету - набросок кода выглядит так:
int SHORT_BC=0; //Short Button Counter - счетчик кратковременных нажатий int LONG_BC=0; // Long Button Counter - счетчик длинных нажатий long START_BP_Millis = 0; // Start button pressed - точка начала отчета после нажатия void setup() { pinMode(13, OUTPUT); pinMode(14, INPUT); } void loop() { if(digitalRead(14)==HIGH)//если нажать кнопку ... { START_BP_Millis-START_BP_Millis // начинаем отсчет длительности нажатия... с нуля if (millis() -long START_BP_Millis < 500) { START_BP_Millis = millis(); // счетчик длительности нажатия обнулить для следуещего отсчета SHORT_BC++; // увеличить счетчик кратковременных нажатий } if (millis() -long START_BP_Millis =>500) // и удерживать 0,5 cекунды или больше... { START_BP_Millis = millis(); // счетчик длительности нажатия обнулить для следуещего отсчета LONG_BC++; // увеличить счетчик длинных нажатий } } }Можно ли написать ещё проще??? У кого есть какие-нибудь идеи?
Вы сначала попробуйте этот код скомпилировать, а потом и дальше можно подумать...
И всё-таки наверно лучше использовать не счетчики нажатия, а переменную вида 01101, т. е. короткое-длинное-длиное-короткое-длинное.
Согласен! Это сэкономило бы память - хватило бы одного байта! Если в зависомости от длитеьности импульса пропихивать в него 1 или 0 командой (1<<x), увеличивая x в цикле (x++) пока он меньше 8 (x<8).
Насчет кода Вы тоже правы - я допустил несколько ошибок, но уже их исправил (в соответствиями с замечаниями компилятора) теперь компиляция проходит без проблем:
Вот код
int SHORT_BC=0; //Short Button Counter - счетчик кратковременных нажатий int LONG_BC=0; // Long Button Counter - счетчик длинных нажатий long START_BP_Millis = 0; // Start button pressed - точка начала отчета после нажатия void setup() { pinMode(13, OUTPUT); pinMode(14, INPUT); } void loop() { if(digitalRead(14)==HIGH)//если нажать кнопку ... { START_BP_Millis-START_BP_Millis; // начинаем отсчет длительности нажатия... с нуля if (millis() - START_BP_Millis < 500) { START_BP_Millis = millis(); // счетчик длительности нажатия обнулить для следуещего отсчета SHORT_BC++; // увеличить счетчик кратковременных нажатий } if (millis() - START_BP_Millis >= 500) // и удерживать 0,5 cекунды или больше... { START_BP_Millis = millis(); // счетчик длительности нажатия обнулить для следуещего отсчета LONG_BC++; // увеличить счетчик длинных нажатий } } }Это не для экономии памяти, а для расшифровки введенной команды. Посмотрите азбуку морзе например...
А если так:
IF (SHORT_BC==1 && LONG_BC==0) { // ...код, который будет выполнен при одном коротком нажатии { IF (SHORT_BC==0 && LONG_BC==2) { // ...код, который будет выполнен при ввух длинных нажатиях { // .. и т.д.Что скажете о таком варианте? По-моему нет ничего проще!
Есть готовое решение, в нем длина нажатия снимаются от одного до 20 раз подряд, потом усредняются и выводятся в форме MIDI, но вы можете допилить код сами http://gameimho.com/?p=54
что то я в коде OUTPUT не нашел
Отвлекитесь от "двух-длинных-двух-коротких", стремитесь к универсальности. Я бы, например, "ловил" все нажатия кнопки подряд, сохраняя нажатия, и "вдвигая" их в какую-нибудь переменную - "0" для короткого нажатия, "1" для длинного.
Вдвигание прекращаем, как только обнаружим слишком длинную паузу между нажатиями. После этого проверяем содержимое нашей переменной: если там одна из нужных нам комбинаций - переключаем соответствующий выход.
... и обязательно обнуляем переменную! Не так ли?
А можно ли вот так?
// функция чтения кнопки int button_read() { byte ButtonClics = B00000001; // переменная, в которую записываются нажатия кнопки long button_press_delay; // переменная для проверки длительности нажатия if(digitalRead(14)== HIGH) { // если нажатие кнопки обраружено, то... button_press_delay = millis; // начинаем отсчет времени нажатия if (button_press_delay - millis > 200) { ButtonClics << 1; // сдвигаем число влево на одну позицию } if(digitalRead(14)== HIGH) { // если нажатие кнопки обраружено, то... button_press_delay = millis; // начинаем отсчет времени нажатия if (button_press_delay - millis > 800) { // если нажатие длительное, то... ButtonClics << 1; // сдвигаем число влево на одну позицию ButtonClics ++; // и прибавляем 1 } else button_press_delay = millis; // ошибочные нажатия и дребезг контактов игнорировать return ButtonClicsК сожалению я не программист, поэтому не знаю, правильно ли написал!
вот мне интересную ссылку скинули
https://code.google.com/archive/p/clickbutton/