Дребезг контактов и способы подавления дребезга.

Что такое дребезг контактов

Дребезг контактов на экране осциллографа

Дребезг контактов на экране осциллографа

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

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

Для понимания сути, нам нужно рассмотреть простой код, который зажигает встроенный в плату Arduino светодиод на пине 13 при нажатии кнопки и гасит светодиод при следующем нажатии. Кнопка подключена ко второму пину (о подключении кнопки читайте статью « Как подключить кнопку к Arduino »):

Это рабочий код, но из-за дребезжания контактов кнопки он поймает много лишних срабатываний. Причём всё происходит так быстро, что программа успеет поймать ложные срабатывания несколько раз и несколько раз включить-выключить светодиод. В итоге, ваше устройство будет работать случайным образом. Если повезёт — светодиод будет гореть после нажатия. Не повезёт — цикл проскочит на состояние, когда светодиод окажется выключенным.

Программный способ избавления от дребезга

Суть программного способа в том, чтобы внутри программы отличить случайные срабатывания из-за дребезга от настоящего нажатия. Самый простой способ: добавить задержку сразу после первого срабатывания. Тогда при срабатывании кнопки мы останавливаем выполнение программы и дожидаемся, пока контакты кнопки перестанут дребезжать. Ложных срабатываний не будет.

Этот способ прост и понятен, но имеет недостаток: выполнение программы останавливается при нажатии кнопки, что может быть недопустимо в некоторых случаях, а при использовании прерывания невозможно в принципе. Следующий вариант избавления от дребезга, засекать время, прошедшее от первого срабатывания кнопки с помощью функции millis:

Этот код обеспечивает избавление от дребезга и при этом не блокирует выполнение программы, как это происходит при использовании функции delay.

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

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

Аппаратный способ подавления дребезга

Аппаратные решения всегда ценились за их надёжность и  возможность облегчить написание программы.

Вот как выглядела схема подключения кнопки без аппаратной защиты от дребезга:

Схема подключения кнопки к Arduino

Схема подключения кнопки к Arduino

Добавив пару дополнительных элементов в схему мы сможем полностью избавиться от дребезга, не усложняя при этом код. А добавим мы инвертирующий триггер Шмитта и конденсатор. Мы построим RC-цепь с инвертирующим триггером.
Вот так это выглядит на схеме:

Подавление дребезга с помощью инвертирующего триггера Шмитта

Резистор 10 кОм у нас теперь подтягивает вывод не к земле, а к +5В. Причём подтягивается не вход Ардуино, а вход инвертирующего триггера и заодно, конденсатор. Кнопка же, наоборот, подключена к земле. Сделано это в связи с тем, что триггер у нас инвертирующий. Суть такова: входящий аналоговый сигнал может быть восходящим, либо нисходящим. Внутри триггера определены пороговые значения: ~1,6 В — для нисходящего сигнала и ~0,9 В — для восходящего. Выход триггера становится логической единицей (5 В), при прохождении нисходящим сигналом через свой порог в 0,9 В, при этом нисхождение восходящим сигналом верхнего порога в 1,6 В будет проигнорировано. Аналогично, выход триггера становится логическим нулём (0 В), только когда восходящий сигнал проходит свой порог в 1,6 В, при этом проигнорируется прохождение нисходящим сигналом нижнего порога в 0,9 В. Зона неопределённости между порогами называется гистерезисом. То есть триггер переворачивает сигнал. Конденсатор с резистором образует RC-цепь. RC — от английских названий резистора и конденсатора (resistor и capacitor). RC-цепь замедляет затухание сигнала. То есть при снятии напряжения, оно пропадёт не сразу, а будет плавно снижаться. При нажатии кнопки мы прижмём RC-цепь к земле, конденсатор начнёт разряжаться и напряжение начнёт плавно падать. После отпускания кнопки, напряжение начнёт так же плавно расти:

График изменения напряжения RC-цепи

График изменения напряжения RC-цепи

Инвертирующий триггер выполняет 2 функции:

1) он инвертирует (переворачивает) логические уровни: единица становится нулём, а ноль становится единицей.

2) он преобразует аналоговый сигнал в цифровой. То есть, в определённый момент, когда конденсатор разрядится до определённого уровня, триггер выдаст логическую единицу. Затем это нужно? При отпускании кнопки, при достижении определённого уровня заряда конденсатора, триггер установит на выходе низкий уровень. Сигнал на выходе триггера не будет зависеть от дребезга:

График изменения напряжения на выходе инвертирующего триггера Шмитта

График изменения напряжения на выходе инвертирующего триггера Шмитта

Дребезг контактов и способы подавления дребезга.: 8 комментариев

  1. sld

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

    0
    1. farodig

      Реализовал аппаратный способ на триггере Шмитта SN74HC14N как на картинке (R 10кОм, С 10mF электролитический), при нажатии кнопки прерывание срабатывает 1 раз, а при отпускании возникает дребезг (множественное срабатывание) может кто знает как исправить дребезг при отпускании?

      0
    1. uscr Автор записи

      Здравствуйте. Это не важно. Работать будет с любым. От ёмкости конденсатора зависит время отработки схемы RC-цепи. Грубо говоря, конденсатор регулирует время задержки срабатывания кнопки.
      Поставьте, например, 10 микрофарад.

      0
        1. uscr Автор записи

          Вольтаж конденсатора определяет максимальное напряжение, которое выдержит конденсатор. Если вы работаете с 5 вольтами, то любой конденсатор с напряжением больше пяти вольт. Хоть 12, хоть 50, хоть 100.

          0

Добавить комментарий