![]() |
![]() |
![]() |
![]() |
Общие сведения
В этом уроке мы научимся обрабатывать состояния кнопки. Для показательности во втором и третьем примере будет использоваться светодиод, с которым мы работали в прошлом уроке.
Для этого урока нам понадобится:
Подключение
Подключим Trema-модуль Светодиод согласно таблице
| Вывод модуля | Вывод Pi Pico |
|---|---|
| Vcc | 3V3(OUT) |
| GND | GND |
| S | GP15 |
Подключим Trema-модуль Кнопку согласно таблице
| Вывод модуля | Вывод Pi Pico |
|---|---|
| Vcc | 3V3(OUT) |
| GND | GND |
| S | GP2 |

Выводим состояние кнопки в монитор последовательного порта
В следующем примере состояние кнопки считывается в цикле и выводится в монитор:
// определяем вывод к которому подключена кнопка
#define BUT_PIN 2
// создаём переменную для хранения последнего состояния кнопки
bool last_button = false;
void setup()
{
// Инициируем последовательный порт
Serial.begin(115200);
// Устанавливаем работу вывода кнопки на вход
pinMode(BUT_PIN, INPUT);
}
void loop()
{
// записываем текущее состояние кнопки
bool button = digitalRead(BUT_PIN);
// если текущее состояние кнопки не соответсвует предыдущему
if (last_button != button) {
// записываем новое состояние кнопки
last_button = button;
// если кнопка нажата, выводи информацию в последовательный порт
if (button) {
Serial.println("Кнопка нажата");
}
}
delay(100);
}
Переключаем светодиод
В данном примере мы переключаем состояние светодиода при помощи кнопки. Это простое исполнение кнопки как переключателя.
Пример:
// определяем вывод к которому подключена кнопка
#define BUT_PIN 2
// определяем вывод к которому подключён светодиод
#define LED_PIN 15
// сосдаём переменные для хранения состояния кнопки и светодиода
bool last_button = false;
bool led_state = false;
void setup()
{
// Инициируем последовательный порт
Serial.begin(115200);
// Устанавливаем работу вывода кнопки на вход
pinMode(BUT_PIN, INPUT);
// устанавливаем режим работы вывода светодиода
pinMode(LED_PIN, OUTPUT);
}
void loop()
{
// записываем текущее состояние кнопки
bool button = digitalRead(BUT_PIN);
// если состояние изменилось
if (last_button != button) {
// записывем состояние в глобальную переменную
last_button = button;
// если состояени - кнопка отжата
if (!button) {
// переключаем состояние переменной светодиода
led_state = !led_state;
// устанавливаем уровень на выводе светодиода
digitalWrite(LED_PIN, led_state);
}
}
delay(100);
}
Устранение дребезга
При нажатии или отпускании кнопка может поменять своё состояние
несколько раз в течении 50-100 миллисекунд (попробуйте убрать строчку
delay(100) из предыдущего примера и посмотрите, что
произойдёт). Это называется дребезг кнопки (bounce).
Для устранение этого в предыдущем примере мы использовали функцию
sleep. Теоретически эта функция отличается от типичного для
ардуино delay, так как она не блокирует другие задачи,
запущенные в операционной системе, если таковая имеется, но в контексте
данных уроков sleep всё же блокирует текущий поток
выполнения. Поэтому рассмотрим неблокирующее устранение дребезга.
Алгоритм данного примера кажется сложным, но на самом деле он очень прост:
- проверяем состояние кнопки
- если состояние кнопки изменилось - записываем время изменения
- продолжаем выполнять программу дальше
- если подошёл интервал проверки DEBOUNCE_MS и состояние кнопки до сих
пор отличается от записанного ранее, значит состояние кнопки
действительно изменилось
- записываем новое состояние
- если подошёл интервал проверки DEBOUNCE_MS и состояние кнопки до сих
пор отличается от записанного ранее, значит состояние кнопки
действительно изменилось
// вывод к которому подключена кнопка
#define BUT_PIN 2
// вывод к которому подключён светодиод
#define LED_PIN 15
// интервал для устранения дребезга
#define DEBOUNCE_MS 100
// интервал для вывода информации в последовательный порт
#define PRINT_INTERVAL 2000
// переменные для хранения состояний кнопки
bool button_state = false;
bool last_state = false;
// переменная для хранения состояние светодиода
bool led_state = false;
// переменные для хранения относительного времени событий
unsigned long debounce_millis, print_millis;
void setup()
{
// инициируем работу с последовательным портом
Serial.begin(115200);
// Устанавливаем работу вывода кнопки на вход
pinMode(BUT_PIN, INPUT);
// Устанавливаем работу вывода светодиода на выход
pinMode(LED_PIN, OUTPUT);
}
void loop()
{
// записываем текущее состояние кнопки
bool current_state = digitalRead(BUT_PIN);
// если состояние изменилось, записываем время изменения
if (current_state != last_state) {
debounce_millis = millis();
}
// если подошёл интервал устранения дребезга
if (millis() - debounce_millis > DEBOUNCE_MS) {
// если состояние кнопки не соответсвует записаному ранее
if (current_state != button_state) {
// записываем новое состояние
button_state = current_state;
// Если новое состояние - отжатая кнопка
if (!button_state) {
// Переключаем светодиод
led_state = !led_state;
digitalWrite(LED_PIN, led_state);
}
}
}
// Записиваем последнее состояние кнопки
last_state = current_state;
// Выводим текст через интервал
if (millis() - print_millis > PRINT_INTERVAL) {
print_millis = millis();
Serial.println("Выполняем что-то ещё, устранение дребезга кнопки не блокирует поток");
}
}





Обсуждение