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

Views: 4955


В настоящее время большой популярностью стали пользоваться светодиоды со встроенным драйвером 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


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


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


  • ch-4000 – универсальная печатная платаch-4000 – универсальная печатная плата
    Views: 1106 На смену устаревшей плате ch-3000, пришла новая ch-4000. Плату уже можно приобрести в магазине Ворон. Схема. Плата позволяет создавать таймеры, часы реального времени, регуляторы температуры, регуляторы влажности, вольтметры, …
  • TDA7294 part 2TDA7294 part 2
    Views: 596 Це друга частина проекту TDA7294, початок дивись тут. Тут ви знайдете повністю проект високоякісного підсилювача на TDA7294, схема, 3D моделі, гербер файли для виготовлення друкованої плати. І звичайно …
  • Униполярный шаговый двигательУниполярный шаговый двигатель
    Views: 2375     В приводах различных устройств часто применяются шаговые двигатели, Шаговый двигатели различают двух типов униполярные – когда обмотки коммутируются током текущим только в одну сторону, например при …
  • MCC PIC24 – модуль OUTPUT COMPARE – в режиме генератора звуковых сигналовMCC PIC24 – модуль OUTPUT COMPARE – в режиме генератора звуковых сигналов
    Views: 738 При проектировании простых устройств автоматики, часто необходимо иметь механизм звукового оповещения. Самый верхний уровень, это формирование голосовых сообщений, но об этом, как то по позже… В самом примитивном …
  • I2C MODULE – PIC18F25K42 Device ID Revision = A001I2C MODULE – PIC18F25K42 Device ID Revision = A001
    Views: 1118 I2C MODULE Обход ошибок в версии I2C MODULE – PIC18F25K42 Device ID Revision = A001 В Серии K42 применен совершенно новый модуль шины I2C, который позволяет поддерживать все …
  • WiFi ESP8266 – AT команды связанные с функцией Wi-FiWiFi ESP8266 – AT команды связанные с функцией Wi-Fi
    Views: 5583 AT команды связанные с функцией Wi-Fi Функции Wi-Fi подключения, запускаться из командной строки Команда Описание  1 AT+CWMODE Проверка, настройка режима работы Wi-Fi (sta/AP/sta+AP), (не рекомендуется для новых проектов). 2 …
  • Мультизоновый индикатор-терморегулятор ch-c3010Мультизоновый индикатор-терморегулятор ch-c3010
    Views: 1297 Часто возникает необходимость получить информацию по температуре с множества точек контроля. Вам необходимо знать температуру в комнате, в коридоре,  температуру на улице, а в погребе (или на балконе) …
  • Тестирование модуля генератораТестирование модуля генератора
    Views: 914  Тестирование модуля генератора Настройка, запуск и проверка рабочей частоты на примере PIC18F26K40. PIC18F26K40 Чтобы понять из-за чего зависит производительность микроконтроллера просто надо понять как работает его задающий тактовый …
  • PIC18 – модуль DMAPIC18 – модуль DMA
    Views: 1276 Введение   Модуль прямого доступа к памяти (DMA) предназначен для обслуживания передачи данных непосредственно между различными областями памяти без вмешательства процессора. Исключив при этом необходимость в интенсивной  обработки …
  • MPLAB® Code ConfiguratorMPLAB® Code Configurator
    Views: 1781 MPLAB ® Code конфигуратор (MCC) является свободно распространяемым плагином, это графическая среда программирования, которая генерирует бесшовный, легкий для понимания кода на Cи, чтобы вставить его в свой проект.



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

Catcatcat

catcatcat

Development of embedded systems based on Microchip microcontrollers.

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

НазадДалее