Библиотека FastLED для управления светодиодами на чипах WS2812 и не только

Led chip

Содержание

Рассмотрим основные моменты и функции, которые предоставляет нам библиотека FastLED версии 3.6.0. Библиотека используется для управления светодиодами на различных чипах.

Установка библиотеки FastLED

Как установить библиотеку для ардуино можно прочитать здесь.

Где скачать библиотеку FastLED


Скачать файлы библиотеки FastLED можно с сайта тут или перейти на GitHub. Также вы можете установить библиотеку из менеджера библиотек Arduino IDE.

Поддерживаемые светодиодные чипы

Вот список поддерживаемых светодиодов библиотекой FastLED, согласно документации:

  • WS2812B, а также WS2811 / WS2812 / WS2813 (компания adafruit продает их под названием «neopixels») с низкой скоростью передачи данных (800 Кбит/с).
  • APA102 (компания adafruit продает их как «dotstars»). Высокая скорость передачи данных (до 24 МГц).
  • SK9822 — клон APA102.
  • LPD8806 — очень быстрые (скорость до 22 Мбит/с).
  • WS2801 — устаревшие, относительно дешевые, но медленные (до 1 Мбит/с). Склонны к сбоям на больших длинах.
  • TM1809/1804/1812 — протокол аналогичен ws2811 (микросхема 1809 управляет 3 пикселями RGB, 1804 управляет 1).
  • TM1803 — более медленная версия TM1809.
  • UCS1903 — аналогично TM1809/WS2811. Очень медленный протокол, около 400 кбит/с.
  • LPD1886 — 3-х проводной набор микросхем с разрядностью 12 бит на пиксель вместо обычных 7/8 бит на пиксель.
  • UCS1904/2903
  • SM16716
  • GW6205
  • Панели SmartMatrix (требуется библиотека SmartMatrix)
ЧипКоличество проводовКоличество бит при передаче цветаСкорость передачи данных
APA102/DOTSTAR48~24 Мбит/с
WS281138800 кбит/с
WS2812B/NEOPIXEL38800 кбит/с
TM1809/TM181238800 кбит/с
TM180338400 кбит/с
TM180438800 кбит/с
WS2801481 Мбит/с
UCS190338400 кбит/с
UCS290338800 кбит/с
LPD8806471-20 Мбит/с
P9813481-15 Мбит/с
SM1671648

Работа с библиотекой FastLED

Подключение библиотеки

Для подключения библиотеки используется директива #include с названием библиотеки, которую необходимо расположить вначале файла проекта:

#include "FastLED.h"

Определение количества светодиодов, пинов подключения и массива светодиодов

Создадим идентификатор NUM_LEDS, который будет хранить количество светодиодов:

NUM_LEDS 1

Теперь определим контакт платы (или контакты) для передачи данных.

Для 3-х проводных светодиодных микросхем, таких как WS2812, у которых есть линия данных, земля и питание, необходимо определить только DATA_PIN.

Для светодиодных микросхем на основе SPI (четырех проводная схема — линия данных, линия тактирования, земля и питание), например LPD8806, необходимо определить два контакта: данные — DATA_PIN, тактирование — CLOCK_PIN.

#define DATA_PIN 3
#define CLOCK_PIN 13

Определяем массив светодиодов, к которому будем обращаться для взаимодействия:

CRGB leds[NUM_LEDS];

Инициализация

При инициализации нужно передать несколько аргументов методу addLeds(). На примере ниже мы передали следующие аргументы:

  • WS2812B — микросхема светодиодов.
  • DATA_PIN — контакт для передачи данных. Мы его установили равным 3.
  • Т.к. у нас микросхема без тактирования, CLOCK_PIN мы не используем. В некоторых микросхема нужно.
  • GRB — порядок следования цветовых битов. Сначала отправляются 8 бит для зеленого цвета, за ним 8 бит для красного, а затем 8 бит для синего.
  • leds — массив светодиодов (объявлен выше).
  • NUM_LEDS — количество светодиодов (объявлен выше).
void setup() { 
   FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
}

Если неправильно отображаются цвета


Если устройство неправильно отображает цветовые оттенки, то вероятнее всего, неправильно задан порядок следования цветов. Например, для WS2812B порядок такой GRB (Green (зеленый), Red (красный), Blue (синий)).

WS2812 Order Color
Рисунок 1. Структура данных для передачи цвета для WS2812B

В примере Blink библиотеки FastLED можно найти примеры для инициализации светодиодов на различных микросхемах. Здесь просто раскомментировать нужный, остальные можно удалить.

void setup() { 
    FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
    // FastLED.addLeds<SM16703, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<TM1829, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<TM1812, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<TM1809, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<TM1804, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<TM1803, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<UCS1903, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<UCS1903B, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<UCS1904, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<UCS2903, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<WS2812, DATA_PIN, RGB>(leds, NUM_LEDS);  // GRB ordering is typical
    // FastLED.addLeds<WS2852, DATA_PIN, RGB>(leds, NUM_LEDS);  // GRB ordering is typical
    // FastLED.addLeds<WS2812B, DATA_PIN, RGB>(leds, NUM_LEDS);  // GRB ordering is typical
    // FastLED.addLeds<GS1903, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<SK6812, DATA_PIN, RGB>(leds, NUM_LEDS);  // GRB ordering is typical
    // FastLED.addLeds<SK6822, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<APA106, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<PL9823, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<SK6822, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<WS2811, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<WS2813, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<APA104, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<WS2811_400, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<GE8822, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<GW6205, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<GW6205_400, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<LPD1886, DATA_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<LPD1886_8BIT, DATA_PIN, RGB>(leds, NUM_LEDS);
    // ## Clocked (SPI) types ##
    // FastLED.addLeds<LPD6803, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<LPD8806, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<WS2801, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<WS2803, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<SM16716, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<P9813, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS); 
    // FastLED.addLeds<DOTSTAR, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<APA102, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
    // FastLED.addLeds<SK9822, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
}

Как установить цвет светодиода

В библиотеке реализованы два основных объекта для работы с цветовыми моделями RGB и HSV — это CRGB и CHSV соответственно.

Цветовая модель RGB

CRGB — это объект, представляющий цвет в цветовом пространстве RGB. CRGB содержит три однобайтовых элемента данных, каждый из которых представляет один из трех цветовых каналов цвета — красный, зеленый и синий:

  • однобайтовое значение ( от 0 до 255), представляющее количество красного цвета;
  • однобайтовое значение ( от 0 до 255), представляющее количество зеленого цвета;
  • однобайтовое значение ( от 0 до 255), представляющее количество синего цвета.
Рисунок 2. Модель RGB

Существует несколько способов доступа к данным RGB. Каждый из следующих примеров делает одно и то же, устанавливает цвет для первого светодиода.

Три значения цветового канала можно задать через точечную нотацию к свойствам red, green и blue:

leds[0].red   = 40;  
leds[0].green = 80;
leds[0].blue  = 170;

Или использовать более короткие записи r, g и b:

leds[0].r = 40;
leds[0].g = 80;
leds[0].b = 170;

Или можно обращаться как к членам трехэлементного массива:

leds[0][0] = 40;  // красный
leds[0][1] = 80;  // зеленый
leds[0][2] = 170; // синий

Цвета CRGB можно установить, указав значения по отдельности красному, зеленому и синему цвету. Кроме того, цвета CRGB можно задать и другими способами, которые зачастую более удобны и компактны. Все примеры ниже выполняют одну и ту же функцию.

Установка цвета индивидуально для красного, зеленого и синего каналов
leds[0].red =   64;
leds[0].green = 224;
leds[0].blue =  208;
Изменение цвета одновременно для всех каналов
leds[0] = CRGB( 64, 224, 208);
Как задать цвета с помощью шестнадцатеричного цветового кода (0xRRGGBB)
leds[0] = 0x40E0D0;
Установка цвета с помощью именованного HTML цвета

Посмотреть все предопределенные цвета можно здесь.

leds[0] = CRGB::Turquoise;
Установка цвета через setRGB
leds[0].setRGB( 64, 224, 208);

Цветовая модель HSV

Объекты CRGB используют отдельно красный, зеленый и синий каналы для представления цвета. Смешивая различные количества красного, зеленого и синего, можно получить миллионы различных цветов.

Однако в некоторых случаях работа с RGB в коде может быть неудобной. Например, трудно работать с различными оттенками одного цвета, используя значения RGB, и может быть особенно сложно описать «цветовую гамму», которая чередуется с радугой оттенков, сохраняя при этом постоянную яркость.

Чтобы упростить работу с цветом этими способами, библиотека предоставляет доступ к альтернативной цветовой модели, основанной на трех разных осях: оттенок, насыщенность и значение («яркость»):

  • Hue (оттенок) — это угол вокруг цветового круга (рис. 3).
  • Saturation (насыщенность) — это насколько «насыщенный» цвет.
  • Value (значение) показывает, насколько «ярким» является цвет.
Цветовой круг HSV
Рисунок 3. Цветовой круг модели HSV
модель HSV
Рисунок 4. Цветовая модель HSV

В библиотеке FastLED угол Hue (оттенок) представлен в диапазоне от 0 до 255. Он изменяется от красного к оранжевому, желтому, зеленому, аквамариновому, синему, фиолетовому, розовому и обратно к красному. Вот восемь основных точек цикла изменения оттенка в библиотеке и соответствующий им угол изменения оттенка.

Обычно в пространствах HSV оттенок представляется как угол от 0 до 360 градусов. Но для компактности, эффективности и скорости в библиотеке оттенок представлен как однобайтовое число от 0 до 255.

«Saturation» (насыщенность) — это однобайтовое значение в диапазоне от 0 до 255, где при значении 255 будет полностью насыщенный, чистый цвет, при значении 128 получится полунасыщенный, светлый, бледноватый цвет, а при 0 цвет полностью ненасыщенный, просто белый.

«Value» (яркость) — это однобайтовое значение в диапазоне от 0 до 255, обозначающее яркость, где при значении 255 цвет максимально яркий и полностью освещенный», при значении 128 будет несколько затемненный, только полуосвещенный», а при 0 будет темный, черный.

Предопределенные значения оттенков для объектов CHSV
  • HUE_RED — Red (0)
  • HUE_ORANGE — Orange (32)
  • HUE_YELLOW — Yellow (64)
  • HUE_GREEN — Green (96)
  • HUE_AQUA — Aqua (128)
  • HUE_BLUE — Blue (160)
  • HUE_PURPLE — Purple (192)
  • HUE_PINK — Pink (224)
void loop() {
  leds[0].setHue(HUE_RED);
  FastLED.show();
  delay(1000);
  leds[0].setHue(HUE_ORANGE);
  FastLED.show();
  delay(1000);
  leds[0].setHue(HUE_YELLOW);
  FastLED.show();
  delay(1000);
  leds[0].setHue(HUE_GREEN);
  FastLED.show();
  delay(1000);
  leds[0].setHue(HUE_AQUA);
  FastLED.show();
  delay(1000);
  leds[0].setHue(HUE_BLUE);
  FastLED.show();
  delay(1000);
  leds[0].setHue(HUE_RED);
  FastLED.show();
  delay(1000);
  leds[0].setHue(HUE_PURPLE);
  FastLED.show();
  delay(1000);
  leds[0].setHue(HUE_PINK);
  FastLED.show();
  delay(1000);
}

В библиотеке объект CHSV используется для представления цвета в цветовом пространстве HSV. Объект CHSV содержит три однобайтовых элемента данных. Создадим объект paleBlue, который будет хранить бледно-голубой цвет, и установим его для первого светодиода:

void loop() {
  CHSV paleBlue(160, 128, 255);   // Создаем объект CHSV, где Hue = 160, Saturation = 128, Value = 255
  leds[0] = paleBlue;             // Устанавливаем созданный цвет для первого светодиода
  FastLED.show();                 // Применяем изменения
}
Задаем цвет по трем параметрам HSV
leds[0] = CHSV(160, 255, 255);

Или с помощью метода setHSV:

leds[0].setHSV(160, 255, 255);

Также можно только изменить цвет, указав значение от 0 до 255 для значения Hue:

leds[0].setHue(0);   // 0 - Красный цвет
/* Равносильно */
leds[0].setHue(HUE_RED);

Сравнение цветов

Цвета CRGB можно сравнивать на предмет точного совпадения, используя == и !=.

А также их можно сравнивать по относительным уровням освещенности, используя <, >, <= и =>.

Обратите внимание


Это простое числовое сравнение, и оно не всегда соответствует воспринимаемой яркости цветов.

Часто бывает полезно проверить, является ли цвет полностью «черным» (то есть светодиод выключен). Это можно сделать проверив цвет с помощью ператора if. Например:

// Проверяем, горит ли первый светодиод
if( leds[0] ) 
{
   /* Горит */
} 
else 
{
   /* Не горит */
}

Математические операции

Библиотека поддерживает набор математических операций, которые можно выполнять с одним или несколькими цветами. Например, чтобы добавить немного красного к существующему цвету светодиода, можно сделать так:

leds[0] += CRGB( 20, 0, 0);
Добавление и вычитание цветов

Для добавление одного RGB цвета к другому можно воспользоваться следующей конструкцией:

leds[0] += CRGB( 20, 0, 0);

Добавление значения яркости ко всем трем каналам RGB одновременно:

leds[0].addToRGB(20);

Добавление единицы ко всем трем RGB каналам:

leds[0]++;

Для вычитание одного цвета из другого можно воспользоваться конструкцией:

leds[0] -= CRGB(20, 0, 0);

Вычитание значения яркости из всех трех (RGB) каналов:

leds[0].subtractFromRGB(20);

Вычитание единицы из всех трех RGB каналов:

leds[0]--;

«Затемнение» и «осветление» цвета

Существует два различных метода затемнения цвета: стиль видео и математический стиль. Стиль видео используется по умолчанию и разработан таким образом, чтобы случайно не затемнять ни один из каналов RGB светящегося светодиода (независимо от того, насколько он тускло горит) до состояния выключенного светодиода. Математический стиль лишен этого свойства.

Цвета всегда затемняются на какую либо часть. Диапазон разбит на 256 частей, поэтому, чтобы уменьшить яркость цвета на 25% от его текущей яркости, нужно выразить значение в 256 частях. В данном случае 25% = 64/256.

leds[0].fadeLightBy(64);   // Снизить яркость на 25%

Есть еще вариант, чтобы уменьшить яркость до 75% от его текущей яркости. 75% — это 192/256. Можно использовать оператор %=. Суть его заключается в том, что вы устанавливаете новый цвет на «процент» от его предыдущего значения:

leds[0] %= 192;   // Уменьшаем цвет до 75% (192/256) от предыдущего значения

Тот же эффект можно достигнуть вызовом напрямую базовой функции масштабирования nscale8_video:

leds[0].nscale8_video(192);

Если необходимо, чтобы цвет со временем стал полностью черным, можно воспользоваться одной из этих функций:

leds[0].fadeToBlackBy(64);   // Уменьшить цвет на 25% (64/256).
// или
leds[0].nscale8(192);   // Уменьшить цвет до 75% (192/256) от предыдущего значения

Также предусмотрена функция, позволяющая повысить яркость данного цвета до максимальной, сохраняя при этом тот же оттенок:

leds[0].maximizeBrightness();

Цвета также можно масштабировать вверх или вниз с помощью умножения и деления:

leds[0] /= 2;   // Делит значение каждого цветового канала на 2
FastLED.show();
FastLED.delay(1000);
leds[0] *= 2;   // Умножает значение каждого цветового канала на 2
FastLED.show();
FastLED.delay(1000);

Инвертирование цвета

Библиотека предоставляет функцию, которая инвертирует каждый канал RGB. Повторное выполнение этой операции приводит к получению того же цвета, с которого вы начинали.

// Инвертирование цвета
leds[0] = -leds[0];

Установка глобального значение яркости

Функция setBrightness() устанавливает яркость для всех светодиодов. Принимает значение от 0 до 255, где 0 — светодиоды выключены, 255 — максимальная яркость.

FastLED.setBrightness(255);  // Установить максимальную яркость для всех светодиодов
FastLED.setBrightness(128);  // Установить среднюю яркость для всех светодиодов
FastLED.setBrightness(0);    // Гасит все светодиоды

Получение глобального значения яркости

Чтобы получить текущую глобальную яркость можно воспользоваться функцией getBrightness():

void loop()
{
   uint8_t current_brightness = FastLED.getBrightness();   // Получаем текущее значение яркости
   Serial.println(current_brightness);   // Например, выводим в порт
   // ...
}

Установка максимальной потребляемой мощности

Установить максимальную потребляемую мощность можно передав функции setMaxPowerInVoltsAndMilliamps(uint8_t volts, uint32_t milliamps) два параметра: вольты (напряжение светодиодов, обычно 5 вольт) и миллиамперы (общий ток для всех светодиодов). Например:

void setup()
{
   FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
   FastLED.setBrightness(255);
   FastLED.clear();
   FastLED.setMaxPowerInVoltsAndMilliamps(5,1000);   // Ограничить мощность 5-ю ваттами (5 вольт, 1 ампер)
}

Или же использовать функцию setMaxPowerInMilliWatts(uint32_t milliwatts), передав параметр в милливаттах:

void setup()
{
   FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
   FastLED.setBrightness(255);
   FastLED.clear();
   FastLED.setMaxPowerInMilliWatts(5000);   // Ограничить мощность 5-ю ваттами 5000 милливатт = 5 Вт
}

Применение последних изменений

После настройки цветов для светодиодов, чтобы изменения отобразились, необходимо вызвать функцию show():

void loop()
{ 
  // применить синий цвет ко всем светодиодам
  for(int i = 0; i < NUM_LEDS; i++)
  {
    leds[i] = CRGB::Blue;
  }
  FastLED.show();        // Отобразить изменения
  FastLED.delay(1000);   // Подождем секунду
}

Функции show можно передать значение от 0 до 255, оно будет использованно в качестве значения яркости:

void loop()
{ 
  // применить синий цвет ко всем светодиодам
  for(int i = 0; i < NUM_LEDS; i++)
  {
    leds[i] = CRGB::Blue;
  }
  FastLED.show(100);        // Отобразить изменения и установить яркость равным 100
  FastLED.delay(1000);   // Подождем секунду
}

«Очистка»

Чтобы «очистить» светодиодный массив, который содержит значения цветов, используется функция clear(bool writeData)

FastLED.clear();

Если нужно очистить и одновременно погасить все светодиоды, то функции передается параметр true:

FastLED.clear(true);

Установка цвета и яркости с применением изменений

Чтобы установить цвет и яркость для всех светодиодов сразу, а также чтобы изменения сразу вступили в силу, используйте функцию showColor(цвет, яркость), передав два параметра:

void loop() {
  // Установить цвет 0x44EEFF и максимальную яркость для всех светодиодов
  FastLED.showColor(0x44EEFF, 255);  
  // Ждем 1 секунду        
  delay(1000);
  // Установить предопределенный цвет LimeGreen и яркость 50% для всех светодиодов
  FastLED.showColor(CRGB::LimeGreen, 128);
  // Ждем 1 секунду 
  delay(1000);
  // Установить цвет 40 - красного, 150 - зеленного, 230 - синего и яркость 25% для всех светодиодов
  FastLED.showColor(CRGB(40, 150, 230), 64);
  // Ждем 1 секунду 
  delay(1000);
}

Чтобы оставить яркость неизменной, можно передать только цвет:

void loop() {
  // Установить цвет 0x44EEFF
  FastLED.showColor(0x44EEFF);  
  // Ждем 1 секунду        
  delay(1000);
  // Установить предопределенный цвет LimeGreen
  FastLED.showColor(CRGB::LimeGreen);
  // Ждем 1 секунду 
  delay(1000);
  // Установить цвет 40 - красного, 150 - зеленного, 230 - синего
  FastLED.showColor(CRGB(40, 150, 230));
  // Ждем 1 секунду 
  delay(1000);
}
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest
0 комментариев
Межтекстовые Отзывы
Посмотреть все комментарии