Ардуино тактовая кнопка

Причины дребезга контактов

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

Чаще всего с дребезгом сталкиваются при подключении кнопки, но почему так происходит? Вот пример при котором это будет:

void loop() { if (digitalRead(PIN_BUTTON)) { Serial.println(«1»); } else { Serial.println(«0»); } }

Кнопка – это один из видов дополнительных модулей под Ардуино, служащих для ввода информации. В основе работы такого механизма лежит простой алгоритм работы – вы надавливаете на механический переключатель, он смыкает контакты, лежащие под оболочкой, и запускается какой-нибудь скрипт. Таким образом, при помощи давления, которое формируется при нажатии, происходит схождение или расхождение металлических пластин, которые и выступают наиболее популярными триггерами.

Программисту остается лишь написать код, который будет как-то засекать данное событие и выполнять определённые действия.

Пример программного решения проблемы:

int currentValue, prevValue; void loop() { currentValue = digitalRead(PIN_BUTTON); if (currentValue != prevValue) { // Что-то изменилось, здесь возможна зона неопределенности // Делаем задержку delay(10); // А вот теперь спокойно считываем значение, считая, что нестабильность исчезла currentValue = digitalRead(PIN_BUTTON); } prevValue = currentValue; Serial.println(currentValue); }

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

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

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

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

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

Ошибки дребезга кнопки

Проще всего заметить основные проблемы, которые доставляет дребезг контактов на Аrduino, на непосредственном проекте, в котором прописан код для обработки события нажатия кнопки.

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

Этого времени вполне достаточно, чтобы код успел отреагировать на «шумы» при нажатии кнопки. А теперь представьте себе ситуацию – в вашей программе прописано запускать процесс, как только кнопка нажимается, и выключать, как только её отпускают. Для регистрации обоих событий применяется перепад напряжения. В результате цикл будет несколько раз запускать и закрывать функции, пока происходит дребезг контактов. Если всё это происходит ещё и в многопоточном режиме, то нагрузку в стеке микроконтроллера не сложно вообразить.

Борьба с дребезгом кнопки с помощью библиотеки Ардуино

Мы поняли, что проблема чисто аппаратная, но, как ни парадоксально, со стороны «железа» её сложно исправить. Вы же не можете лично под микроскопом отполировать контакты, да ещё и просить пользователя нажимать на кнопку лишь с одной силой и на постоянной основе.

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

А всё на самом деле просто, ведь перед нами стоит такой перечень условий:

  1. На срок до 10-100 мС, система пребывает в нестабильном состоянии и может выдавать ошибки.
  2. Далее идет срок от 1 до 2-ух секунд, что в 10 раз больше от предыдущего, пока кнопку нажимают.
  3. И вновь, под конец, 10-100 мС, длится дребезг.

Все, кто работал с многопоточностью на Си, уже заприметили очевидные триггеры, от которых мы и будем отталкиваться. Дело в том, что для предотвращения проблем по программной части нам достаточно выдержать тишину на каком-то промежутке времени, пока дребезг не пройдет, то есть достаточно воспользоваться уже готовой функцией delay().

Борьба с дребезгом библиотекой «bounce»

Как вариант борьбы с дребезгом в Ардуино — библиотека Bounce, которую можно .

Методы библиотеки:

Название Назначение
Bounce() инициализация объекта «Bounce»;
void interval (мсек) устанавливает время задержки в миллисекундах;
void attach (номерПина) задаёт вывод, к которому подключена кнопка;
int update() обновляет объект и возвращает true, если состояние пина изменилось, и false в противном случае;
int read() считывает новое состояние пина.

Сам код.

#include <Bounce2.h>; #define PIN_BUTTON 2 #define PIN_LED 13 // Создаем объект Bounce debouncer = Bounce(); void setup() { // Устаовили тип пина pinMode(PIN_BUTTON, INPUT_PULLUP); // Даем бибилотеке знать, к какому пину мы подключили кнопку debouncer.attach(PIN_BUTTON); debouncer.interval(5); // Интервал, в течение которого мы не буем получать значения с пина //Setup the LED : pinMode(PIN_LED, OUTPUT); } void loop() { // Даем объекту бибилотеки знать, что надо обновить состояние — мы вошли в новый цкил loop debouncer.update(); // Получаем значение кнопки int value = debouncer.read(); // Теперь мы точно знаем, в каком состоянии находится наша кнопка if ( value == LOW ) { digitalWrite(PIN_LED, HIGH ); } else { digitalWrite(PIN_LED, LOW ); } }

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

Ваш e-mail не будет опубликован. Обязательные поля помечены *