Своим появлением адресные светодиоды сильно упростили создание всяких адаптивных подстветок и прочих художественных инсталляций. Такими светодиодами "по умолчанию" обычно считают WS2812B, их в своё время под именем NeoPixel популяризировала фирма Adafruit. Однако меня больше привлекает SK9822 - ему требуется два сигнальных проводника вместо одного, но зато в качестве интерфейса используется понятный человеческий SPI.
Впрочем, это не значит, что я не найду, где споткнуться :) И в этот раз это будет история про мутный даташит.
Предыстория
Как вы можете быть уже в курсе, адресные светодиоды (и WS2812, и SK9822) соединяются друг за другом по цепочке. После того, как один светодиод схавает свою порцию данных, он начнёт пропускать остальное насквозь.

Из этого следует, что он должен стать невосприимчив к сигналам, и установить цвет можно только один раз, что не очень практично. Но это если у нас не найдётся способа вытащить светодиод из ступора и скормить новые данные - а способ этот уже предусмотрен производителем. Например, для SK9822 он заключается в отправке 32 нулей подряд в качестве признака начала новой транзакции.

Так же даташит приводит порядок байт для цветовой информации, и предписывает отправить 32 единицы (0xFFFFFFFF) подряд в конце транзакции.
Что ж, формат в целом понятен, выглядит как достаточно простая работа, как раз на новом микроконтроллере поиграться. Написанный мною недавно код быстро завёлся, и лента начала подавать признаки жизни... но делала она при этом не совсем то, что я ожидал. Проблемы проявились сразу две - неправильные цвета и появление лишнего белого светодиода в конце отрезка.
Цвета
С первой проблемой всё сразу понятно, надо просто поменять порядок байт для каждого пикселя. Но на какой и почему, если я делал всё по даташиту? Оказалось, в течение нескольких лет я сохранил на компе 3 разных версии даташита на SK9822, похожих оформлением и содержимым, но с разным количеством страниц. В этот раз мне под руку подвернулся более новый - ревизия №7.

В новой версии порядок был указан как GRB, хотя на практике правильным оказался BGR (что соответствует тому, что написано в старом даташите ревизии №1 от Dongguang Opsco Optoelectronics). Казалось бы, новый даташит должен внушать больше доверия, в нём на 5 страниц больше и реально есть правки - например, появилась рекомендация ставить резисторы между МК и первым светодиодом. И тем не менее, в нём закралась такая странная ошибка.
Белый хвост
Вторая проблема лечится путём игнорирования всех версий даташита :) В принципе, мне изначально казалось странным, что 32 единицы в конце транзакции выглядят так же, как вполне легальная посылка белого цвета на максимальной яркости. Однако для первого теста я решил всё же поверить даташиту. Мало ли, вдруг там в исключение предусмотрено?
На самом деле нет, логика изначально подсказывала правильно - именно посылка 32 единиц и зажигает белым светодиод N+1. Но как тогда обозначить конец посылки? А просто выдать вместо этого новое начало - в моём случае приём 32 нулей в конце заставил ленту защёлкнуться и отобразить только что принятые данные. Следующую пачку данных можно отправлять как обычно, ничего страшного в двух стартах подряд нет.
К этому выводу можно прийти самостоятельно путём экспериментов, либо прочитать, к чему пришли другие люди (тем временем, тому посту 10 лет стукнет в конце 2026). Правда, там предлагается поступить немного иначе - послать RESET из 32 нулей и добавить ещё хотя N/2 нулей (где N - длина ленты) в качестве признака конца транзакции. Причину я пока не до конца понял - либо это сделано ради совместимости с APA102, либо это нужно обоим типам светодиодов при большой длине ленты. В общем, надо иметь в виду на будущее.