ESP32 Arduino IDE. Подавление дребезга контактов кнопки.

В данном уроке рассматривается проблема дребезга контактов, возникающая при использовании механических кнопок и переключателей с микроконтроллером ESP32. Описаны причины возникновения дребезга, его влияние на работу микроконтроллера и представлены программные методы его устранения. Статья ориентирована на техническую аудиторию и содержит примеры кода на языке C/C++ для среды разработки Arduino IDE. Дребезг контактов это паразатный эффект, усложняющий разработку и отладку проекта.

Проблема дребезга контактов ESP32 Arduino IDE.

дребезг кнопки посмотрим рисунок,При нажатии или отпускании механической кнопки (или переключении тумблера) ее состояние не изменяется мгновенно с LOW на HIGH (или наоборот). Вместо этого, из-за физических свойств материалов и конструкции кнопки, происходит кратковременное многократное замыкание и размыкание контакта. Это явление называется "дребезгом контактов" (chattering). В результате микроконтроллер (например, ESP32) может воспринять одно физическое нажатие как несколько последовательных нажатий, что приводит к некорректной работе устройства.

Схема подключения ESP32 и кнопки.

Схема с кнопкой для монтажа на печатную плату (PCB-mount).

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

Пример 1: Чтение состояния кнопки без подавления дребезга.

/*
*  ESP32 Arduino IDE. Подавление дребезга контактов кнопки.
* https://arduino-tex.ru/news/204/esp32-podavlenie-drebezga-kontaktov-knopki.html
*/
#define BUTTON_PIN 21  // GIOP21 пин подключен к кнопке
// Переменные, которые будут изменяться:
int lastState = LOW;  // предыдущее состояние от пина входа
int currentState;     // текущее состояние считываемое с пина
void setup() {
  // инициализация последовательного соединения на скорости 115200 бит в секунду:
  Serial.begin(115200);
  // инициализировать пин кнопки как вход с подтяжкой,
  // пин входа с подтяжкой будет иметь состояние HIGH когда переключатель открыт и LOW когда переключатель закрыт.
  pinMode(BUTTON_PIN, INPUT_PULLUP);
}
void loop() {
  // считать состояние переключателя/кнопки:
  currentState = digitalRead(BUTTON_PIN);
  if (lastState == HIGH && currentState == LOW)
    Serial.println("Кнопка нажата");
  else if (lastState == LOW && currentState == HIGH)
    Serial.println("Кнопка отпущена");
  // сохранить последнее состояние
  lastState = currentState;
}

В этом примере при каждом изменении состояния кнопки (нажатие или отпускание) в последовательный порт выводится соответствующее сообщение. Однако, из-за дребезга контактов, при одном нажатии можно увидеть несколько сообщений "Кнопка нажата" и "Кнопка отпущена".

После загрузки откройте Монитор порта на скорости 115200.

Пример 1: Чтение состояния кнопки без подавления дребезга.

Пример 2: Чтение состояния кнопки с подавлением дребезга (программный метод).

/*
*  ESP32 Arduino IDE. Подавление дребезга контактов кнопки.
* https://arduino-tex.ru/news/204/esp32-podavlenie-drebezga-kontaktov-knopki.html
*/
#define BUTTON_PIN 21     // Пин GIOP21, подключенный к кнопке
#define DEBOUNCE_TIME 50  // Время подавления дребезга в миллисекундах, увеличьте это время, если дребезг остается
// Переменные, которые будут изменяться:
int lastSteadyState = LOW;       // Предыдущее устойчивое состояние пина кнопки
int lastFlickerableState = LOW;  // Предыдущее состояние пина кнопки, которое может быть нестабильным (дребезг)
int currentState;                // Текущее состояние пина кнопки
// Следующие переменные имеют тип unsigned long, потому что время, измеряемое в
// миллисекундах, быстро станет большим числом, которое не может быть сохранено в int.
unsigned long lastDebounceTime = 0;  // Время последнего изменения состояния кнопки
void setup() {
  // Инициализация последовательной связи на скорости 115200 бит в секунду:
  Serial.begin(115200);
  // Инициализация пина кнопки как входа с подтяжкой (pull-up):
  // Вход с подтяжкой будет иметь состояние HIGH, когда переключатель разомкнут, и LOW, когда переключатель замкнут.
  pinMode(BUTTON_PIN, INPUT_PULLUP);
}
void loop() {
  // Чтение состояния переключателя/кнопки:
  currentState = digitalRead(BUTTON_PIN);
  // Проверка, была ли только что нажата кнопка
  // (т.е. вход изменился с LOW на HIGH), и прошло ли достаточно времени
  // с момента последнего нажатия, чтобы игнорировать любой шум:
  // Если состояние переключателя/кнопки изменилось из-за шума или нажатия:
  if (currentState != lastFlickerableState) {
    // Сброс таймера подавления дребезга
    lastDebounceTime = millis();
    // Сохранение последнего нестабильного состояния
    lastFlickerableState = currentState;
  }
  if ((millis() - lastDebounceTime) > DEBOUNCE_TIME) {
    // Если с момента последнего изменения прошло больше времени, чем DEBOUNCE_TIME,
    // то текущее значение считавается устойчивым.
    // Если состояние кнопки изменилось:
    if (lastSteadyState == HIGH && currentState == LOW)
      Serial.println("Кнопка нажата");
    else if (lastSteadyState == LOW && currentState == HIGH)
      Serial.println("Кнопка отпущена");
    // Сохранить последнее устойчивое состояние
    lastSteadyState = currentState;
  }
}

В этом примере используется метод "таймера". При обнаружении изменения состояния кнопки запускается таймер ( lastDebounceTime = millis(); ). Если в течение заданного времени (DEBOUNCE_TIME, обычно 50-100 мс) состояние кнопки остается стабильным, то считается, что дребезг закончился, и новое состояние кнопки регистрируется.

После загрузки откройт Монитор порта на скорости 115200.

Пример 2: Чтение состояния кнопки с подавлением дребезга (программный метод).

Использование библиотеки EZButton для упрощения работы с кнопками.

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

Использование библиотеки EZButton для упрощения работы с кнопками.

Пример 3: Использование библиотеки EZButton (одна кнопка).

/*
*  ESP32 Arduino IDE. Подавление дребезга контактов кнопки.
* https://arduino-tex.ru/news/204/esp32-podavlenie-drebezga-kontaktov-knopki.html
*/
#include <EZButton.h>  // Подключение библиотеки EZButton для упрощения работы с кнопкой
#define DEBOUNCE_TIME 50  // Время подавления дребезга в миллисекундах, увеличьте это время, если дребезг все еще присутствует
#define BTN_1_PIN 21      //пину GPIO21
#define BTN_1 0
void ReadButtons(bool *states, int num) {
  //Read all button states however you want
  states[BTN_1] = !digitalRead(BTN_1_PIN);
}
//Считывайте состояния кнопок с помощью функции 'ReadButtons'
//Порог удержания: 500 мс
//Интервал удержания: 300 мс
//Время ожидания: 50 мс  DEBOUNCE_TIME
EZButton _ezb(1, ReadButtons, 1000, 200, DEBOUNCE_TIME);
void setup() {
  Serial.begin(115200);  // Инициализация последовательного соединения на скорости 115200 бит/с
  pinMode(BTN_1_PIN, INPUT_PULLUP);
  //subscribe to needed events
  _ezb.Subscribe(BTN_1, Btn1Pressed, PRESSED);
  _ezb.Subscribe(BTN_1, Btn1Released, RELEASED);
}
void loop() {
  _ezb.Loop(); // Необходимо вызывать функцию loop() для обработки состояний кнопки
}
void Btn1Pressed() { // Проверка, была ли кнопка нажата (переход из отпущенного состояния в нажатое)
  Serial.println("Кнопка нажата"); // Вывод сообщения в последовательный порт
}
void Btn1Released() { // Проверка, была ли кнопка отпущена (переход из нажатого состояния в отпущенное)
  Serial.println("Кнопка отпущена"); // Вывод сообщения в последовательный порт
}

После загрузки откройте Монитор порта на скорости 115200.

Пример 3: Использование библиотеки EZButton (одна кнопка).

Пример 4: Использование библиотеки EZButton (несколько кнопок).

Использование библиотеки EZButton (несколько кнопок).

/*
*  ESP32 Arduino IDE. Подавление дребезга контактов кнопки.
* https://arduino-tex.ru/news/204/esp32-podavlenie-drebezga-kontaktov-knopki.html
*/
#include <EZButton.h>  // Подключение библиотеки ezButton для упрощения работы с кнопкой
#define DEBOUNCE_TIME 50  // Время подавления дребезга в миллисекундах, увеличьте это время, если дребезг все еще присутствует
#define BTN_1_PIN 21  //пину GPIO21
#define BTN_2_PIN 22  //пину GPIO22
#define BTN_3_PIN 23  //пину GPIO23
#define BTN_1 0
#define BTN_2 1
#define BTN_3 2
void ReadButtons(bool *states, int num) {
  //Read all button states however you want
  states[BTN_1] = !digitalRead(BTN_1_PIN);
  states[BTN_2] = !digitalRead(BTN_2_PIN);
  states[BTN_3] = !digitalRead(BTN_3_PIN);
}
//Считывайте состояния кнопок с помощью функции 'ReadButtons'
//Порог удержания: 500 мс
//Интервал удержания: 300 мс
//Время ожидания: 50 мс  DEBOUNCE_TIME
EZButton _ezb(3, ReadButtons, 1000, 200, DEBOUNCE_TIME);
void setup() {
  Serial.begin(115200);  // Инициализация последовательного соединения на скорости 115200 бит/с
  pinMode(BTN_1_PIN, INPUT_PULLUP);
  pinMode(BTN_2_PIN, INPUT_PULLUP);
  pinMode(BTN_3_PIN, INPUT_PULLUP);
  //subscribe to needed events
  _ezb.Subscribe(BTN_1, Btn1Pressed, PRESSED);
  _ezb.Subscribe(BTN_1, Btn1Released, RELEASED);
  _ezb.Subscribe(BTN_2, Btn2Pressed, PRESSED);
  _ezb.Subscribe(BTN_2, Btn2Released, RELEASED);
  _ezb.Subscribe(BTN_3, Btn3Pressed, PRESSED);
  _ezb.Subscribe(BTN_3, Btn3Released, RELEASED);
}
void loop() {
  _ezb.Loop();  // Необходимо вызывать функцию loop() для обработки состояний кнопки
}
void Btn1Pressed() {                // Проверка, была ли кнопка нажата (переход из отпущенного состояния в нажатое)
  Serial.println("Кнопка 1 нажата");  // Вывод сообщения в последовательный порт
}
void Btn1Released() {                 // Проверка, была ли кнопка отпущена (переход из нажатого состояния в отпущенное)
  Serial.println("Кнопка 1 отпущена");  // Вывод сообщения в последовательный порт
}
void Btn2Pressed() {                // Проверка, была ли кнопка нажата (переход из отпущенного состояния в нажатое)
  Serial.println("Кнопка 2 нажата");  // Вывод сообщения в последовательный порт
}
void Btn2Released() {                 // Проверка, была ли кнопка отпущена (переход из нажатого состояния в отпущенное)
  Serial.println("Кнопка 2 отпущена");  // Вывод сообщения в последовательный порт
}
void Btn3Pressed() {                // Проверка, была ли кнопка нажата (переход из отпущенного состояния в нажатое)
  Serial.println("Кнопка 3 нажата");  // Вывод сообщения в последовательный порт
}
void Btn3Released() {                 // Проверка, была ли кнопка отпущена (переход из нажатого состояния в отпущенное)
  Serial.println("Кнопка 3 отпущена");  // Вывод сообщения в последовательный порт
}

После загрузки откройте Монитор порта на скорости 115200.

Пример 4: Использование библиотеки EZButton (несколько кнопок).

Дополнительные замечания:

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

Заключение.

Дребезг контактов – распространенная проблема при работе с механическими кнопками и переключателями. Программные методы подавления дребезга, описанные в данной статье, позволяют эффективно устранить этот эффект и обеспечить надежную работу устройства на базе микроконтроллера ESP32. Использование библиотеки EZButton значительно упрощает реализацию подавления дребезга, особенно при работе с несколькими кнопками.

Дополнительная информация к данному уроку:


Понравился урок: Как избежать дребезга контактов на ESP32: полное руководство? Не забудь поделиться с друзьями в соц. сетях.

А также подписаться на наш канал на YouTube, вступить в группу Вконтакте, в Telegram.

Спасибо за внимание!

Технологии начинаются с простого!

Фотографии к статье

Файлы для скачивания

Пример 1: Чтение состояния кнопки без подавления дребезга Пример 1: Чтение состояния кнопки без подавления дребезга.ino3 Kb 18 Скачать
Пример 2: Чтение состояния кнопки с подавлением дребезга Пример 2: Чтение состояния кнопки с подавлением дребезга.ino2 Kb 19 Скачать
Пример 3: Использование библиотеки EZButton (одна кнопка) Пример 3: Использование библиотеки EZButton (одна кнопка).ino4 Kb 18 Скачать
Пример 4: Использование библиотеки EZButton (несколько кнопок) Пример 4: Использование библиотеки EZButton (несколько кнопок).ino3 Kb 18 Скачать

Комментарии

Ваше Имя*


Разработка проектов