MicroPython с ESP32 и ESP8266: работа с GPIO
В этой статье мы рассмотрим, как взаимодействовать с GPIO ESP32 и ESP8266 с помощью MicroPython. Мы покажем, как считывать цифровые и аналоговые входы, как управлять цифровыми выходами и как генерировать ШИМ-сигналы.
Необходимые условия
Для программирования ESP32 и ESP8266 с помощью MicroPython мы используем uPyCraft IDE в качестве среды программирования. Для установки uPyCraft IDE и прошивки MicroPython на вашу плату следуйте приведённым ниже руководствам:
Установка uPyCraft IDE: Windows PC, MacOS X, или Linux Ubuntu
Как альтернативу, если у вас возникли проблемы с uPyCraft IDE, мы рекомендуем использовать Thonny IDE: Начало работы с Thonny MicroPython (Python) IDE для ESP32 и ESP8266
Если вы впервые работаете с MicroPython, вам могут быть полезны следующие руководства:
Обзор проекта
С помощью этого руководства вы научитесь использовать GPIO ESP32 или ESP8266 с MicroPython. Вы можете прочитать отдельное руководство по каждой теме:
Мы создадим простой пример, который работает следующим образом:
Считываем состояние кнопки и устанавливаем состояние светодиода соответственно — при нажатии кнопки светодиод загорается.
Считываем напряжение с потенциометра и регулируем яркость светодиода в соответствии с положением движка потенциометра.
Схема
Схема для данного проекта включает подключение двух светодиодов, кнопки и потенциометра. Вот список всех необходимых компонентов:
ESP32 или ESP8266
2x светодиода
2x резистора 330 Ом
Кнопка (pushbutton)
Потенциометр
Макетная плата (Breadboard)
Провода (Jumper wires)
ESP32 – Схема
Следуйте приведённой ниже схеме, если вы используете ESP32:
Примечание: ESP32 поддерживает аналоговое чтение на нескольких GPIO: 0, 2, 4, 12, 13, 14, 15, 25, 26, 27, 32, 33, 34, 35, 36 и 39.
Рекомендуемое чтение: Распиновка ESP32: какие GPIO пины следует использовать?
ESP8266 – Схема
Следуйте приведённой ниже схеме, если вы используете ESP8266:
Примечание: ESP8266 поддерживает аналоговое чтение только на пине ADC0 (A0).
Код
Скопируйте следующий код в файл main.py в uPyCraft IDE.
Примечание: аналоговое чтение работает по-разному на ESP32 и ESP8266. Код работает сразу на ESP32. Для использования с ESP8266 вам необходимо раскомментировать и закомментировать строки, указанные в скрипте MicroPython.
# Полная информация о проекте: https://RandomNerdTutorials.com
# Автор: Rui Santos
from machine import Pin, ADC, PWM
from time import sleep
led = Pin(2, Pin.OUT)
button = Pin(15, Pin.IN)
# Настройка АЦП для ESP32
pot = ADC(Pin(34))
pot.width(ADC.WIDTH_10BIT)
pot.atten(ADC.ATTN_11DB)
# Настройка АЦП для ESP8266
# pot = ADC(0)
led_pwm = PWM(Pin(4), 5000)
while True:
button_state = button.value()
led.value(button_state)
pot_value = pot.read()
led_pwm.duty(pot_value)
sleep(0.1)
Как работает код
Продолжайте чтение, чтобы узнать, как работает код.
Импорт библиотек
Для взаимодействия с GPIO необходимо импортировать модуль machine, который содержит классы для работы с GPIO. Импортируйте класс Pin для взаимодействия с пинами, класс ADC для чтения аналоговых значений и класс PWM для генерации ШИМ-сигналов.
from machine import Pin, ADC, PWM
Импортируйте метод sleep() из модуля time. Метод sleep() позволяет добавлять задержки в код.
from time import sleep
Инициализация пинов
После импорта всех необходимых модулей создайте объект Pin с именем led на GPIO 2, который является выходом (OUTPUT).
led = Pin(2, Pin.OUT)
Объект Pin принимает следующие атрибуты в указанном порядке:
Pin(Pin number, pin mode, pull, value)
Pin number — номер GPIO, которым мы хотим управлять;
Pin mode — может быть вход (IN), выход (OUT) или открытый сток (OPEN_DRAIN);
Аргумент pull используется, если мы хотим активировать внутренний подтягивающий резистор к питанию или к земле (PULL_UP или PULL_DOWN);
value соответствует состоянию GPIO (включён или выключен): может быть 0 или 1 (True или False). Установка 1 означает, что GPIO включён. Если мы не передаём параметр, его состояние по умолчанию равно 0 (именно так мы и поступим в этом примере).
После инициализации объекта led нужно создать ещё один экземпляр класса Pin для кнопки. Кнопка подключена к GPIO 15 и настроена как вход. Это выглядит следующим образом:
button = Pin(15, Pin.IN)
Инициализация АЦП
На ESP32 для создания объекта ADC для потенциометра на GPIO 34:
pot = ADC(Pin(34))
Если вы используете ESP8266, он поддерживает АЦП только на пине ADC0 (A0). Для создания объекта ADC с ESP8266:
pot = ADC(0)
Следующая строка применяется только к ESP32. Она определяет, что мы хотим считывать напряжение в полном диапазоне. Это означает, что мы хотим считывать напряжение от 0 до 3,3 В.
pot.atten(ADC.ATTN_11DB)
Следующая строка означает, что мы хотим показания с 10-битным разрешением (от 0 до 1023):
pot.width(ADC.WIDTH_10BIT)
Метод width() принимает другие параметры для установки другого разрешения:
WIDTH_9BIT: диапазон от 0 до 511
WIDTH_10BIT: диапазон от 0 до 1023
WIDTH_11BIT: диапазон от 0 до 2047
WIDTH_12BIT: диапазон от 0 до 4095
Если вы не укажете разрешение, по умолчанию на ESP32 будет 12-битное разрешение.
Инициализация ШИМ
Затем создайте объект PWM с именем led_pwm на GPIO 4 с частотой 5000 Гц.
led_pwm = PWM(Pin(4), 5000)
Для создания объекта PWM необходимо передать следующие параметры: пин, частоту сигнала и коэффициент заполнения.
Частота может быть значением от 0 до 78125. Частота 5000 Гц для светодиода подходит отлично.
Коэффициент заполнения (duty cycle) может быть значением от 0 до 1023. При этом 1023 соответствует 100% коэффициенту заполнения (полная яркость), а 0 — 0% (светодиод не горит).
Мы установим коэффициент заполнения в цикле while, поэтому пока не нужно передавать параметр duty cycle. Если вы не установите коэффициент заполнения при создании объекта PWM, по умолчанию он будет равен 0.
Получение состояния GPIO
Далее у нас есть цикл while, который всегда True. Это аналогично функции loop() в Arduino IDE.
Начинаем с получения состояния кнопки и сохранения его в переменной button_state. Для получения состояния пина используйте метод value() следующим образом:
button_state = button.value()
Это возвращает 1 или 0 в зависимости от того, нажата кнопка или нет.
Установка состояния GPIO
Для установки состояния пина используйте метод value(state) объекта Pin. В данном случае мы передаём переменную button_state в качестве аргумента. Таким образом, светодиод загорается при нажатии кнопки:
led.value(button_state)
Чтение аналоговых входов
Для чтения аналогового входа используйте метод read() объекта ADC (в данном случае объект ADC называется pot).
pot_value = pot.read()
Управление коэффициентом заполнения
Для управления коэффициентом заполнения используйте метод duty() объекта PWM (led_pwm). Метод duty() принимает значение от 0 до 1023 (где 0 соответствует 0% коэффициенту заполнения, а 1023 — 100%). Поэтому передайте в качестве аргумента pot_value (которое варьируется от 0 до 1023). Таким образом, вы изменяете коэффициент заполнения, вращая потенциометр.
led_pwm.duty(pot_value)
Тестирование кода
Загрузите файл main.py на ваш ESP32 или ESP8266. Для этого откройте uPyCraft IDE и скопируйте предоставленный код в файл main.py. Перейдите в Tools > Serial и выберите последовательный порт. Выберите вашу плату в Tools > Board.
Затем загрузите код на ESP32 или ESP8266, нажав кнопку Download and Run.
Примечание: для ознакомления с uPyCraft IDE вы можете прочитать следующее руководство — Начало работы с MicroPython на ESP32 и ESP8266
После загрузки кода нажмите кнопку EN/RST на плате ESP32/ESP8266, чтобы запустить новый скрипт.
Теперь протестируйте вашу установку. Светодиод должен загораться при нажатии кнопки.
Яркость светодиода изменяется при вращении потенциометра.
Подведение итогов
Этот простой пример показал вам, как считывать цифровые и аналоговые входы, управлять цифровыми выходами и генерировать ШИМ-сигналы на платах ESP32 и ESP8266 с помощью MicroPython.
Если вам нравится MicroPython, вам могут понравиться следующие проекты:
MicroPython: Адресные RGB-светодиоды WS2812B с ESP32/ESP8266
Метеостанция с низким энергопотреблением: логгер данных на ESP8266 и BME280 с MicroPython
Мы надеемся, что эта статья о работе с GPIO ESP32 и ESP8266 с помощью MicroPython была для вас полезной.