Бегущие огни на WS2812B

Visits: 4805


В настоящее время большой популярностью стали пользоваться светодиоды со встроенным драйвером WS2812B. Текущий проект предназначен показать возможность использования и управления этими светодиодами. Это и проект и исследование по работе с этими светодиодами.

Для тестирования выбрана плата ILLISSI с контроллером PIC18F26R22.

Catcatcat_electronics_bo_02


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

Техническое описание
[wpdm_file id=241]

Функциональная схема

Catcatcat_electronics_bo_03

 

Драйвер поддерживает напряжение питания в диапазоне +3,5 до 5,3 вольт, и имеет защиту от переполюсовки. Для подавления помех рядом с каждым светодиодом WS2812B необходимо установить конденсатор 0,1 uF.

Для управления используется однопроводная шина с управлением временными интервалами. Основные характеристики передачи данных:

Сигнал Описание Длительность Допустимое отклонение
T0H 0 code, длительность высокого уровня 0.4us ±150ns
T1H 1 code, длительность высокого уровня 0.8us ±150ns
T0L 0 code, длительность низкого уровня 0.85us ±150ns
T1L 1 code, длительность низкого уровня 0.45us ±150ns
RES Длительность импульса СТАРТ Более 50μs

Все данные передаются по битам, старшим битом в перед. Общая длительность передачи суммы двух бит 0 и 1 должна быть в пределах TH+TL=1.25μs±600ns

Передача бита 0:

Catcatcat_electronics_bo_04

 

Передача бита 1:

Catcatcat_electronics_bo_05

Принцип подключения драйверов-светодиодов.

Catcatcat_electronics_bo_06

Принцип передачи данных следующий:

  1. Сформировать условие СТАРТ – отрицательный импульс длительностью не менее 50 us.
  2. Начать передавать данные по битам. Данные передаются старшим битом в перед, каждый бит должен быть сформирован с учетом выше описанных условий.
  3. Для управления одним RGB светодиодом необходимо передать 24 бита.
  4. Если в цепочке N- светодиодов, то необходимо передать N*24 бит.
  5. Для передачи новых данных повторить пункты 1-4.

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

Последовательность передачи цветов GRB

Catcatcat_electronics_bo_07

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


Простой принцип формирования цветов и загрузки данных в ленточки из N-светодиодов.

Для гибкого управления необходимо взять несколько параметров используемых в ch-светомузыке. Для нас это цвет, яркость светодиода и параметр интеграция – это скорость изменения яркости.

Для гибкого управления драйверами WS2812B необходимо следующие параметры:

  • Указать количество используемых светодиодов
#define LEDC    72  // количество светодиодов ws2812b на полметра ленты.
  •  Описать цветовые массивы
char ledred[LEDC][2];// массив красных
char ledblue[LEDC][2];// массив синих
char ledgreen[LEDC][2];//массив зеленых

где параметр, например, ledred[LEDC][0] – яркость свечения, а ledred[LEDC][1] – скорость интеграции.

Скорость интеграции 0 – нет интеграции, – (минус, например, -3) уменьшение яркости, положительное число увеличение яркости. Если включено увеличение яркости, то при достижении максимума, выполняется автоматическое переключение на уменьшение с такой же величиной. При достижении яркости 0 функция интеграции устанавливается равной 0.

Тестирование WS2812B

 

 Для любопытных программа выполняющая этот эффект

        if(++c==9)
        {
            c=0;

            d++;
            if(d>72)
            {
                d=rand()%72;
                red=rand();
            }

            d1++;

            if(d1>72)
            {
                d1=rand()%72;
                blue=rand();
            }

            d2++;
            if(d2>72)
            {
                d2=rand()%72;
                green=rand();
            }

                 pointred (d,red,-2);
                 pointred (LEDC-d1,red,-2);
                 pointgreen (d2,green,-2);
                 pointgreen (LEDC-d,green,-2);
                 pointblue (d1,blue,-2);
                 pointblue (LEDC-d2,blue,-2);
        }

Каждый драйвер получает данные и формирует на выходе данные для передачи на следующие светодиоды, Только длительности формируемых данных 0 и 1 несколько отличаются от паспортных:

Передача бита нуля близка к описанию

Catcatcat_electronics_bo_08

 

а передача бита единицы значительно отличается

Catcatcat_electronics_bo_09

эти сигналы сняты с выхода драйвера WS2812B. Опытным путем было получено, что скорость передачи не может превышать 500 кбит, если её увеличивать, то происходит потеря данных при передачи через цепочки свыше 30 светодиодов. Я склоняюсь к мнению, что драйвер отслеживает только длительность положительного импульса, длительность отрицательного, просто должна быть не меньше 0.9-1 микросекунды.

В связи с этим пример драйвера для загрузки данных в светодиоды

/*char ledred[LEDC];// массив красных где 0 - яркость в формате 0-255
 * char ledblue[LEDC];// массив синих
 * char ledgreen[LEDC];//массив зеленых
*/
//----------------------------------------------------------------------------------------
#define PORTOUT LATA2 // порт для WS2812B
// функция загрузки данных в ленточку, количество светодиодов задается в константе LEDC
void loadWS2812B (void)
{
char a,b,temp;
// формирование сброса
    PORTOUT=0;
    _delay(350);//50us
//--------------------------------
    for(a=0;a<LEDC;a++)
    {
        for(b=0;b<3;b++)
        {
            switch (b)
            {
                case 0 :
                    temp=ledgreen[a];
                    break;
                case 1 :
                    temp=ledred[a];
                    break;
                case 2 :
                    temp=ledblue[a];
            }
            // загрузка байта
            if(temp&0b10000000)
            {
                //формирование бита 1
                PORTOUT=1;
                _delay(5);
                PORTOUT=0;
                _delay(2);//0.45us
            }
            else
            {
                //формирование бита 0
                PORTOUT=1;
                _delay(2);//0.4us
                PORTOUT=0;
                _delay(2);//0.85us
            }

            if(temp&0b01000000)
            {
                //формирование бита 1
                PORTOUT=1;
                _delay(5);
                PORTOUT=0;
                _delay(2);//0.45us
            }
            else
            {
                //формирование бита 0
                PORTOUT=1;
                _delay(2);//0.4us
                PORTOUT=0;
                _delay(2);//0.85us
            }

            if(temp&0b00100000)
            {
                //формирование бита 1
                PORTOUT=1;
                _delay(5);
                PORTOUT=0;
                _delay(2);//0.45us
            }
            else
            {
                //формирование бита 0
                PORTOUT=1;
                _delay(2);//0.4us
                PORTOUT=0;
                _delay(2);//0.85us
            }

            if(temp&0b00010000)
            {
                //формирование бита 1
                PORTOUT=1;
                _delay(5);
                PORTOUT=0;
                _delay(2);//0.45us
            }
            else
            {
                //формирование бита 0
                PORTOUT=1;
                _delay(2);//0.4us
                PORTOUT=0;
                _delay(2);//0.85us
            }

            if(temp&0b00001000)
            {
                //формирование бита 1
                PORTOUT=1;
                _delay(5);
                PORTOUT=0;
                _delay(2);//0.45us
            }
            else
            {
                //формирование бита 0
                PORTOUT=1;
                _delay(2);//0.4us
                PORTOUT=0;
                _delay(2);//0.85us
            }

            if(temp&0b00000100)
            {
                //формирование бита 1
                PORTOUT=1;
                _delay(5);
                PORTOUT=0;
                _delay(2);//0.45us
            }
            else
            {
                //формирование бита 0
                PORTOUT=1;
                _delay(2);//0.4us
                PORTOUT=0;
                _delay(2);//0.85us
            }

            if(temp&0b00000010)
            {
                //формирование бита 1
                PORTOUT=1;
                _delay(5);
                PORTOUT=0;
                _delay(2);//0.45us
            }
            else
            {
                //формирование бита 0
                PORTOUT=1;
                _delay(2);//0.4us
                PORTOUT=0;
                _delay(2);//0.85us
            }

            if(temp&0b00000001)
            {
                //формирование бита 1
                PORTOUT=1;
                _delay(5);
                PORTOUT=0;
//                _delay(2);//0.45us
            }
            else
            {
                //формирование бита 0
                PORTOUT=1;
                _delay(1);//0.4us
                PORTOUT=0;
//                _delay(2);//0.85us
            }

        }
    }
}

Пример функции приведен для PIC контроллеров 12-16-18 серии с тактовой частотой 32 МГц. Длительности в передачи последнего бита закомментированы, так как они не имеют значения, потому, что выборка следующего байта в пределах более 1 микросекунды.


Для серии PIC18.

Вариант 1. Функции для PIC18 с тактовой частотой 64 МГц.

#define PORTOUT LATC1 // порт для WS2812B
// функция загрузки данных в ленточку, количество светодиодов задается в константе LEDC
void loadWS2812B (void)
{
char a,b,c,temp;
// формирование сброса
    PORTOUT=0;
    _delay(800);//50us
//--------------------------------
    for(a=0;a<LEDC;a++)
    {
        for(b=0;b<3;b++)
        {
            switch (b)
            {
                case 0 : 
                    temp=ledgreen[a][0];
                    break; 
                case 1 :
                    temp=ledred[a][0];
                    break; 
                case 2 : 
                    temp=ledblue[a][0];
            }
            // загрузка байта
            if(temp&0b10000000)
            {
                //формирование бита 1
                PORTOUT=1;
                _delay(12);//0.41
                PORTOUT=0;
                _delay(10);//1.00us
            }
            else
            {
                //формирование бита 0
                PORTOUT=1;
                _delay(5);//0.4us
                PORTOUT=0;
                _delay(10);//1.00us
            }

            if(temp&0b01000000)
            {
                //формирование бита 1
                PORTOUT=1;
                _delay(12);//0.83us
                PORTOUT=0;
                _delay(10);//1.00us
            }
            else
            {
                //формирование бита 0
                PORTOUT=1;
                _delay(5);//0.4us
                PORTOUT=0;
                _delay(10);//1.00us
            }

            if(temp&0b00100000)
            {
                //формирование бита 1
                PORTOUT=1;
                _delay(12);//0.83us
                PORTOUT=0;
                _delay(10);//1.00us
            }
            else
            {
                //формирование бита 0
                PORTOUT=1;
                _delay(5);//0.4us
                PORTOUT=0;
                _delay(10);//1.00us
            }

            if(temp&0b00010000)
            {
                //формирование бита 1
                PORTOUT=1;
                _delay(12);//0.83us
                PORTOUT=0;
                _delay(10);//1.00us
            }
            else
            {
                //формирование бита 0
                PORTOUT=1;
                _delay(5);//0.4us
                PORTOUT=0;
                _delay(10);//1.00us
            }

            if(temp&0b00001000)
            {
                //формирование бита 1
                PORTOUT=1;
                _delay(12);//0.83us
                PORTOUT=0;
                _delay(10);//1.00us
            }
            else
            {
                //формирование бита 0
                PORTOUT=1;
                _delay(5);//0.4us
                PORTOUT=0;
                _delay(10);//1.00us
            }

            if(temp&0b00000100)
            {
                //формирование бита 1
                PORTOUT=1;
                _delay(12);//0.83us
                PORTOUT=0;
                _delay(10);//1.00us
            }
            else
            {
                //формирование бита 0
                PORTOUT=1;
                _delay(5);//0.4us
                PORTOUT=0;
                _delay(10);//1.00us
            }

            if(temp&0b00000010)
            {
                //формирование бита 1
                PORTOUT=1;
                _delay(12);//0.83us
                PORTOUT=0;
                _delay(10);//1.00us
            }
            else
            {
                //формирование бита 0
                PORTOUT=1;
                _delay(5);//0.4us
                PORTOUT=0;
                _delay(10);//1.00us
            }

            if(temp&0b00000001)
            {
                //формирование бита 1
                PORTOUT=1;
                _delay(12);//0.83us
                PORTOUT=0;
//                _delay(2);//1.00us
            }
            else
            {
                //формирование бита 0
                PORTOUT=1;
                _delay(5);//0.4us
                PORTOUT=0;
//                _delay(2);//1.00us
            }
        }
    }
}

Вариант 2, для PIC18, более компактный, но по быстродействию он хуже.

#define PORTOUT LATC1 // порт для WS2812B
// функция загрузки данных в ленточку, количество светодиодов задается в константе LEDC
void loadWS2812B (void)
{
char a,b,c,temp;
// формирование сброса
    PORTOUT=0;
    _delay(800);//50us
//--------------------------------
    for(a=0;a<LEDC;a++)
    {
        for(b=0;b<3;b++)
        {
            switch (b)
            {
                case 0 : 
                    temp=ledgreen[a][0];
                    break; 
                case 1 :
                    temp=ledred[a][0];
                    break; 
                case 2 : 
                    temp=ledblue[a][0];
            }
            // загрузка байта
            for(c=0;c<8;c++)
            {
                if(temp&0b10000000)
                {
                    //формирование бита 1
                    PORTOUT=1;
                    _delay(12);//0.8us
                    PORTOUT=0;
                    _delay(2);//0.45us

                }
                else
                {
                    //формирование бита 0
                    PORTOUT=1;
                    _delay(5);//0.4us
                    PORTOUT=0;
                    _delay(8);//0.85us
                }
                temp<<=1;// cдвиг переменной
            }
        }
    }
}

Важное условие подключения драйвера к контроллеру.

Необходимо всегда (особенно для первого включения) устанавливать между микроконтроллером и первым драйвером резистор 430-330 ом.

Catcatcat_electronics_bo_10


Продолжение следует….


Это может быть интересно


  • Проект с использованием MCC часть 10Проект с использованием MCC часть 10
    Visits: 777 Алгоритм управления освещением от нажатия кнопки. Обработка удержания кнопки: Мы должны проверить кнопка в настоящий момент нажата и флаг удержания установлен, если да Проверить таймер удержания “отработал” – …
  • УКВ – радиоприем, часть 1УКВ – радиоприем, часть 1
    Visits: 9502 Музыкальная тема к статье, слушаем: Первый мой радиоприемник, выглядел так. Использовал исключительно в школе на уроках, держась за одно ухо и преданно смотря на училку и сладко улыбаясь. …
  • MCC PIC24 – модуль REAL-TIME CLOCK AND CALENDAR (RTCC)MCC PIC24 – модуль REAL-TIME CLOCK AND CALENDAR (RTCC)
    Visits: 435 RTCC предоставляет пользователю часы реального времени и функция календаря (RTCC), точность “хода” может быть откалибрована. Основные особенности модуля RTCC: • Работает в режиме глубокого сна. • Возможность выбора источника …
  • MTouch® Модуль Емкостной Библиотеки для MPLAB®X Code Configurator (MCC)MTouch® Модуль Емкостной Библиотеки для MPLAB®X Code Configurator (MCC)
    Visits: 1133 Введение MTouch ® Модуль Емкостной Библиотеки для MPLAB ® X Code Configurator (MCC) позволяет быстро и легко генерировать решение кода на  Cи для емкостной сенсорной кнопки, датчика приближения и слайдера. В …
  • Стабилизатор тока на SN3350, часть 2Стабилизатор тока на SN3350, часть 2
    Visits: 1125 Если вам необходимо разработать устройство с применением мощных светодиодов, то никак не обойтись без применения стабилизатора тока. На настоящий момент стабилизаторы тока являются самым эффективным механизмом, для питания светодиода в течение всего …
  • Просто о структурах и объединениях в СиПросто о структурах и объединениях в Си
    Visits: 2128 Какие задачи нам позволяют решать структуры и объединения? Для разработчика встроенных систем эффективность и компактность кода всегда на первом месте. Если программировании на Ассемблере ты сам определяешь как …
  • ch-4000 – универсальная печатная платаch-4000 – универсальная печатная плата
    Visits: 983 На смену устаревшей плате ch-3000, пришла новая ch-4000. Плату уже можно приобрести в магазине Ворон. Схема. Плата позволяет создавать таймеры, часы реального времени, регуляторы температуры, регуляторы влажности, вольтметры, …
  • Проект с использованием MCC часть 01Проект с использованием MCC часть 01
    Visits: 2467 Для изучения MCC я выбрал простой контроллер PIC16F1509. Выбор его был обусловлен богатой новой периферией которую можно изучить. Для начала была собрана схема на макетной плате Внешний вид …
  • Контроллер управления светодиодным освещением с дистанционным управлениемКонтроллер управления светодиодным освещением с дистанционным управлением
    Visits: 1979 Все активнее светодиоды входят в нашу жизнь. Всё эффективнее становится светодиодное освещение. Всё ниже опускаются цены. Всё больше появляется возможностей получения сочных цветов, простоты в управлении. Всё чаще …
  • Мультизоновый индикатор-терморегулятор ch-c3010Мультизоновый индикатор-терморегулятор ch-c3010
    Visits: 1139 Часто возникает необходимость получить информацию по температуре с множества точек контроля. Вам необходимо знать температуру в комнате, в коридоре,  температуру на улице, а в погребе (или на балконе) …



Поделись этим!

Catcatcat

catcatcat

Development of embedded systems based on Microchip microcontrollers.

Продолжайте читать

НазадДалее