Здравствуйте, уважаемые форумчане, только что зарегался, специально, чтобы рассказать про нюансы работы ws2812b с esp8266 и их решения.
Лирическое отступление
Судьба распорядилась так, что я стал с++ разработчиком, но чисто софтверником, электроника для меня остаётся в качестве хобби. Я не являюсь ардуинщиком, т.к. ввиду своего стажа(~17 лет) и опыта мне проще писать на нативном СИ, но это никак не влияет на тот материал, который я собираюсь здесь изложить.
Проблемы:
К сожалению, когда я столкнулся с кристаллом ws2812b я влетел с "шашкой наголо" и думал, что сейчас всё сделаю за пару дней....практически так и случилось, но потом начали возникать проблемы, которые я решал по выходным в течении целого месяца!
1) Питание ленты
2) Падение напряжений
3) Логические уровни
4) Помехи
Решения и "разбор полётов"
1) Первое, что необходимо уяснить это то, что что кристалл ws2812b достаточно прожорливая штука - токи на одном кристалле судя из даташита, могут доходить до 60 мА! Теперь посчитаем на примере моей ленты 96 светодиодов на метр, лента у меня 2.5 м:
60ма * 96 * 2.5 = 14.4 А - вдумайтесь пиковый ток 14 А. Хорошо, что в реальности это вряд ли будет происходить (если только включить полностью белый свет и долго сидеть), да и мои замеры по токам китайских ws2812b говорят, что они не потребляют более 30-40 мА, но к 6-7А вполне нужно быть готовыми.
Соответственно, чем выше ток, тем сечение проводников должно быть толще - для моего случая рекомендую сечение не менее 1 мм2.
Если выбрать маленькое сечение - у Вас будут греться питающие провода - и возникнет вероятность ВОЗГОРАНИЯ!
2) Вторая ситуация, которую хотелось бы рассмотреть это падение напряжений! При таких токах дай бог, если у Вас на "хвосте" ленты останется 4.5 вольта, при питании "головы" от 5.5 вольт. Поэтому решение поставить стабилитрон и понизить питание до 4.5в дабы согласовать логические уровни - неприемлемо! Да... на коротких обрезках ленты это будет работать, но когда у Вас появится желание сделать реальный проект с длинной лентой Вам придётся питать ленту максимально возможным напряжением. Максимальное напряжение для кристалла ws2812b - это 5.5 в - я питаю 5.4в.
Второй вариант - это проложить провода питания достаточного сечения - и паять на ленте через каждый, допустим, метр. Второе решение мне не очень нравится из-за дополнительной проводки, но на совсем длинных лентах оно будет, фактически, единственным выходом.
3) Вот это самая интересная тема - дело в том, что esp8266 питается от 3.3 вольт - и логическую единицу она физически не сможет выдавать выше этого значения. Сама лента питается от 5 вольт и на вход логические уровни принимает в рамках 5 вольт.
Как можно заметить во многих других проектах согласование в таких случаях, обычно не требуется. Т.е. например если Вы возьмёте esp8266 с её 3.3 вольтами и atmega328(Arduino UNO) c 5 вольтами, то согласование не потребуется, т.к. atmega328 толерантна по своим входам и её логическая единица начинается от 2-2.5 вольт, поэтому 3.3 вполне хватает.
НО! У нас кристалл ws2812b - соответственно, открыв даташит - мы с удивление узнаём, что границы лог. нуля и лог. единицы - достаточно разнесены друг от друга. Более того они ещё и зависят от опорного напряжения, которым является напряжение питания.
Исходя из даташита - максимальный уровень лог. нуля 0.3vdd, а минимальный уровень лог. единицы 0.7vdd.
Считаем самое интересное уровень лог. единицы:
0.7 * 5.5 вольт = 3.85 вольт - а это значит, что лог. единица должна лежать в диапазоне от 3.85в до 5.5в, естественно esp8266 с её 3.3в ну никак не подходит.
Собственно поэтому решение со стабилитроном понижающим питание и помогает, потому что опорное напряжение тоже снижается(0.7 * 4.5 в = 3.15 в) - но оно неверное(см. пункт 2.). да и к тому же мы получаем предельные 3.15 в - т.е. любая помеха и единица НЕ ПРОЙДЁТ(3.15 очень близко к 3.3в), как результат вы получите те самые мерцания
Как же быть?
В интернете полным полно различных схем согласования уровней, например такая классическая схема на мосфете
Но она работать не будет.
И вот мы подходим к ещё одной большой проблеме с ws2812b - шина данных очень скоростная, например, время трансляции единицы всего 200 наносекунд!! Транзистор просто не будет успевать открыться. Либо нужно искать очень быстрый транзистор, но собрав такую схему на разных мосфетах, доступных для обычного потребителя(встречающихся на материнских платах) изучав их даташиты и засев с осциллографом, я так и не нашёл подходящего... нужно покупать, либо найти другой способ.
Классический подход к решению данных проблем использовать специализированные микросхемы, например SN74LVC1T45 (1-битный шинный приемопередатчик с двуполярным питанием)
как раз должен подойти для этого - но я нашёл более простое, доступное и дешевое решение.
Есть такие микросхемы, как микросхемы логических операций например 74ACT04SC, которая является инвертором, её без проблем можно найти на видеокарточках, материнских платах и пр. она достаточно быстра, дешёва(8 российских рублей если покупать) - и прекрасно справляется с шиной данных ws2812b.
Но Вы спросите как же быть - ведь 74ACT04SC инвертор и уровни получатся перевернутыми - здесь можно поступить очень просто. т.к 74ACT04SC имеет 6 каналов - мы будем инвертировать сигнал 2 раза.
К сожалению я забыл сделать скрин с осциллографа(у меня DS1104Z-S), но опять всё разбирать, чтобы это сделать мне крайне не хочется, поэтому придётся поверить мне на слово.
Схема естественно элементарна
Схема подключения(для тех кто не умеет читать схемы):
4) Вы думаете в предыдущем пункте, согласовав уровни мы избавились от мерцания - нет Вы ошибаетесь, всё ещё впереди.
Я к сожалению не в курсе тех библиотек, которые используются в Arduino для ws2812b, но на своей esp8266 я использовал i2s(не путать с i2c) линию - чтобы посылать сигнал на ленту. Это аппаратно-ускоренное решение, которое фактически полностью разгрузило процессор esp8266, теперь я могу делать даже различные физические эффекты не беспокоясь, что анимация будет тормозить на любой длине.
К чему я это - те кто знаком с линией i2s сразу представляют данные, которые по ней можно передавать - данные больших объемов. Точно такие-же данные мы шлём на ws2812b. А для этого необходима высокая скорость.
Итак скорость, с которой передаются данные на ленту примерно ~4 мегабита в секунду!! Осциллограф показывает частоту линии в 5 мегагерц!
На таких частотах - Вы не сможете сделать эту линию длинной. Я рекомендую ставить микроконтроллер(причем не важно Arduino Uno или esp8266 или какой либо другой) КАК МОЖНО БЛИЖЕ ко входу ленты!!
Дело всё в том, что на частоте 5 мГц - ваш провод начинает работать как антенна! Т.е. помимо того, что Вы можете ловить помехи по питанию, Вы ещё можете поймать помехи от эфира самой esp8266 - как произошло у меня. Хотя провод был всего 20 сантиметров. Никакого контроля ошибок у кристалла ws2812b нет и в помине...
Выход здесь только один - Вы должны применять экранированный кабель - например я использовал RG-58(50омный высокочастотный), если он толстый - рекомендую посмотреть в сторону RG316(Pigtail) или RG178.
Экран кабеля ОБЯЗАТЕЛЬНО должен быть подключен к минусу питания.
ИТОГО
Если Вы будете следовать указанным выше рекомендациям - всё у Вас получится
ПС
Предвосхищая гневные и недовольные возгласы про лишние детали и комменты "да у меня и так всё работает", поздравляю, лично Вам повезло - но всё может круто изменится, через месяц, полгода или год, когда рядом построят очередную вышку сотовой связи, или соседи передвинут свой вайфай роутер или DECT телефон.... и Вам придётся разбирать свой фальш-потолок или расковыривать проводку ws2812b потому, что последняя "внезапно" начнет глючить