Arduino:Примеры/Гайд по использованию светодиодной ленты WS2812B с Arduino

Материал из Онлайн справочника
Версия от 21:29, 21 апреля 2017; Myagkij (обсуждение | вклад)
(разн.) ← Предыдущая версия | Текущая версия (разн.) | Следующая версия → (разн.)
Перейти к навигацииПерейти к поиску

Перевод: Максим Кузьмин
Проверка/Оформление/Редактирование: Мякишев Е.А.


Черновик


Гайд по использованию светодиодной ленты WS2812B с Arduino[1]

Это статья об адресуемой светодиодной RGB-ленте WS2812B. Впрочем, информация из этого руководства подойдет и для других похожих светодиодных лент – вроде других лент семейства WS28xx, ленты Neopixel и т.п.

Описание

WS2812B – это адресуемая светодиодная лента, которая поставляется в разных версиях – с разным размером, заполнителем и плотностью светодиодов. Выберите ту, что подходит вам лучше всего.

Где купить?

Например, на eBay.

На фото ниже изображена WS2812B, которую я купил для себя. Ее длина составляет 5 метров, а светодиоды спрятаны за водонепроницаемым силиконом. То есть ее можно спокойно оставить там, где может быть дождливо или даже пыльно.

На мой взгляд, это самый лучший тип светодиодных лент. Вы можете управлять яркостью и цветом каждого светодиода по отдельности, что позволяет делать сложные и очень красивые эффекты.

Светодиоды в ленте WS2812B подключены друг к другу последовательно. Кроме того, каждый светодиод оснащен собственным чипом, что позволяет управлять лентой через 1-проводной интерфейс. Это значит, что вы можете управлять всеми светодиодами на ленте, используя лишь один цифровой контакт Arduino.

На фото ниже показан чип, которым оснащен каждый светодиод. Кроме того, каждый светодиод – это RGB-светодиод.

Светодиодные ленты такого типа – очень гибкие. Их даже можно разрезать, чтобы получить куски нужной длины. На рисунке ниже видно, что лента состоит из сегментов, и каждый сегмент состоит из одного RGB-светодиода.

Разрез нужно делать в специальном месте, которое помечено черной полоской.

На каждом конце полосы находится коннектор. Я решил отрезать коннекторы и припаять вместо них гребешковые контакты. Так удобней, если вы хотите подключить светодиодную полосу к Arduino или макетной плате.

Подключение питания к WS2812B

Ленту WS2812B нужно питать от 5 вольт. При 5 вольтах каждый светодиод, включенный на полную яркость, тянет около 50 мА. Это значит, что все 30 светодиодов одновременно могут тянуть 1,5 А. Поэтому обязательно убедитесь, что ваш источник питания потянет такую нагрузку.

Если вы используете внешний источник питания, не забудьте подключить его заземляющий контакт к контакту GND на Arduino.

Схема

В этом проекте лента WS2812B будет питаться от контакта 5V на Arduino, но этого достаточно, т.к. в моем случае лента состоит всего из 14 светодиодов. Но если хотите управлять большим количеством светодиодов, вам понадобится внешний источник питания.

Полезные советы

  • Чтобы смягчить ток, идущий от источника питания, между питающим контактом и контактом GND можно подключить конденсатор номиналом от 100 до 1000 мкФ.
  • Чтобы ослабить шум на линии, соединяющей выходной цифровой контакт Arduino и входной контакт светодиодной ленты, между ними можно подключить резистор номиналом от 220 до 470 Ом.
  • Чтобы минимизировать потерю напряжения, сделайте провода между Arduino, источником питания и светодиодной лентой как можно короче.
  • Если лента не работает, проверьте, исправен ли первый светодиод. Если исправен, отрежьте его, снова припаяйте штырьковые контакты, и все должно заработать.

Код

Чтобы управлять светодиодной лентой WS2812B, вам понадобится библиотека «FastLED». Чтобы установить ее, проделайте следующее:

  • Кликните здесь, чтобы скачать ZIP-архив с библиотекой. В итоге он должен загрузиться в папку «Загрузки».
  • Распакуйте скачанный ZIP-архив. В итоге у вас должна появиться папка «FastLED-master».
  • Переименуйте ее на «FastLED».
  • Переместите папку «FastLED» в папку «libraries» IDE Arduino.
  • Перезапустите IDE Arduino.

Установив библиотеку «FastLED», загрузите в IDE Arduino скетч, показанный ниже. Его можно просто скопировать и вставить, а можно кликнуть в IDE Arduino на Файл > Примеры > FastLED > ColorPalette (File > Examples > FastLED > ColorPalette), т.к. этот скетч идет в комплекте с библиотекой FastLED, установленной вами ранее.

#include <FastLED.h>

#define LED_PIN     5
#define NUM_LEDS    14
#define BRIGHTNESS  64
#define LED_TYPE    WS2811
#define COLOR_ORDER GRB
CRGB leds[NUM_LEDS];

#define UPDATES_PER_SECOND 100

// Этот скетч демонстрирует, как при помощи библиотеки FastLED
// создавать и использовать цветовые палитры.
//
// Пользоваться палитрами на практике – это гораздо проще, 
// чем читать о них в теории. Поэтому просто запустите скетч
// и понаблюдайте за поведением светодиодов, попутно читая код.
// Этот скетч умеет создавать восемь (или больше) разных палитр,
// но его скомпилированная версия на AVR составляет всего 6,5 Кб.
//
// В библиотеку FastLED уже встроено несколько палитр. Кроме того,
// функционал библиотеки позволяет без особого труда создавать 
// собственные палитры.
//
// Теорию того, как работают так называемые «компактные палитры»
// библиотеки FastLED, читайте в самом конце скетча.

CRGBPalette16 currentPalette;
TBlendType    currentBlending;

extern CRGBPalette16 myRedWhiteBluePalette;
extern const TProgmemPalette16 myRedWhiteBluePalette_p PROGMEM;

void setup() {
    delay( 3000 ); // небольшая задержка для того, чтобы цепь
                   // «устаканилась» после включения питания

    FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
    FastLED.setBrightness(  BRIGHTNESS );
    
    currentPalette = RainbowColors_p;
    currentBlending = LINEARBLEND;
}


void loop()
{
    ChangePalettePeriodically();
    
    static uint8_t startIndex = 0;
    startIndex = startIndex + 1; // скорость движения
    
    FillLEDsFromPaletteColors( startIndex);
    
    FastLED.show();
    FastLED.delay(1000 / UPDATES_PER_SECOND);
}

void FillLEDsFromPaletteColors( uint8_t colorIndex)
{
    uint8_t brightness = 255;
    
    for( int i = 0; i < NUM_LEDS; i++) {
        leds[i] = ColorFromPalette( currentPalette, colorIndex, brightness, currentBlending);
        colorIndex += 3;
    }
}

// Этот фрагмент скетча демонстрирует несколько разных 
// цветовых палитр. В библиотеку FasLED уже встроено несколько 
// палитровых шаблонов: RainbowColors_p, RainbowStripeColors_p,
// OceanColors_p, CloudColors_p, LavaColors_p, ForestColors_p и 
// PartyColors_p.
//
// Кроме того, вы можете создавать собственные палитры или даже 
// написать код, создающий палитры прямо на ходу. 
// Ниже продемонстрировано, как все это сделать.

void ChangePalettePeriodically()
{
    uint8_t secondHand = (millis() / 1000) % 60;
    static uint8_t lastSecond = 99;
    
    if( lastSecond != secondHand) {
        lastSecond = secondHand;
        if( secondHand ==  0)  { currentPalette = RainbowColors_p;         currentBlending = LINEARBLEND; }
        if( secondHand == 10)  { currentPalette = RainbowStripeColors_p;   currentBlending = NOBLEND;  }
        if( secondHand == 15)  { currentPalette = RainbowStripeColors_p;   currentBlending = LINEARBLEND; }
        if( secondHand == 20)  { SetupPurpleAndGreenPalette();             currentBlending = LINEARBLEND; }
        if( secondHand == 25)  { SetupTotallyRandomPalette();              currentBlending = LINEARBLEND; }
        if( secondHand == 30)  { SetupBlackAndWhiteStripedPalette();       currentBlending = NOBLEND; }
        if( secondHand == 35)  { SetupBlackAndWhiteStripedPalette();       currentBlending = LINEARBLEND; }
        if( secondHand == 40)  { currentPalette = CloudColors_p;           currentBlending = LINEARBLEND; }
        if( secondHand == 45)  { currentPalette = PartyColors_p;           currentBlending = LINEARBLEND; }
        if( secondHand == 50)  { currentPalette = myRedWhiteBluePalette_p; currentBlending = NOBLEND;  }
        if( secondHand == 55)  { currentPalette = myRedWhiteBluePalette_p; currentBlending = LINEARBLEND; }
    }
}

// Эта функция заполняет палитру совершенно случайными цветами.

void SetupTotallyRandomPalette()
{
    for( int i = 0; i < 16; i++) {
        currentPalette[i] = CHSV( random8(), 255, random8());
    }
}

// Эта функция делает палитру из черных и белых линий.
// Поскольку палитра – это, в сущности, массив 
// из шестнадцати CRGB-цветов, для ее создания можно использовать 
// различные функции fill_* – вроде fill_solid(), fill_gradient(),
// fill_rainbow() и т.д.

void SetupBlackAndWhiteStripedPalette()
{
    // сначала делаем все фрагменты черными...
    fill_solid( currentPalette, 16, CRGB::Black);
    // ...а потом делаем каждый четвертый фрагмент белым:
    currentPalette[0] = CRGB::White;
    currentPalette[4] = CRGB::White;
    currentPalette[8] = CRGB::White;
    currentPalette[12] = CRGB::White;
    
}

// Эта функция заполняет палитру фиолетовыми и зелеными полосами.
 
void SetupPurpleAndGreenPalette()
{
    CRGB purple = CHSV( HUE_PURPLE, 255, 255);
    CRGB green  = CHSV( HUE_GREEN, 255, 255);
    CRGB black  = CRGB::Black;
    
    currentPalette = CRGBPalette16(
                                   green,  green,  black,  black,
                                   purple, purple, black,  black,
                                   green,  green,  black,  black,
                                   purple, purple, black,  black );
}

// Фрагмент кода ниже показывает, как создать статичную палитру,
// хранящуюся в памяти PROGMEM (т.е. во flash-памяти).
// Этот тип памяти, как правило, просторней, чем RAM.
// Статичная палитра вроде той, создание которой показано ниже,
// занимает, как правило, 64 байта flash-памяти.

const TProgmemPalette16 myRedWhiteBluePalette_p PROGMEM =
{
    CRGB::Red,
    CRGB::Gray, // белый – слишком яркий свет 
                // по сравнению с красным и синим
    CRGB::Blue,
    CRGB::Black,
    
    CRGB::Red,
    CRGB::Gray,
    CRGB::Blue,
    CRGB::Black,
    
    CRGB::Red,
    CRGB::Red,
    CRGB::Gray,
    CRGB::Gray,
    CRGB::Blue,
    CRGB::Blue,
    CRGB::Black,
    CRGB::Black
};

// Теперь немного теории о том, как работают компактные палитры 
// библиотеки FastLED.
//
// В компьютерной графике, как правило, палитра 
// (или «справочная таблица цветов») состоит из 256 фрагментов, 
// которые содержат 256 разных 24-битных RGB-цветов. Соответственно,
// вы можете обратиться к нужному вам цвету при помощи простого
// 8-битного (т.е. 1-байтного) значения.
// Но 256-фрагментная палитра занимает 768 байт RAM-памяти, 
// и для Arduino это, как правило, слишком много.
//
// FastLED поддерживает эти традиционные 256-фрагментные палитры -
// на тот случай, если RAM-память вашей сборки в состоянии потянуть 
// необходимые 768 байт.
//
// Но в библиотеке FastLED есть и более компактная альтернатива. 
// Эта функция называется «компактной палитрой» и состоит
// из 16 фрагментов. Впрочем, доступ к ней осуществляется так, 
// будто на самом деле в ней 256 фрагментов, и это выполняется за счет 
// интерполяции между имеющимися 16 фрагментами. Другими словами, 
// между каждыми двумя смежными фрагментами генерируется пятнадцать 
// виртуальных промежуточных фрагментов.
//
// К примеру, если для первого фрагмента компактной таблицы задать
// зеленый цвет (0,255,0), а для второго – синий (0,0,255),
// а затем запросить первые шестнадцать цветов, то библиотека вернет
// зеленый цвет, а следом – пятнадцать цветов, формирующих плавный 
// градиент от зеленого к синему.

Примечание: Поменяйте значение в строчке #define NUM_LEDS 14 на количество светодиодов, имеющихся в вашей ленте. В моем случае их было «14».

Демонстрация

В результате светодиодная лента начнет показывать разные эффекты. Вроде такого...

Такого...

И такого...

И так далее...

Использование корпуса для светодиодной ленты

Светодиодные ленты, как правило, идут в комплекте с отклеиваемой лентой, благодаря чему их можно прикрепить практически к любой поверхности. Этот клей, впрочем, держится не очень хорошо, поэтому лента может отклеиться уже на следующий день.

Решение: Можно воспользоваться корпусом вроде того, что показан на картинке ниже. Он хорошо рассеивает свет, и его можно шурупами прикрутить к какой-нибудь твердой поверхности. Например, к книжной полке.

См.также

Внешние ссылки