15 июня 2012 г.

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

Дребезг контактов - крайне неприятная вещь, от которой нужно избавляться. Можно это делать софтверно. К счастью, нам не придется самостоятельно ручками писать алгоритм в Arduino IDE, поскольку для нас разработчики уже написали библиотеку. Знакомимся с Bounce.



Дребезг

Когда мы нажимаем на кнопку, мы ожидаем от нее, что она нам что-то включит, и это будет радостно работать. То есть сигнал будет вести себя так:


Но все далеко не так радужно. Из-за дребезга при нажатии кнопки сигнал ведет себя вот так:

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

Дребезг можно подавлять как хардверно, так и софтверно. Распространены два программных алгоритма подавления дребезга.
Тупой алгоритм заключается в простой задержке срабатывая на несколько сот микросекунд после нажатия кнопки. Этот алгоритм тормозной и не исключает случайного нажатия.
Продвинутый алгоритм считает время нахождения кнопки в положении "нажато". Если это время больше некоторого значения, то кнопка считается действительно нажатой. Как только кнопка меняет свое состояние, счетчик обнуляется.
С Arduino нам можно не размышлять об этом, а использовать библиотеку Bounce.

Библиотека Bounce

Библиотека Bounce предназначена для подавления дребезга. Она предоставляет нам в пользование замечательный класс Bounce, в котором мы можем создавать объекты.

Сам объект выглядит так:
Bounce (byte pin, unsugned long debounce_interval),
где pin - это номер пина Arduino, на котором сидит кнопка, а debounce_interval - время дребезга.

Полезные функции в этом классе:

int update() - проверка смены состояния, возвращает 1, если состояние пина изменилось;
void interval(unsigned long interval) - изменяет время дребезга (в мс);
int read() - читает состояние пина;
void write(int state) - устанавливает значение пина;
void rebounce(unsignet long interval) - заставляет пин менять состояние через промежуток времени, указанный в interval, даже если на самом деле оно не меняется;
unsigned long duration(void) - возвращает время в мс, в которое пин был в текущем состоянии;
bool risingEdge() - возвращает 1 во время первого чтения, если состояние пина сменилось с 0 на 1;
bool fallingEdge() - возвращает 1 во время первого чтения, если состояние пина сменилось с 1 на 0.

Библиотечку качаем отсюда. Распаковываем это безобразие в Папку_Arduino/libraries.

Собираем схему

Кнопка при нажатии соединяет две ее левые ноги с двумя правыми. Левую ее ногу посадим на +5V, а правую подключим к пину 2. Пин 2 также должен быть притянут к земле через резистор. Светодиод подключаем к пину 8 (мне просто так захотелось) через ограничивающий резистор.



Пишем скетч

Все очень просто:



//подключаем библиотеку Bounce
#include <Bounce.h>
//дефайним значения пинов с кнопкой и со светодиодом
#define BUTTON 2
#define LED 8
//создаем объект класса Bounce. Указываем пин, к которому подключена кнопка, и время дребезга в мс.
Bounce bouncer = Bounce(BUTTON,5); 

//задаем начальное состояние светодиода "выключен"
int ledValue = LOW;



void setup() {
  //определяем режимы работы пинов
  pinMode(BUTTON,INPUT);
  pinMode(LED,OUTPUT);
}



void loop() {
  //если сменилось состояние кнопки
  if ( bouncer.update() ) {
    //если считано значение 1
    if ( bouncer.read() == HIGH) {
     //если свет был выключен, будем его включать
     if ( ledValue == LOW ) {
       ledValue = HIGH;
     //если свет был включен, будем выключать
     } else {
       ledValue = LOW;
     }
     //записываем значение вкл/выкл на пин со светодиодом 
     digitalWrite(LED,ledValue);
    }
  }
}



Наслаждаемся

Никакого дребезга!

4 комментария:

  1. На LaunchPad из-под Energia тоже заработало))
    #include
    Bounce b1 = Bounce(5,10);
    Bounce b2 = Bounce(11,10);
    const int i1 = 5;
    const int i2 = 11;
    const int q1 = 2;
    const int q2 = 14;
    int s1 = 0;
    int s2 = 0;
    void setup() {
    pinMode(i1,INPUT_PULLUP);
    pinMode(q1,OUTPUT);
    pinMode(i2,INPUT_PULLUP);
    pinMode(q2,OUTPUT);
    }
    void loop() {
    if ( b1.update() ) {if ( b1.read() == 0) {s1=!s1; digitalWrite(q1,s1);}}
    if ( b2.update() ) {if ( b2.read() == 0) {s2=!s2; digitalWrite(q2,s2);}}
    }

    ОтветитьУдалить
    Ответы
    1. Супер! А вы лончпэд под виндой запускали или под линухой? У меня две платки валяются, под линухом чёт не запустились даже с пинка

      Удалить
  2. Куда-то схавалось Bounce.h в <> после #include

    ОтветитьУдалить
  3. Кнопка с 5 ножки включает красный светодиод со 2 ножки, а замыкание 11 ножки на землю (там рядом) включает зеленый светодиод с 14 ножки.

    ОтветитьУдалить