
В этой статье мы научимся работать с адресной светодиодной RGB лентой WS2812B. Лента состоит из RGB пикселей WS2812B в корпусе LED 5050 (физические размеры каждого элемента составляют 5×5 мм).
В этой статье мы научимся работать с адресной светодиодной RGB лентой WS2812B. Лента состоит из RGB пикселей WS2812B в корпусе LED 5050 (физические размеры каждого элемента составляют 5×5 мм).
Каждый пиксель содержит в себе красный, зелёный и синий светодиоды и контроллер ШИМ, с помощью которого можно управлять яркостью каждого светодиода и получать множество различных цветов из трёх основных.
Так как каждый WS2812B состоит из трёх светодиодов и контроллера ШИМ, будет лучше называть их пикселями, а не светодиодами. На фото справа можно увидеть устройство такого пикселя.
Немного о характеристиках адресных светодиодов WS2812B:
В начале нам необходимо подключить светодиоды к Arduino. Сделать это предельно просто. Контакты +5V и GND подключаем к плюсу и минусу источника питания, соответственно. Din подключаем к любому цифровому пину Arduino, по умолчанию это будет 6-ой цифровой пин, но можно использовать любой другой.
Кроме того, желательно соединить землю Arduino с землей источника питания. Нежелательно использовать Arduino в качестве источника питания, так как выход +5V может обеспечить ток лишь в 800 мА. Этого хватит не более чем на 13 пикселей светодиодной ленты.
С другой стороны ленты есть выход Do, он подключается к следующей ленте, позволяя управлять лентами по принципу каскада, как одной. Разъём питания в конце также продублирован.
Далее будем разобираться с управлением лентой. Описание протокола управления присутствует в Datasheet к WS2812B.
Все пиксели по умолчанию подключены друг к другу последовательно. Вход Din каждого их них подключается к выходу Do следующего. Сигнал управления должен поступать на первый из них.
Команды управления подаются пакетами по 3 байта, по одному для каждого из трёх цветов. Между пакетами идет пауза длительностью 50 мкс, пауза более 100 мкс означает конец передачи.
Длительность любого бита – 1,25 мкс. Бит “1” кодируется импульсом длительностью 0,8 мкс и паузой в 0,45 мкс. Бит “0”– 0,4 и 0,85 мкс. Возможны расхождения по времени до 150 нс. Такой пакет должен быть отправлен для каждого пикселя в светодиодной ленте. На диаграмме изображён требуемый сигнал.
Глядя на данную схему, несложно догадаться, что такое невозможно воплотить в жизнь стандартными функциями Wiring, вроде digitalWrite и delay. Однако ленты WS2812B достаточно популярны и для них уже есть библиотеки на языках более низкого уровня. Вам достаточно только выбрать любую из них.
Самые популярные библиотеки:
Поддерживает все версии Ардуино и множество протоколов передачи данных (не только для нашей ленты). Язык программирования, на котором она написана – чистый C.
Библиотека предназначена для работы со светодиодными кольцами NeoPixel Ring, разработки и производства Adafruit. Работает медленнее, обладает меньшими возможностями, но содержит в себе лишь самое нужное. Написана на C, языке ассемблера и немного на Wiring. Поддерживает всю линейку Ардуино.
Давайте попробуем обе библиотеки и сравним их. Напишем стандартный скетч Blink, чтобы лента загоралась красным на полсекунды и выключалась на такой же интервал.
По умолчанию, количество пикселей в ленте – 30, но при необходимости это можно изменить в скетче.
Пример с использованием библиотеки FastLED:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
// Подключаем библиотеку FastLED. #include "FastLED.h" // Указываем, какое количество пикселей у нашей ленты. #define LED_COUNT 30 // Указываем, к какому порту подключен вход ленты DIN. #define LED_PIN 6 // Создаем переменную strip для управления нашей лентой. CRGB strip[LED_COUNT]; void setup() { // Добавляем ленту FastLED.addLeds<WS2812B, LED_PIN, RGB>(strip, LED_COUNT); } void loop() { // Включаем все светодиоды for (int i = 0; i < LED_COUNT; i++) { strip[i] = CRGB::Red; // Красный цвет. } // Передаем цвета ленте. FastLED.show(); // Ждем 500 мс. delay(500); // Выключаем все светодиоды. for (int i = 0; i < LED_COUNT; i++) { strip[i] = CRGB::Black; // Черный цвет, т.е. выключено. } // Передаем цвета ленте. FastLED.show(); // Ждем 500 мс. delay(500); } |
Скетч займёт 3758 байт в программной памяти Arduino и 187 байт ОЗУ.
Теперь попробуем тоже самое с библиотекой Adafruit NeoPixel:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
// Подключаем библиотеку Adafruit NeoPixel. #include "Adafruit_NeoPixel.h" // Указываем, какое количество пикселей у нашей ленты. #define LED_COUNT 30 // Указываем, к какому порту подключен вход ленты DIN. #define LED_PIN 6 // Создаем переменную strip для управления нашей лентой. Adafruit_NeoPixel strip = Adafruit_NeoPixel(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800); void setup() { // Инициализируем ленту. strip.begin(); } void loop() { // Включаем все светодиоды. for (int i = 0; i < LED_COUNT; i++) { strip.setPixelColor(i, strip.Color(255, 0, 0)); // Красный цвет. } // Передаем цвета ленте. strip.show(); // Ждем 500 мс. delay(500); // Выключаем все светодиоды. for (int i = 0; i < LED_COUNT; i++) { strip.setPixelColor(i, strip.Color(0, 0, 0)); // Черный цвет, т.е. выключено. } // Передаем цвета ленте. strip.show(); // Ждем 500 мс. delay(500); } |
Скетч займёт 2592 постоянной и 40 байт оперативной памяти Arduino.
Как можно увидеть, библиотека FastLED более ресурсоёмка. Кроме того, используя её в Arduino с 2 Кб ОЗУ (таковой является, например, UNO) можно управлять не более чем 600 пикселями светодиодной ленты. Это связано с тем, что на каждый пиксель резервируется 3 байта памяти.
А вот в Adafruit NeoPixel минимум нужных функций и меньший расход памяти. Какую из них использовать – ваш выбор. Удачи в проектах!
40 комментариев. Оставить новый
Ваш код не работает. Выдаётся ошибка no matching function for call to ‘CFastLED::addLeds(CRGB [30], int)’ с указанием строки FastLED.addLeds(strip, LED_COUNT);
Вы правили исходный скетч? Если да, напишите, наши специалисты посмотрят и ответят в комментариях.
в первом коде ошибка в инициализации ленты, строку 16 надо заменить на:
FastLED.addLeds<WS2812B, LED_PIN, RGB>(strip, LED_COUNT);
и будет вам счастье))
Огромное спасибо за комментарий! Исправили в коде скетча.
Господа. Пытаюсь сделать подсветку лестницы.У меня 876 светиков, это 16 ступеней в районе 90 см. Платформа Уно. Пробовал Адафрут, горят 606 светиков, подключаю ещё 54 (лента такого количества), на работает вся. ФастЛЕД тяжёлая и не записывается. Тыкните носом, какую библиотеку использовать для такого количества диодов и чтоб ч УНО совмещалась. Спасибо заранее
Здравствуйте, для работы с большим количеством адресных светодиодов требуется достаточно много памяти (RAM). Для управления 876 светодиодами нужно примерно 2.5 Кбайт, в то время как на Arduino доступно всего 2 Кбайт. Arduino Uno просто не имеет достаточно памяти для управления таким количеством светодиодов. Вам следует использовать контроллер с большим количеством памяти, например, Arduino Mega.
Скажите пожалуйста, можно ли на ардуино подключить с десяток разных лент и каждой управлять отдельно? Вся земля лент так же проходят через минус ардуины?
Здравствуйте! Вся земля лент должна объединяться на единую шину питания данных лент, от ардуино к ленте питание подать не получится (только передачу данных). Количество светодиодов зависит от используемой библиотеки.
В библиотеке FastLED к Arduino можно подключить не более 600 пикселей ленты, используя Adafruit NeoPixel – около 800.
Скажите пожалуйста, а как в таком случае: Если я хочу собрать большой стенд из, допустим 10-000 пикселей, как это делается? Картинка при этом общая. Это каждые 3 матрицы 16*16 необходимо приваривать свой ледпин и стыковать общую картинку? А если картинка-анимация, это усложнит работы в разы
Кто может объяснить как работает DIN и можно ли без ардуино регулировать цвет каждого из светодиодов?
Выше указано что необходимо подавать на пин DIN чтобы светодиоды светились нужными цветами.
А именно подавать на пин напряжение с интервалами в 40-45мкс и 80-85мкс, а так же между пакетами 50мкс и окончание >100мкс.
Удачи!
Всем привет на монохромную ленту какой должен быть код, при добавлении ленты в setap
Что подразумеваете под “монохромностью”. Чтобы она светила черно-белым или нужно просто одним определенным цветом?
имеется адресная лента на 335 диодов. есть желание сделать разбегающийся и сбегающийся стопсигнал. где взять такую библиотеку?
Здравствуйте. Можно посмотреть примеры стандартной библиотеки adafruit, уверены, что бегущий маячок там есть.
Добрый день.
Подскажите а возможно сделать так что бы:
Через ПК я передаю цвет который нужно отправить на ленту.
То есть получается связка ПК- АРДУИНО- ЛЕНТА.
например я на компе выбираю цвет и он отправляется на ленту.
На ПК можно в порт (Serial) отправлять информацию, на ардуиной получать инфу и, собственно, творить…
arduino1507@gmail.com
Здравствуйте ,подскажите как добавить дублирующий выход 12 к имеющемуся выходу 11 чтобы работали синхронно ?
#include
int b1=0;
int b2=0;
int b3=0;
int p_top, p_bottom;
int t_top, t_bottom;
int state_top, state_bottom;
char buf[32];
unsigned long prev_top, prev_bottom;
int pin_bottom = 11;
int pin_top = 13;
int tick = 200;
unsigned long prev_t;
int thermoDO = 4;
int thermoCLK = 5;
int thermoCS_b = 6;
int thermoCS_t = 7;
MAX6675 thermocouple_b(thermoCLK, thermoCS_b, thermoDO);
MAX6675 thermocouple_t(thermoCLK, thermoCS_t, thermoDO);
void setup()
{
Serial.begin(9600);
pinMode(pin_top, OUTPUT);
digitalWrite(pin_top, 0);
pinMode(pin_bottom, OUTPUT);
digitalWrite(pin_bottom, 0);
t_top = 10;
t_bottom = 10;
p_top = 0;
p_bottom = 0;
state_top = LOW;
state_bottom = LOW;
prev_top = millis();
prev_bottom = millis();
}
void loop()
{
if (Serial.available() > 0) {
b3 = b2; b2 = b1;
b1 = Serial.read();
if ((b1 == ‘T’) && (b2 == ‘E’) && (b3 == ‘S’)) {
p_top = Serial.parseInt();
if (p_top 100) p_top = 100;
p_bottom = Serial.parseInt();
if (p_bottom 100) p_bottom = 100;
t_bottom = thermocouple_b.readCelsius();
t_top = thermocouple_t.readCelsius();
sprintf (buf, “OK%03d%03d%03d%03d\r\n”, p_top, p_bottom, t_top, t_bottom);
Serial.print(buf);
}
}
if ((state_top == LOW) && ((millis()-prev_top) >= tick * (100-p_top) / 100)) {
state_top = HIGH;
prev_top = millis();
}
if ((state_top == HIGH) && ((millis()-prev_top) >= tick * p_top / 100)) {
state_top = LOW;
prev_top = millis();
}
digitalWrite(pin_top, state_top);
if ((state_bottom == LOW) && ((millis()-prev_bottom) >= tick * (100-p_bottom) / 100)) {
state_bottom = HIGH;
prev_bottom = millis();
}
if ((state_bottom == HIGH) && ((millis()-prev_bottom) >= tick * p_bottom / 100)) {
state_bottom = LOW;
prev_bottom = millis();
}
digitalWrite(pin_bottom, state_bottom);
}
Ребята спасайте. замучился пробовать. С библиотекой Адафруит работает прекрасно и ваш скетч и часы, а с Фастлед ваш тестовый скетч только зажигает нужное количество диодов Белым цветом и стоит не моргает.
Arduino Nano (CH340) v.3 и IDE 1.8.5
“функциями Wiring, вроде digitalWrite и delay. ”
даладно – В ЛЁГКУЮ!, вместо делая просто микроделай юзай
а Диггитал врайт всего 60 тактов тратит – даже на аттини 13 , на 8мГц уже вытянет это!
а если по нормальному делать, то и на 1.2мгц уже справится!
Подскажите, как добавить к скетчу включение и выключение ленты сенсорной кнопкой?
Подскажите почему у меня в скетче написано Red а моргает зеленым?
поменяйте RGB на GRB
Вопрос к знатокам. Подскажите пожалуйста сколько адресных светодиодов можно подключить к ардуино, если питание самих светодиодов будет от блока питания и светодиоды ws2812b расположены на ленте
На сколько памяти хватит. В статье же описано.
какой скачать библиотеку? Adafruit NeoPixel. по ссылке выходит большой список
Просто найдите по названию в менеджере библиотек прямо Ардуино, я лично там нашёл FastLED.
Здравствуйте. Кто-нибудь работал с адресными светодиодами (не лентой, а именно отдельные светодиоды)?
Имеются такие светодиоды как WS6812 и SK6812. И у тех и у других одна и та же проблема – при работе все время горят с произвольными параметрами, вне зависимости от прошивки. Использую библиотеку Fastled. Светодиодов всего 37 штук, блоки питания пробовал разные, ставил конденсаторы, все равно такой эффект. Платы нано и Уно подключал.
Скорее всего где то не пропай.
FastLED не поддерживает RGBW ленты. У него три байта на светодиод, а у ленты – четыре. Поэтому цвета смещаются, к тому же порядок цветов у ленты GRBW, что добавляет путаницы. Проблему уже года три никак не пофиксят, но, вроде, есть какой-то форк.
В ленте светодиоды далеко не всегда тянут 20 мА на цвет: при подключении питания с двух сторон мне не удалось получить больше 5А на метр ленты со 144 светодиодами. И это с учётом примерно 0,9мА, которые потребляет чип, когда все цвета установлены в 0. БП 5В 20А.
Помогите, нужна прошивка для адресной ленты на ардуино нано, нажимаешь сенсорную кнопку, включаетса белий свет, нажымаешь еще раз, включаютса различные ефекты. Можно сделать с пультом ДУ
тоже такую ищу. если вдруг попадётся буду благодарен если поделитесь ссылкой на эмайл.
Как доработать скетч,что бы лента загоралась плавно и так же плавно гасла?
Здравствуйте. Везде пишут “адресная” , но нигде не видел чтобы эти самые адреса упоминалось…. вот например, есть кусок ленты, пусть будет из 5 диодов, какой адрес у диода в центре? И как его отдельно заставить светится одним цветом, а следующий после него другим?
Здравствуйте! Лента кодируется через свой проприетарный протокол, используя однопроводной интерфейс с ШИМ и определенной скважностью. Управлять диодами можно путем программирования МК на нужный вам алгоритм.
спасибо за инфу ! (никак не мог найти скетч “бегущий огонь”)
А зачем использовать эту конструкцию, если в библиотеке есть своя?
// Выключаем все светодиоды.
for (int i = 0; i < LED_COUNT; i++)
{
strip.setPixelColor(i, strip.Color(0, 0, 0)); // Черный цвет, т.е. выключено.
}
strip.clear();
Всем Доброго! Если сведения о долговечности работы лент? В моем понимании при отказе одного из светодиодов в ленте – последующие за ним будут погашены.
Здравствуйте! Если линия данных на одном из светодиодов будет повреждена, остальные дальше по линии перестанут работать. Однако питание всех светодиодов осуществляется параллельно, поэтому если линия данных не будет нарушена, перестанет работать только один светодиод.