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 с риском вывести из строя входную ножку. Поэтому дополнительно я поставил по диоду Шоттки на землю и питание перед самым входом данных первого светодиода.

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

Комментарии (9)


  1. jonic
    05.05.2015 18:00
    +1

    Это на самом деле, самое достойное и не костыльное решение. Плюс, однозначно.


  1. VT100
    05.05.2015 21:11
    +3

    Подбор таймингов RC-цепочками? Сделайте развидеть это мной.
    Для DIY пойдёт, но всё-равно режет глаза.


    1. homesoft Автор
      06.05.2015 10:29
      +1

      Есть тысячи способов, как задать тайминги. RC — не самый плохой вариант из всех, и наверное, самый распространенный. Целые МК тактируют RC цепочками, когда допроцентная точность не важда. Про ШИМ-контроллеры даже не упоминаю. Главное достоинство — простота.
      А какие варианты можно было бы применить в данной схеме, не добавляя большого числа доп. компонентов?


      1. Eddy_Em
        06.05.2015 11:02

        Какой смысл было городить такую конструкцию, если можно напрямую ноги МК подсоединить к SPI ленты? Работать в режиме open-drain. Т.к. SPI'ные ноги обычно 5V-tolerant, ничего им от +5В не будет!
        Уровень логической единицы на ленте выше напряжения питания не прыгнет, т.к. будет сформирован подтягивающим резистором. Если этот резистор запихнуть в самом конце ленты, то и «автоматом» будет напряжение не выше VCC даже на первом светодиоде.


        1. homesoft Автор
          06.05.2015 11:24

          Можно было и open-drain сделать (на проводе в 1м фронты скорее всего потянутся, хотя десяток-другой нс не критично). Но вход-то у ленты не SPI, а широтно-модулированный. Задача как раз и стояла не делать программных задержек или многобитных посылок на каждый бит, а сделать аппаратную поддержку нормального человеческого SPI.


      1. VT100
        07.05.2015 21:44

        Целые МК тактируют RC цепочками, когда допроцентная точность не важда. Про ШИМ-контроллеры даже не упоминаю.

        Не передёргивайте. Да их можно тактировать от RC-генератора и с хорошим результатом. Но это потому, что внутри всё синхронно и нет никаких RC-цепочек. А то-бы мы так и топтались на уровне 8031 с минимальной тактовой в районе 3.5 МГц.
        А какие варианты можно было бы применить в данной схеме, не добавляя большого числа доп. компонентов?

        Мне ШИМ больше по душе. В посте реализация протокола ws2812b на ATmega я было и думал дать такой комментарий. Но там это невыгодно по сравнению с «ногодрыгом» — при минимально достаточном разрешении ШИМ (3 бита) контроллеру надо отвлекаться каждые 8 тактов. Он будет на пролог с эпилогом (даже если на ассемблере) всё время тратить. АРМатура по-быстрее, тут это уже может иметь практический смысл.


  1. Javelines
    05.05.2015 21:18

    Во, как раз эти светодиоды можно для цветомузыки использовать в такой штуке: habrahabr.ru/post/225653


  1. GarryC
    07.05.2015 14:19

    То есть Вы сэкономили 24/2=12 байт памяти данных, заменив их 6 резисторами, 2 диодами, 2 конденсаторами и 3 корпусами.
    Супер. Неужели сейчас память данных ТАК подорожала?
    Ах да, я забыл еще про 200-300 байтов памяти программ для подпрограммы распаковки. Тогда да, конечно, экономия несомненна.


    1. homesoft Автор
      07.05.2015 15:25

      Замечание несомненно по делу. Но просто сделаю акцент еще раз на том, что, цель учебная, а не сдлеать промышленное решение и запустить в производство. Статься не преследует никаких бизнес целей. Хотя иногда стоимость 3х дополнительных копеечных корпусов может быть дешевле, чем МК из старшего семейства (который дороже в 2 раза). А предложенное решение универсально для любых МК, даже когда памяти нет совсем (а-ля 128 байт), а светодиодов много (скажем 1000), и зажигать их надо в реальном времени, с определенным FPS, при этом еще обрабатывая входные данные (АЦП например).