Светодиоды (пиксели) WS2812B и светодиодные ленты на базе этих пикселей довольно популярны и это оправдано по нескольким причинам:
— компактность — пиксель содержит в своем корпусе (размером всего 5х5 мм) 3 светодиода и драйвера для них
— простота управления – пиксель управляется посредством простого последовательного интерфейса, который легко реализовать как программно, так и используя аппаратные интерфейсы МК (такие как SPI и UART)
— управление всего по одной линии (не считая проводов питания)
— неограниченное количество включенных последовательно пикселей
— относительно небольшая стоимость (если посчитать стоимость отдельно 3х светодиодов и драйверов к ним выйдет гораздо дороже)
Эта статья попытка обобщить информацию (наверное, больше для себя) об умных светодиодах WS2812B в одном месте.
Начнем знакомство с серией WS
Первым идет WS2801
Фактически, это не светодиод а микросхема-драйвер для RGB-светодиода с последовательным интерфейсом SPI (есть линия данных и тактовая линия). Эти микросхемы используются во встраиваемых конструкциях пикселей:
Есть и ленты с использованием этих драйверов, но, наверное, их не найти уже.
WS2801.pdf (4758 Загрузок)
Дальше — WS2811
Это тоже микросхема для управления RGB-светодиодом, но она уже компактней (8 ног, в отличие от WS2801 — 14 ног) и имеет однолинейный последовательный интерфейс.
WS2811.pdf (Одна Загрузка)
Приближаемся — WS2812(S)
Это уже интегрированные в SMD корпусе 5050 и драйвер и сами светодиоды. Корпус 6-ти ножечный
Как и в предыдущем WS2811 интерфейс однолинейный, но тайминги протокола другие несовместимые.
WS2812.pdf (5860 Загрузок)
И, наконец, WS2812B
Это почти аналог предыдущего светодиода, но уже с 4-мя ножками и слегка измененными таймингами протокола (совместимы, при использовании компромиссных значений временных периодов сигналов)
WS2812B.pdf (9328 Загрузок)
Еще существует WS2812D (аналог PD9823)
Это полностью WS2812B но в корпусе обычного 8мм светодиода.
WS2812D.pdf (4392 Загрузки)
Нас, прежде всего, интересует именно WS2812B, так как он наиболее популярный и недорогой. Его чаще всего используют радиолюбители в своих конструкциях как отдельно, так и в лентах.
Принцип работы WS2812B — официальная информация из даташита.
Физически в WS2812B имеется 3 излучающих светодиода (красный, синий и зеленый) и ШИМ-драйвера управляющие их яркостью. ШИМ-драйвера 8-ми битные, то есть для каждого из цветов возможны 256 градаций яркости и, соответственно, для того чтобы установить яркости для каждого из 3-х светодиодов нужно передать пикселю 8х3=24 бит (3 байта) информации. Протокол передачи информации светодиоду однолинейный с фиксированной скоростью. Единички и нули информации о яркости кодируются длительностью высокого и низкого уровня сигнала в линии.
Время передачи одного бита составляет 0.8+0.45=1.25 мкС — это довольно быстро. Время передачи всего пакета из 24 бит для одного пикселя WS2812B составляет 24*1.25=30 мкС. Для 1000 штук — 1000*30=30 мС (что, например, позволяет обновлять по одной линии панно 30х30 пикселей с частотой 30 раз в секунду!).
Каждый из пикселей WS2812B имеет 2 вывода питания (VDD, VSS), вход (DIN) и выход (DOUT).
На вход DIN подается информация (24бита) для установки нового цвета. Информация о цвете передается побитно (начиная со старшего бита) последовательно для каждой из составляющей цветов G, R, B.
Пиксели соединяются в цепочку следующим образом:
Запись значений цвета цепочке пикселей происходит следующим способом:
Первые 24 бита поданные на DIN записывает себе во временную память (цвет пока остается неизменным с предыдущего раза) первый пиксель. Последующие биты первый пиксель пропускает через себя и выдает на выход DOUT. Второй пиксель повторяет действия первого (оставляя себе первые дошедшие до него 24 бита) и так по цепочке. Для того, чтобы значения цветов из временной памяти пикселей стали активными должна быть выдержана пауза в передаче (reset code) в течении 50мкС. После этой паузы цикл можно повторять снова.
Вот это основное, что нам говорит довольно скудный даташит.
Теперь более интересная часть –
Практические способы включения ленты и реализации протокола WS2812B.
То, о чем умалчивает даташит, я собрал из разных источников у людей имевший практический опыт работы с WS2812B. Конечно, это больше касается лент.
Для начала, общие советы (по большей части взятые с https://learn.adafruit.com):
— подключайте к ленте (между линиями питания) конденсатор побольше, вплоть до 1000 мкФ
— в разрыв линии данных (от МК к ленте) добавляйте резистор 300 — 500 Ом, устанавливая его ближе к ленте.
— по возможности, делайте короче провод данных к ленте
— при «горячем» подключении ленты, подключайте «землю» первой (отключайте последней)
— если лента запитана от отдельного источника питания, ее нужно запитать первой (после чего запитать схему управления)
— не допускайте статического электричества при монтаже ленты
— используйте преобразователь уровня, если лента и устройство управления запитаны от источников питания с разным напряжением
— напряжение питания пикселей, заявленное в даташите, лежит в пределах +3.5 ~ +5.3 вольт. Из чего видно, что предпочтительней подавать на ленту меньше 5ти вольт (этим правилом следует пользоваться при выборе количества элементов при батарейном питании)
— максимальный ток каждого пикселя составляет 60мА (при полной яркости белого цвета). Если Вы не планируете использовать ленту WS2812B как источник белого света (для этого лучше взять обычную светодиодную ленту с белыми светодиодами), то принято считать, что, усреднено, каждый пиксель потребляет 20мА.
Соответственно:
минимальный ток ИП = 20мА*количество_пикселей.
максимальный ток ИП = 60мА*количество_пикселей
— из последнего пункта вытекает следующее: если лента длинная, то недопустимо подавать на нее питание только с одной стороны. Для того чтобы исключить перегревание (или даже перегорание) токопроводящих дорожек ленты, питание ленты необходимо распределить по всей ее длине, подводя питание в нескольких местах отдельными проводами.
Теперь более ценные советы по реализации протокола
Есть несколько способов реализовать протокол умных светодиодов:
— аппаратный при помощи SPI-интерфейса
— аппаратный при помощи UART-интерфейса
— программный
Достоинство первых двух способов – это возможность освободить МК от части работы по передаче бит информации о цвете пикселю. Недостатки этих способов – во-первых, ограниченное количество линий управления пикселями (у МК редко бывает много незадействованных интерфейсных выходов), во-вторых, требуется дополнительное разбитие байтов информации о цвете на пачки битов (что частично съедает свободное время МК в моменты аппаратной передаче бит)
Реализация протокола WS2812B (NeoPixel) при помощи SPI
Прежде, чем приступить к реализации, следует акцентировать внимание, что у WS2812B кодирование нулей и единичек происходит по правилу 1/3 (смотрите даташит выше). То есть ноль передается как 1/3 времени высокий уровень и 2/3 низкий. Единица – это 2/3 высокий и 1/3 низкий. Из этого следует, что для передачи одного бита для WS2812B нам достаточно 3х бит переданных по SPI.
Как видно на картинке, чтобы сформировать нужную последовательность нулей и единиц, нам придется дробить первичную информацию о цвете на кусочки, кроме того, в байт, передаваемый по SPI, не вписывается триады и их придется дробить тоже, перенося часть информации о бите для пикселя в следующую посылку… выходит очень запутано и сложно.
Но есть решение этой проблемы! Забегая наперед, сообщу, что для пикселя важна длительность периода высокого уровня, а низкий уровень может быть с бОльшим отклонением, чем указано в даташите. Поэтому мы может удлинить наши цепочки бит SPI с трех до четырех:
Вот теперь алгоритм становится более простым и приемлемым к реализации.
Для выдачи информации на пиксели используется только один вывод SPI – MOSI. Выводы MISO и SCK остаются незадействованными. Частота SPI должна быть 1/0.4мкС = 2.5МГц
Реализация протокола WS2812B (NeoPixel) при помощи UART
Все, о чем я писал для SPI, подходит и для UART, но тут есть несколько моментов, которые усложнят реализацию:
— UART в паузах удерживает свою выходную линию (TXD) в высоком уровне, что для пикселей недопустимо, так как невозможно будет избежать неопределенностей в моменты начала и окончании передачи
— соответственно, нужно инвертировать сигнал перед подачей его на пиксели
— а, так как линия инвертируется, нужно инвертировать и передаваемые данные
— UART-пакет, в отличии от SPI, содержит служебные биты – это старт-бит и стоп-бит (бит четности нужно отключать в настройках UART — он не нужен). Дополнительные биты служебной информации нужно учитывать при формировании передаваемого байта, так как они тоже пойдут в пиксель
В итоге, если учесть все нюансы, получается идеальная реализация протокола. Устанавливаем скорость UART 2.5 МГц (это нестандартно), устанавливаем размер кадра 7 бит (вместо стандартных 8-ми), убираем бит четности, оставляем один стоп-бит и получаем следующую картинку:
Программная реализация протокола WS2812B (NeoPixel)
Переходим к тому разделу, ради которого я и писал эту статью (но, видимо, увлекся по ходу 🙂 ). Для меня интересней реализовать этот протокол программно, так как эта реализация дает мне произвольное количество линий у МК к которым можно подключить ленты и управлять ими независимо. Это плюс. Минусом является то, что протокол довольно быстрый и это накладывает ограничения на процедуру формирования сигналов и, конечно, в моменты вывода значений цвета все прерывания у МК должны быть запрещены.
Первая проблема, которую придется решать – это формирование малых временных интервалов.
Для примера. МК работает на частоте 16МГц. Время одного такта 0,0625 мкС
Для формирования интерфейса WS2812B нам нужно формировать 2 временных интервала: 0,4мкС (6 тактов) и 0,85мкС (14 тактов). Всего период бита составляет 20 тактов. Очевидно, язык высокого уровня не способен сформировать код с точной размерностью по тактам. Это возможно реализовать только на языке низкого уровня – придется использовать ассемблер (по крайней мере, только для этой процедуры).
Дальше возникает проблема с точностью формирования этих промежутков. Если мы говорим о передаче данных только для одного пикселя (3 байта), то периоды можно соблюсти очень точно, прописав отдельно буквально каждый бит. Другое дело если нам нужно передавать массив значений в одной посылке без пауз. Тут придется создавать алгоритм, который, кроме того что формирует сигнал (дрыгает ногой МК), еще и считывает данные с массива данных в SRAM (или Flash), возможно, осуществляет несложную обработку данных. В этом случае очень сложно будет уложиться в 20 тактов периода передачи бита и, неизбежно, будут возникать ситуации, где потраченное на обработку время превысит допустимые значения. Вот тут нам помогут исследования проведенные здесь:
Привожу итоговую таблицу того что допускает протокол в плане ухода от даташита.
Более детально читайте в статье по ссылке выше, но если кратко — протокол требует более жесткого формирования периодов сигнала с высоким уровнем, а периоды с низким уровнем могут быть значительно затянуты. Это дает нам простор для реализации «тяжелых» мест.
Далее, даташит нам дает время паузы после которой происходит защелкивание новых значений цвета – 50 мкС. По факту, защелкивание начинается уже после 10 мкС – нужно стараться не делать паузы больше 10 мкС во время передачи длинных пакетов данных.
И последнее, как видно из приведенных выше даташитов, у пикселей WS2812 и WS2812B разные временные периоды, формирующие нули и единички. Но используя допустимые отклонения по времени можно реализовать протокол, который сможет работать без проблем с обоими пикселями.