Дребезг кнопки

Тема в разделе "Флудилка", создана пользователем AlexU, 28 ноя 2015.

  1. AlexU

    AlexU Гуру

    Тема скорее будет интересна начинающим, но профи смогут поделится своим опытом.

    При использовании кнопок, герконов и т.п. встает проблема дребезга. Что в некоторых случаях может стать причиной неработоспособности проекта. Чаще всего дают совет программно бороться с этим неприятным явлением -- использовать delay(), библиотеку Bounce и т.п.
    Я же хочу напомнить о простом способе аппаратной борьбы с дребезгом -- использованием низкочастотных фильтров (НЧ-фильтров). Данный способ не является каким-то ноу-хау, но почему-то о нём редко вспоминают.
    На первой картинке приведены два вида простейших НЧ-фильтров:
    LF_filters.jpg На второй картинке -- как подключать кнопку к Arduino с помощью НЧ-фильтра (использован второй вариант):
    Filter_Button.jpg

    Для приведенной схемы 9й пин Arduino нужно подтянуть к +5V:
    Код (C++):
    pinMode(9, INPUT_PULLUP);
    . При отжатой кнопке digitalRead(9) будет возвращать HIGH, при нажатой -- LOW.
    Элементы взяты из набора "Матрешка", поэтому имеют соответствующие номиналы -- R = 1 kOm, C = 100 nF. С номиналами можно поэкспериментировать.

    Как видно решение простое и не дорогое, но помогает упростить написание кода.

    UPD:
    поэкспериментировав с разными схемами, пришёл к выводу -- RC цепочка не всегда полезна. В некоторых случаях количество ложных срабатываний, наоборот, возрастало. Но решение оказалось ещё проще -- нужно убрать резистор, а конденсотор "вешать" параллельно кнопке. В большинстве случаев хватало конденсатора 100 nF (из набора Матрёшка).
     
    Последнее редактирование: 24 дек 2015
    Mestniy, DrProg и nailxx нравится это.
  2. DrProg

    DrProg Вечный нерд

    На эту тему есть пример в эксперименте 20 от Амперки. RC цепь для сглаживания скачков, правда в том примере еще триггером инвертируется, а в вашем все проще, за что отдельное спасибо. Очень полезная информация для работы с кнопками, особенно когда они висят на прерываниях. Да и вообще упрощает программу.

    И еще, нарисовать бы уж полную схему тогда:
    [​IMG]
    И тестовый код приложить:
    Код (C++):
    bool oldPress = 1;
    bool Press = 0;

    void setup() {
      pinMode(7, INPUT);
      pinMode(13, OUTPUT);
    }

    void loop() {
      Press = digitalRead(7);
      if (!Press) {
        if  (Press != oldPress) {
          digitalWrite(13, !digitalRead(13));
          oldPress = 0;
        }
      } else {
        oldPress = 1;
      }
    }
     
    Последнее редактирование: 29 ноя 2015
    ИгорьК нравится это.
  3. Salk

    Salk Гик

    Тогда позвольте добавить для полноты картины. RC-цепочки можно ставить не только на кнопки, но и на всё, что относится к классу "кнопочных", к примеру энкодеры.
    rotenc.jpg
     
  4. DrProg

    DrProg Вечный нерд

    Когда есть выбор, аппаратное решение лучше.
     
    Desert Ops и ИгорьК нравится это.
  5. Salk

    Salk Гик

    Не всегда, не всегда...
     
  6. Спасибо , мне это очень пригодилось!
     
  7. DrProg

    DrProg Вечный нерд

    Программный антидребезг это всегда небольшая но задержка. А если кнопка не одна, если их 10 или 100? Представьте как будет тормозить программа при обработке, особенно одновременного нажатия.
     
    Desert Ops и ИгорьК нравится это.
  8. ИгорьК

    ИгорьК Давно здесь

    +100500! Если кнопок не 100 а 1000 то МК только и будет делать что проверять их на дребезг! Свободу МК! Пикофарады - наше все! Ни такта простоя врагу! Долой надежность: жалеем процессор нежно и искренне!
     
  9. Desert Ops

    Desert Ops Нерд

    Я за аппаратное решение проблемы антидребезга. Инвертирующий триггер Шмитта решает эту проблему.
     
    DrProg нравится это.
  10. DrProg

    DrProg Вечный нерд

    Один триггер Шмитта проблему не решает, нужна аппаратная задержка фронта или спада, что достигается при помощи RC цепи. А при правильно подобранных резисторе и конденсаторе и триггер не нужен, главное чтобы дребезг не успел пробить гистерезис пина.
     
    ИгорьК нравится это.
  11. avex

    avex Нерд

    А как правильно подобрать? От чего в этом случае будут зависеть номиналы?
     
  12. AlexU

    AlexU Гуру

    Перечитайте первый пост, особенно последний абзац ( UPD: ).
     
  13. Unixon

    Unixon Оракул

    Кстати, когда такая необходимость возникла в одном проекте, была сделана одна простая оптимизация: состояния всех кнопок собирались побитово в длинное целое (битовую карту) и процедура антидребезга применялась к этой карте, а не к отдельным кнопкам. Может это и не совсем правильно, но работало идеально.
     
    Последнее редактирование: 19 янв 2017
    ИгорьК нравится это.
  14. mcureenab

    mcureenab Гуру

    Номиналы определяются требованиями к скорости срабатывания кнопки (время падения напряжения от Vcc до значения LOW <= 0.3 Vcc или наоборот от 0 до уровня HIGH >= 0.7 Vcc). Это примерно 2RC. Подробнее посмотрите статьи про постоянную времени RC цепи.
    Однако время RC должно быть достаточно большим, чтобы рост или спад напряжения на выходе кнопки был монотонным не смотря на дребезг контакта.

    В диапазоне от 0.3 Vcc до 0.7 Vcc имеем неопределенность. Т.е. кнопка сработает раньше чем напряжение достигнет уровня HIGH или LOW. Это уровень threshold на рисунке.

    [​IMG]

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

    Чтобы получить гарантированное время срабатывания и быстрый переход сигнала на пине МК вместе с RC фильтром нужно использовать триггер Шмитта.

    Вместо внешнего резистора R2 на правой схеме
    [​IMG]
    с тем же успехом можно использовать встроенный подтягивающий резистор и режим пина INPUT_PULLUP. С кнопкой его следует использовать в любом случае чтобы пин не остался висеть в воздухе. Встроенный подтягивающий резистор имеет номинал около 35 кОм (вилка 20 - 50 кОм). Исходя из этого рассчитываем емкость конденсатора.
    Для 100нФ имеем время срабатывания при размыкании IN от GND 7 мс.
    Время срабатывания при замыкании IN на GND почти нулевое. Ток с C2 течет через кнопку.

    На левой схеме скорость переключения ON тоже отличается от скорости переключения OFF. Поскольку при замыкании IN на GND ток течет через R1, C1 а при размыкании через C1 на out и PULLUP резистор. Резистор R1 делает график спада напряжения более гладким и монотонным.
     
    Последнее редактирование: 19 янв 2017
  15. rkit

    rkit Гуру

    Нельзя в нч-фильтре просто так менять резистор и конденсатор местами.
    Если прямо подключить источник к кондесатору, то эффект будет совсем другой, не говоря уж о рисках спалить источник, или просадить питание в случае с кнопкой.
     
  16. mcureenab

    mcureenab Гуру

    В данном случае источником служит Ардуино, а кнопка сбрасывает заряд с конденсатора. Кнопка источником не является, очевидно.
     
  17. AlexU

    AlexU Гуру

    От куда информация?
    Документация сообщает о 20 .. 50 кОмах.
     
  18. mcureenab

    mcureenab Гуру

    Действительно, не в туда посмотрел.
     
  19. ycuk

    ycuk Нуб

    Товарищи, подскажите пжлст. Законченное устройство будет питаться от аккумов/батарей (этакая минисигнализация на герконе). Ардуина всегда спит и просыпается при разрыве на герконе.
    Какую схему подключения выбрать для минимального энергопотребления?
    Есть ли Триггеры Шмитта с одним входом и выходом (инвертором)?
     
  20. ostrov

    ostrov Гуру

    В этом случае не проще сделать подачу питания при разрыве геркона? На одном транзисторе и одном резисторе.