Pull to refresh

WS2812B/WS2811 + STM32

Level of difficultyEasy
Reading time4 min
Views7.1K

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

Платка

Круглое число светодиодов (8 штук) + 9-й светодиод с драйвером для проверки. Кроме самих светодиодов судя по datasheet не нужно ничего, даже шунтирующих конденсаторов по 0,1 мкФ. Хотя для варианта с отдельным драйвером конденсатор советуют. Отдельно советуют, но не обязывают пощадить порт микроконтроллера, а заодно и выходной порт светодиода токоограничивающим резистором на 30 Ом. Я же ошибок себе не прощаю, потому им пренебрег. Вот что значит современные высоко-интегрированные решения, плата свободно вывелась в одном слое. По итогу можно смело подключать к контроллеру, Остается одна проблема, светодиоды питаются от 5В, и рассчитаны на пятивольтовый порт ввода-вывода, а в STM32 3.3.

Порт ввода-вывода (совместимость 5В и 3,3В)

Судя по datasheet к старым микросхемам 70х, единица начинается у них с 2,4В, а падение напряжения на Pull-Up транзисторе микроконтроллера 0,2В и не более 0,3В. Получается что +3В при +2,4 предельно допустимых, уже на грани, но в большинстве случаях может и прокатить. Прокатило и здесь.

Если по честному тогда в случае с STM32 подойдут не все порты, а только те что допускают 5В. Отличие обычных от пятивольтовых одно, на обычных стоит защитный диод, выравнивающий напряжения с напряжением питания, который и не разрешит подать 5В. Пятивольтовые помечаются пометкой FV в таблице datasheet. В итоге для работы с пятивольтовой логикой нужно сконфигурировать такой порт в режиме открытый сток (open drain), подтянув к +5В внешним резистором. Но здесь была замечена еще одна странность или пятивольтовых портов не бывает, или порт WS2812 очень прожорливый. Сформировать 0-5В получилось только с 500 омным резистором, с килоомными резисторами единица падала до 3,4В. Но опять же все эти трюки необязательны, потому как прокатывает и так.

Протокол светодиода

Код доступа к светодиодам в файле ws2812.c. В datasheet что то говорится про NRZ, я же чую что их протокол похож на 1-wire в DS18B20. С той лишь разницей что тайминги там наносекундные, в то время как на ds микросекундные. Организовать такой протокол сложнее, атмеговоды пишут код на ассемблере что бы строго отмеренным количеством NOP-ов поддерживать нужные тайминги. В случае с STM можно обойтись и обычным таймером, главное убрать из функции передачи данных в светодиод лишнее барахло вроде вызова других функций, тогда получится вписаться в строгие тайминги. У меня получилось не сразу, сразу не понял, что таймер для следующего бита нужно обнулять в конце цикла а не в начале, т.к. иначе на каждый бит уходит не одинаковое время и это сбивает отправку. Вообще оставалось еще два крайних варианта, это либо использование ШИМ с DMA, либо UART. В uartе каждый байт бы символизировал бит (с dsками такой трюк работал), а в варьируя по dma скважность ШИМ так же можно было бы подавать 0 и 1. Но опять же раз уж прокатил ручной вариант, то пускай он и работает, да и меня буфферы с intом для каждого бита не впечатляют.

Остальные особенности

Видимо из за удобства разводки светодиоды не RGB а ГРУ, вернее GRB. В то время как драйвер нормальный, RGB. Пришлось добавить отдельную функцию переворачивалку туда и обратно. В остальном очень удобно объявить union который когда надо три переменных по 8 бит с красным синим и зеленым цветом, а для функции отправки одно 32 битное число. По итогу все происходит внутри библиотеки, а вам нужно запихать массив структур с цветами светодиодов в функцию wsUpdateCascade(*led_array, size), не забыв указать при этом какой из них 11й, а какой 12й в поле type. На этом низкоуровневые мучения заканчиваются, начинается веселье.

Random

Какие же эффекты без рандома. Благо что за целочисленным рандомом далеко ходить не надо. Я скачал исходники AVR-libc и скопировал оттуда функцию rand. Там она целочисленная и 32 битная, то что нужно для STM32, но никак не для меги. Обожаю opensource за такие возможности.

Эффекты

Больше трех так и не выдумал. Эффекты лежат в файле.

  1. Радуга, в которой все светодиоды выстроены во все цвета радуги и плавно перетекают из одного цвета в следующий.

  2. Из сериала рыцарь дорог с бегущим огоньком, и еще эмуляцией залипания огонька как на лампочках накаливания. Заранее написанную функцию радуги добавил и в него.

  3. Огонь. Тупее всех остальных, просто пихаем в канал красного цвета рандомное число 0–255. А что бы огонек переливался с красного в желтый, генерируем рандом и для зеленого канала, но не даем ему быть ярче чем четверть красного. А еще ловим условием моменты когда красный больше 250, тогда включаем на всю все цвета, чтобы эмулировать искорки.

С одной стороны это обычная рутинная отладочная плата, с другой можно залипнуть возле этой полоски на пол дня, еще и в интернетах полно самостоятельных мегапроектов, ничего кроме тех же самых огоньков не предлагающих. Эффекты масштабируемые, можете зашивать их себе в ваши контроллеры со светодиодной лентой, меняя макрос Line size по вашему усмотрению.

Вывод

Чудная дрянь эти RGB светодиоды. Спокойно ужились и отдельный драйвер и светодиоды в одной цепи, не понадобилось никаких внешних элементов и ассемблерных вставок кода. Побольше бы такого дешевого китайского интегрального, простого в использовании и залипательного, и тик ток не нужон будет это ваш.

Tags:
Hubs:
Total votes 13: ↑12 and ↓1+11
Comments23

Articles