В этой статье мы научимся работать с адресной светодиодной RGB лентой WS2812B. Лента состоит из RGB пикселей WS2812B в корпусе LED 5050 (физические размеры каждого элемента составляют 5×5 мм).
Адресные модули и ленты WS2812B в нашем магазине
Каждый пиксель содержит в себе красный, зелёный и синий светодиоды и контроллер ШИМ, с помощью которого можно управлять яркостью каждого светодиода и получать множество различных цветов из трёх основных.
Так как каждый WS2812B состоит из трёх светодиодов и контроллера ШИМ, будет лучше называть их пикселями, а не светодиодами. На фото справа можно увидеть устройство такого пикселя.
Немного о характеристиках адресных светодиодов WS2812B:
- Напряжение питания: 5 ± 0.5 В;
- Потребление тока: ~20 мА один светодиод, т.е. ~60 мА весь пиксель.
В начале нам необходимо подключить светодиоды к 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. Поддерживает всю линейку Ардуино.
Подключение WS2812B в Arduino IDE
Давайте попробуем обе библиотеки и сравним их. Напишем стандартный скетч 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 минимум нужных функций и меньший расход памяти. Какую из них использовать – ваш выбор. Удачи в проектах!
36 комментариев. Оставить новый
Ваш код не работает. Выдаётся ошибка 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);
и будет вам счастье))
Огромное спасибо за комментарий! Исправили в коде скетча.
Скажите пожалуйста, можно ли на ардуино подключить с десяток разных лент и каждой управлять отдельно? Вся земля лент так же проходят через минус ардуины?
Здравствуйте! Вся земля лент должна объединяться на единую шину питания данных лент, от ардуино к ленте питание подать не получится (только передачу данных). Количество светодиодов зависит от используемой библиотеки.
В библиотеке 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();