Что такое дребезг контактов, и как с ним бороться? Для ответа на этот вопрос необходимо решить простенькую задачку.
ЗАДАЧА:
Написать программу, переключающую состояние светодиода (горит/не горит) при каждом нажатии кнопки. При каждом нажатии кнопки выводить в программу монитор порта сообщение "click". Нажали на кнопку светодиод загорелся, еще раз нажали - светодиод погас.
Для реализации задачи можно использовать простой алгоритм.
Программа висит в бесконечном цикле, ожидая нажатия кнопки. После нажатия, переключает состояние светодиода, выводит сообщение и висит в другом бесконечном цикле пока кнопку не отпустят.
Тест я буду делать на ESP32, хотя и на Arduino пример будет работать. Кнопка подтянута к плюсу резистором 10кОм.
Проще всего такой алгоритм реализуется с помощью оператора while(); Операторы, входящие в тело цикла выполняются до тех пор, пока условие в круглых скобках истина. Сам цикл {} в данном случае пустой.
Поклацав кнопку можно легко убедиться, что результат работы программы абсолютно непредсказуем. В момент замыкания или размыкания любых металлических контактов, происходит много быстрых замыканий/размыканий. Данное явление называется дребезг контактов.
Программный метод борьбы с дребезгом достаточно прост: обнаружив любое состояние изменения контактов, нужно сделать небольшую задержку (не опрашивать кнопку), чтобы контакты кнопки полностью успокоились.
Необходимая величина этой задержки зависит исключительно от конструкции и качества контактов кнопки.
В таком варианте все будет работать как нужно. Выглядит просто. Сложности начинаются тогда, когда в работе программы есть жесткая необходимость, чтобы в тот период времени когда кнопка не опрашивались, работала остальная программа. Минимизировать задержку можно используя таймер на millis();. Полностью от неё избавиться можно используя, аппаратный таймер микроконтроллера. Можно использовать и готовые библиотеки.
У меня на канале есть 2 возможных варианта программной реализации алгоритма "антидребезга", ссылки будут в конце статьи, а пока выкинем из программы оператор delay(); и рассмотрим один из простейших вариантов аппаратной реализации устранения дребезга.
Все популярные решения из Интернет с конденсатором, на ESP32 у меня почему-то нормально не работали.
Существует специализированная микросхема MC14490. Микросхема работает в широком диапазоне входных напряжений 3....18V, а также:
- есть защитные диоды на всех входах
- есть подтягивающие резисторы на цифровых входах
- возможность использования внутреннего генератора или внешнего тактового сигнала
- ТТЛ совместимые уровни входов и выходов
- подавление дребезга на обоих фронтах сигнала
Для работы необходимо лишь установить конденсатор малой емкости между выводами OSCin и OSCout. В документации приведены формулы расчета емкости конденсатора в зависимости от напряжения питания, но ее можно подобрать и опытным путем.
Данная микросхема имеет 6 каналов для подключения кнопок, из обвязки требуется только конденсатор, что дает ей большое преимущество перед другим популярным решением на триггере Шмитта - не нужно паять отдельно обвязку на каждую кнопку.
Микросхема продается в Китае по цене 84,47 руб за 5 штук
Ну, а те кто посчитают данную статью наглой рекламой микросхемы за 17 рублей, могут перейти по ссылкам размещенным ниже, скачать из них бесплатно примеры кода, разобраться как они работают и вообще ничего не покупать.
Код и документация на MC14490 доступны по этой ссылке. В практических целях код бесполезен, за то дает возможность быстро проверить работу аппаратных "антидребезговых" решений да и в целом понять это такое.
Полный список всей статей канала доступен по этой ссылке
Всем удачи!