Купил на пробу светодиодов со встроенным драйвером сразу двух вариантов, в варианте отдельного драйвера и в варианте светодиода. Понимая что радиолюбитель не мигавший красиво диодиками не радиолюбитель. Распаял и я свою примитивную мигалочку, по сути отладочную плату.
Платка
Круглое число светодиодов (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 за такие возможности.
Эффекты
Больше трех так и не выдумал. Эффекты лежат в файле.
Радуга, в которой все светодиоды выстроены во все цвета радуги и плавно перетекают из одного цвета в следующий.
Из сериала рыцарь дорог с бегущим огоньком, и еще эмуляцией залипания огонька как на лампочках накаливания. Заранее написанную функцию радуги добавил и в него.
Огонь. Тупее всех остальных, просто пихаем в канал красного цвета рандомное число 0–255. А что бы огонек переливался с красного в желтый, генерируем рандом и для зеленого канала, но не даем ему быть ярче чем четверть красного. А еще ловим условием моменты когда красный больше 250, тогда включаем на всю все цвета, чтобы эмулировать искорки.
С одной стороны это обычная рутинная отладочная плата, с другой можно залипнуть возле этой полоски на пол дня, еще и в интернетах полно самостоятельных мегапроектов, ничего кроме тех же самых огоньков не предлагающих. Эффекты масштабируемые, можете зашивать их себе в ваши контроллеры со светодиодной лентой, меняя макрос Line size по вашему усмотрению.
Вывод
Чудная дрянь эти RGB светодиоды. Спокойно ужились и отдельный драйвер и светодиоды в одной цепи, не понадобилось никаких внешних элементов и ассемблерных вставок кода. Побольше бы такого дешевого китайского интегрального, простого в использовании и залипательного, и тик ток не нужон будет это ваш.
Комментарии (21)
Hisoka
00.00.0000 00:00Жирный минус этих светиков - слишком яркие на минимальной яркости и эффектов не получишь кроме вкл/выкл, т.к. яркость "регулируется цветом". Потому, для ламп-ночников не годятся.
IvanPetrof
00.00.0000 00:00Можно прикрыть их чем-нить полупрозрачным - покрасить, наклеить тонировочную плёнку ( для авто продаётся разной плотности)
csharpreader
00.00.0000 00:00Вот бы сейчас в 2023-м красить и плёнку колхозить. В 80-е накрасились и наколхозились.
Dakar
00.00.0000 00:00Правильно. Лучше мерзотный ШИМ вкорячить на частоте поменьше.
MW_dem1305
00.00.0000 00:00+1Всё там нормально управляется. Сделал драйвер без проблем, куча эффектов на фастлед, IR, датчик света, микрофон+FHT и PIR. Работает как надо.
dltex Автор
00.00.0000 00:00в те же 80е все газоразрядники прикрывались тонированным прозрачным пластиком, что бы яркие цвета стали загадочными полутонами. Кстати светодиодные индикаторы в китайских дивидишниках и тв dvbt приставках до сих пор тонированные, норм решение.
Sun-ami
00.00.0000 00:00Тонированный пластик нужен, чтобы при внешней засветке люминофор или рассеиватель выключенных сегментов не светился отраженным светом — это увеличивает уровень внешней засветки, при котором индикатор хорошо читается.
aumi13
00.00.0000 00:00+1слишком яркие на минимальной яркости и эффектов не получишь кроме вкл/выкл, т.к. яркость "регулируется цветом". Потому, для ламп-ночников не годятся.
какая-то ересь. нет такого.
osmanpasha
00.00.0000 00:00+1А зачем вам копировать рандом из AVR-libc? У gcc-arm свой должен быть (скорее всего примерно такой же). Точнее у newlib-nano или что там
dltex Автор
00.00.0000 00:00Я сперва себе для проекта с attiny вот эту функцию написал, https://github.com/dltech/desk_lamp/blob/main/lib/random127.c . А тут уже чисто по привычке скопировал, щас заглянул в исходники libnewlib, понял что тупанул.
comargo
00.00.0000 00:00+1Я В своё время пытался сделать HAL для светодиодов. В качестве исходных кодов для переписывания нашел работу через DMA и bit-banding и библиотеку для Ардуино от Алекса Гивера.
https://www.martinhubacek.cz/blog/stm32-ws2812b-dma-library/
agalakhov
Идея с UART хорошая, SPI конкретно на STM32 работает хуже. DMA не обязателен, достаточно включения буферизации у UART. Скорость должна быть 3.75 Мбод, 8-N-1, отправляются два бита в одном байте. Формат байта: 0xx100yy, где xx - первый бит, yy - второй бит (каждый бит повторяется дважды). Алгоритм проверен на WS2812 и SK6812. Моя реализация.
По-колхозному можно подавать на WS2812 и 3-вольтовую логику, в большинстве случаев они ее воспринимают, хотя это не гарантируется. Преобразовывать уровень в случае, если между диодами и схемой есть провод, надежнее не подтяжкой, а любым 74LVT. Если диодов очень много, то в качестве этого 74-го можно использовать демультиплексор, чтобы разбить светодиоды на несколько независимых групп, а не ставить все одной цепью.
AlanDrakes
Собрал как раз на SPI. Частота ядра - 20МГц, предделитель SPI - /4 (5МГц). 8 бит-слотов занимают 12.8мкс, 1 бит-слот - 1.6мкс (по какой-то причине светодиоды лучше всего заработали именно с этой скоростью). Данные отправляются по DMA. Используется 48 байт. 0x70 = '1', 0x40 = 0. Буфер кольцевой, 2*24 байта (бита). По прерыванию DMA уже отправленная половина буфера заполняется новыми значениями для передачи. 20 светодиодов вообще без сбоев приёма обновляются.
Диоды работают от того же питания 3.3В и чувствуют себя хорошо, как минимум, не отключаются и даже выходят на полную яркость (но ток потребления в батарейном устройстве для такого режима черезмерен, как и яркость для индикаторов).
agalakhov
На SPI пакость в том, что SPI довольно значительно различается между разными STM32 и местами даже между ревизиями одного и того же чипа, про него много Errata. Поэтому код получается плохо переносим. Это не значит, что он не будет работать, но с UART просто проще и переносимее. Код для UART вообще можно написать полностью переносимым и не зависящим от архитектуры контроллера, если его параметризовать функцией "послать байт".
dltex Автор
повторители ставят обычно что бы защитить нежные порты от агрессивного внешнего мира, а схема с OD внутри корпуса вполне нормальная, все I2C шины так и цепляются, и никто им логику дополнительно не ставит. В демультиплексорах смысл отпал, портов у современных контроллеров как котов у поехавшей старушки.
agalakhov
I2C работает на очень небольших дистанциях и чувствительна к помехам из-за большого сопротивления подтяжки и отсутствия согласования линии как класса. Повторитель с push-pull выходом имеет меньшее выходное сопротивление и допускает более длинные кабели, что как раз для светодиодов актуально.
Простое решение для длинного кабеля без отдельного повторителя - поставить первый светодиод на саму плату с контроллером, а кабель уже после него.
Демультиплексоры актуальны, если процессор рулит не только светодиодами. Израсходовать 100+ пинов гораздо проще, чем кажется, особенно если нужно вешать внешнюю память и/или дисплей. Если не уложиться в 176 пинов, придется паять BGA.
dltex Автор
Сперва покажи мне проект со 100+ матрицами на 1024 светодиода на длинных проводах подключенных к обычному контроллеру, потом уже говори что так нельзя. Пока что ваше решение разве что дороже, но не лучше.
agalakhov
Приезжай в Ольденбург, покажу. У нас хакспейс на полторы тысячи квадратных метров, все этими светодиодами увешано.