Что делать, когда обычные гирлянды надоели, а пора встречать Новый год с детьми? Можно создать эффект снегопада и другие эффекты с помощью адресных светодиодов NeoPixels, добавить ИК-пульт для управления выбором эффектов, их скоростью и яркостью и, при желании, мини-дисплей для отображения текущих параметров. Так мы займем время до праздников и создадим свое устройство для украшения елки и не только елки.
Нам понадобятся микроконтроллер Raspberry Pi Pico (около 4$) или его разновидности на чипе RP2040, простейший ИК-пульт (дешевле 1$ вместе с приемником, батарейкой и белым светодиодом в комплекте) и соединенные последовательно адресные ленты WS2812B (10 светодиодов на метр, напряжение 5V, стоимость около 1$/метр). Также можно подключить миниатюрный I2C или SPI дисплей (1-3$), если таковой найдется под рукой. Код MicroPython реализует 5 разных эффектов, доступных при нажатии кнопок 1 — 5 на ИК пульте, а также обеспечивает управление яркостью гирлянды (кнопками вверх и вниз) и скоростью эффектов (кнопками вперед и назад).
Введение
Создание самодельных устройств дает возможность попрактиковаться на реальных задачах, а еще обсудить разные теоретические и технические вопросы. Реализация любой идеи это компромисс между придуманным и реальным, между идеей и ее физическим воплощением., а задача инженера — создать в реальном мире то, что пока существует лишь в воображении.
Если следовать спецификациям подключения каждого компонента — получится много избыточных элементов, если не следовать — полученное устройство может работать не стабильно или вовсе сломаться. Мы посмотрим, как сделать стабильно работающую гирлянду с дистанционным управлением из минимума деталей на микроконтроллере RPI Pico, используя особенности его схемотехники.
Материалы и оборудование
В первую очередь, нужно выбрать микроконтроллер, так как именно его возможности определяют и схемотехнику и программу. Raspberry PI Pico — это не просто современный микроконтроллер, пусть и двухядерный, это еще и 8 дополнительных микроконтроллеров в едином корпусе, которые могут работать в реальном времени с периферийными устройствами, не нагружая основной процессор (такая технология названа PIO, Programmable Input/Output). Кроме того, Pico содержит отличный регулятор напряжения для преобразования питающего напряжения 5 V в необходимые микроконтроллеру 3.3 V, который решает все проблемы с нестабильностью основного напряжения, вызыванные изменением потребления тока подключенной светодиодной гирлянды. И более того, Pico поддерживает аппаратные прерывания, так что подключение ИК-приемника не вызывает никаких проблем, поскольку регистрация поступающих с приемника импульсов производится независимо от потока выполнения основного кода.
Поскольку у нас есть под рукой несколько разных основанных на RP2040 плат, мы использовали их все по штуке, из интереса. Все, что нам нужно для проекта, это PIO пин для управления одной гирляндой, GPIO пин для подключения ИК-приемника, 5 V пин для подключения гирлянды непосредственно к USB коннектору и 3.3 V пин подключения ИК-приемника и пины для опционального дисплея — все это доступно на практически любой RP2040 плате.
Стандартный Raspberry Pi Pico — самый бюджетный вариант, которого более чем достаточно для проекта. Схема пинов из даташита показана ниже:
Подключение пинов: лента к пину 15, ИК-приемник 28.
- LilyGO T-Display RP2040 — включает дисплей 135х240 пикселов на чипе ST7789. Кстати, на этой же плате распаян вайфай чип ESP32, и оба чипа доступны напрямую, если перевернуть USB-C коннектор, при этом доступный для программирования чип индицируется зеленым или синим светодиодом. И это работает — интересный хак, за это девайс и куплен. Вайфай тоже работает (используя AT-команды). Из минусов — чип RP2040 заметно греется даже в бездействии, так что поставить его на устройство с малым энергопотреблением нельзя, а вот для управления мощной светодиодной гирляндой вполне годится.
Подключение пинов: лента к пину 20, ИК-приемник 24, пины управления дисплеем показаны на схеме.
- Plasma Stick 2040 W — содержит встроенный коннектор для подключения светодиодной ленты и вайфай модуль. Куплен в сезон распродаж со скидкой ради стеклянного черепа. Схема пинов соответствует базовому микроконтроллеру, плюс добавлены кнопка RESET и пара разъемов для подключения светодиодной гирлянды и датчиков:
Подключение пинов: лента к встроенному коннектору для светодиодной ленты (пин 15 или plasma_stick.DAT), ИК-приемник 28 (аналогично стандартному Raspberry Pi Pico).
- Tiny 2040 — миниатюрная RP2040 платка с 4-мя аналого-цифровыми интерфейсами, 8 PIO и USB-C коннектором. Если прямо на нее напаять ИК-приемник, получается очень миниатюрное устройство. Пинов немного, но все необходимые есть, и даже предлагается один дополнительный аналогово-цифровой вход:
Подключение пинов: лента к пину 26 (A0), ИК-приемник 29 (A3).
Пульт с ИК-приемником HX1838 на стандартные 38KHZ стоит всего лишь 0.8\$, на что стоит обратить внимание — чтобы отсек с батарейкой не выпадал (обычно это заметно прямо на фото товара, когда отсек не полностью входит в корпус). В более дорогих пультах за 5-10\$ разница лишь в том, что производитель предлагает готовые библиотеки для MicroBit и других контроллеров, где все клавиши доступны по их наименованиям, а не по кодам.
Опциональный SPI дисплей размером 135х240 пикселов на чипе ST7789 достаточно распространненный и легко доступный модуль, равно как и на другие разрешения. Указанный дисплей уже встроен в плату LilyGO T-Display RP2040, так что им мы и воспользовались, раз уж он уже есть и подключен.
Светодиодные ленты WS2812B на 5 V имеют несколько разных вариаций, мы выбрали вариант с проводами в прозрачной силиконовой изоляции (и влагозащитой IP67). Порядок цветов светодиодной ленты, обычно RGB (ленты из фирменных магазинов) или BGR (ленты с aliexpress).
MicroPython vs CircuitPython
Выбор языка программирования это, во многом, дело вкуса, и все же есть необходимые требования, которые мы и рассмотрим. Можно писать на достаточно низкоуровневом языке C — это займет больше времени и позволит воспользоваться всеми ресурсами микроконтроллера. Или выбрать скриптовый язык, писать на котором проще и быстрее, но часть возможностей микроконтроллера окажется недоступна. Поскольку для RPI Pico больше всего примеров на Python, то мы будем выбирать между популярными диалектами Python для микроконтроллеров. Их два: MicroPython и CircuitPython, и в обоих практически недоступно второе ядро микроконтроллера. Также CircuitPython, в отличие от MicroPython, не поддерживает прерывания — что создает проблемы при работе с ИК-приемником (часть сигналов теряется, когда микроконтроллер обрабатывает код управления гирляндой, к примеру). Значит, оптимальным выбором для нашей задачи является именно MicroPython, а необходимые нам модули можно установить отдельно или же воспользоваться прошивкой MicroPython Pimoroni Libraries, в которой многие уже включены (кроме модуля IR приемника). Эта прошивка доступна как на гитхабе Pimoroni Pico Libraries and Examples, так и в MicroPython редакторе Thonny для установки "в один клик".
RPI Pico позволяет сделать управление светодиодной лентой с множеством светодиодов, используя лишь один PIO, соответствующий MicroPython модуль доступен на гитхабе: Pimoroni Plasma Для управления ИК-приемником (и передатчиком) доступен модуль MicroPython IR Для дисплеев доступно множество библиотек, для единообразия и удобства мы воспользуемся модулем PicoGraphics от Pimoroni, который поддерживает нужный дисплей на чипе ST7789 и входит в состав MicroPython Pimoroni Libraries.
Устройство NeoPixels WS2812B
Светодиодная лента NeoPixels представляет собой набор адресных светодиодов, где каждый элемент состоит из адресуемого контроллера и трех светодиодов (красный, зеленый, синий) с управляемой яркостью (управляющий байт из 8 битов вмещает 2^8 = 256 уровней):
Схема светодиодной ленты, см. Driving WS2812b with STM32 and PWM strange behavior Заметим, что для каждого светодиода в ленте предусмотрен свой фильтрующий конденсатор, расположенный максимально близко к светодиоду. Подробнее об устройстве ленты можно прочитать по ссылке Умные светодиоды WS2812B NeoPixels
Благодаря своему устройству, лента имеет неожиданно большую максимальную мощность. При всех включенных светодиодах излучается белый свет и потребление для выбранной ленты (WS2812 4020 IC) указано как 0.1 W/LED, что дает 35 W для 35 метров ленты из 350 светодиодов. Для любого одного цвета на максимальной яркости потребление примерно втрое меньше и составляет около 12 W. Ток по спецификации равен 12W/5V = 2.4 A, а с учетом падения напряжения на гирлянде примерно 2 A. Соответственно, при питающем напряжении 5 V ток потребления составляет около 2 A. Таким образом, для питания гирлянды достаточно блока питания или power bank на 2 A.
Для стандартной управляющей частоты 800 kHz время переключения одного светодиода (передачи трех байтов — по одному байту для каждого цвета) составляет 24/800000 = 30 мкс, так что при визуально комфортной частоте обновления 60 Hz можно управлять лентой не более чем из 500 светодиодов, а при частоте 30 Hz — 1000. Имея 8 PIO выходов, можно подключить тысячи светодиодов, что более чем достаточно для домашних проектов.https://electronics.stackexchange.com/questions/390743/driving-ws2812b-with-stm32-and-pwm-strange-behavior)
Питающее напряжение для WS2812B находится в диапазоне 3.3 — 5V, соответственно, требуют логический уровень управляющего сигнала от 3 — 5 V. Заметим, что старые ленты WS2812 требуют питающего напряжения 5 V и не срабатывают от логического уровня 3 V, так что для них и только для них необходим конвертор уровня.
Эффекты для гирлянды
Светодиодные ленты NeoPixels позволяют создавать замечательные эффекты бегущего огня или падающих снежинок и многие такие эффекты уже реализованы и доступны в виде примеров на MicroPython. Мы выбрали наборы эффектов из гитхаб репозитория Plasma Stick MicroPython Examples, предлагаемые в дополнение к продукту Wireless Plasma Kit (Pico W Aboard) — на странице продукта доступны схема, ссылка на примеры и видео получаемых эффектов. Эти примеры работают и на базовом RPI Pico, нужно лишь правильно указать пин, к которому подключена гирлянда. Для большего интереса мы добавили возможность управления яркостью светодиодов кнопками вверх-вниз на ИК пульте, скоростью эффектов кнопками влево-вправо, а также переключения различных программ числовыми кнопками.
Используя встроенные аналогово-цифровые преобразователи RPI Pico, можно замерить потребляемый гирляндой ток, пример доступен на гитхабе радуга и сенсор тока Эту информацию тоже можно отобразить на дисплее, но для гирлянды на елке мы не стали этого делать.
Создание эффекта радуги
Существует много способов задать любой нужный цвет — например, в графических редакторах часто используют RGB представление цвета. В то же время, цветные струйные принтеры используют чернила 4-х цветов CMYK для печати любого цвета — поскольку передача черного цвета смешиванием трех базовых работает хорошо только в теории, а на практике не очень. Есть и другие подходы, применимые для других задач. Для эффекта радуги, когда мы хотим создать непрерывную циклическую смену цветов, подойдет вариант кодирования HSV (hue, saturation, value — цвет, насыщенность, яркость):
Такой метод позволяет контролировать яркость отдельно от значения цвета, так что можно легко изменять яркость всех светодиодов разом, независимо от их цветов. Кроме того, цвета циклические с периодом 360 градусов, так что значения 0 или 360 или 720 и так далее равнозначны и обозначают красный цвет. Для эффекта радуги требуется распределить цвета равномерно в кольце 0-360 градусов и далее плавно сдвигать их (60 раз в секунду) по кольцу. Аналогичный код в цветовой схеме RGB будет гораздо более сложным.
Работа с ИК-приемником
ИК-приемник способен принимать сигналы как комплектного, так и всех прочих ИК-передатчиков, таких, как пульты от телевизора или кондиционера. Во избежание путаницы, в дополнение к коду нажатой клавиши каждый пульт отправляет еще и свой идентификатор. Это позволяет как игнорировать сигналы от "чужого" пульта, так и настроить отдельные реакции на них — к примеру, можно включать и выключать гирлянду одновременно со включением и выключением телевизора,… или наоборот, по желанию. Каждое нажатие клавиши на ИК-пульте приводит к передаче примерно 100 сигналов с заданным интервалом (зависит от рабочей частоты пульта). Из-за различных помех и отражений сигнала эти интервалы и передаваемые сигнальные последовательности искажаются, и задача при емника состоит в том, чтобы принять их "как есть" и передать программному декодеру. При декодировании сигналы сравниваются с эталонными, и если они достаточно похожи — декодер распознает сигнал как нажатие определенной кнопки, а иначе сообщает об ошибке декодирования. Повторные сигналы декодер идентифицирует отдельно, что позволяет просто их игнорировать или сделать ускоренное изменение параметров — нажав, к примеру, стрелку вверх на пульте, мы можем быстро изменять значение яркости гирлянды. Именно последний вариант реализован в предлагаемой программе.
Сборка устройства
Если прямо следовать спецификациям, то нам потребуются достаточно емкий конденсатор на входе гирлянды, резистор, подключенный между пином микроконтроллера и сигнальным входом гирлянды, а также конвертор логического уровня микроконтроллера 3.3 V в логический уровень 5 V гирлянды. На самом деле, все это не нужно, рассмотрим, почему.
Конденсатор для компенсации помех в питающей сети, подключенный между пинами питания гирлянды, позволяет снизить уровень помех в цепи питания. Есть некоторая "городская легенда", что это способствует стабильности работы самой гирлянды, но это не так, поскольку конденсатор устанавливается максимально близко к микроконтроллеру и далеко от светодиодов. Для работы RPI Pico с качественным регулятором питания пользы от указанного конденсатора нет никакой, в то время как для других микроконтроллеров этот конденсатор может быть необходим.
Также часто рекомендуется резистор между выходом микроконтроллера и входом гирлянды. Номинал этого резистора зависит от длины и толщины сигнального провода от микроконтроллера до гирлянды, для коротких толстых проводов (мало помех, малое падение напряжение на проводах) можно поставить резистор на 2 kohm, а для тонких длинных проводов (много помех, большое падение напряжения на проводах) около 200 ohm. В теории, этот резистор позволяет снизить выходной ток микроконтроллера и снизить энергопотребление схемы — но для мощной гирлянды это не даст никакого заметного эффекта. Еще резистор контролирует логический уровень на выходе — при слишком большом токе падение напряжения внутри микроконтроллера может оказаться неприемлимо большим и выходное напряжение станет недостаточным для надежного управления внешними устройствами. Также такой резистор обеспечивает стабильность работы микроконтролллеров без контроля выходного тока каждого пина по отдельности — слишком большой ток на одном из пинов снижает ток на всех остальных, приводя к нестабильности работы подключенных устройств. Все это важно, но микроконтролллер RPI Pico ограничивает выходной ток каждого пина значением 30 mA, что соответствует значению дополнительного резистора около 100 ohm. И более того, можно программно ограничить ток, см. "Output drive strength can be set to 2mA, 4mA, 8mA or 12mA" (в PDF мануале по RPI это описано более подробно, зато на онлайн мануал проще дать прямую ссылку), код на MicroPython для установки максимального тока 12 mA пина GPIO28 выглядит так:
import machine
machine.mem32[0x4001c074]=0x42
Такой ток соответствует значению внешнего резистора около 250 ohm, аналогично можно задать ток, соответствующий резисторам почти до 2 kohm. Таким образом, установка внешнего резистора совершенно бесполезна, если правильно воспользоваться возможностями микроконтроллера. Для нашей задачи стандартное ограничение выходного тока пина 30 mA вполне разумно — так гирлянда будет работать стабильно даже при длинном сигнальном проводе от микроконтроллера.
Для светодиодов WS2812B конвертор логических уровней не нужен, поскольку от уровня 3 V лента надежно срабатывает по спецификации, а ограничение выходного тока микроконтроллера гарантирует наличие такого уровня на выходе, как показано выше. Для старых светодиодов WS2812 однонаправленный конвертор от микроконтроллера к светодиодной ленте можно реализовать на одном транзисторе и одном резисторе, см, схему двунаправленного конвертора логических уровней, где второй резистор (правый на схеме) может быть исключен для превращения двунаправленного конвертора в однонаправленный (поскольку светодиоды не передают сигналы микроконтроллеру), а транзистор мы используем более распространенный 2N2700.
SparkFun Logic Level Converter — Bi-Directional — Schematic
Остается рассмотреть подключение ИК-приемника. Как мы помним, ранее мы отказались от использование помехогасящего конденсатора на входе гирлянды, так что шина питания 5 V микроконтроллера не пригодна для подключения датчиков. К счастью, RPI Pico имеет вывод внутреннего стабилизированного напряжения 3.3 V, мощность которого более чем достаточно для ИК приемника. Поскольку приемник не требует большого тока питания и не создает помех по питанию, совершенно допустимо его подключение к этому выводу микроконтроллера. Выбранный модуль HX1838 работает стабильно при напряжениях питания 2.7 — 5.5 V, как нам и требуется.
Опциональный дисплей SPI подключается к SPI входам микроконтроллера (см. схему пинов выше) и внутреннему стабилизированному регулятору напряжения 3.3 V (аналогично ИК приемнику).
Резюмируя, сборка устройства сводится к присоединению ИК-приемника, светодиодной ленты и, опционально, дисплея к пинам микроконтроллера напрямую или через соединительные провода, никакие дополнительные детали нам не нужны. Для сборки мы используем пайку, как более котоустойчивый метод, также можно собрать на беспаечной макетной плате или просто на коннекторах.
На фото выше показаны все четыре собранных устройствах на разных микроконтроллерах на чипе RP2040. Можно заметить наличие логического конвертора уровней на одном транзисторе и резисторе на самой большой плате (в центре сверху) — у детей была идея разместить один контроллер далеко от гирлянды (подсоединив к гирлянде сигнальный провод и "землю" и обеспечив для гирлянды и контроллера отдельные источники питания), но в итоге это не потребовалось.
И пара слов про падение питающего напряжения на светодиодных лентах. Ленты оснащены разъемами с обоих концов, так что можно их соединять последовательно или подавать питание с двух сторон. На двухметровую елку нам потребовалось 35 метров гирлянды (можно и больше, 40 — 50 метров вполне уместится), а измеренное напряжение на выходе гирлянды равно 3.7 V (вместо 5 V на входе). При этом, первые 20 — 25 метров гирлянды имеют визуально равную яркость, а далее яркость снижается и светодиоды выглядят заметно тусклее. При подаче питающего напряжения еще и на выход нашей гирлянды ее яркость становится равномерной. Таким образом, для гирлянды длиной от 20 и до 50 метров лучше предусмотреть подачу питающего напряжения с двух сторон. Мы используем пауэрбанк с двумя USB выходами, так что можно легко отключить подачу питающего напряжения к окончанию светодиодной ленты и продемонстрировать детям эффект падения напряжения.
Программирование устройства
Простой способ загрузки прошивки MicroPython Pimoroni Libraries на устройство и записи файлов программы предоставляет редактор Thonny, по ссылке доступны описания, как его установить и использовать на разных операционных системах (есть различия). Установка прошивки Raspberry Pi Pico начинается с его подключения к компьютеру при нажатой кнопке "BOOTSEL" на плате и выбора нужной прошивки в редакторе:
В списке также присутствует прошивка для платы Tiny 2040, но она работает очень нестабильно, так что пришлось раз пять перепрошить устройство, прежде чем удалось записать на него программу и библиотеку ИК приемника, а после перезагрузки плата перестала опозначаваться и работать. Проблема решилась использованием стандартной прошивки, как показано выше на скриншоте.
Для автозапуска файл программы должен иметь наименование main.py и размещаться в корневом каталоге устройства вместе с папкой lib для библиотеки работы с ИК приемником:
Для работы с разными микроконтроллерами RP2040 и подключения разных адресных лент в коде определены нужные константы, значения которых необходимо установить в зависимости от выбранной конфигурации.
Порядок цветов ленты задается константой:
# led strip colors order
#COLOR = plasma.COLOR_ORDER_RGB ;# Pimoroni LED strip and cube
COLOR = plasma.COLOR_ORDER_BGR ;# aliexpress LES strips
В случае, когда порядок цветов неизвестен, его легко можно проверить самостоятельно с помощью нижеследующего кода, перебирая все возможные варианты plasma.COLORORDER… или используя числовые коды от 0 до 5 включительно:
import plasma
led_strip = plasma.WS2812(350, 0, 0, 20, color_order=plasma.COLOR_ORDER_BGR)
led_strip.start()
led_strip.set_hsv(0, 0, 1.0, 1) ;# red
led_strip.set_rgb(0, 255, 0, 0) ;# red
led_strip.set_rgb(0, 0, 255, 0) ;# green
led_strip.set_rgb(0, 0, 0, 255) ;# blue
При правильно выбранном "color_order" цвет первого пиксела ленты должен соответствовать ожидаемым.
Количество светодиодов в ленте:
# Set how many LEDs you have
NUM_LEDS = 350
Пин подключения светодиодной ленты:
# LED strip pin
PIN_LED = 20 ;# LilyGO T-Display RP2040
#PIN_LED = 26 ;# Tiny 2040
#PIN_LED = 15 ;# plasma_stick (plasma_stick.DAT)
Пин подключения ИК-приемника:
# IR sensor pin
IR_PIN = 24 ;# LilyGO T-Display RP2040
#IR_PIN = 29 ;# Tiny 2040
#IR_PIN = 28 ;# plasma_stick
Код проекта смотрите по ссылке код MicroPython
Результаты
На видео показано, как выглядит гирлянда с эффектом снежинок:
И c эффектом радуги:
Заключение
И вот гирлянды собраны и работают, а дети научились новому и радуются необычным эффектам и возможности настроить все гирлянды с помощью пультов. После праздников елки мы уберем, а сделанные устройства будут служить дальше как пульты для машинок и для многих других самоделок, нужно будет лишь обновить программу. Всех с наступающим Новым годом!