Найти тему
170 подписчиков

ℹ️ Повторяем пройденное и вспоминаем забытое!


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

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

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

Ссылка на проект в TinkerCad: https://www.tinkercad.com/things/eFYKEbV4XB0-arduinobutton

// Определение пина для кнопки и светодиода
#define BUTTON_PIN 2
#define LED_PIN 3

// Глобальные переменные для отслеживания состояния кнопки и времени последнего нажатия
uint8_t buttonState = 0; // Текущее состояние кнопки (0 - не нажата, 1 - нажата)
uint8_t buttonPressed = 0; // Флаг, указывающий была ли кнопка нажата (0 - нет, 1 - да)
uint32_t buttonTimer = 0; // Таймер для отслеживания времени последнего изменения состояния кнопки

// Функция для переключения состояния светодиода
void buttonFunction(){
// Читаем текущее состояние светодиода и устанавливаем противоположное значение
digitalWrite(LED_PIN, !digitalRead(LED_PIN));
}

// Функция для управления состоянием кнопки и вызова функции buttonFunction при ее нажатии
void buttonControl(){
// Читаем состояние кнопки с инверсией результат (с учетом INPUT_PULLUP, когда нажатое состояние будет 0)
buttonState = !digitalRead(BUTTON_PIN); // нажатое состояние - 1

// Проверяем, прошло ли достаточно времени с момента последнего изменения состояния кнопки
if (millis() - buttonTimer > 50) {
// Если кнопка была нажата и не была вызвана функция
if (!buttonPressed and buttonState){
buttonTimer = millis();
buttonFunction(); // Вызываем функцию для переключения светодиода
buttonPressed = 1; // Устанавливаем флаг, что кнопка была нажата
}
// Когда отпустили кнопку
else if (buttonPressed and !buttonState){
buttonPressed = 0; // Сбрасываем флаг нажатия кнопки
}
}
}

// Настройка начальных параметров
void setup()
{
pinMode(LED_PIN, OUTPUT); // Устанавливаем пин светодиода как выход
pinMode(BUTTON_PIN, INPUT_PULLUP); // Устанавливаем пин кнопки как вход с подтяжкой к питанию
}

// Основной цикл программы
void loop()
{
buttonControl(); // Вызываем функцию управления кнопкой
}
2 минуты