КОРЗИНА
магазина
8 (499) 500-14-56 | ПН. - ПТ. 12:00-18:00
ЛЕСНОРЯДСКИЙ ПЕРЕУЛОК, 18С2, БЦ "ДМ-ПРЕСС"

Raspberry Pi Pico: подключаем кнопку в MicroPython





Общие сведения

В этом уроке мы научимся обрабатывать состояния кнопки. Для показательности во втором и третьем примере будет использоваться светодиод, с которым мы работали в прошлом уроке.

Для этого урока нам понадобится:

Для работы данных примеров в Pi Pico необходимо загрузить прошивку MicroPython и установить Thonny IDE, о том как это сделать можно прочитать в этой статье: https://lesson.iarduino.ru/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 мы назначаем ему режим работы на вход:

button = Pin("GP2", mode = Pin.IN)

В этом состоянии вывод принимает высокое входное сопротивление из него практически не выходит ток, зато мы можем понять какое на нём напряжение, логической единицы (максимальное напряжение относительно GND) или логического нуля (минимальное напряжение относительно GND).

В переменную last_state мы сохраняем текущее состояние кнопки:

last_state = button.value()

Функция print выводит текст в оболочку:

print("Кнопка не нажата")

В следующем примере состояние кнопки считывается в цикле и выводится в оболочку:

# Подключаем модуль для работы с выводами
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)

Переключаем светодиод

В данном примере мы переключаем состояние светодиода при помощи кнопки. Это простое исполнение кнопки как переключателя, но на самом деле в данном примере переключателем является не кнопка, а сам объект светодиода:

led.toggle()

Пример:

# Подключаем модуль для работы с выводами
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 (более подробно данный алгоритм мы рассмотрим в уроке работа с ШИМ)

toggle_state = False
...
    if button.value():
        toggle_state = not toggle_state
...

    if (toggle_state):
        # код, если кнопка была переключена

Устранение дребезга

При нажатии или отпускании кнопка может поменять своё состояние несколько раз в течении 50-100 миллисекунд (попробуйте убрать строчку sleep(.1) из предыдущего примера и посмотрите, что произойдёт). Это называется дребезг кнопки (bounce).

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

Алгоритм данного примера кажется сложным, но на самом деле он очень прост:

  • проверяем состояние кнопки
    • если состояние кнопки изменилось - записываем время изменения
  • продолжаем выполнять программу дальше
    • если подошёл интервал проверки DEBOUNCE_MS и состояние кнопки до сих пор отличается от записанного ранее, значит состояние кнопки действительно изменилось
      • записываем новое состояние
# Подключаем модуль для работы с выводами
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("Выполняем что-то ещё, устранение дребезга кнопки не блокирует поток")

Ссылки




Обсуждение

Гарантии и возврат Используя сайт Вы соглашаетесь с условями