минимальный код для устранения дребезга нескольких кнопок
У меня есть 4 кнопки, подключенные к 4 контактам, настроенным как входы с активированным внутренним подтягивающим резистором...
достаточно ли этой функции для получения состояния устранения дребезга нажатой кнопки?
byte buttonPressed(){
byte btn = 0;
if (digitalRead(30)==LOW) btn = 1; else
if (digitalRead(9)==LOW) btn = 2; else
if (digitalRead(31)==LOW) btn = 3; else
if (digitalRead(8)==LOW) btn = 4;
delay(20);
return btn;
}
любые строго необходимые улучшения приветствуются...
@moyoumos, 👍1
4 ответа
Лучший ответ:
Да, ваш код должен работать как самое простое средство устранения дребезга, хотя Время отката может быть немного короче. Однако следует отметить, что во многих случаях хотелось бы иметь немного больше, чем самое основное. Один также может понадобиться:
- отказ от работы: при нажатии кнопки ваша рука может сделать Контакты немного смещаются, создавая всплески показаний, которые не являются связано с реальным изменением положения кнопки; вы не хотите эти шипы следует читать как «отпущены и нажаты снова»
- обнаружение края: во многих случаях вас больше интересует кнопка событие нажатия, чем знание того, нажата ли кнопка или поднята; это может обрабатываться другой функцией, но может быть удобно интегрировать это с отскоком
- неблокирующая операция: у вашей программы могут быть дела поважнее
чем тратить циклы ЦП внутри
delay()
.
Вот почему большинство кодов устранения дребезга значительно более эффективны. сложно. Но часто оно того стоит.
Правка 1: В свете комментариев, некоторые разъяснения кажутся необходимыми. нужно. Есть два вида сбоев, которые может вызвать механическая кнопка опыт:
- когда кнопка механически меняет положение, т.е. она нажато или отпущено; это называется отскок
- когда кнопка удерживается нажатой, особенно если давление на кнопка расположена низко, а палец, оказывающий на нее давление, несколько шаткий.
Большинство библиотек устранения дребезга, которые вы можете найти, на самом деле решают оба типа глюки. Таким образом, они делают больше, чем просто устранение дребезга, они делают то, что я называется «deglitching». Предыдущие ответы неявно предполагают, что правильный код устранения дребезга должен учитывать оба типа.
Код, указанный в вопросе, относится только к первому типу глюки, т.е. отскоки в строгом смысле. Вот почему я написал что он делает «самое основное устранение дребезга». Однако он восприимчив к второй тип глюков. Так что да, с этим кодом глюки могут сохраняться даже после устранения дребезга.
Правка 2: В качестве примера рассмотрим библиотеку Bounce 2. Она обеспечивает обнаружение краев, неблокируемую работу и, по умолчанию, конфигурация, полное устранение сбоев. Однако, его можно настроить на использование альтернативный алгоритм устранения дребезга под названием «Блокировка интервал», который более чувствителен, но не защищает от Ошибки «типа 2», упомянутые выше: он «не устраняет шум», как документация гласит.
Нет. На самом деле он просто проверяет каждую кнопку по одной. Кроме того, проверяется только последняя кнопка, поскольку она перезаписывает переменную btn.
Самый простой способ использования кнопки устранения дребезга 1:
byte buttonPressed()
{
byte btn = 0;
byte btn1Before = digitalRead(30);
delay(50); // Подождать 50 мс или 100 в зависимости от времени дребезга
byte btn1After = digitalRead(30);
if ((btn1Before == LOW) && (btn1After == LOW))
{
btn = 1;
}
}
Вам нужно сделать то же самое, что и другим. Вы можете использовать только одну задержку (просто добавьте 4 переменные до и после и проверьте их.
byte buttonPressed()
{
byte btn = 0;
byte btn1Before = digitalRead(30);
byte btn2Before = digitalRead( 9);
byte btn3Before = digitalRead(31);
byte btn4Before = digitalRead( 8);
delay(50); // Подождать 50 мс или 100 в зависимости от времени дребезга
byte btn1After = digitalRead(30);
byte btn2After = digitalRead( 9);
byte btn3After = digitalRead(31);
byte btn4After = digitalRead( 8);
if ((btn1Before == LOW) && (btn1After == LOW))
{
btn = 1;
}
else if ((btn2Before == LOW) && (btn2After == LOW))
{
btn = 2;
}
else if ((btn3Before == LOW) && (btn3After == LOW))
{
btn = 3;
}
else if ((btn4Before == LOW) && (btn4After == LOW))
{
btn = 4;
}
return btn;
}
Обратите внимание, что таким образом программа не будет отвечать в течение 50 мс. Если вы этого не хотите, вам придется использовать millis, но это усложнит задачу. Проверьте пример устранения дребезга на сайте Arduino.
Нет - просто delay()
после считывания кнопки не скажет вам, подпрыгивает ли кнопка или, что еще важнее, каково ее конечное состояние. Для устранения подпрыгивания требуется, чтобы вы знали, что кнопка
- измененное состояние;
- перестал менять состояние;
- в каком состоянии он находится.
Вам нужно будет заметить, что текущее состояние не соответствует последнему состоянию с устраненным дребезгом, которое вы видели; затем либо часто проверяйте его до тех пор, пока оно не перестанет менять состояние в течение некоторого количества тестов, либо просто подождите известное максимальное время, необходимое для стабилизации; затем считайте, сохраните и верните конечное состояние.
Хотя ответ @MichelKeijzers — это хорошее решение для простых запросов в основном цикле. Это непрактично для прерываний. Прерывания могут заблокировать весь MCU, а прерывание процедуры прерывания может вызвать серьезные проблемы.
В зависимости от ваших требований я бы посоветовал рассмотреть возможность использования конденсаторов и резисторов для устранения дребезга. Благодаря этому вы получаете более простой код и не нуждаетесь в решении аппаратных проблем в программном обеспечении. Конечно, за счет дополнительных деталей в вашей аппаратной настройке.
Если, например, ваш микроконтроллер использует вывод в качестве прерывания, это прерывание будет вызвано только один раз, а не будет вызвано повторно.
- Устранение дребезга кнопки с помощью прерывания
- Хорошая кнопка debouncing/Библиотека StateChange
- Управление несколькими светодиодами с помощью нескольких кнопок
- Будет ли простой RC-фильтр работать с механическим поворотным энкодером или понадобится триггер Шмитта?
- Кодировщик + Библиотека Bounce2
- Прерывание при нажатии кнопки + устранение дребезга
- Прерывание срабатывает дважды при установке на ПАДЕНИЕ
- Чтение поворотного энкодера с использованием цифровых контактов Mega 2560 напрямую с помощью регистров порта?