Протокол ws2812b на stm32 без пустых циклов и прерываний и как сделать правильную радугу

Обновлено: 04.07.2024

Недавно мне в комментариях написали, что хотели бы видеть на канале, пример как сделать бегущую строку на светодиодной ленте. А мне как раз пришла посылка с матрицей 32х8. Так что я с удовольствием исполняю просьбу подписчика.
По мимо этого в этом видео будет рассказано как можно менять шрифт для вывода на ленту используя встроенные шрифты в библиотеку Adafruit GFX, а так же создавать свои шрифты и загружать их в свой проект.
Правда это не работает с русскими шрифтами, но научиться всё равно надо, так как вы сможете сами нарисовать свои буквы или скачать библиотеки с готовыми шрифтами. Я их тоже находил в интернете, но все они работают если ширина ленты от 12 пикселей, а вот на 8 мне найти не удалось. А может быть плохо искал.
Если будут пожелания, то я сделаю 2 часть конкретно про шрифты, но мне кажется что и одного шрифта вполне достаточно.
Быстро рассмотрим скетч и перейдём к примерам. Для работы надо установить библиотеки. Так как я показываю на примере светодиодной матрицы, то мне и надо скачать библиотеку для матрицы.
Набираем матрих и нам выбираем библиотеку NeoMatrix. В подсказках вам будет сказано, что для работы вам надо установить ещё библиотеку GFX и НеоПиксель. Вторая нам необязательна, но все равно установим. Она будет нужна для работы со светодиодной лентой.
Нажимаем установить и ждём когда установится. Но не всё так просто. Если всё так и оставить, то у вас не будет отображаться русский шрифт, а только англоязычный. Для вывода нашего могучего надо заменить файл glcdfont.c или проще установить библиотеки из моего архива.
Теперь скетч.
Это подключение двух библиотек которые необходимы для работы.
Чтобы не рыскать по коду я создал переменную текст и сохранил в ней текст для вывода. Количество букв может быть и больше. Какое максимальное значение я не проверял. Если будут энтузиасты, то напишите в комментариях сколько букв вам удалось вывести.
Светодиодную Матрицу я подключил к выходу 9 Ардуино. Не забываем, что подключать надо через токоограничивающий резистор примерно 300 - 500 Ом. Впрочем как и любой светодиод.
Здесь основные настройки матрицы.
Сначала указываем ширину и высоту матрицы. У меня это 32 x 8.
Дальше указываем где первый светодиод, то есть откуда начинать отсчёт.
Затем указываем что матрица сделана столбцами и подключена зигзагом. В предыдущих видео я рассказывал что это такое.
Указываем расположение цветов на ленте. GRB. Это именно так. Сначала идёт Зелёный, затем Красный, и последний Синий, а не как мы привыкли RGB.
Ну и наконец скорость передачи данных 800 кГц.
Теперь создаём массив цветов которым будет выводиться цвет. Он может быть любым и цвета могут быть любыми. Дальше в видео я всё это буду объяснять более подробно. Здесь я вывел красный, зелёный и синий, для простоты кода.

Setup программы очень простой.

Функция руссификатор переводит буквы в киррилицу.
Начнём с подключения ленты. Схему подключения я покажу дальше, а пока объясню код.
У вас может быть разное подключение, то есть начало ленты может быть в разных местах. У меня сейчас начало справа снизу, поэтому я и указываю так в скетч. Если у вас с другой стороны то вам надо поменять эти строчки. Сейчас я переверну ленту и у меня начало будет слева сверху. И как видите текст выводится к верх ногами. Изменим код, и как видите теперь всё показывается правильно.
Это мы экспериментировали со статичным текстом. Теперь давайте его оживим.

Всё оживление – это вот этот цикл который выводит посимвольно наш текст и передвигает его на одну позицию влево. Зная размер матрицы, а мы её знаем это сделать не сложно.
Теперь изменим текст на более длинный. Ещё вам надо увеличить это значения, если этого не сделать, то не все символы могут быть показаны или если текст маленький а значение большое, то между повторами будет большой интервал и на матрице между просмотрами будет пустой экран.

В скетче который будет для скачивания я создал переменную для хранения текста и вынес её наверх кода для лучшего и более простого изменения.
Теперь поиграемся со шрифтами. Напоминаю, что мы можем это делать только с текстами на латинице.
Вот список доступных шрифтов который находится в папке FONTS, который стал доступен после установки библиотеки Adafruit GFX. Он находится в папке с библиотекой, в папке FONTS.
Как можно видеть, все шрифты сделаны для вывода на 9, 12, 18 и 24 пикселя. Так что если вы делаете для матрицы 16 на 32 или больше, то спокойно можете использовать любой из этих шрифтов.

Ну вот. Теперь мы видим, что шрифт изменился. Выглядит конечно он не очень хорошо, ну это и понятно, ведь эти шрифты сделаны не для светодиодов а для OLED или TFT дисплеев. Там они смотрятся просто отлично.

Давайте посмотрим как обстоят дела с другим шрифтом. Всё так же берём его из папки FONTS. Подключаем его и смотрим.
Этот выглядит ещё хуже, но нам важен сам процесс. Нам надо научиться менять шрифты, и на какие будем разбираться позже. Возможно вы сами сделаете свой шрифт и подключите его.
Для закрепления темы подключим ещё один шрифт, может повезёт и мы найдём шрифт посимпатичнее. Как подключать я уже рассказывать не буду, просто сделаем и посмотрим.
Вот этот вроде ничего себе так. На нём и остановимся. Теперь я надеюсь, что вопросов как подключать шрифты из библиотеки быть не должно. Но есть ещё шрифты созданные другими пользователями. Есть программы для создания шрифтов. Если будут желающие, то я сниму продолжение этого видео.
Например есть вот такая программа для создания кода из уже имеющихся шрифтов. Как выглядит шрифт можно посмотреть на экранчике. Повторюсь что здесь так же будет не доступен русский шрифт, но если вам подходит латиница. Например вы хотите написать WELCOME то это как раз для вас. В этой программе нет ничего сложного. После создания вы копируете код и сохраняете его с расширение h. И подключаете как мы это уже делали. Если что не понятно спрашивайте в комментариях. Постараюсь ответить на все вопросы. Правда сами понимаете, вас много, а я один. Так, что не обижайтесь если ответ затянится по времени или его не будет. Я делаю всё возможное.

Вот так выглядит шрифт из программы.
Ну и последним в этом видео рассмотрим как изменять цвета светодиодов а матрице. Чтобы не запоминать значения к разным цветовым палитрам можно использовать онлайн программы. Это одна из них. Здесь можно выбрать нужный цвет, скопировать значения и вставить в свой код. И ваш текст окрасится в нужный вам оттенок.

Рассмотрим подключение светодиодной ленты или панели со светодиодами WS2812/WS2812B, принцип и особенности их работы, а также управление панелью с помощью микросхемы FT2232H по интерфейсу SPI.

Для проекта нам понадобятся:

    или лента со светодиодами WS2812B; ;
  • персональный компьютер или ноутбук.

1 Описание RGB светодиодов WS2812 и WS2812B

Светодиод WS2812 (или его модификация WS2812B, которая и будет использована в данной статье) представляет собой RGB светодиод. То есть в одном корпусе представлены сразу три светодиода разных цветов: красный, зелёный и синий.

Внешний вид и габариты светодиодов WS2812

Внешний вид и габариты светодиодов WS2812

Светодиод WS2812 имеет 6 выводов, в то время как WS2812B – лишь 4.

А вот назначение выводов светодиода WS2812B:

Для примера на схеме показано последовательное подключение трёх светодиодов. На вход DIN первого светодиода подаётся управляющий сигнал. Светодиод обрабатывает его и передаёт далее со своего выхода DOUT на вход следующего в цепочке светодиода. И так сигнал проходит по всей цепочке светодиодов, каждый из которых считывает свою управляющую последовательность и изменяет свой цвет и интенсивность в соответствии с пришедшей командой.

Последовательное подключение светодиодов WS2812B

Последовательное подключение светодиодов WS2812B

На фотографии представлена панель размером 10 на 10 светодиодов, с которой мы и будем экспериментировать. Как видно, на нижней части панели светодиоды соединены в единую цепочку.

Внешний вид панели из светодиодов WS2812B
Верхняя сторона панели светодиодов WS2812B
Внешний вид панели из светодиодов WS2812B
Нижняя сторона панели из светодиодов WS2812B

Управление светодиодной панелью WS2812B

Управление светодиодной панелью WS2812B

Приблизительное потребление вашего устройства можно оценть так. Один канал светодиода на максимальной яркости потребляет около 20 мА. В одном корпусе располагаются 3 светодиода. Следовательно, один RGB светодиод в максимуме потребляет до 60 мА тока. Умножаете это число на количество светодиодов в вашей матрице или ленте – это и будет максимально возможное потребление, и ваш источник питания должен иметь возможность выдать такой ток.

2 Управление светодиодами WS2812B (или WS2812)

Если просто подать на светодиодную ленту напряжение, ничего не произойдёт. Светодиоды ждут определённый сигнал, который будет ими управлять. Для управления используется последовательный однопроводный интерфейс. Биты "0" и "1" кодируются импульсами различной длины.

Коды нуля, единицы и сброса светодиода WS2812B

Коды нуля, единицы и сброса светодиода WS2812B

На диаграмме обозначены:

  • T0H – время выдержки высокого уровня при передаче кода логического нуля;
  • T0L – время выдержки низкого уровня при передаче кода логического нуля;
  • T1H – время выдержки высокого уровня при передаче кода логической единицы;
  • T1L – время выдержки низкого уровня при передаче кода логической единицы;
  • Treset – время сигнала оповещения об окончании управляющей последовательности.

Причём временные допуски заданы весьма жёстко. Так, для WS2812B время T0H = T1L и составляет 0,35 мкс, а время T1H = T0L и составляет 0,9 мкс. Для светодиода WS2812 временные параметры более изощрённые: T0H = 0,35 мкс, T1H = 0,7 мкс, T0L = 0,8 мкс, T1L = 0,6 мкс. Но длительность передачи одного бита и там, и там составляет 1,25 мкс.

Для указания цвета светодиода используется 24-битная схема RGB: под каждый из трёх каналов отводится по 8 бит. И расположены цвета в следующем порядке:

Кодирование цвета в пространстве RGB для светодиода WS2812B

Кодирование цвета в пространстве RGB для светодиода WS2812B

Осталось дело за малым: передать цепочке светодиодов WS2812B осмысленную управляющую последовательность.

На этот счёт есть такая идея. По сути нам необходимо передавать 24-битные значения цвета в соответствии с положением светодиода в матрице 10 на 10. Аналогичным образом данные хранятся в графических файлах формата *.BMP. Только у них в начале файла ещё присутствует заголовок, который содержит дополнительную информацию: размер изображения, сколько бит приходится на один пиксель, есть ли сжатие и т.д. Вот как в деталях устроен формат BMP:

Внутреннее устройство формата BMP

Внутреннее устройство формата BMP

Обратите внимание, что в массиве данных о точках изображения BMP содержатся заполнители (Padding), которые дополняют строку байтов до числа, кратного 4. Т.е., например, в нашем случае строка содержит 10 пикселей по 24 бита на цвет (3 байта). Соответственно, строка будет содержать 3×10=30 байтов. Но 30 не кратно 4. Ближайшее число, кратное 4, это 32. Соответственно, в файле BMP будет на каждую строку изображения на 2 байта заполнителя больше. Байты-заполнители нужно пропускать и не включать в управляющий массив.

Ах, да, чуть не забыл. В файле изображения BMP данные о цвете хранятся в формате R-G-B, а светодиод WS2812 принимает цвет в формате G-R-B. Необходимо поменять местами цвета, иначе все изображения будут совсем не тех цветов, которые мы ожидаем.

3 Управление светодиодной панелью WS2812B по SPI с помощью FT2232H

Предлагаю использовать для управления диодами WS2812B отладочную плату с микросхемой FT2232H и программу SPI via FTDI, которые уже не раз нас выручали. Единственная загвоздка в том, что FT2232H не может формировать импульсы с заданной длительностью. Придётся сымитировать их. Идея здесь следующая.

Будем использовать режим SPI и его линию MOSI для передачи двоичных данных загрузки светодиодов. Причём необходимо выбрать такую частоту передачи, чтобы длительность одного бита равнялась 1,25 мкс. Т.к. нам вместо одного бита нужно передавать четыре, то для обеспечения той же длительности одного бита управляющей последовательности частота SPI должна быть в 4 раза выше: вместо 1/1.25 будет 4/1.25 мкс = 3.2 МГц. Это микросхема FT2232H способна обеспечить.

Если сформировать произвольную управляющую последовательность и посмотреть её на осциллографе, то увидим, что эта идея вполне работоспособна: на осциллограмме видны 6 логических единиц, а затем логический ноль. Причём длительность передачи одного бита в среднем равняется как раз тем самым 1.25 мкс.

Осциллограмма части управляющего сигнала светодиодами WS2812B

Осциллограмма части управляющего сигнала светодиодами WS2812B

Теперь, когда мы умеем формировать биты необходимой длительности, нужно взять массив, считанный из соответствующего раздела BMP файла, и преобразовать его побитово в то, что нам нужно (бит "0" – в 0x8, "1" – в 0xE).

Параметры программы при загрузке управляющего массива WS2812

Параметры программы при загрузке управляющего массива WS2812

Включение первых трёх светодиодов панели WS2812B

Включение первых трёх светодиодов панели WS2812B

Когда мы загрузим управляющую последовательность, сгенерированную программой, на панели загорится изображение, которое мы чуть ранее нарисовали в графическом редакторе.

Управление светодиодной панелью WS2812B

Управление светодиодной панелью WS2812B

С помощью такой панели можно создавать довольно красивые и зрелищные эффекты, как, например, цветовые градиенты:

Рисование с помощью светодиодной панели WS2812B
Рисование с помощью светодиодной панели WS2812B
Градиент с помощью светодиодной панели WS2812B
Градиент с помощью светодиодной панели WS2812B

Как развитие данной идеи, с помощью такой LED-панели можно воспроизводить анимацию. Для этого можно создать управляющий файл, в котором последовательно будут содержаться управляющие массивы для всех кадров анимации, а для обеспечения пауз между кадрами будет необходимое число нулей. Посчитать число нулей несложно, если вспомнить, что время передачи одного бита составляет 1,25 мкс.

Адресная светодиодная лента – это украшение любого проекта Arduino. С ее помощью вы можете создавать светомузыку, умную подсветку для телевизора, бегущие строки и другие проекты, в которых требуется отобразить информацию на широком экране. Благодаря встроенным контроллерам, вы можете управлять каждым из светодиодов ленты в отдельности, управляя ими как пикселями на экране. В этой статье мы разберемся, как работает адресная светодиодная лента, как ее подключить к Ардуино и какие библиотеки лучше использовать для управления.

Адресные светодиодные ленты

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

Адресная светодиодная лента WS2811

Сегодня наибольшей популярностью пользуются разноцветные светодиодные ленты RGB-формата, позволяющие получать множество цветов. Благодаря конструкции есть возможность управления цветом каждого светодиода, что позволяет создавать оригинальные световые эффекты. Главное отличие адресной светодиодной ленты от обычной RGB ленты – это наличие специальных контроллеров (конструктивно выполненных в виде микросхем) возле каждого светодиода, что и дает возможность индивидуальной адресации и регулирования каждого оттенка.

Как правило,л ента содержит 3-4 контакта для подключения. Два вывода используются для питания – 5 Вольт и земля, остальные один или два – логический, для управления свечением.

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

Самыми популярными адресными светодиодными лентами являются устройства на чипах WS2812b и WS2811. В первом случае чип находится прямо внутри светодиода, то есть один прибор управляет свечением одного излучающего диода. Питание ленты составляет 5 вольт. Во втором случае чип помещается отдельно, и к нему подключаются 3 диода. Мощность – 12 вольт.

Купить адресную светодиодную ленту

Как работает адресная светодиодная лента

Принцип работы ленты следующий. Она поделена на сегменты, в каждом из которых находятся светодиод и конденсатор. Они все подключены параллельно, а данные передаются последовательно от одного сегмента к другому. Управление осуществляется контроллером, в котором прописывается программа функционирования. Управлять лентой можно через платформу Ардуино.

Маркировка адресной ленты:

  • Black PCB / White PCB – цвета подложки;
  • 1м/5 м – длина адресной ленты;
  • 30/60/74 и т.д. – сколько светодиодов приходится на 1 метр ленты;
  • IP30, IP65, IP67 – степень влаго- и пылезащищенности ленты =.

Адресные светодиодные ленты используются для сборки полноценных модулей, в конструировании ламп с управлением soft lights, для декоративной подсветки, в построении диодных экранов уличной рекламы.

Видео инструкции и ролики

Обучающее видео на канале HomeMade:

Лента на базе ws2812b

Лента на базе ws2812b

Лента на чипе ws2812b является более совершенствованной, чем ее предшественник. ШИМ драйвер в адресной ленте компактен, и размещается прямо в корпусе светоизлучающего диода.

Основные преимущества ленты на основе ws2812b:

  • компактные размеры;
  • легкость управления;
  • управление осуществляется всего по одной линии + провода питания;
  • количество включенных последовательно светодиодов не ограничено;
  • невысокая стоимость – покупка отдельно трех светодиодов и драйвера к ним выйдет значительно дороже.

Лента оснащена четырьмя выходами:

  • питание;
  • выход передачи данных;
  • общий контакт;
  • вход передачи данных.

Максимальный ток одного адресного светодиода равняется 60 миллиамперам. Рабочие температуры лежат в пределах от -25 до +80 градусов. Напряжение питания составляет 5 В +-0,5.

1 бит передается за 1,25 мкс. Весь пакет из 24 бит для одного светодиода передается за 30 мкс.

Пример подключения к ардуино

Любая адресная светодиодная лента имеет начало и конец, которые важно не перепутать во время сборки. На них есть специальные обозначающие стрелки, которые указывают направление сигнала.

Лента ws2812B подключается к Ардуино следующим образом.

Лента ws2812B подключается к Ардуино следующим образом

Еще один вариант подключения:

Подключение ws2128 к Ардуино

Выходы питания с ленты 5В и земля соединяются с соответствующими контактами на микроконтроллере Ардуино. При подключении отрезка с более чем 13 светодиодами потребуется выносной блок питания. Земля и минус блока питания должны быть соединены друг с другом. DINможно подключить к любому цифровому порту на Ардуино. Он используется для получения данных с контроллера.

Цифровой вход ленты идет на вход контроллера, поэтому между ними нужен токоограничивающий резистор номиналом 100-500 Ом. С его использованием нагрузка на пин будет ниже. На другом конце ленты также есть 3 контакта, к которым можно подключить отрезки различной длины.

Каждый блок ленты состоит из трех светодиодов. Соответственно, для управления подсветкой потребуется 3 байта – по одному на каждый свет. Каждый байт принимает значение от 0 до 255 – это значит, что есть возможность задания более 16 миллионов оттенков.

Данные передаются следующим образом:

  • ШИМ драйвер забирает первые 3 байта, остальные передаются на выход D0;
  • затем пауза длительностью 50 мкс;
  • второй драйвер принимает следующие 3 байта.И так далее.
  • Когда длительность задержки становится более 50 мкс, передача окончена и начинается второй цикл.

Причины проблем при работе с адресной светодиодная лентой:

  • неправильное соединение с землей;
  • сигнальный провод идет не в начало схемы;
  • перепутаны земля и 5 В;
  • если получаются цвета ближе к красному, проблема с блоком питания, пайкой линии или слишком тонкие провода;
  • после подключения без резистора пин на Ардуино может сломаться, поэтому придется переключать на другой.

Библиотеки Ардуино для работы со светодиодной лентой

Для управления адресной светодиодной лентой существует 3 библиотеки: FastLED, AdafruitNeoPixel и LightWS2812. Наиюолее популярной является первая. Она поддерживает все версии Ардуино и различные протоколы данных, которые используются не только для адресной ленты. Но надо иметь в виду, что FastLED более ресурсоемкая.

Вторая библиотека, AdafruitNeoPixel, чаще используется при работе со светодиодными кольцами. Возможностей меньше, скорость ниже, но она менее требовательна к ресурсам, в ее составе только самое нужное. Поддерживает все версии Ардуино. Третья библиотека используется не очень часто.

Работать с библиотеками FastLED и Adafruit NeoPixel одинаково просто. Их отличия заключаются в функциональности и объеме занимаемой памяти.

Основные моменты подключения ленты:

  • Команды передаются друг за другом, и нужно не перепутать начало и конец. D1 принимает команды, D0 используется для подключения дополнительных отрезков.
  • Для подключения цифрового входа нужно резистор.
  • При монтаже адресной светодиодной ленты нельзя допускать статического электричества.
  • Если между лентой и Ардуино расстояние более 15 см, сигнальный провод и землю нужно перекрутить в косичку. Это поможет избежать наводок.
  • Питание. Каждому светодиоду в сегменте нужно 20 мА. Суммарный ток будет составлять 60 мА. Нужно просчитать общий ток ленты, и, исходя из полученного значения, подбирать блок питания. Например, лента длиной 1 м с 60 диодами будет потреблять 60*60=3600 мА=3,6 Ампер. Блок питания подбирается с похожей мощностью.
  • Силовые точки должны быть запаяны качественно. Провода должны иметь такое сечение, чтобы выдерживать подаваемую нагрузку. Минимальное сечение 1,5 кв.м. При тонких проводах заданный программно белый цвет будет отдавать красным оттенком.
  • Помехи. Лента, которая мигает, может создать помехи на линии. Если она с контроллером получает напряжение от одного источника, то помехи пойдут на микроконтроллер. Это может привести к нестабильности работы и различным сбоям. Решением проблемы будет установка электролитического конденсатора емкостью 470 мкФ на питание микроконтроллера и конденсатор на 1000 или 2200 мкФ на питание ленты.
  • Если лента и устройство управления питаются от источников с разным напряжением, нужно использовать преобразователь уровня.
  • Рекомендуется подавать на ленту менее 5 В питания.
  • Питание в длинной ленте советуется распределить по всей длине. В ином случае моет произойти перегрев токопроводящих дорожек.
  • На ленте имеется толстый слой меди. От точки питания по ленте может падать напряжение. Для удаления подобной проблемы нужно дублировать питание при помощи медного провода сечением минимум 1,5 кв.м. через каждый метр.

Соблюдение основных моментов и следование инструкции позволяет самостоятельно подключить адресную светодиодную ленту к вашему проекту.

Драйвер для STM32 для реализации протокола адресных светодиодов (WS2812, WS2811, SK6812, и т.д.), с рациональным использованием буферной памяти и DMA.

Подключение и настройка

На пин DIN первого светодиода (начало ленты) подаётся сигнал, формируемый STM32. Из-за разницы питающих напряжений, сигнал следует поднять до уровня 5 вольт с помощью специальной микросхемы-транслятора логики или с помощью настройки GPIO-пина в режиме Open Drain, подтянув его резистором. Подробнее про это — ниже в статье.

ВАЖНО!
При использовании Open Drain нужно убедиться, что пин выдержит 5 вольт. Узнать это можно в даташите на свой МК.
Пример:

Настройка таймера в CubeMX

ОГРАНИЧЕНИЯ: Из-за особенностей таймеров, минимально стабильная частота работы — 32 МГц.

Сперва нужно настроить таймер в режиме ШИМ. Обратите внимание на отмеченные стрелками настройки.

Отправка значений в таймер происходит с использованием DMA, поэтому настроим и этот блок.

Ножка должна иметь высшую скорость из доступных. Если выбран режим Open Drain, то не забудьте переключиться.

Также проверьте, что генерация DMA_Init стоит выше, чем TIM_Init. Иначе таймер не узнает про DMA, сигнал генерироваться не будет.

Настройка библиотеки

Сгенерируем код, добавим файлы библиотеки в проект. Откроем .h-файл и посмотрим, что можно настроить.

Function reference

Теперь можно попробовать забилдить проект и посмотреть на доступные функции. Все методы возвращают enum-статусы.

Пример использования

Описание

Адресные светодиоды ленты используют для различной индикации, как бытовой, так и коммерческой. Ключевое отличие от обычных RGB-диодов в том, что их можно зажигать отдельно, каждый своим цветом.

Это поведение обусловлено тем, что у каждого диода стоит чип-драйвер. Снаружи, как в случае с WS2811, или внутри, как у WS2812 и остальных. Чип принимает сигнал, запоминает первые импульсы, а остальные передаёт далее по цепочке.

Протокол данных

Свечение каждого субпикселя кодируется 8 битами. Т.е. для RGB (WS281X) 24 бита, для RGBW (SK6812) 32 бита.
Код бита задаётся длиной импульса, то есть скважностью.

Существует и код RET — пауза, означающая конец передачи.

У всех контроллеров разные тайминги.

Реализация на STM32

Большинство решений основаны на использовании пустых тактов. Это означает, что весь процессор тормозит на время отправки сигнала. Такой способ не только тратит уйму процессорного времени, но и рискует сломаться, в случае возникновения прерывания.

Посчитаем длину передачи сигнала на 1 диод: 1,25 мкс * 24 бит = 30 мкс.
Для n диодов: T = 30 * n + 50 мкс.
30 диодов — уже 1 миллисекунда.

Иными словами, протокол на задержках стоит использовать только для малого количества диодов, чтобы не мешать основной программе.
Именно из-за этой проблемы я в своё время впервые обратился к STM32.

В других вариантах используется шина SPI, которую настраивают на частоту 800 КГц. Я не проверял, но многие пишут про ощутимую потерю точности сигнала.

Что же делать?

В почти всех микроконтроллерах STM32 существует блок DMA (Direct Memory Access). Он позволяет передавать данные между периферией и памятью в разных направлениях без участия процессора.

В качестве исполнительной периферии используется таймер, настроенный в режиме ШИМ.

Буферный массив

Любой способ передачи сигнала подразумевает буфер, в котором хранятся значения скважности сигнала.

Реализация моего метода была придумана не мной. В ней очень хитро используется память.
Буфер здесь двойной. Первый имеет размер N диодов * 3 байта. В нём хранится цвет в представлении RGB.
Второй буфер — для скважностей. Он фиксированный, занимает всего 48 байт, или 64 байта для RGBW. В него вмещаются всего 2 диода.
Прерывания DMA позволяют заполнять одну часть буфера, пока отправляется вторая. Используя такой подход, можно растягивать цепочку диодов почти до бесконечности, покуда хватит памяти для первичного буфера или частоты обновления.

Преобразование логики

Дело в том, что адресные диоды воспринимают сигнал, опираясь на напряжение своего питания.
Открыв даташит на WS2812b, мы увидим такие строки:

Это приводило к тому, что первый диод в ленте считывал этот импульс и зажигался.

Даже с помощью остановки-запуска таймера невозможно было достичь нормальной работы. Либо из-за массивности HAL-функций, либо из-за особенностей работы периферии, возникала небольшая временная задержка, которой было достаточно для зажигания этого диода.

Решение было не таким очевидным, но нашлось довольно быстро. В функции HAL_TIM_PWM_Stop_DMA была обнаружена такая строчка:

Это и есть отключение GPIO-канала таймера. После её удаления, удалось достичь стабильной работы. Поэтому пришлось скопировать код этой функции к себе и немного отредактировать.

Третья проблема — фундаментальная. Заключается в особенностях работы таймеров. Если задать частоту ниже 32 МГц, то ощутимо теряется точность сигнала. Например, для 8 МГц: Для получения частоты 800 КГц задаётся ARR = 9. Значит регистру CCRx доступны только значения 0..8. А это примерно 100 КГц точности или разброс в 10 мкс, что уже очень критично.

Вариант борьбы с этим — уничтожение этой концепции генерации сигнала, переход на ассемблерные задержки или прерывания. В любом случае, зачастую в проектах используют максимальную тактовую частоту, а снижают её только для энергосбережения, когда светодиоды уже должны быть выключены. Другой вариант — использование отдельного МК, например F0 или G0, как UART/SPI/I2C -> ARGB драйвер. Такие проекты уже существуют.

Мой выбор — принять все ограничения, а для open-source сделать пометку.

Оценка скорости

Максимальная частота обновления адресной ленты упирается напрямую в протокол.
Посчитаем предел для 25 FPS.
25 Гц -> 40 мс = 40.000 мкс. Передача для 1 диода занимает 30 мкс.
Таким образом, предельное значение — порядка 1300 шт.

Читайте также: