Найти в Дзене
Электроника, ESP32, Arduino

Обработка дребезга в процедуре прерываний на ESP32

Оставлю это здесь, может кому-то понадобится..... Будет работать на любой плате ESP32, главное чтобы для GPIO, к которому будет подключена кнопка, была возможность активировать внутренний "подтягивающий" резистор (на ESP32 не для всех портов ввода/вывода доступна такая возможность). В этом примере кнопка подключена к GPIO1 (отладочная плата ESP32-S3-DevKitC-1). После выполнения строки кода: pinMode(buttonPin, INPUT_PULLUP); на выходе IO1 будет логическая 1. При нажатии кнопки логический 0. Пример выводит в монитор порта строку "buttonClick" при однократном нажатии на кнопку. Код: В секции setup определяется название функции (debounceButton), которая будет вызываться каждый раз при изменении состояния порта ввода/вывода buttonPin. где режим прерывания (FALLING) определяет, когда прерывание будет происходить. Другие возможные режимы: При нажатии на кнопку, состояние порта меняется c 1 на 0 (кнопка "подтягивает" выход к земле) - поэтому используется режим "FALLING". Вся магия происходит в

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

В этом примере кнопка подключена к GPIO1 (отладочная плата ESP32-S3-DevKitC-1).

Обработка дребезга контактов в прерываниях.
Обработка дребезга контактов в прерываниях.

После выполнения строки кода:

pinMode(buttonPin, INPUT_PULLUP);

на выходе IO1 будет логическая 1. При нажатии кнопки логический 0.

Пример выводит в монитор порта строку "buttonClick" при однократном нажатии на кнопку. Код:

-2

В секции setup определяется название функции (debounceButton), которая будет вызываться каждый раз при изменении состояния порта ввода/вывода buttonPin.

-3

где режим прерывания (FALLING) определяет, когда прерывание будет происходить. Другие возможные режимы:

  • RISING: Прерывание срабатывает, когда вывод переходит из низкого состояния в высокое (нарастающий фронт).
  • FALLING: Прерывание срабатывает, когда вывод переходит из высокого состояния в низкое (падающий фронт).
  • CHANGE: Прерывание срабатывает как по восходящему, так и по нисходящему фронту.

При нажатии на кнопку, состояние порта меняется c 1 на 0 (кнопка "подтягивает" выход к земле) - поэтому используется режим "FALLING".

Вся магия происходит в функции обратного вызова (ISR). Эта функция должна иметь тип данных void и не должна принимать никаких аргументов. В ней происходит изменение состояния переменной "buttonClick"

-4

После этого происходит запоминание момента времени, в который мы зафиксировали первое изменение состояния GPIO и в течении времени заданного константой:

const int timeThreshold = 100;

изменение состояния переменной "buttonClick" не производится. Константу имеет смыл подобрать опытным путем - так как кнопки все разные по конструкции, и время в течении которого контакты могут "телепаться" вызывая ложные срабатывания может оказаться разным.

В основном цикле производится опрос состояния переменной "buttonClick" и выполнение любых необходимых действий.

-5

Микроконтроллер приостанавливает выполнение основной программы и в этом примере производит изменение состояния переменной "buttonClick". Таким образом пропустить нажатие кнопки, когда микроконтроллер занят чем-то другим уже не получится.

p.s: Если в какой-то момент вы захотите отключить прерывание, вы можете использовать detachInterrupt()функцию. Эта функция принимает в качестве аргумента номер контакта GPIO, на котором было сконфигурировано прерывание.

detachInterrupt(digitalPinToInterrupt(interruptPin)); // отключить прерывание

Резюме:

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

Когда происходит событие, которое генерирует прерывание, основная программа временно останавливается и выполняется функция обратного вызова . После завершения функции обратного вызова основная программа продолжает свое выполнение.

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

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

Код примера доступен по этой ссылке:

ESP32_interrupts_Button.zip

Оглавление канала тут:

Всем удачи!