image

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

Не буду подробно останавливаться на протоколе. Достаточно сказать, что кодирование бит 0 и 1 осуществляется импульсами разной длительности. Вывод этих импульсов как раз и представляет собой головную боль при программировании MCU (использование готовых библиотек для Arduino в расчёт не беру, так как цель статьи показать именно детали процесса).

Мой выбор микроконтроллера пал на TI Stellaris LM4F120 по двум причинам:
  • Был в наличии (недорогая плата LaunchPad от TI);
  • Мой проект достаточно требователен к ресурсам, а MCU ARM® Cortex™-M4F c возможностями прямого доступа к памяти (DMA) как раз подходящее решение.


Существует разные варианты организации вывода данных по протоколу WS2812B на микроконтроллерах ARM:
  • Вывод через SPI многобитными посылками на каждый бит (1000, 1110);
  • Вывод через PWM.

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

Я решил пойти по пути использования SPI DMA, но так, чтобы не было необходимости «раздувать» каждый бит ��о нескольких. Меня интересовала возможность вывода данных через SPI «как есть». Т.е. 24 бита на светодиод, на скорости 800 kHz. Для этого потребовалось сделать небольшой преобразователь SPI -> WS2812B. Это, может, покажется лишним «городить огород», если можно напрямую всё подключить. Но мне всё равно требовалось делать плату, на которой кроме протокольного преобразователя находился еще разъем карты памяти SD, а также импульсный преобразователь 12В -> 5В / 5А (линейка из 144 светодиодов достаточно прожорлива, что, к тому же, накладывает ограничение на длину и сечение проводов её питающих). А еще решается проблема преобразования логического уровня 3,3В в 5В.

Привожу принципиальную схему (используется всего 2 корпуса 74HCT).

image

Номиналы резисторов R1 и R2 примерные, подбираются эмпирически с помощью осциллографа (нужно вывести тестовую последовательность с микроконтроллера, померить осциллографом длительности и подогнать номиналы по мере необходимости). Реальная схема чуть-чуть другая, так как у меня не было в запасе 74HCT132 и 74HCT74, а были 74HC74, 74HCT14 и 74HCT00, поэтому корпусов получилось 3.

Схема протестирована в полевых условиях на линейке из 144 светодиодов и на длине провода между выходом схемы и входом светодиодов порядка метра. Каких либо сбоев и помех не наблюдалось.

Кстати, по поводу проводов. Как я упомянул выше, светодиодные линейки на WS2812B кушают порядочный ток на максимальном включении. Соответственно, нужно подбирать сечение провода питания, достаточное, чтобы падение напряжения на нем было не критическим. Я взял кусок трех-проводного провода питания (обычного, который для 220В) сечением 1мм2. Даже такого сечения оказалось недостаточно для провода длиной 1М. На 50% мощности всех одновременно включенных светодиодов напряжение «просело» до 4х Вольт. Еще один феномен, про который не надо забывать это то, что когда питающее напряжение проседает, линия данных остается с уровнем в 0В и 5В. Таким образом, по отношению к питанию первого светодиода уровень оказывается ниже GND и выше VCC с риском вывести из строя входную ножку. Поэтому дополнительно я поставил по диоду Шоттки на землю и питание перед самым входом данных первого светодиода.

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