119-Умные светодиоды WS2812B NeoPixels

Автор: | 24.07.2015

Светодиоды (пиксели) WS2812B и светодиодные ленты на базе этих пикселей довольно популярны и это оправдано по нескольким причинам:

— компактность — пиксель содержит в своем корпусе (размером всего 5х5 мм) 3 светодиода и драйвера для них
— простота управления – пиксель управляется посредством простого последовательного интерфейса, который легко реализовать как программно, так и используя аппаратные интерфейсы МК (такие как SPI и UART)
— управление всего по одной линии (не считая проводов питания)
— неограниченное количество включенных последовательно пикселей
— относительно небольшая стоимость (если посчитать стоимость отдельно 3х светодиодов и драйверов к ним выйдет гораздо дороже)

Эта статья попытка обобщить информацию (наверное, больше для себя) об умных светодиодах WS2812B в одном месте.

Начнем знакомство с серией WS

Первым идет WS2801

Фактически, это не светодиод а микросхема-драйвер для RGB-светодиода с последовательным интерфейсом SPI (есть линия данных и тактовая линия). Эти микросхемы используются во встраиваемых конструкциях пикселей:

Есть и ленты с использованием этих драйверов, но, наверное, их не найти уже.

WS2801.pdf - Даташит


Дальше — WS2811

Это тоже микросхема для управления RGB-светодиодом, но она уже компактней (8 ног, в отличие от WS2801 — 14 ног) и имеет однолинейный последовательный интерфейс.

WS2811.pdf - Даташит


Приближаемся — WS2812(S)

Это уже интегрированные в SMD корпусе 5050 и драйвер и сами светодиоды. Корпус 6-ти ножечный

Как и в предыдущем WS2811 интерфейс однолинейный, но тайминги протокола другие несовместимые.

WS2812.pdf - Даташит


И, наконец, WS2812B

Это почти аналог предыдущего светодиода, но уже с 4-мя ножками и слегка измененными таймингами протокола (совместимы, при использовании компромиссных значений временных периодов сигналов)

WS2812B.pdf - Даташит


Еще существует WS2812D (аналог PD9823)

Это полностью WS2812B но в корпусе обычного 8мм светодиода.

WS2812D.pdf - даташит


Нас, прежде всего, интересует именно 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 разные временные периоды, формирующие нули и единички. Но используя допустимые отклонения по времени можно реализовать протокол, который сможет работать без проблем с обоими пикселями.

(Visited 81 180 times, 1 visits today)

119-Умные светодиоды WS2812B NeoPixels: 67 комментариев

  1. Глеб

    Тогда еще вопрос,это наверное уже больше к пониманию. Почему у меня сначала почти все горело, потом при контакте погасло? И еще вопрос, получается дорожка Di последовательная? То есть, если я просто соединю провод сигнала с Arduino nano с со следующим неработающим диодом после того треснутого, то остальная дорожка должна засветиться?

  2. GetChiper Автор записи

    Да, сигнал данных проходит через каждый пиксель последовательно.
    Почему згорело не могу сказать — подобного у меня не было.
    Кстати, рекомендуется подключать линию данных через резистор до 1кОм

  3. Глеб

    Не помогло, вырезал сгоревший-не помогло, горят все также 6 диодов. Резистор установил,330 ом

  4. Глеб

    При изменении библиотеки и кода можно проверить каждый диод отдельно, все также не работают 6 и далее диоды. Эту ленту ведь можно резать каждый диод? Одна секция равна 1 диоду?

  5. GetChiper Автор записи

    Да, пиксели работают каждый самостоятельно. Можно подключать каждый отдельно.

  6. Юрий

    Привет! Вот заказал я ленту, 4 метра 30 светодиодов на метр, посчитал, и получается лента потребляет 2.4 ампера, т.к. она у меня будет работать и в режиме подсветки (не на всю) он будет потреблять около 5 ампер, можно ли подключить питание ленты посередине (знаю, вопрос детский) или все-таки лучше подключить питание в начале и в середине? P.S. Огромное спасибо за информацию!

  7. Артем

    Привет кто нибудь знает почему некоторые светодиодные ленты WS2812B зависают во время работы. На одном и том же оборудовании в равных условиях как это можно объяснить?

  8. Артем

    Без резистора и без конденсатора сама лента тоже без конденсаторов.
    https://ru.aliexpress.…311.0.0.151733edmkT45K
    WS2812B оснащена квадратным ШИМОМ красный и синий диод расположены на одной подложке а зеленый на другой все работает идеально.
    WS2812B-ECO оснащена прямоугольным ШИМОМ все диоды расположены на одной подложке зависает в разных местах.

  9. Юрий

    попробуйте с конденсатором на 1000мкф и резистором от 100ом до 500ом

  10. GetChiper Автор записи

    to Юрий
    При больших токах (и длинах ленты) обязательно подводящие линии питания нужно делать в нескольких местах по ленте, иначе лента будет перегреваться (вплоть до перегорания линий) и падение напряжения на конце ленты будут значительным.

  11. Юрий

    У самого теперь почему-то проблемы, пытался решить проблемы с ардуиной ( неправильно работал скетч), теперь при подключении питания ( просто + и — ) горят светодиоды (они как-будто застыли и горят так, как нужно было бы). Что делать?

  12. Юрий

    Я подключал с резистором на 100 ом и конденсатором по цепи питания на 3300 мкф

  13. Юрий

    Пытался решить проблемы с ардуиной ( неправильно работал скетч),переодически подключал светодиодную ленту, думал починил, но нет, теперь при подключении питания к светодиодной ленте ( просто + и — ) горят светодиоды (они как-будто застыли и горят так, как нужно было бы). Что делать? Я подключал с резистором на 100 ом и конденсатором по цепи питания на 3300 мкф. Пытался сделать цветомузыку, и до сих пор не получается, при подключении питания к ардуине, у нее горит красный светодиод и все, при подключении другой ленты, она не горит.
    Так легче понять

  14. Vladimir

    На очередной ленте обнаружилась неработоспособность на 1/256 яркости. Код один и тот же, многократно проверенный, подстройка кода ничего не дала. Оказалось — продавец подсунул WS2812B-ECO вместо настоящих. До этого с таким не сталкивался. Дальнейшее исследование выявило, что WS2812B-ECO используют просто сдвиг данных на 1 бит, что, разумеется приведёт к тому, что на полной программируемой яркости будет 50% ШИМ — что и подтвердилось. Указанное поведение даёт возможность сэкономить на светодиодных кристаллах и их монтаже без особого усложнения чипа (драйверы остаются 20 мА). Кристаллы СИД действительно оказались расположены на одной подложке, как и написано здесь. Будьте осторожны, возможно рынок ожидает наводнение очередным суррогатом. Спрашивайте продавца точную модель (не-ЭКО в явном виде). Из обычных пикселей при необходимости «ЭКО» делается сдвигом яркостей на 1 бит, но, к сожалению, из «ЭКО» обычных уже не сделать. Спасибо. P.S. Покупал здесь по причине того, что это одно из немногих мест, где доступен шаг пикселей 10 мм (это требовалось по ТЗ).

  15. Артем

    Vladimir Добрый день. Могли бы вы подсказать как сделать из обычной ленты ЭКО сдвинув яркость на один бит? Я так понимаю это должно уменьшить минимальную яркость самой ленты сравняв его с ЭКО вариантом верно?

Добавить комментарий