Дребезг кнопки. Урок 2.3. Ардуино

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

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

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

Подключаем кнопку. Урок 2.2. Ардуино

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

Так что, сегодня рассмотрим проблему дребезга кнопки и программных способах её решения.

Чтобы выполнить этот урок нам понадобятся.

  • Ардуино UNO
  • Макетная плата
  • Перемычки
  • Резистор номиналом 10 кОм
  • Кнопка
  • Кабель USB

Дребезг кнопки

Обычно кнопка представляет собой механическое устройство с пружиной. При нажатии на кнопку контакт срабатывает не сразу, а на протяжении нескольких миллисекунд меняется от 0 к 1 несколько раз. Соответственно, нельзя просто прочитать значение на контакте ардуино, необходимо избавиться от этого «дребезга».

Дребезг кнопки
Дребезг кнопки

Устранить этот эффект можно как аппаратным путем, так и программным. Но поскольку мы имеем в своем распоряжении ардуино, рассмотрим программу, которая решает эту проблему. Тем более, что такая программа уже есть в стандартной библиотеке ардуино ide.

Debounce.ino

Откроем программу из меню File — Examples — Digital — Debounce

Программа уже имеет исчерпывающий комментарий прямо в тексте, но рассмотрим как все работает.

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

const int buttonPin = 2;    // Подключим кнопку к контакту 2
const int ledPin = 13;      // Для светодиода используем контакт 13

int ledState = HIGH;         // Состояние светодиода
int buttonState;             // Состояние кнопки
int lastButtonState = LOW;   // Предыдущее состояние кнопки

unsigned long lastDebounceTime = 0;  // Время нажатия кнопки
unsigned long debounceDelay = 50;    // Время задержки для проверки состояния кнопки

Здесь мы ввели переменные buttonState и lastButtonState для проверки и сравнения состояния кнопки. Когда кнопка будет нажата, мы сравним ее состояние с переменной lastButtonState. И если состояние будет отличаться от ранее сохраненного, счетчик lastDebounceTime будет сброшен.

Переменные lastDebounceTime и debounceDelay используют тип unsigned long потому, что время исчисляется в миллисекундах и простого int будет недостаточно.

В функции setup() настроим состояние пинов и светодиода. Пин кнопки на чтение, пин светодиода на вывод, напряжение на пин светодиода = HIGH

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

Далее в цикле loop() будем постоянно проверять состояние кнопки. И если состояние в момент проверки будет отличаться от предыдущего, запустим процесс повторной проверки.

void loop() {

  int reading = digitalRead(buttonPin);

  if (reading != lastButtonState) {
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {

    if (reading != buttonState) {
      buttonState = reading;

      if (buttonState == HIGH) {
        ledState = !ledState;
      }
    }
  }

  digitalWrite(ledPin, ledState);

  lastButtonState = reading;
}

Здесь мы видим новую функцию millis(). Она возвращает количество миллисекунд с момента начала работы программы на плате Arduino. Это количество сбрасывается в 0, из-за переполнения значения, примерно через 50 дней непрерывной работы.

Принципиальная схема подключения кнопки
Принципиальная схема подключения кнопки

Итак, в цикле loop() мы постоянно считываем напряжение на пине 2 и записываем его в переменную reading.

Если reading не равно предыдущему состоянию кнопки, то счетчику lastDebounceTime присваивается значение функции millis().

Через 50 миллисекунд значение переменной reading сравнивается с текущим состоянием кнопки и, если они не равны, то текущее состояние кнопки приравнивается к reading.

И, наконец, если кнопка нажата, то состояние светодиода меняется на противоположное.

После этого на пин светодиода посылаем состояние, которое мы определили, а предыдущее состояние кнопки сохраняем для проверки в следующем витке цикла.

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

Подавление дребезга кнопки
Подавление дребезга кнопки

Полный текст программы

// constants won't change. They're used here to set pin numbers:
const int buttonPin = 2;    // the number of the pushbutton pin
const int ledPin = 13;      // the number of the LED pin

// Variables will change:
int ledState = HIGH;         // the current state of the output pin
int buttonState;             // the current reading from the input pin
int lastButtonState = LOW;   // the previous reading from the input pin

// the following variables are unsigned longs because the time, measured in
// milliseconds, will quickly become a bigger number than can be stored in an int.
unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers

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

  // set initial LED state
  digitalWrite(ledPin, ledState);
}

void loop() {
  // read the state of the switch into a local variable:
  int reading = digitalRead(buttonPin);

  // check to see if you just pressed the button
  // (i.e. the input went from LOW to HIGH), and you've waited long enough
  // since the last press to ignore any noise:

  // If the switch changed, due to noise or pressing:
  if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer than the debounce
    // delay, so take it as the actual current state:

    // if the button state has changed:
    if (reading != buttonState) {
      buttonState = reading;

      // only toggle the LED if the new button state is HIGH
      if (buttonState == HIGH) {
        ledState = !ledState;
      }
    }
  }

  // set the LED:
  digitalWrite(ledPin, ledState);

  // save the reading. Next time through the loop, it'll be the lastButtonState:
  lastButtonState = reading;
}

Заключение

В этот раз мы рассмотрели программу Debounce из стандартной библиотеки программ ардуино ide. Она позволяет избавиться от дребезга кнопки используя программу ардуино. В следующий раз мы оформим эту программу в отдельную функцию и будем использовать ее для управления группы светодиодов.

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

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