Общие сведения
В этом уроке мы научимся обрабатывать состояния кнопки. Для показательности во втором и третьем примере будет использоваться светодиод, с которым мы работали в прошлом уроке.
Для этого урока нам понадобится:
Для работы данных примеров в Pi Pico необходимо загрузить прошивку MicroPython и установить Thonny IDE, о том как это сделать можно прочитать в этой статье: /page/pi-pico-python-ide
Подключение
Подключим Trema-модуль Светодиод согласно таблице
| Вывод модуля | Вывод Pi Pico |
|---|---|
| Vcc | 3V3(OUT) |
| GND | GND |
| S | GP15 |
Подключим Trema-модуль Кнопку согласно таблице
| Вывод модуля | Вывод Pi Pico |
|---|---|
| Vcc | 3V3(OUT) |
| GND | GND |
| S | GP2 |

Выводим состояние кнопки в оболочку
В этом примере, как и в предыдущем уроке мы создаём объект вывода (пина) Pi Pico, но на этот раз вместо назначения его на выход Pin.OUT мы назначаем ему режим работы на вход:
Копировать1button = Pin("GP2", mode = Pin.IN)
В этом состоянии вывод принимает высокое входное сопротивление из него практически не выходит ток, зато мы можем понять какое на нём напряжение, логической единицы (максимальное напряжение относительно GND) или логического нуля (минимальное напряжение относительно GND).
В переменную last_state мы сохраняем текущее состояние кнопки:
Копировать1last_state = button.value()
Функция print выводит текст в оболочку:
Копировать1print("Кнопка не нажата")
В следующем примере состояние кнопки считывается в цикле и выводится в оболочку:
Копировать12345678910111213141516171819202122232425262728293031`# Подключаем модуль для работы с выводами from machine import Pin
Подключаем функцию сна (задержки)
from time import sleep
Создаём объект кнопки, передавая в конструктор номер вывода и режим работы
button = Pin("GP2", Pin.IN)
Сохраняем текущее состояние кнопки
last_state = button.value()
Бесконечный цикл
while True:
Читаем состояние кнопки
button_state = button.value()
Если состояние изменилось
if button_state != last_state:
Сохраняем новое состояние
last_state = button_state
Выводим состояние в оболочку
if button_state: print("Кнопка нажата") else: print("Кнопка не нажата")
Ждём сто миллисекунд
sleep(.1)`
Переключаем светодиод
В данном примере мы переключаем состояние светодиода при помощи кнопки. Это простое исполнение кнопки как переключателя, но на самом деле в данном примере переключателем является не кнопка, а сам объект светодиода:
Копировать1led.toggle()
Пример:
Копировать12345678910111213141516171819`# Подключаем модуль для работы с выводами from machine import Pin
Подключаем функцию сна (задержки)
from time import sleep
Создаём объект светодиода, передавая в конструктор номер вывода и режим работы
led = Pin("GP15", Pin.OUT)
Создаём объект кнопки, передавая в конструктор номер вывода и режим работы
button = Pin("GP2", Pin.IN)
Бесконечный цикл
while True:
Если кнопка нажата - переключаем светодиод
if button.value(): led.toggle()
sleep(.1)`
Если нужно, чтобы кнопка переключала что-то абстрактное, можно либо придумать класс-оболочку для кнопки, либо переключать глобальную переменную и led.toggle() заменить на toggle_state = not toggle_state (более подробно данный алгоритм мы рассмотрим в уроке работа с ШИМ)
Копировать12345678`toggle_state = False ... if button.value(): toggle_state = not toggle_state ...
if (toggle_state):
код, если кнопка была переключена`
Устранение дребезга
При нажатии или отпускании кнопка может поменять своё состояние несколько раз в течение 50-100 миллисекунд (попробуйте убрать строчку sleep(.1) из предыдущего примера и посмотрите, что произойдёт). Это называется дребезг кнопки (bounce).
Для устранение этого в предыдущем примере мы использовали функцию sleep. Теоретически эта функция отличается от типичного для ардуино delay, так как она не блокирует другие задачи, запущенные в операционной системе, если таковая имеется, но в контексте данных уроков sleep всё же блокирует текущий поток выполнения. Поэтому рассмотрим неблокирующее устранение дребезга.
Алгоритм данного примера кажется сложным, но на самом деле он очень прост:
- проверяем состояние кнопки если состояние кнопки изменилось - записываем время изменения
- продолжаем выполнять программу дальше если подошёл интервал проверки DEBOUNCE_MS и состояние кнопки до сих пор отличается от записанного ранее, значит состояние кнопки действительно изменилось записываем новое состояние
Копировать1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253`# Подключаем модуль для работы с выводами from machine import Pin
Подключаем функцию счётчика миллисекунд и называем её знакомым для Arduino словом millis
from time import ticks_ms as millis
Создаём объект светодиода, передавая в конструктор номер вывода и режим работы
led = Pin("GP15", Pin.OUT)
Создаём объект кнопки, передавая в конструктор номер вывода и режим работы
button = Pin("GP2", Pin.IN)
Инициируем переменные, в которых будут храниться миллисекунды для кнопки и для вывода
debounce_millis = print_millis = millis()
Инициируем переменные состояния кнопки
last_state = button_state = button.value()
Интерваля для устранения дребезга и для вывода
DEBOUNCE_MS = 100 PRINT_INTERVAL = 2000
Бесконечный цикл
while True:
Записываем текущее состояние кнопки
current_state = button.value()
Если состояние изменилось, записываем время изменения
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.toggle()
Записиваем последнее состояние кнопки
last_state = current_state
Выводим текст через интервал
if millis() - print_millis > PRINT_INTERVAL: print_millis = millis() print("Выполняем что-то ещё, устранение дребезга кнопки не блокирует поток")`
Ссылки
Комплект для повторения проекта
Что понадобится
Это быстрый ориентир по основным модулям и деталям. Полный список для повторения проекта смотрите в самой статье.
3 позиции
Raspberry Pi Pico IO Trema Shield
Плата расширения к контроллерам Raspberry Pi Pico для подключения Trema-модулей
Открыть в iArduino
Светодиод 10мм - синий (Trema-модуль)
Trema-модуль Светодиод
Открыть в iArduino
Кнопка, красная (Trema-модуль)
Тактовая кнопка, которая может служить источником сигналов (команд) для Ваших проектов
Открыть в iArduino



