Светодиоды ws2812b весьма интересная штука. О реализации протокола их работы я и хочу сейчас поведать. Как и в прошлой статье, код написан в среде IAR под микроконтроллер ATmega32 c 16МГц кварцем. Хочу сразу уточнить, что кварца менее 16МГц скорее всего не хватит, данный протокол рассчитан на весьма жесткие тайминги. Ноль выставляется временным интервалом 0.4 мкс, единица 0.8 мкс.
Первым делом напишем функции выставления 0 и 1 в линию. Количество nop’ов в функциях подобрано экспериментальным путем через логический анализатор. Скриншоты прилагаются немного ниже.
#define ClearOutBit PORTC &= ~(1<<1) //0 на выход
#define SetOutBit PORTC |= 1<<1 //1 на выход
void Set0( void ) //Выставляем в правую линию ноль ~0.4 мкс
{
SetOutBit;
asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");
ClearOutBit;
//После этого временной интервал немного увеличен, в связи с выполнением циклов, но диоды сигнал ловят исправно
}
void Set1( void ) //Выставляем в правую линию единицу ~0.85 мкс
{
SetOutBit;
asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");
ClearOutBit;
//После этого временной интервал немного увеличен, в связи с выполнением циклов, но диоды сигнал ловят исправно
}
Далее у нас есть массив значений. Я создал 32 битный массив из 30 значений (да, понимаю, что это излишество, но мне показалось это решение допустимо). Для каждого светодиода нам необходимо загрузить 24 бита, причем первым выгружается в линию значение для зеленого цвета, далее красного и потом синего.

На выставление в линию значений для всех 30 светодиодов у контроллера уходит не более 4 мс, что достаточно быстро. Конечно, если увеличить тактовую частоту, можно выиграть немного времени между битами. В идеале, если все временные интервалы будут соответствовать, для 30 светодиодов загрузка будет длиться менее 1 мс.
unsigned long int mas[30]; //32 битный массив из 30 значений
void setMas( void ) //выставление всего массива в линию
{
unsigned long int a;
unsigned int j,i;
for (j=0; j<30; j++) { //количество светодиодов 30
a = 0x1000000; //первым выставляется G (Hi->Low), потом R и B
for (i=0;i<24;i++){ //три байта G,R,B
a=a>>1;
if ((mas[j]&a)==0x00000000) {
Set0(); //ноль
} else {
Set1(); //единица
}
}
}
}
По факту получается, что выдерживаются только временные интервалы “high voltage time” 0.4 и 0.8 мкс, а вот “low voltage time” программой не контролируются – они получаются за счет работы микроконтроллера между выставлением значений в линию. Ему ведь надо время, чтобы проверить условие и прокрутить цикл. Но тем не менее, светодиоды ловят посылку исправно. И конечно это время не должно превышать 50 мкс, иначе светодиод воспримет это как Reset и загрузит полученное “неполное” значение себе на индикацию.


В конце статьи видео работы этих 30 светодиодов с круговым сдвигом исходного массива по таймеру и управлением через ИК пульт с NEC протоколом. Получилось весело.
Комментарии (11)

e_asphyx
30.04.2015 14:04+3О, здорово. Сам только недавно доделал проект на WS2812B: imgur.com/a/0I84E
Вот как-то так это сейчас выглядит: youtu.be/fmolAxGdiCE

BalinTomsk
30.04.2015 19:00кстати такой проект вполне полиции можно продавать — им не надо будет маячки ставить ручные

lorc
30.04.2015 19:01+4Я бы предложил использовать SPI для вывода данных.
Настроить частоту на 2.5МГц, для передачи 0 запихивать в MOSI 0b100, для передачи 1 — 0b110.
Памяти в меге хватит на то, что бы сформировать сразу весь массив данных. Таким образом получите очень точные тайминги.
Мы таким образом (тоже через SPI) умудрялись формировать Ч/Б сигнал для VGA. Правда, не на меге, а на Atmel AT91SAM7x
oWart Автор
30.04.2015 22:05Интересно, спасибо за совет. Но в данном случае мне точные тайминги не нужны.

yanvasilij
06.05.2015 22:45Спасибо за статью, пришлась как нельзя кстати. Подскажите только такой момент, если микросхема запитана от 12 вольт, управляющий сигнал может быть 5 вольт?

oWart Автор
07.05.2015 08:39Про какую «микросхему» речь? У светодиодов питание 5В, от 12В они помрут, соответственно и сигнал им нужен 5В.

yanvasilij
07.05.2015 08:43У меня светодиодная лента на микросхеме ws2812b. Питание ленты 12 В, могу ли я управлять 5 В, при таком питании?
madguru
Автору спасибо за статью!
По теме тюнинга фар, хочу предостеречь использовать красный цвет в фарах. Бывает выезжаешь в сумерках на обгон и видишь красные габариты в далеке, предполагая что кто-то далеко уже кого-то обгоняет. Потом О-очень удивляешься, почему габариты так _быстро_ приближаются :)
Не нужно вводить в заблуждение других водителей.
oWart Автор
Поделка исключительно для развлечения зевак на автостоянках. Езжу только с белым цветом. Любой другой цвет (кроме желтого само собой) запрещен.