Урок 8. Arduino: Дребезг — программное устранение. Нажатие кнопки без ложных срабатываний.
В предыдущем уроке: «Урок 7. Подключаем тактовую кнопку к Arduino и управляем светодиодом» мы научились подключать кнопку к Arduino и зажигать светодиод, когда нажата кнопка. Если отпустить кнопку, светодиод гаснет. Возникает логически обоснованный вопрос, как сделать так, чтобы светодиод загорался при однократном нажатии на тактовую кнопку, и гас при повторном нажатии?
Схема подключения кнопки к Arduino.
Схему подключения тактовой кнопки и светодиода к Arduino UNO возьмем из предыдущего урока.
Установим на макетную плату тактовую кнопку, и подключим одну ножку к +5v, вторую ножку, с помощью подтягивающего резистора, подключим к GND. Для чего это нужно читайте в предыдущем уроке.
Немного доработаем скетч и сделаем так, чтобы при нажатии кнопки у нас включался или выключался светодиод. Знаний у нас для этого уже достаточно. Если есть вопросы по коду, задавайте в комментариях и смотрите предыдущие уроки.
После загрузки кода и проверки можно заметить, что у нас работает как-то неправильно. Мы неправильно написали код или другая причина? Дело в том, что при нажатии на кнопку устойчивое состояние наступает не сразу. Происходит так называемый дребезг кнопки. Еще его называют дребезгом контактов. Вот что написано в Википедии.
Дре́безг конта́ктов — явление, происходящее в электромеханических коммутационных устройствах и аппаратах (кнопках, реле, герконах, переключателях, контакторах, магнитных пускателях и др.), длящееся некоторое время после замыкания электрических контактов. После замыкания происходят многократные неконтролируемые замыкания и размыкания контактов за счет упругости материалов и деталей контактной системы — некоторое время контакты отскакивают друг от друга при соударениях, размыкая и замыкая электрическую цепь.
В зависимости от размеров, массы, материала и конструкции контактной системы время дребезга (время от первого соприкосновения контактов до затухания механических колебаний и установления стабильного контактирования) составляет 0,5—2 мс. у миниатюрных герконов и до сотен миллисекунд у мощных контакторов.
Как устранить ложные срабатывания при нажатии кнопки?
Дребезг кнопки можно устранить 2 способами:
- Аппаратное устранение дребезга кнопки.
- Программное устранение дребезга кнопки.
Аппаратное устранение дребезга кнопки.
Аппаратное устранение дребезга кнопки представляет собой изменение схемы подключения путем установки элементов, которые способны устранить дребезг. Самым простым решением является установка сглаживающего конденсатора. Вот так будет выглядеть схема подключения.
Также существуют и другие аппаратные способы устранения дребезга контактов.Но для ознакомления с аппаратным устранением дребезга достаточно данного примера.
Программное устранение дребезга кнопки.
Для того, чтобы понять как устранить дребезг кнопки посмотрим рисунок, на котором изображен дребезг кнопки. Как видим, дребезг длится недолго, и если сделать небольшую задержку после нажатия на кнопку и считать значение еще раз, то считаное значение будет уже в установившемся состоянии.
Так как кнопки используются в большом количестве Arduino проектов, для упрощения написания кода существует несколько библиотек, которые позволяют устранить дребезг кнопки. Одна из библиотек Bounce. Используя её не нужно задумываться, как устроен дребезг кнопки, и что нужно делать, чтобы с ним бороться. Но мы в уроке напишем небольшую функцию, которая поможет устранить ложные срабатывания программным способом.
Для этого нам нужно добавить вспомогательные переменные.
Функция boolean debvance достаточно простая. Получаем прошлое состояние кнопки.
Ждем 5 миллисекунд и присваиваем текущее состояние кнопки
И возвращаем значение current.
Затем напишем небольшую функцию.
Осталось в скетче прописать небольшие изменения.
Для работы с функцией устранения дребезга достаточно прописать всего одну строчку кода.
Также нужно проверить отпустили кнопку или нет.
После условия нужно обязательно сделать переприсваивание предыдущего состояния кнопки, для дальнейшего определения нажатия кнопки.
Дальше пишем код, который должен выполняться при нажатии кнопки. В нашем Arduino уроке необходимо включить светодиод без ложных срабатываний.
Светодиод включается и выключается при нажатии на кнопку, и нет ни каких ложных срабатываний. Поставленная цель достигнута.
Загружаем код в Arduino UNO.
Данный код можно использовать не только в симуляторе, но и при программировании реальной Arduino UNO. Если у вас есть такая возможность, подключите её к компьютеру, выберите нужный Порт и плату Arduino UNO, как показано на картинке ниже.
Нажмите на кнопку «Загрузить», после удачной компиляции и загрузки кода в плату, вы увидите надпись «Загрузка завершена».
Если у вас возникли сложности с загрузкой кода, посмотрите эту статью:
Понравился Урок 8. Arduino: Дребезг — программное устранение. Нажатие кнопки без ложных срабатываний? Не забудь поделиться с друзьями в соц. сетях.
А также подписаться на наш канал на YouTube, вступить в группу Вконтакте, в группу на Facebook.
Спасибо за внимание!
Технологии начинаются с простого!
Дребезг кнопки. Урок 2.3. Ардуино
Привет. Продолжаем работать с кнопками. Пожалуй, это одна из самых важных частей в любом устройстве. Ведь, без кнопок, переключателей и переменных резисторов управлять вашим устройством будет намного сложнее.
В прошлый раз мы уже попробовали подключить кнопку к ардуино, настроить пины ардуино на чтение информации и управлять светодиодом с помощью этой кнопки. Если вы уже забыли или пропустили эту статью, пожалуйста, посмотрите её.
Но подключение кнопки не такое простое как кажется на первый взгляд. Особенно, когда речь идет об ардуино и цифровых сигналах.
Так что, сегодня рассмотрим проблему дребезга кнопки и программных способах её решения.
Чтобы выполнить этот урок нам понадобятся.
- Ардуино UNO
- Макетная плата
- Перемычки
- Резистор номиналом 10 кОм
- Кнопка
- Кабель USB
Дребезг кнопки
Обычно кнопка представляет собой механическое устройство с пружиной. При нажатии на кнопку контакт срабатывает не сразу, а на протяжении нескольких миллисекунд меняется от 0 к 1 несколько раз. Соответственно, нельзя просто прочитать значение на контакте ардуино, необходимо избавиться от этого «дребезга».
Дребезг кнопки
Устранить этот эффект можно как аппаратным путем, так и программным. Но поскольку мы имеем в своем распоряжении ардуино, рассмотрим программу, которая решает эту проблему. Тем более, что такая программа уже есть в стандартной библиотеке ардуино ide.
Debounce.ino
Откроем программу из меню File — Examples — Digital — Debounce
Программа уже имеет исчерпывающий комментарий прямо в тексте, но рассмотрим как все работает.
Алгоритм довольно простой. Нам нужно сравнить состояние кнопки несколько раз через небольшой промежуток времени. Чтобы это сделать, необходимо использовать несколько переменных. Инициируем их в области объявления переменных.
Здесь мы ввели переменные buttonState и lastButtonState для проверки и сравнения состояния кнопки. Когда кнопка будет нажата, мы сравним ее состояние с переменной lastButtonState. И если состояние будет отличаться от ранее сохраненного, счетчик lastDebounceTime будет сброшен.
Переменные lastDebounceTime и debounceDelay используют тип unsigned long потому, что время исчисляется в миллисекундах и простого int будет недостаточно.
В функции setup() настроим состояние пинов и светодиода. Пин кнопки на чтение, пин светодиода на вывод, напряжение на пин светодиода = HIGH
Далее в цикле loop() будем постоянно проверять состояние кнопки. И если состояние в момент проверки будет отличаться от предыдущего, запустим процесс повторной проверки.
Здесь мы видим новую функцию millis(). Она возвращает количество миллисекунд с момента начала работы программы на плате Arduino. Это количество сбрасывается в 0, из-за переполнения значения, примерно через 50 дней непрерывной работы.
Принципиальная схема подключения кнопки
Итак, в цикле loop() мы постоянно считываем напряжение на пине 2 и записываем его в переменную reading.
Если reading не равно предыдущему состоянию кнопки, то счетчику lastDebounceTime присваивается значение функции millis().
Через 50 миллисекунд значение переменной reading сравнивается с текущим состоянием кнопки и, если они не равны, то текущее состояние кнопки приравнивается к reading.
И, наконец, если кнопка нажата, то состояние светодиода меняется на противоположное.
После этого на пин светодиода посылаем состояние, которое мы определили, а предыдущее состояние кнопки сохраняем для проверки в следующем витке цикла.
В результате мы получим возможность включать светодиод нажатием кнопки, но не держать кнопку нажатой постоянно. А только менять состояние светодиода нажатием.
Подавление дребезга кнопки
Полный текст программы
Заключение
В этот раз мы рассмотрели программу Debounce из стандартной библиотеки программ ардуино ide. Она позволяет избавиться от дребезга кнопки используя программу ардуино. В следующий раз мы оформим эту программу в отдельную функцию и будем использовать ее для управления группы светодиодов.
Работа с кнопками
Кнопка является простейшим устройством, при помощи которого можно управлять ходом программы на микроконтроллере, но физически она выполняет очень простую функцию: замыкает и размыкает контакт. Кнопки бывают нескольких типов:
- С фиксацией – кнопка остаётся нажатой после отпускания, без фиксации – отключается обратно.
- Нормально разомкнутая (Normal Open, NO) – при нажатии замыкает контакты. Нормально замкнутая (Normal Closed, NC) – при нажатии размыкает контакты.
- Тактовые кнопки – замыкают или размыкают контакт. У обычных тактовых кнопок ноги соединены вдоль через корпус (см. картинку ниже). Переключатели – обычно имеют три контакта, общий COM, нормально открытый NO и нормально закрытый NC. При отпущенной кнопке замкнута цепь COM-NC, при нажатой замыкается COM-NO.
Подключение и подтяжка
Из урока про цифровые пины вы помните, что микроконтроллер может считывать напряжение со своей ноги. Соответственно кнопка может подать на пин тот уровень, к которому подключена её вторая нога. В том же уроке мы обсуждали, что не подключенный никуда цифровой пин принимает наводки из воздуха, и считанное с него значение будет практически случайным. То есть подключив к пину 5V (сигнал высокого уровня) через кнопку, мы ничего не добьёмся: при нажатой кнопке на пине будет считываться четкий сигнал высокого уровня, а при отпущенной – случайное значение. Для решения этой проблемы существует такое понятие, как подтяжка (pull) пина. Подтяжка выполняется к земле (pull down) или питанию (pull up) микроконтроллера при помощи резистора. Подтяжка выполняется противоположно принимаемому сигналу, т.е. если нужно ловить высокий сигнал, подтяжка выполняется к земле, если ловить нужно сигнал земли – подтяжка выполняется к питанию. Вот два варианта подключения кнопки, с подтяжкой к VCC и GND соответственно: Как выбирается сопротивление резистора? Тут всё очень просто: при нажатии на кнопку через резистор потечёт ток, так как в любом случае замыкается цепь питание-земля. Чем выше ток, больше потери энергии и нагрев резистора, а это никому не нужно, поэтому сопротивление резистора подтяжки обычно выбирается в диапазоне 5-50 кОм. Если ставить больше – подтяжка может не обеспечить стабильный уровень сигнала на пине, а если ставить меньше – будут больше потери энергии в нагрев резистора: при сопротивлении в 1 ком через него потечёт ток величиной 5 В/1000 Ом = 5 мА, для сравнения плата Ардуино с МК в активном режиме потребляет 20-22 мА. Чаще всего для подтяжки используется резистор на 10 кОм. Как вы помните из урока о цифровых пинах, у МК AVR есть встроенные резисторы для всех GPIO, эти резисторы подключены к питанию (к VCC), то есть буквально дублируют первую схему из этого урока и позволяют не использовать внешний резистор. У микроконтроллеров другой архитектуры бывает подтяжка к GND, или вообще может не быть внутренней подтяжки. При использовании подтяжки к питанию мы получим инвертированный сигнал – функция digitalRead() вернёт 1 при отпущенной кнопке, и 0 при нажатой (при использовании нормально-разомкнутой кнопки). Давайте подключим кнопку на пин D3 (и GND):
Алгоритмы
Отработка нажатия
В большинстве реальных применений работать с текущим состоянием кнопки очень неудобно, например когда действие должно быть выполнено однократно при нажатии на кнопку, т.е. по клику. Чуть усложним конструкцию, добавив один флаг, который будет помнить состояние кнопки. Такая конструкция позволяет отслеживать нажатие и отпускание кнопки и реагировать на них однократно:
Дребезг контактов
Кнопка не идеальна, и контакт замыкается не сразу, какое-то время он “дребезжит”. Прогоняя данный алгоритм, система опрашивает кнопку и условия приблизительно за 6 мкс, то есть кнопка опрашивается 166’666 раз в секунду! Этого достаточно, чтобы получить несколько тысяч ложных срабатываний. Избавиться от дребезга контактов можно как аппаратно, так и программно: аппаратно задача решается при помощи RC цепи, то есть резистора (
1-10k) и конденсатора (
100nF). Выглядит это следующим образом:
Программно можно ввести простейший таймер нажатия, основанный на millis() , время гашения дребезга примем 100 миллисекунд. Вот так будет выглядеть код:
Рекомендуется конечно же использовать аппаратный способ, так как он не нагружает ядро лишними расчетами. В 99.99% проектов будет достаточно программного антидребезга, так то смело используйте конструкцию с millis() .
“Импульсное” удержание
В устройствах с управлением кнопкой очень часто бывает нужна возможность изменения значения как однократно кликом по кнопке, так и “автоматически” с тем же шагом – при удержании. Такой вариант реализуется очень просто, добавлением ещё одного условия в наш предыдущий алгоритм, а именно: если кнопка была нажата, но ещё не отпущена, и прошло времени больше, чем задано – условие вернёт true . В примере ниже периодичность “нажатий” при удержании настроена на 500 миллисекунд (2 раза в секунду):
Пользоваться таким кодом напрямую будет неудобно, поэтому можно “обернуть” его в класс (читай урок про классы и урок про написание библиотек).
Простейший класс кнопки
Вот так предыдущий пример можно сделать классом (мы делали это вот в этом уроке), положить его в отдельный файл (button.h) и пользоваться:
Другие возможности кнопки
Кнопка только с виду кажется простым устройством, дающим 0 и 1, но, подключив фантазию и время, можно придумать гораздо больше применений обычной кнопке. В моей библиотеке GyverButton реализовано очень много всяких интересных возможностей по работе с кнопкой, вот список:
- Работа с нормально замкнутыми и нормально разомкнутыми кнопками
- Работа с подключением PULL_UP и PULL_DOWN Опрос кнопки с программным антидребезгом контактов (настраиваемое время)
- Отработка нажатия, удерживания, отпускания, клика по кнопке (+ настройка таймаутов)
- Отработка одиночного, двойного и тройного нажатия (вынесено отдельно)
- Отработка любого количества нажатий кнопки (функция возвращает количество нажатий)
- Функция изменения значения переменной с заданным шагом и заданным интервалом по времени
- Возможность работы с “виртуальными” кнопками (все возможности библиотеки используются для матричных и резистивных клавиатур)
Подробное описание библиотеки можно почитать в заголовочном файле на странице библиотеки, также там есть много примеров.
Аналоговые клавиатуры
Аналоговые клавиатуры – достаточно глубокая тема, достойная отдельного урока (у меня его пока что нет). Максимально подробный урок-исследование можно посмотреть на сайте Codius.
Видео