Бегущие огни на 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


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


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


  • Altium Designer my Libraries, Project templates, System settings by Catcatcat V23.04Altium Designer my Libraries, Project templates, System settings by Catcatcat V23.04
    Visits: 157 Смотри как установить и подключить библиотеку тут.   V.  – 23_04 – Component Database Update. – configuration file name – DXPPreferences1.DXPPrf. – Added two projects for audio amplifier …
  • Простой цифровой милливольтметр постоянного токаПростой цифровой милливольтметр постоянного тока
    Visits: 4020 Простой цифровой вольтметр постоянного тока. Три диапазона измерений с автоматическим переключением 1 – 0,001 – 0,999 V, 2 – 0,01-9,99 V, 3 – 0,1-99,9. Четыре управляемых выхода с возможностью задания функции контроля …
  • Altium Designer my Libraries, Project templates, System settings by Catcatcat V23.09Altium Designer my Libraries, Project templates, System settings by Catcatcat V23.09
    Visits: 228   September 2023 component base update.  Release updates V.  – 23_09 added new components. Changed the structure of the database. Configuration file name – DXPPreferences1.DXPPrf. Added project CLUBBEST_50_Light. …
  • MCC PIC24 – модуль OUTPUT COMPARE – режиме ШИМMCC PIC24 – модуль OUTPUT COMPARE – режиме ШИМ
    Visits: 1082 Во многих системах управления, для формирования управляющих сигналов требуется модуль ШИМ, он позволяет не только формировать импульсы заданной длительности, но и с применением обычного RC фильтра строить простые …
  • JDY-62A Audio bluetooth moduleJDY-62A Audio bluetooth module
    Visits: 1614 Простой модуль для простого аудио блютуса. Встроенные подсказки на английском языке. Модуль включён, режим муте – после подачи питания. Контроль разряда батареи предупреждение что батарея разряжена и необходима …
  • AD9833 – Programmable Waveform GeneratorAD9833 – Programmable Waveform Generator
    Visits: 2729 Простой генератор звуковых частот на AD9833. Для тестирования БПФ в светомузыке мне нужен был генератор звуковых частот. Я  использовал советский Г3-112, но он себя давно изжил.  Все думал купить …
  • Проект с использованием MCC часть 08Проект с использованием MCC часть 08
    Visits: 986 И так создадим проект в котором при помощи двух кнопок мы сможем управлять яркостью светодиодов. При использовании МСС у нас лафа полная, добрые дяди с Microchipa подготовили функции, …
  • Altium Designer first projectAltium Designer first project
    Visits: 212 Эта статья подразумевает, что у вас установлен и настроен Altium Designer как описано в статье  Altium Designer my setup system and project structure.  Обратите внимание! Библиотека постоянно обновляется, …
  • Регулятор влажностиРегулятор влажности
    Visits: 1351 Регулятор ILLISSI-CH-1000 предназначен для контроля и регулировки относительной влажности в диапазоне от 0 до 100%. Регулятор позволяет работать как в режиме осушения, так и увлажнения. Для измерения возможно …
  • MAX7219/21 и 8х8 LED дисплеиMAX7219/21 и 8х8 LED дисплеи
    Visits: 903 MAX7219, MAX7221 предназначены для вывода информации на 8 разрядов семисегментного индикатора, но на нем легко организовать вывод на светодиодные индикаторы 8х8. продолжение следует…. Это может быть интересно Метки: MAX7219, …



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

Catcatcat

catcatcat

Development of embedded systems based on Microchip microcontrollers.

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

НазадДалее