Как бороться с дребезгом контактов в Ардуино?

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

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

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

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

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

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, которую можно скачать на Github.

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

Название Назначение
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 );
  }
}

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

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

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

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

25 июля 2018 в 18:29 | Обновлено 7 ноября 2020 в 01:20 (редакция)
Опубликовано:
Статьи,

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

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

Adblock
detector