MicroPython: Адресные RGB-светодиоды WS2812B с ESP32 и ESP8266
В этом руководстве показано, как управлять адресными RGB-светодиодами WS2812B (NeoPixel) с помощью ESP32 и ESP8266, используя MicroPython.
В MicroPython есть встроенная библиотека, которая делает управление этими светодиодами чрезвычайно простым: библиотека neopixel. Мы покажем вам, как управлять отдельными светодиодами, создавать функции для создания потрясающих световых эффектов и построить простой проект, чтобы показать, как всё работает вместе.
Это руководство применимо к любой ленте или плате, на которой установлены адресные RGB-светодиоды WS2812B (NeoPixel), например:
Адресные RGB-светодиодные ленты WS2812B
Адресные RGB-светодиодные кольца WS2812B
Адресные RGB-светодиодные платы-палочки WS2812B
В этом руководстве мы будем управлять двумя адресными RGB-светодиодными кольцами и одной адресной светодиодной платой-палочкой, подключёнными последовательно.
Предварительные требования
Для прохождения этого руководства вам необходима прошивка MicroPython, установленная на плате ESP32 или ESP8266. Также вам потребуется IDE для написания и загрузки кода на плату. Мы рекомендуем использовать Thonny IDE или uPyCraft IDE:
Thonny IDE:
uPyCraft IDE:
Знакомство с RGB-светодиодами WS2812B
Светодиоды WS2812B — это адресные RGB-светодиоды, которые можно подключать последовательно и управлять каждым из них индивидуально, используя всего один цифровой вывод микроконтроллера. Эти светодиоды имеют встроенную микросхему, которая делает всё это возможным.
Вы можете спаять несколько светодиодных колец и палочек, и они будут работать как единое целое. Каждая плата имеет выводы IN и OUT, что делает подключение очень простым:
На следующем изображении показано, как выглядит наша установка после пайки светодиодов.
Для подключения RGB-светодиодной ленты к ESP32 или ESP8266 всё очень просто. Нужно подать 5 В на вывод VCC, GND к GND и подключить GPIO к выводу Din (данные). Мы подключим вывод данных к GPIO 5.
Управление RGB-светодиодами WS2812B
В MicroPython есть встроенный модуль neopixel для управления адресными светодиодами WS2812B. Например, следующий скрипт управляет 4 отдельными пикселями:
import machine, neopixel
n = 48
p = 5
np = neopixel.NeoPixel(machine.Pin(p), n)
np[0] = (255, 0, 0)
np[3] = (125, 204, 223)
np[7] = (120, 153, 23)
np[10] = (255, 0, 153)
np.write()
Импорт библиотек
Сначала импортируйте модули neopixel и machine:
import machine, neopixel
Создание объекта neopixel
Задайте количество пикселей в вашей ленте в переменной n:
n = 48
Сохраните номер GPIO, который будет управлять лентой, в переменной p:
p = 5
Создайте объект NeoPixel с именем np на указанном ранее GPIO и с заданным количеством светодиодов:
np = neopixel.NeoPixel(machine.Pin(p), n)
Управление отдельными пикселями
После инициализации объекта neopixel вы можете начать управлять светодиодами. Управление отдельным пикселем очень простое. Вы можете представить ленту как массив из n элементов (количество пикселей в ленте). Затем нужно просто задать цвет определённому элементу. Например, чтобы установить первый пиксель в красный цвет:
np[0] = (255, 0, 0)
Следующая схема поможет лучше понять, как это работает:
Затем используйте метод write() для применения изменений.
np.write()
Световые эффекты WS2812 RGB LED
Теперь, когда вы знаете, как управлять отдельными пикселями, вы можете создавать собственные световые эффекты. Мы предоставим несколько функций (на основе примеров из библиотеки), которые вы можете использовать в своих проектах.
Очистка всех пикселей
Очистка всех пикселей — это то же самое, что установка всех пикселей в цвет (0, 0, 0).
def clear():
for i in range(n):
np[i] = (0, 0, 0)
np.write()
Установка одного цвета для всех пикселей
Аналогичным образом, чтобы установить для всех пикселей один и тот же цвет, можно использовать следующую функцию, которая принимает в качестве аргументов параметры цвета r, g и b.
def set_color(r, g, b):
for i in range(n):
np[i] = (r, g, b)
np.write()
Эффект отскока (bounce)
Функция bounce() создаёт эффект отскока и принимает параметры r, g и b для задания цвета, а также время ожидания. Время ожидания определяет, насколько быстрым будет эффект отскока.
def bounce(r, g, b, wait):
for i in range(4 * n):
for j in range(n):
np[j] = (r, g, b)
if (i // n) % 2 == 0:
np[i % n] = (0, 0, 0)
else:
np[n - 1 - (i % n)] = (0, 0, 0)
np.write()
time.sleep_ms(wait)
Этот эффект показывает выключенный пиксель, который бегает по всем позициям ленты.
Эффект бегущего пикселя (cycle)
Эффект бегущего пикселя работает аналогично эффекту отскока. Один включённый пиксель пробегает по всем позициям ленты, в то время как остальные пиксели выключены.
def cycle(r, g, b, wait):
for i in range(4 * n):
for j in range(n):
np[j] = (0, 0, 0)
np[i % n] = (r, g, b)
np.write()
time.sleep_ms(wait)
Эффект движущейся радуги
Для создания эффекта движущейся радуги вам понадобятся две функции. Функция wheel() генерирует спектр цветов радуги, варьируя каждый параметр цвета от 0 до 255.
def wheel(pos):
# Введите значение от 0 до 255, чтобы получить значение цвета.
# Цвета представляют собой переход r - g - b - обратно к r.
if pos < 0 or pos > 255:
return (0, 0, 0)
if pos < 85:
return (255 - pos * 3, pos * 3, 0)
if pos < 170:
pos -= 85
return (0, 255 - pos * 3, pos * 3)
pos -= 170
return (pos * 3, 0, 255 - pos * 3)
После этого используйте функцию rainbow_cycle(), которая использует результаты функции wheel() для распределения радуги по количеству светодиодов в вашей ленте.
def rainbow_cycle(wait):
for j in range(255):
for i in range(n):
rc_index = (i * 256 // n) + j
np[i] = wheel(rc_index & 255)
np.write()
time.sleep_ms(wait)
Эта функция принимает в качестве аргумента время ожидания. Время ожидания определяет, насколько быстро движется эффект радуги.
Зная, как работают эти функции, вы можете создавать собственные проекты для получения потрясающих световых эффектов. Чтобы увидеть, как всё работает вместе, в следующем разделе мы построим простой проект для управления набором адресных RGB-светодиодов.
Проект: WS2812B RGB LED с MicroPython
Здесь мы построим простую схему с 4 кнопками. Она будет создавать различные световые эффекты в зависимости от нажатой кнопки.
Необходимые компоненты
В этом проекте мы используем два адресных RGB-светодиодных кольца разного размера и одну адресную RGB-светодиодную палочку. Однако вы можете использовать RGB-светодиодную ленту или адресные RGB-светодиоды в другой конфигурации.
ESP32 или ESP8266
Адресные RGB-светодиоды (кольцо, палочка, лента)
4x тактовые кнопки
4x резистора 10 кОм
Макетная плата
Соединительные провода
Схема подключения
Для ESP32 и ESP8266 мы подключим компоненты следующим образом:
Компонент |
GPIO |
|---|---|
Кнопка 1 |
GPIO 14 |
Кнопка 2 |
GPIO 12 |
Кнопка 3 |
GPIO 13 |
Кнопка 4 |
GPIO 15 |
Вывод данных адресных RGB LED |
GPIO 5 |
Примечание
Вы можете выбрать любые другие цифровые выводы при необходимости.
ESP32
Вы также можете следовать следующей схеме подключения для ESP32:
ESP8266
Следуйте следующей схеме подключения, если используете ESP8266:
Код
Загрузите следующий код на ESP32 или ESP8266 как main.py.
from machine import Pin
import machine, neopixel, time
# определение функции обработки прерывания
def button_handler(pin):
global button_pressed
button_pressed = pin
# настройка кнопок как прерываний
button1 = Pin(15, Pin.IN)
button1.irq(trigger=Pin.IRQ_RISING, handler=button_handler)
button2 = Pin(14, Pin.IN)
button2.irq(trigger=Pin.IRQ_RISING, handler=button_handler)
button3 = Pin(12, Pin.IN)
button3.irq(trigger=Pin.IRQ_RISING, handler=button_handler)
button4 = Pin(13, Pin.IN)
button4.irq(trigger=Pin.IRQ_RISING, handler=button_handler)
button_pressed = button1
# Конфигурация LED-ленты
# количество пикселей
n = 48
# GPIO для управления лентой
p = 5
np = neopixel.NeoPixel(machine.Pin(p), n)
# ФУНКЦИИ СВЕТОВЫХ ЭФФЕКТОВ
# отскок
def bounce(r, g, b, wait):
for i in range(2 * n):
for j in range(n):
np[j] = (r, g, b)
if (i // n) % 2 == 0:
np[i % n] = (0, 0, 0)
else:
np[n - 1 - (i % n)] = (0, 0, 0)
np.write()
time.sleep_ms(wait)
# бегущий пиксель
def cycle(r, g, b, wait):
for i in range(n):
for j in range(n):
np[j] = (0, 0, 0)
np[i % n] = (r, g, b)
np.write()
time.sleep_ms(wait)
# функция для перебора всех цветов
def wheel(pos):
# Введите значение от 0 до 255, чтобы получить значение цвета.
# Цвета представляют собой переход r - g - b - обратно к r.
if pos < 0 or pos > 255:
return (0, 0, 0)
if pos < 85:
return (255 - pos * 3, pos * 3, 0)
if pos < 170:
pos -= 85
return (0, 255 - pos * 3, pos * 3)
pos -= 170
return (pos * 3, 0, 255 - pos * 3)
# радуга
def rainbow_cycle(wait):
for j in range(255):
for i in range(n):
rc_index = (i * 256 // n) + j
np[i] = wheel(rc_index & 255)
np.write()
time.sleep_ms(wait)
# выключить все пиксели
def clear():
for i in range(n):
np[i] = (0, 0, 0)
np.write()
while True:
if button_pressed == button1:
clear()
elif button_pressed == button2:
bounce(23, 210, 15, 70)
elif button_pressed == button3:
cycle(123, 0, 154, 50)
elif button_pressed == button4:
rainbow_cycle(1)
Как работает код
Продолжайте читать этот раздел, если хотите узнать, как работает код. В противном случае вы можете перейти к разделу «Демонстрация».
Начните с импорта необходимых библиотек:
from machine import Pin
import machine, neopixel, time
Кнопки будут настроены как прерывания. Поэтому нам нужно создать функцию обработки прерывания, которая будет вызываться каждый раз при возникновении прерывания — в данном случае это функция button_handler().
def button_handler(pin):
global button_pressed
button_pressed = pin
Функция обработки прерывания имеет входной параметр (pin), в который при возникновении прерывания будет передан объект класса Pin. Это позволяет нам узнать, какой вывод сгенерировал прерывание.
В нашем примере функция обработки прерывания называется button_handler, и она сохраняет нажатую кнопку в переменной button_pressed.
Примечание
button_pressed определена как глобальная переменная, потому что мы хотим, чтобы она была доступна во всём коде, а не только внутри функции button_handler().
После этого настройте кнопки как выводы прерываний:
button1 = Pin(15, Pin.IN)
button1.irq(trigger=Pin.IRQ_RISING, handler=button_handler)
button2 = Pin(14, Pin.IN)
button2.irq(trigger=Pin.IRQ_RISING, handler=button_handler)
button3 = Pin(12, Pin.IN)
button3.irq(trigger=Pin.IRQ_RISING, handler=button_handler)
button4 = Pin(13, Pin.IN)
button4.irq(trigger=Pin.IRQ_RISING, handler=button_handler)
По умолчанию переменная button_pressed равна button1, потому что эта кнопка очищает светодиоды, и мы хотим, чтобы они были выключены по умолчанию.
button_pressed = button1
Затем мы создаём объект neopixel на GPIO 5 с 48 светодиодами. Вы должны изменить переменную n на количество управляемых вами светодиодов.
n = 48 # количество пикселей
p = 5 # GPIO для управления лентой
np = neopixel.NeoPixel(machine.Pin(p), n)
После этого мы определяем функции, которые были рассмотрены в предыдущем разделе: bounce(), cycle(), wheel(), rainbow_cycle() и clear().
В цикле while мы проверяем, какая кнопка была нажата, и вызываем соответствующую функцию в зависимости от нажатой кнопки:
Кнопка 1: очищает ленту (все NeoPixel выключены)
Кнопка 2: эффект отскока
Кнопка 3: эффект бегущего пикселя
Кнопка 4: эффект радуги
while True:
if button_pressed == button1:
clear()
elif button_pressed == button2:
bounce(23, 210, 15, 10)
elif button_pressed == button3:
cycle(123, 0, 154, 20)
elif button_pressed == button4:
rainbow_cycle(1)
Примечание
Вы можете изменить аргументы функций, чтобы установить светодиоды в другие цвета или настроить параметр ожидания, чтобы сделать эффект быстрее или медленнее.
Демонстрация
После загрузки предыдущего кода на ESP32 или ESP8266 в качестве main.py нажмите кнопку Enable/Reset на ESP, чтобы запустить новый код.
Нажимайте каждую кнопку для получения различных эффектов.
Примечание
Когда вы нажимаете кнопку для выбора эффекта, он начнётся только после завершения текущего выполняемого эффекта.
Заключение
В этом руководстве вы узнали, как управлять адресными RGB-светодиодами WS2812B (кольца, ленты или палочки). Управление этими светодиодами с помощью MicroPython является простым благодаря библиотеке neopixel. Вы также узнали, как настроить несколько прерываний с помощью MicroPython.
Теперь вы можете применить концепции, изученные в этом руководстве, в своих собственных проектах. Например, вы можете создать веб-сервер с различными кнопками для удалённого управления светодиодами.
Вам также могут быть полезны другие руководства по MicroPython: