APA102-2020 (он же DotStar) — это адресный трёхцветный светодиод с управлением по двум линиям. В действительности, это даже не один светодиод, а целый модуль, внутри которого есть три отдельных светодиода: красного, зелёного и синего свечения, а также специальная микросхема, которая позволяет соединять такие модули в цепочку и управлять ими по шине. Мы называем такие модули пикселями, так как это слово наиболее точно отражает их суть.
APA102-2020 имеет размер всего 2 x 2 миллиметра, так что из них можно собирать компактные сверхяркие матрицы. Также APA102 существуют в форм-факторе 5 x 5 мм (5050).
Надо отметить, что самым популярным адресным светодиодом является WS2812B, о котором мы уже рассказывали в одном из уроков: WS2812. Но в отличие от него, пиксель APA102 имеет ряд преимуществ:
- более быстрая шина, что позволяет делать POV устройства;
- может работать на низких частотах, что делает возможным его использование даже на относительно медленных контроллерах;
- для управления не требуется использовать DMA и прерывания; с одной стороны — это расширяет список применяемых контроллеров, а с другой — не занимает линии прерывания, от которых зависит работа других ценных устройств, в частности, динамиков (функция tone() в Arduino).
Однако, есть и недостатки:
- эти светодиоды имеют более высокую цену;
- для управления используется два контакта, вместо одного у WS2812.
На этом уроке мы научимся управлять одним, встроенным в плату Графит-RP2040, пикселем, а также сразу восемью APA102 на модуле светодиодный циферблат. Программу напишем при помощи CircuitPython.
Разумеется, эта инструкция подойдет и для других плат под управлением CircuitPython, таких как, например: Графит-S2, Raspberry Pi Pico, XIAO SAMD21 и т.д.
Список необходимых компонентов
Для выполнения примеров из данного урока, кроме светодиодного циферблата, потребуется отладочная плата Графит-RP2040 или аналогичная, с установленным CircuitPython, а также немного проводов розетка-розетка. Необходимые компоненты можно добавить в корзину прямо здесь, и затем оформить заказ в нашем интернет-магазине.
Библиотеки
Для работы с APA102 используем библиотеку adafruit_dotstar, которая имеется в стандартном наборе библиотек от Adafruit (ссылка в конце урока). Всё, что нам нужно сделать для её установки — это скопировать файл adafruit_dotstar.mpy в папку lib на накопителе CIRCUITPY.
Более подробно о работе с библиотеками CircuitPython мы писали в одном из ранних наших уроков: Библиотеки для CircuitPython
Программа
Первая наша программа будет зажигать пиксель тремя цветами по очереди: красный, зелёный, синий. Для работы понадобится подключить три python-пакета (они же библиотеки):
- time — для организации паузы;
- board — для использования имён контактов, соответствующих используемому контроллеру Графит-RP2040;
- adafruit_dotstar — собственно, для управления пикселем.
Затем инициализируем программный драйвер пикселя (в терминах ООП — создадим экземпляр класса DotStar):
pixels = dotstar.DotStar(board.APADI, board.APACI, 1, brightness=0.1)
В примере мы используем контакты APACI и APADI, которые подключены к ножкам CLK и MOSI встроенного пикселя. В общем же случае, для работы с пикселями мы можем использовать любые другие контакты контроллера, что и будет продемонстрировано позже, при работе со светодиодным циферблатом.
Третий аргумент — количество пикселей в цепочке. Пока у нас только один.
Четвёртый аргумент — brightness (яркость), отвечает за яркость всей цепочки. Этот параметр бывает полезен, когда нужно увеличить или снизить яркость цепочки пикселей, не изменяя конкретные цветовые компоненты каждого пикселя.
Для задания цвета пикселю с индексом 0 используем выражение вида:
pixels[0] = (255,0,0)
Три числа в скобках — это RGB (Red-красный, Green — зелёный, Blue — синий) компоненты цвета. В данном случае, светодиод вспыхнет красным цветом.
Наконец, вся программа целиком:
import time
import board
import adafruit_dotstar as dotstar
pixels = dotstar.DotStar(board.APADI, board.APACI, 1, brightness=0.5)
while True:
pixels[0] = (255,0,0)
time.sleep(0.25)
pixels[0] = (0,255,0)
time.sleep(0.25)
pixels[0] = (0,0,255)
time.sleep(0.25)
Сохраняем программу и пиксель начинает мигать разными цветами! С одним светодиодом разобрались, переходим к цепочке.
Цепочка пикселей
Подключим модуль светодиодного циферблата к любым двум цифровым контактам платы. Пусть линия CI (Clock In) модуля будет подключена к D5, а линия DI (Data In) к контакту D6 отладочной платы Графит-RP2040.
Напишем программу, которая будет зажигать по очереди все восемь пикселей. С учётом такой постановки, необходимо изменить параметры инициализации драйвера:
pixels = dotstar.DotStar(board.D5, board.D6, 8, brightness=0.5)
Теперь указаны нужные контакты и размер цепочки. Яркость поднимем до 0,5.
Для реализации задуманного используем цикл for, на каждой итерации которого мы будем сначала гасить все светодиоды разом, а потом зажигать очередной. Разумеется, можно поступить и по другому — гасить только предыдущий, не трогая все остальные.
Для того чтобы окрасить все пиксели в один цвет, применим функцию fill. В качестве единственного аргумента функции выступает цвет заливки.
В данном случае мы заливаем всю цепочку светодиодов чёрным цветом, а если быть более
pixels.fill((0,0,0))
Цвет (0,0,0) по сути отключает все компоненты пикселя, что нам и требуется. Вся программа целиком:
import time
import board
import adafruit_dotstar as dotstar
pixels = dotstar.DotStar(board.D5, board.D6, 8, brightness=0.1)
while True:
for i in range(0,8):
pixels.fill((0,0,0))
pixels[i] = (0,255,255)
time.sleep(0.25)
Сохраняем файл и смотрим на результат.
Радуга
Напоследок, перепишем на python программу, которая была написана для Arduino IDE в уроке про светодиодный циферблат. Данная программа рисует на циферблате радужный градиент и в цикле смещает начало радуги по кругу.
import time
import board
import adafruit_dotstar as dotstar
pixels = dotstar.DotStar(board.D5, board.D6, 8, brightness=0.5)
def Wheel(WheelPos):
WheelPos = 255 - WheelPos
if WheelPos < 85:
return (255 - WheelPos * 3, 0, WheelPos * 3)
if WheelPos < 170:
WheelPos -= 85
return (0, WheelPos * 3, 255 - WheelPos * 3)
WheelPos -= 170
return (WheelPos * 3, 255 - WheelPos * 3, 0)
while True:
for j in range(0,256,16):
for i in range(0,8):
pixels[i] = Wheel(int((i * 256 / 8) + j) & 255)
time.sleep(0.01)
Сохраняем файл и смотрим на буйство красок!
Полезные ссылки
Репозиторий Adafruit для библиотек CircuitPython:
https://github.com/adafruit/Adafruit_CircuitPython_Bundle/releases
Исходные коды библиотеки adafruit_dotstar:
https://github.com/adafruit/Adafruit_CircuitPython_DotStar
Документация по функциям библиотеки adafruit_dotstar: