Найти в Дзене
Электроника, ESP32, Arduino

Борьба с дребезгом контактов (программно и без библиотек)

Согласно вездесущей википедии:

Дребезг контактов — явление, происходящее в электромеханических коммутационных устройствах и аппаратах (кнопках, реле, герконах, переключателях, контакторах, магнитных пускателях и др.), длящееся некоторое время после замыкания электрических контактов. После замыкания происходят многократные неконтролируемые замыкания и размыкания контактов за счет упругости материалов и деталей контактной системы — некоторое время контакты отскакивают друг от друга при соударениях, размыкая и замыкая электрическую цепь.

Чтобы лучше понять, что означает весь этот набор слов, возьмем какой нибудь микроконтроллер (Arduino, ESP) и попробуем решить простенькую задачку. Соберем устройство которое будет подсчитывать сколько раз мы нажали на кнопку и выводить данное значение в монитор порта. У меня под рукой есть плата ESP32, ну соответственно потребуется кнопка. (на Arduino данный код также будет работать). Внешний подтягивающий резистор мы использовать не будем, подключим внутренний с помощью команды INPUT_PULLUP в функции pinMode(). Соответственно при чтении состояний кнопки не забываем добавлять оператор отрицания "!" так как HIGH будет означать что кнопка не нажата, а LOW - нажата. Во всем остальном все будет работать точно также как если бы мы использовали внешнюю подтяжку.

Схема подключения: При нажатии на кнопку pin D4 будет замыкаться на землю
Схема подключения: При нажатии на кнопку pin D4 будет замыкаться на землю
Испытательный стенд
Испытательный стенд

Перед тем как копипасить чужой код из интернет, начинать разрабатывать свою программу необходимо составить алгоритм её работы. Для того, чтобы считалось именно одно нажатие, заведем дополнительную логическую переменную buttonPressed, (кнопка нажата?) чтобы счетчик не считал все то время, пока мы удерживаем кнопку.

Алгоритм работы программы.
Алгоритм работы программы.

Пишем код и прошиваем им плату:

Тестовый код без защиты от антидребезга контактов
Тестовый код без защиты от антидребезга контактов

Открываем монитор порта и один раз клацаем по кнопке

Дребезг контактов практика
Дребезг контактов практика

Вместо увеличения счетчика на единицу, программа посчитала целых 8 нажатий. Причем результат за одно нажатие абсолютно не предсказуем

Дребезг контактов практика
Дребезг контактов практика

Причина была озвучена в начале этой статьи, микроконтроллер опрашивает кнопку много много много раз в секунду, и поэтому в момент замыкания(размыкания) механических контактов мы видим, что микроконтроллер посчитал заодно и весь дребезг. Простая на первый взгляд задача оказалась не такой уж и простой.

В таком виде в практических целях программу разумеется использовать не получится. Для устранения данной проблемы можно использовать и аппаратное решение, но в этой статье речь пойдет о программной реализации.

Самый простой способ - обнаружив изменение состояние входа к которому подключена кнопка, спросить еще раз: "а что это было?" дребезг или действительно на кнопку нажали. Задержка должна быть такой, чтобы контакты кнопки полностью успокоились. Перерисуем наш алгоритм.

Алгоритм борьбы с дребезгом
Алгоритм борьбы с дребезгом

Код:

Код с антидребезгом
Код с антидребезгом

Теперь все работает как нужно: при одном нажатии счетчик увеличивается на одну единицу.

Данный код легко превратить в кнопочный переключатель:
один раз нажали - нагрузка включилась
второй раз нажали - нагрузка выключилась.
Разберем на примере переключения встроенного светодиода.

Алгоритм кнопочного переключателя
Алгоритм кнопочного переключателя

Нажимая на кнопку можно включать и выключать встроенный в плату светодиод.

Пример реализации кнопочного переключателя
Пример реализации кнопочного переключателя

Плюсы данного решения: простота реализации, отсутствие необходимости применять дополнительные электронные компоненты.
Минусы, дополнительная нагрузка на микроконтроллер, дополнительный код, невозможность использовать данный механизм при работе с прерываниями.
Является или нет критичной задержка в 10....20 мс зависит от решаемой Вами задачи. Естественно можно применить более сложное программное решение на основе классического алгоритма (Blink Without Delay) или аппаратный таймер микроконтроллера, чтобы избавиться от ненужного в программе простоя (команды (delay()). Еще один из способов избежать "тормозов" в программе
разобран в моей второй статье.

Также вы можете ознакомиться
с полным списком статей на моем канале.
Всем удачи!