Individální projekty MPOA

Mikroprocesory s architekturou ARM

Uživatelské nástroje

Nástroje pro tento web


2018:rgb-controller

Řízení digitálních RGB diod


Zadání

Naprogramujte řízení digitálních RGB diod WS2812B(SK6812) zapojených za sebou na externí DPS s rozložením 8×4 s využitím desky STM32F4DISCOVERY. V programu nadefinujte vlastní funkce pro překlápění úrovní pro bity 1 a 0 dle standardu v datasheetu. Pro zobrazení určitých barev na jednotlivých diodách využijte dvourozměrné pole s odpovídajícími hodnotami.

Úvod

RGB diody WS2812B jsou určeny pro inteligentní ovládání LED světelných zdrojů. Mají v sobě zabudovaný čip, který podle vstupního řídícího signálu ovládá barvy a blikání diod. Jsou k dostání v typech pouzder 5050, 3535 nebo 4020 a to na pásku nebo samostatně.

Hlavní výhodou těchto diod je, že více než jedna z nich může být řízena jedním signálem. Jsou tedy vyžadovány pouze tři vodiče - 5V, GND a řídící signál. Zapojení je řešeno kaskádním způsobem, jak je znázorněno na obrázku níže.

Jedna dioda vyžaduje příjem 24 bitů - každá ze tří základních barev má 8 bitovou úroveň se kterou dosahuje 256 úrovní jasu. Celkově je tedy možné využít 16,7 milionů barev.

Každá dioda provádí změnu a zesílení signálu. To umožňuje dosáhnout větších vzdáleností.

Přenos dat probíhá tak, že se pošlou data pro všechny diody. První dioda je přijme a převezme si svých prvních 24 bitů. Ty poté odebere a zbylé pošle dál. Druhá dioda udělá to samé a tento proces se dále opakuje. Na konci signálu musí být nastaven krátký reset, jinak se ani jedna dioda nerozsvítí. Potom se můžou poslat nové data. Na obrázku je tento proces znázorněn.

data_transfer.jpg

Jednotlivé bity se posílají v pořadí nejdříve pro zelenou pak červenou a nakonec modrou barvu od nejvyššího významného bitu po nejnižší.

bits_of_colors.jpg

Čas přenosu jednoho bitu je 1,25 us, to odpovídá frekvenci 800 kHz, přenosová rychlost tím pádem je 800 kbit/s. Během jedné periody se nastaví nejdříve vysoká a pak nízká úroveň. Bit 1 nebo 0 se rozlišuje podle délky nastavení těchto úrovní (viz obrázek a tabulka). Reset je daný nízkou úrovní.

code_level.jpg level_time_table.jpg

Další vlastnosti

  • Pokud má být obnovovací frekvence 30 Hz (33,3 ms), může být v jedné řadě připojeno kolem 1000 LED diod
  • Mezi dvěma diodami může být vzdálenost větší než 5 m bez dalších komponent
  • Ochrana proti přepólování napájení, nepoškozuje IC
  • Nízká cena

Zdroj textu


Řešení

Generování signálu

Jak je uvedeno v zadání je jako zdroj řídícího signálu použita deska STM32F4DISCOVERY. Pro vygenerování je využit časovač TIM2 CH2 s PWM signálem na pinu PB3 s periodou 1,25 us (800kHz) bez předděličky a s ARR o hodnotě 105-1. Ke generování bitů 1 nebo 0 se pouze mění střída signálu (1 - 67% , 0 - 33% ). Zdroj způsobu řešení Zdroj kódu pro generování PWM signálu

Problém se zapojením diod

Označení pinů pouzdra diody WS2812B bylo dle jejich datasheetu 1 2 a jednoho projektu odlišné. Proto se nejdříve vyrobila deska s oběmi verzemi zapojení (viz obrázek), aby se zjistilo, které je správné.

board.jpg

Po vyslání signálu pro rozsvícení diod se ale ani jedna nerozsvítila. Po dlouhém zkoumání se zjistilo, že jenom horní dioda má na výstupu signál. Proto byl předpoklad, že správné zapojení je podle datasheetu. Signál byl ale stejný jako na vstupu a prvních 24 bitů měly být oříznuté. Počítalo se tedy s tím, že je dioda vadná. Po výměně byl ale výsledek stejný. Když se ale horní dioda vyjmula a poslal se signál do druhého zapojení, tak se zde dioda rozsvítila.

K oběma zapojením tedy nesmělo být zároveň přivedeno napájení. Nakonec bylo zjištěno, že pro projekt byly zakoupeny diody typu SK6812, což je kopie WS2812B akorát mají jiné uspořádaní výstupních pinů a trochu odlišné šířky pulzů. datasheet SK6812mini srovnání WS2812B a SK6812

Kód

Způsob řešení pro rozsvícení diod o určitých barvách, je založen na využití pole se zadanými 24 bitovými hodnotami. Podle těchto vstupních dat se bude každou periodu určovat hodnota střídy PWM signálu, tedy zda má být generován bit 1 nebo 0.

Pro nastavení střídy PWM signálu se vytvořila funkce set_duty(). Parametry pro funkci jsou hodnota barvy a pořadí bitu, který má být přečten.

  void set_duty (uint32_t copycolor, uint8_t bitposition){
 
                copycolor = copycolor << bitposition;
                uint32_t bit = copycolor & 0x800000;
                bit = bit >> 23;
                //if ( bit == 0x800000 ){
                    if ( bit == 1 ){
                        htim2.Instance -> CCR2 = 50; //set duty cycle
                    }
                    else
                    {
                        htim2.Instance -> CCR2 = 20; //set duty cycle
                    }
 
  }

V hlavním kódu jsou v nekonečné smyčce dvě podmínky pro přečtení všech bitů ze zadaného pole. V opačném případě je nastaven reset a cyklus se pak opakuje. Pro časování změny střídy a nastavení resetu je využita funkce pro zpoždění v mikrosekundách DWT_Delay_us() převzatá zde. Aby se diodám měnila barva jsou na konci smyčky přidány další dvě podmínky, které způsobují změnu v pořadí čtení pole.

Zadaných hodnot v poli nemusí přímo odpovídat počtu zapojených diod. Způsobí to pouze vygenerování delšího signálu a výstupní signál z poslední diody nebude tím pádem přijat. Při kratším signále by se poslední diody nerozsvítily. Důležité je, aby byl nastavený reset. Uvádí se hodnota alespoň 50 us. Experimentálně bylo zjištěno, že ještě při 40 us se diody rozsvítili. V kódu je nastavena větší hodnota 1 ms kvůli měnění barev.

int main(void)
{
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
 
    uint32_t arrayRGB[] = {0xFFFFFF,0xFF0000,0x00FF00,0x0000FF,0x00FFFF,0xFF00FF,0xFFFF00,0x000000}; 
    uint8_t arrayRGBsize = 8;
    uint8_t numbit = 0; //number of bit
    uint8_t numcolor = 0; //number of color
    uint8_t moves = 0;
 
  while (1)
  {
  /* USER CODE END WHILE */
 
  /* USER CODE BEGIN 3 */
 
    //if (numcolor < sizeof(arrayRGB)){
    if (numcolor < arrayRGBsize ){
             if ( numbit < 24) {
                uint8_t movecolor = (numcolor + moves) % arrayRGBsize ;
                set_duty(arrayRGB[movecolor],numbit);
                numbit++;
            }
            else
            {
                numbit=0;
                numcolor++;
            }
        DWT_Delay_us(0.9);
    }
    else
    {
         numbit=0;
         numcolor=0;
         htim2.Instance -> CCR2 = 0; //set duty cycle
         DWT_Delay_us(1000);
 
            //delay for change color
            static uint16_t i=0;
            if ( i > 500 ){
                    if (moves>=arrayRGBsize){
                            moves=0;
                    }
                    moves++;
                    i=0;
            }
            i++;
    }
 
  }//end while(1)
  /* USER CODE END 3 */
 
}

Hodnota u funkce DWT_Delay_us() se musela korigovat tak, aby zadané barvy přibližně odpovídali zobrazeným. S přibývajícím kódem se totiž rychlost procesoru snižuje a časování pak není přesné. V ukázce jde vidět, že jedna dioda problikává, což znamená, že se střída mění tam kde by neměla. Pro více zapojených diod by tento způsob nebyl dostačující. Lepším způsobem by bylo využití jiného časovače se stejnou periodou, ve kterém by se v každém cyklu střída signálu měnila. Ideálně při každé náběžné hraně PWM signálu, jak je zřejmě naznačeno zde. Bohužel se tohoto nepodařilo docílit.

Ukázka

V horním zapojení desky je přidaná jedna dioda typu WS2812B a ve spodním jsou SK6812.


Závěr

Prostudoval se princip řízení digitálních RGB diod a vygeneroval signál pro jejich ovládání barev. Z časových důvodů, kdy nastal problém se zapojením diod, nebyla vyrobena deska s rozložením 8×4, jak je uvedeno v zadání, ale ponechala se původní se čtyřmi diodami. Vytvořený kód zajišťuje rozsvícení barev podle zadaného pole a po krátkém čase dělá jejich změnu.

Zdrojové soubory projektu

2018/rgb-controller.txt · Poslední úprava: 2019/01/15 00:08 autor: Lukáš Gerych