Ошибка счетчика нажатий кнопки на прерываниях.
- Войдите на сайт для отправки комментариев
Вс, 03/11/2019 - 18:17
volatile int counter = 0; // переменная-счётчик void setup() { Serial.begin(9600); // открыли порт для связи // подключили кнопку на D2 и GND pinMode(2, INPUT_PULLUP); \ // D2 это прерывание 0 // обработчик - функция buttonTick // FALLING - при нажатии на кнопку будет сигнал 0, его и ловим attachInterrupt(0, buttonTick, FALLING); } void buttonTick() { counter++; // + нажатие } void loop() { Serial.println(counter); // выводим delay(1000); // ждём }
Здравствуйте. Не могу понять почему некорректно считает нажатия на кнопку. кнопку пустил в разрыв между минусом и 2 пином. в мониторе порта происходит какая-то фигня - нажатие прибавляет 1 или 2, иногда 3...
что за ерунда и как это лечится?
дребезг.
причину понял - дребезг кнопки.
нашел способ - использование задержки для сравнения положений кнопки. ситуация не изменилась((
Поставь параллельно кнопке конденсатор на 1мкФ и увеличь время до 60...150мс. Или используй триггер Шмидта.
delay() в обработчике прерывания не работает. Если хочется придержать считывание - принимайте delayMicroseconds() сразу после входа в ISR. А потом уже вход чекайте.
Поставь параллельно кнопке конденсатор на 1мкФ и увеличь время до 60...150мс. Или используй триггер Шмидта.
баловался с задержками - результат нулевой. кондера, к сожалению, под рукой нет пока, поэтому и пытаюсь программно решить проблему. в источниках с программным решением проблемы не было кондера, а просто задержка, а вот с аппаратным - там и триггер Шмидта и кондер используются одновременно.
тут вопрос в другом - когда используются несколько кнопок для управления менюшкой на дисплее придется на каждую лепить кондер с триггером, если программно не получится решить проблему ? и почему-таки программно без кондера результата нет - может в коде ошибка какая ?
спасибо, где-то проскакивала инфа что такие задержки не работают - упустил из виду) сейчас поковыряю ваш вариант решения.
delay() в обработчике прерывания не работает. Если хочется придержать считывание - принимайте delayMicroseconds() сразу после входа в ISR. А потом уже вход чекайте.
попробовал разные варианты расположения задержки - результата практически нет((
Но навигацию по менюшке лепить на прерываниях - это оверкилл. Достаточно библиотеки дебаунсера.
нашел проблему - оказывается задержка delayMicroseconds() в микросекундах и то, что у меня 1650 равнозначно 1.65 милисекунд ))) увеличил до 10650 - и всё заработало как часы.
огромное спасибо!!!
сейчас библиотеку поизучаю, спасибо)
две миллисекунды маловато видимо будет, тут осциллограмку кто-то выкладывал,там три всплеска на обычной кнопке, найти бы, там и временные отрезки видны
Но навигацию по менюшке лепить на прерываниях - это оверкилл. Достаточно библиотеки дебаунсера.
не пойму что за библиотека дебаунсера ?
две миллисекунды маловато видимо будет, тут осциллограмку кто-то выкладывал,там три всплеска на обычной кнопке, найти бы, там и временные отрезки видны
10650 микросекунд уже работают) для тестирования устранения дребезга - долее чем достаточно) буду ковырять дальше...
две миллисекунды маловато видимо будет, тут осциллограмку кто-то выкладывал,там три всплеска на обычной кнопке, найти бы, там и временные отрезки видны
От раздолбанности кнопки зависит, безусловно. Пример я написал, двоечку менять на что-то другое - наверное хватит соображалки.
Вообще - 5-8 мс дебаунса покрывали все мои старые тактовые кнопки. Конечно, в прерываниях я задержки не ставил, не для того они.
P.S.
Картинка из интернета:
да картинку выкладывали как замечание на мой код обрабатывающий и нажатие и отпускание...
Это да, не дело в прерывании лепить задержки, но тут по другому видимо никак
Поставьте на входе интегрирующую цепочку на 10-16 мс и забудьте о
перхотидребезге от слова совсем (ну, если кнопка не совсем вдрызг убитая). В программе тогда вообще ничего делать не надо.Или можно взять SPDT кнопку и сделать как здесь. С таким подходом дребезг невозможен в принципе независимо от степени убитости кнопки. И опять же в программе ничего делать не надо.
10650 микросекунд уже работают) для тестирования устранения дребезга - долее чем достаточно) буду ковырять дальше...
Если кнопка на прерывании, то что-бы нормально работала безо всяких конденсаторов и интегрирующих цепочек надо делать так
- В прерывании считываем кнопку раз 5 подряд (для отсекания "иголок"). Если все пять раз кнопка "нажата", то ставим флаг, что кнопка нажата (и увеличиваем счетчик нажатий, если так надо) и и игнорируем прерывания от пина миллисекунд на 10. Лучше их вообще запретить, что бы проц дребезгом не грузить. Но тогда потребуется использовать прерывания от таймера, что бы прерывания от кнопки опять разрешить. Ну или их можно опять разрешить в Loop() если он у вас крутится быстрее чем за 10мс.
Потом проверям прямым чтением пина - если кнопка все еще нажата, то аналогичным образом ловим отпускание и тогда симаем флаг "нажато".
Вот такие триггеры (https://ru.aliexpress.com/item/32844342674.html?spm=a2g0s.9042311.0.0.7fa133edAqthaZ) копейки стоят и сразу 4шт в одном корпусе. Есть smd исполнение. Дёшево и работает )))
Вот такие триггеры (https://ru.aliexpress.com/item/32844342674.html?spm=a2g0s.9042311.0.0.7fa133edAqthaZ) копейки стоят и сразу 4шт в одном корпусе. Есть smd исполнение. Дёшево и работает )))
Тока их там шесть в одном корпусе
BOOM, триггер шмитта уже есть в МК на каждом входе, подключать ещё и внешний в целях формирования логических уровней не имеет смысла. Действительно работающие варианты аппаратного дребезгоподавления это MC14490, MAX6816.
Вот такие триггеры (https://ru.aliexpress.com/item/32844342674.html?spm=a2g0s.9042311.0.0.7fa133edAqthaZ) копейки стоят и сразу 4шт в одном корпусе. Есть smd исполнение. Дёшево и работает )))
Тока их там шесть в одном корпусе
и не копейки а три рубля за корпус )))
BOOM, триггер шмитта уже есть в МК на каждом входе, подключать ещё и внешний в целях формирования логических уровней не имеет смысла. Действительно работающие варианты аппаратного дребезгоподавления это MC14490, MAX6816.
хорошие девайсы, первые аж на 6 каналов, за то вторые с защитой по входу от наводок до 15 киловольт, а принцип действия одинаковый, возьму на заметку )))
ua6em, mc14490 я уже как-то обозревал с картинками :)
ua6em, mc14490 я уже как-то обозревал с картинками :)
я тогда даже слова такого - ардуино - не слышал )))