Arduino и адресная светодиодная лента
Описание
Адресная светодиодная лента, в отличие от обычной RGB, позволяет управлять цветом и яркостью каждого своего светодиода. Благодаря этому на ней можно отображать различные интересные эффекты, как статические, так и динамические. Сама по себе лента ничего не может, поэтому генерацией эффектов занимается микроконтроллер (или плата на его основе, например Arduino). Более подробно про виды адресных лент можно прочитать в моей статье.
В наборе GyverKIT есть 1 метр адресной светодиодной ленты WS2812b. При желании ленту можно докупить в том же магазине, где продаётся набор – Giant4.
Подключение
- GND ленты соединяется с GND микроконтроллера, так как все сигналы ходят относительно “земли”
- У любого отрезка ленты есть вход, а есть выход: у входа средний пин называется DI, а у выхода – DO. К Arduino подключается именно вход ленты, то есть пин DI
- DI подключается на любой цифровой пин. Если лента питается отдельно от Arduino – DI нужно подключать через резистор 100-500 Ом, чтобы избежать питания ленты через пин, что приведёт к выходу из строя пина Arduino или первого светодиода в ленте. Лучше ставить резистор в любом случае, чтобы исключить такую возможность
- 5V ленты подключается к питанию. Питание может быть общим с Arduino
- Лента потребляет большой ток, поэтому питать её от Arduino, подключенной к USB – нельзя. В наборе GyverKIT есть сетевой адаптер на 5V, ленту нужно питать от него
В рассмотренных выше схемах Arduino питается от USB. Для работы от адаптера можно подключить питание с него на пин 5V платы:
При наличии на ленте штекера можно подключать управление и питание следующим образом:
Примечание:
- Ленту можно питать напрямую от Arduino (при подключении к USB), если ток потребления не будет превышать 500 мА. В библиотеке FastLED можно настроить программное ограничение тока:
FastLED.setMaxPowerInVoltsAndMilliamps(5, 500);
– 5V 500mA - Ленту можно подключать без резистора, если исключена возможность наличия сигнала на ленту без подключенного питания, т.е. когда лента питается от одного источника с микроконтроллером
При работе с Wemos есть особенность: у него логический уровень 3.3V, чего не всегда хватает для передачи сигнала на ленту. При возникновении “артефактов” в эффектах можно подключить питание по следующей схеме: питать Wemos через диод (есть в наборе GyverKIT):
Библиотеки
Самой функциональной и известной библиотекой является FastLED, можно установить через диспетчер библиотек по названию FastLED. В библиотеке ОЧЕНЬ много возможностей, см. официальную вики-документацию, а также полный список модулей, классов и функций.
Как работать с FastLED
Коротко рассмотрим как работать с библиотекой FastLED и самые основные инструменты.
Логика работы с адресной лентой сводится к следующему: лента представляется в виде одномерного массива, каждый элемент – светодиод, точнее его цвет. Цвет светодиода кодируется тремя байтами, то есть 256 значений на каждый канал: красный, зелёный, синий. В программе можно производить различные манипуляции с этим массивом, то есть задавать цвета светодиодам при помощи различных инструментов библиотеки. Как только построение “кадра” закончено – массив можно отправить на ленту и светодиоды включатся соответственно заданным цветам.
Для начала обозначим константами длину ленты и пин, к которому она подключена, просто чтобы проще было редактировать программу в дальнейшем:
#define LED_PIN 5 // пин #define LED_NUM 50 // количество светодиодов
Подключаем библиотеку:
#include "FastLED.h"
Создаём массив цветов, он имеет тип данных CRGB
. Размер – сколько светодиодов в ленте, то есть наша константа. Пусть массив будет глобальным, чтобы доступ к нему был у всей программы:
CRGB leds[LED_NUM];
В блоке setup нам нужно передать в библиотеку информацию о подключенной ленте, а также подключить созданный выше массив. Чтобы программа знала, откуда брать информацию о цветах. По порядку указывается тип ленты, пин, порядок цветов. В круглых скобках – имя нашего массива, а также его размер – длину ленты:
void setup() { FastLED.addLeds< WS2812, LED_PIN, GRB>(leds, LED_NUM); }
Отлично! Всё настроено и готово к работе.
Общие функции
Помимо задания цветов в массиве, существуют следующие управляющие функции:
FastLED.show()
– выводит массив на ленту, т.е. обновляет её текущими цветамиFastLED.clear()
– очищает ленту, буквально обнуляет все цвета в массиве, задаёт “чёрный” цвет. Для применения нужно вызвать show()FastLED.setBrightness(0-255)
– устанавливает яркость всей ленты. Не меняет значения в массиве светодиодов, просто “приглушает” итоговую отображаемую яркость. Для применения нужно вызвать show()FastLED.setMaxPowerInVoltsAndMilliamps(вольты, миллиамперы)
– включает автоматическое ограничение яркости по настроенному току и напряжению. Полезно для длинных лент и/или слабых блоков питанияFastLED.showColor(CRGB цвет)
– залить всю ленту указанным цветом
Тип данных CRGB
Библиотека организована так, что переменной типа CRGB можно задать значение несколькими способами. Рассмотрим задание цвета первому светодиоду в нашей ленте, то есть элемент массива под номером ноль: leds[0]
leds[0] = 0xFF44DD; // цвет в HEX формате leds[0].setRGB(255, 68, 221); // RGB, 0-255 leds[0].setHSV(224, 187, 255); // HSV, 0-255 leds[0].setHue(224); // Hue из HSV, S и V будут 255 // готовый цвет. весь список тут https://github.com/FastLED/FastLED/wiki/Pixel-reference#colors leds[0] = CRGB::Red;
Подробнее про цветовые модели RGB и HSV можно почитать вот здесь.
Примеры
Итак, с базовыми понятиями разобрались, переходим к практике. Для начала зальём всю ленту статичной радугой. Для этого покрасим светодиоды в цикле, задав цвет от 0 до 255 от первого до последнего светодиода в ленте. Конструкция i * 255 / LED_NUM
позволяет получить значения от 0 до 255 при изменении i от 0 до LED_NUM:
#define LED_PIN 5 #define LED_NUM 50 #include "FastLED.h" CRGB leds[LED_NUM]; void setup() { FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, LED_NUM); FastLED.setBrightness(50); for (int i = 0; i < LED_NUM; i++) { leds[i].setHue(i * 255 / LED_NUM); } FastLED.show(); } void loop(){}
Можно сделать подвижную радугу, это будет уже полноценная анимация. Для этого ленту нужно постоянно обновлять новыми цветами, например 30 раз в секунду. Чтобы плавно менять цвет – добавим к нему счётчик, который будет меняться от 0 до 255 и так по кругу.
#define LED_PIN 5 #define LED_NUM 50 #include "FastLED.h" CRGB leds[LED_NUM]; void setup() { FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, LED_NUM); FastLED.setBrightness(50); } byte counter; void loop() { for (int i = 0; i < LED_NUM; i++) { leds[i].setHue(counter + i * 255 / LED_NUM); } counter++; // counter меняется от 0 до 255 (тип данных byte) FastLED.show(); delay(30); // скорость движения радуги }
Можно сделать один бегающий светодиод: каждый раз очищать ленту и красить светодиод под номером, который задаётся счётчиком. Изменение счётчика закольцевать от 0 до количества светодиодов:
#define LED_PIN 5 #define LED_NUM 50 #include "FastLED.h" CRGB leds[LED_NUM]; void setup() { FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, LED_NUM); FastLED.setBrightness(50); } byte counter; void loop() { FastLED.clear(); leds[counter] = CRGB::Red; if (++counter >= LED_NUM) counter = 0; FastLED.show(); delay(30); }
И таких эффектов можно придумать очень много! Займёмся этим уже в блоке проектов
Домашнее задание
- Заставить светодиод бегать “туда и обратно”
- Сделать плавное изменение яркости (от 0 до 255) всей ленты с эффектом радуги