Arduino:Примеры/Debounce

Материал из Онлайн справочника
Перейти к навигацииПерейти к поиску

Перевод: Максим Кузьмин
Проверка/Оформление/Редактирование: Мякишев Е.А.


Антидребезг [1]

Данный пример демонстрирует, как программным путем обойти такое явление как дребезг контактов при нажатии на кнопку (другими словами, ложные повторные нажатия). Для этого программе даются инструкции, чтобы она дважды за короткий промежуток времени проверяла, действительно ли кто-то нажал на кнопку или все же нет – этот способ называется антидребезгом. Если им не воспользоваться, программа будет считывать одно единственное нажатие на кнопку как множество разных нажатий. Отслеживание времени в данном примере будет осуществляться при помощи функции millis().

Необходимое оборудование

Цепь

Рис. 1. Плата Arduino с подключенной кнопкой.
Рис. 1. Плата Arduino с подключенной кнопкой.

Схема

Рис. 2. Схема подключения кнопки к плате Arduino
Рис. 2. Схема подключения кнопки к плате Arduino

Код

Код ниже основан на антидребезге от Лимор Фрид, но мы немного переиначили логику ее программы. В ее примере при нажатии на кнопку функция возвращает значение LOW, а если кнопку отпустить, то HIGH. У нас же наоборот: нажимаем кнопку – получаем HIGH, отпускаем – получаем LOW.

/* 
 Антидребезг
 
Каждый раз, когда входной контакт переключается из LOW в HIGH (например, из-за нажатия на кнопку), 
выходной контакт переключается из LOW в HIGH или из HIGH в LOW. 
Чтобы устранить антидребезг (другими словами, чтобы подавить «шум»), 
между этими переключениями ставится небольшая задержка.

 Цепь:
 * светодиод подсоединен к «земле» и 13-му контакту 
 * кнопка подсоединена ко 2-му и 5-вольтовому контактам
 * 10000-омовый резистор подсоединен к «земле» и 2-му контакту 
 
 * Примечание: На большинстве плат Arduino уже есть светодиод, подсоединенный у 13-му контакту. 
   То есть, если ваша Arduino именно такая, то для этого примера 
никаких дополнительных компонентов вам не требуется.

 
Создан 21 ноября 2006 Дэвидом Э. Мэллисом (David A. Mellis),
модифицирован 30 августа 2011 Лимор Фрид (Limor Fried),
еще раз модифицирован 28 декабря 2012 Майком Уолтерсом (Mike Walters).
 
 Данный пример кода не защищен авторским правом.
 
 http://www.arduino.cc/en/Tutorial/Debounce
 */

// Тут вписываем константы – это постоянные значения. 
// Используем их, чтобы задать номера контактов: 
const int buttonPin = 2;    // номер контакта для кнопки 
const int ledPin = 13;      // номер контакта для светодиода 

// Тут вписываем переменные – это значения, которые изменятся:
int ledState = HIGH;         // текущее состояние выходного контакта 
int buttonState;             // результат текущего считывания с входного контакта 
int lastButtonState = LOW;   // результат предыдущего считывания с входного контакта 

// для нижеследующих переменных будет использован тип данных long,
// поскольку время измеряется в миллисекундах, 
// и получившаяся цифра слишком велика, 
// чтобы уместить ее в int. 
long lastDebounceTime = 0;  // время, когда выходной контакт был переключен в последний раз 
long debounceDelay = 50;    // время антидребезга; если выходной контакт продолжает дребезжать – увеличиваем это время 

void setup() {
  pinMode(buttonPin, INPUT);
  pinMode(ledPin, OUTPUT);

// задаем начальное состояние светодиода
  digitalWrite(ledPin, ledState);
}

void loop() {
  // записываем состояние кнопки в локальную переменную:
  int reading = digitalRead(buttonPin);

  // проверяем, нажата ли кнопка
  // (т.е. не перешло ли значение входного контакта из LOW в HIGH),
  // и ждем некоторое время, не обращая внимание на дребезг:

  // если состояние кнопки поменялось 
  // (будь причиной хоть дребезг, хоть реальное нажатие на кнопку):
  if (reading != lastButtonState) {
    // сбрасываем таймер антидребезга
    lastDebounceTime = millis();
  } 
  
  if ((millis() - lastDebounceTime) > debounceDelay) {
    // каким бы ни было время дребезга, 
    // оно все же продлилось дольше, чем время антидребезга, 
    // поэтому примем его за текущее состояние: 

    // и если состояние кнопки изменилось:
    if (reading != buttonState) {
      buttonState = reading;

      // переключаем светодиод только в том случае,
      // если новое состояние кнопки равно HIGH
      if (buttonState == HIGH) {
        ledState = !ledState;
      }
    }
  }
  
  // задаем состояние светодиода:
  digitalWrite(ledPin, ledState);

  // записываем результат считывания.
  // в следующий раз при прохождении через главный цикл этот результат будет в переменной lastButtonState:
  lastButtonState = reading;
}

См.также

  1. pinMode()
  2. digitalWrite()
  3. digitalRead()
  4. if()
  5. millis()
  6. DigitalReadSerial
  7. Blink
  8. Button State Change

Внешние ссылки