LED NeoPixel – jak na ně s Arduinem

Běžné LED pásky zná asi každý. Řada segmentů tvořených obvykle trojicí LED a rezistorem je spojena paralelně, takže po připojení napájecího napětí se celý LED pásek rozsvítí stejně. Barevné RGB pásky jsou v principu totéž, červené, zelené a modré LED jsou opět napájené paralelně, řízením napájecího napětí nebo PWM modulací můžeme nastavit barvu světla celého pásku. LED NeoPixel od firmy Adafruit toho dovolují mnohem víc.

Základní myšlenkou je to, že každou jednotlivou LED v pásku nebo matici musí být možné ovládat samostatně co do barvy i intenzity světla. LED NeoPixel obsahují na čipu kromě tří barevných LED ještě řadič a paměť na 3 byty. Součástka má čtyři vývody, dva jsou nutné pro napájení (5V), další pro vstup dat a poslední jako výstup dat. LED se zapojují z hlediska dat za sebe jako články řetězu, z hlediska napájení pochopitelně paralelně. Intenzita svitu každé z barevných složek je určena osmi bity, celkem tedy máme k dispozici 24 bitovou informaci o barvě (16777215 kombinací).

Ovládání NeoPixel lze popsat snadno. Na počátku je na vstupu úroveň L po dobu nejméně 50 μs, ta dá řadiči WS2812B najevo, že se má připravit pro příjem dat. Přicházející bity mají podobu pulzů s celkovou délkou (periodou) 1,25 μs. Logickou 1 reprezentuje pulz o délce 400 ns v úrovni H a 850 ns v úrovni L, logickou nulu pulz o délce 800 ns v úrovni H a 450 ns v úrovni L. Všechny časy mají podle výrobce řadiče povolenou toleranci ±150 ns. Řadič připravený na příjem dat přečte prvních 24 bitů, které dorazí na jeho vstup, a uloží je do své paměti. V každém z bytů barvy jde nejvýše významný bit jako první. Následně až do doby, než bude na vstupu opět nejméně 50 μs úroveň L, všechna další přicházející data řadič okamžitě propustí na výstup. V této době LED svítí stále podle minulých dat, nová jsou jen uložena v paměti. Nové nastavení barvy se projeví na LED až když se řadič úrovní L delší než 50 μs přepne do čekání na příjem dalších dat.

protokol

Pulzy pro ovládání NeoPixel (24 pro jednu LED)

Použitý systém má svoje výhody i nevýhody. Jediný datový vodič stačí k ovládání teoreticky libovolně velkého počtu LED a každou z nich lze nastavit nezávisle na ostatních. Pokud má být stav měněn každých 20 ms (aby nebylo vidět blikání při pohybu) je v praxi při datovém toku 800 kbit/s určeném protokolem počet LED omezen asi na 600. Při změně nedochází k tomu, že by LED na nějakou dobou zhasla nebo blikla, jak by tomu bylo u principu posuvného registru. Nevýhodou je poměrně velký datový tok, při změně stavu kterékoli LED je nutné vyslat nejméně tolik bitů, kolik je 24x pořadové číslo LED, obvykle se ale obnovuje stav celého řetězce konstantní délky. Z toho plyne i další věc, řídící elektronika (respektive mikrokontrolér) si musí pamatovat nebo rychle spočítat stav všech LED, to znamená, že při standardním přístupu potřebuje paměť o velikosti 3 byty na každou LED NeoPixel.

Stačí-li ovládat LED podle nějakého jednoduchého algoritmu, pak samozřejmě nemusí být uložen jejich stav v paměti. Algoritmus musí fungovat rychle, aby nenarušil přenos dat. Naštěstí se protokol ve skutečnosti nemusí úplně přesně držet normy uvedené v katalogovém listu řadiče, například odstup dvou po sobě následujících bitů může být až 5 μs, to poskytuje cenný čas. V podstatě čtení bitů pracuje tak, že asi 600 ns po náběžné hraně pulzu se řadič podívá na stav vstupu, je-li H, přečte se logická 1, je-li L, přečte se logická 0.

IMGP0602b

Detail LED NeoPixel na kruhové desce

LED NeoPixel vyrábí firma Adafruit jako samostatné součástky, moduly s jednou LED, kruhové moduly s 12, 16, 24 nebo 60 LED, pásky s 30, 60 nebo 144 LED na metr délky, případně i jako čtvercové matice 8×8 LED nebo shield na Adruino s maticí 5×8 LED. Pásky se 144 LED/m se prodávají v délce 1 m, ohebnější a ne tak hustě osazené až v délce 4 až 5 m. Z výroby jdou vždy pásky půlmetrové, které se následně spojují do delších.

pasekneo

Pásek s LED NeoPixel (foto z internetových stránek výrobce)

Každá barevná složka každé LED má při plném rozsvícení odběr 20 mA. Není to mnoho, nicméně při plném svitu je to 60 mA na jedno pouzdro a metr dlouhý pásek se 30 LED (nejřidší) už bere 1,8 A, pásek se 144 LED teoreticky přes 8,5 A. Nebo jinak, metr pásku při napájení 5 V má příkon podle počtu LED 9, 18 nebo 35 W. Světlo je velmi intenzivní, tak jak to odpovídá příkonu. I když jsou na pásku napájecí linie dost široké, na větší délce už je odpor znatelný. Dochází k úbytkům napětí, a protože na zelených a modrých LED se projeví pokles víc, než na červených, na konci pásku příliš vzdáleném od napájení je nejen svit slabší, ale také v barvě převažuje červená. Aby se barvy zobrazovaly správně, je lepší vést data a napájení odděleně. Zatímco data musí vstupovat do pásku na jeho konci, napájení pokud možno připojíme do bodů uprostřed délky pásku nebo u dlouhých pásků vedeme silné silové napájení podél a připojujeme ve více bodech nejvýše po jednom metru. Silnější vodiče a přiměřeně dimenzovaný zdroj 5 V jsou v tomto případě opravdu na místě, například 5 m hustě osazeného pásku bude mít při plném svitu bílé barvy odběr přes 43 A! Napájení delších pásků je vhodnější rozdělit na několik sekcí se samostatnými zdroji. Odběr jedné zhasnuté LED je menší než 1 mA.

napajeni

Doporučený způsob napájení pásku (obrázek z dokumentace výrobce)

Pro připojení datového vodiče na mikrokontrolér se kvůli ochraně před špičkami napětí doporučuje zařadit sériově odpor kolem 470 Ω. Na napájení se doporučuje připojit elektrolytický kondenzátor s kapacitou asi 1 mF. Zejména to platí v případě, když malý počet LED napájíme ze stejného zdroje jako mikrokontrolér.

K vyzkoušení LED NeoPixel nestačí připojit je na napájení. Pokud potřebujeme jen ověřit funkci, poslouží přípravek podle následujícího obrázku. Přepínačem volíme délku pulzů kolem 440 ns nebo 810 ns, frekvence je 500 až 455 kHz. Krátké pulzy přivedeme na datový vstup NeoPixel. Když data odpojíme, celý řetězec by měl zhasnout. Přivedením delších pulzů se bíle rozsvítí. Vlivem přechodových jevů při spínání se některé LED mohou rozsvítit barevně.

schema555

Přípravek pro vyzkoušení funkčnosti LED NeoPixel

Ovládání LED NeoPixel mají optimálně usnadněné uživatelé Arduina, kteří na adrese https://github.com/adafruit/Adafruit_NeoPixel najdou potřebnou knihovnu. Knihovna Adafruit_NeoPixel se zkopíruje do příslušného adresáře ve složce „dokumenty“ a při následujícím spuštěním je už vidět mezi dostupnými knihovnami. V ukázkových příkladech je formou komentářů vysvětlené praktické použití.

Nejprve se parametry jednoho příkazu musí zadat, kolik LED je zapojeno v řetězci, na kterém pinu Arduina má být výstup dat, jestli jsou barvy v pořadí GRB (standard NeoPixel) nebo RGB (Arduino FLORA) a jestli být použita frekvence pulzů 800 kHz pro řadič WS2812 nebo 400 kHz pro starší řadič WS2811. Před použitím se provede inicializace (vynulování paměti) a pak už se dá pracovat s jednotlivými LED rozlišenými pořadovým číslem počínaje nulou. Zadává se jednobytová hodnota pro každou barevnou složku. Operace se provádí jen ve vyhrazené paměti mikrokontroléru, do řetězce LED celý blok dat přenese jiný povel.

Jako příklad si uvedeme program, který vytvoří efekt pomalého „nalití“ barvy do pásku dlouhého 1 m s 30 LED/m, bude se cyklicky střídat sedm barev. Po rozsvícení celý pásek plynule pohasne :

// Pokus s páskem LED NeoPixel - nalití barvy do 30 LED a postupné stvívání
#include <Adafruit_NeoPixel.h>                                   // přičlenění knihovny
#define pocet 30                                                 // počet LED v pásku
#define pin 3                                                    // výstup signálu na pinu  
Adafruit_NeoPixel LED = Adafruit_NeoPixel(pocet,pin,NEO_GRB + NEO_KHZ800);
  // inicializace - definuje objekt LED třídy Adafruit_NeoPixel, parametry jsou počet diod v řadě
  // pin pro výstup signálu, pořadí barev a kmitočet pulzů 
int zelena,cervena,modra;                                        // pracovní proměnné

void setup() {
  LED.begin();                                                   // vynulování paměti vyhrazené LED
}

void loop() {                                                    // smyčka demonstračního programu
  for (int barva=0; barva<=6; barva++){                          // ... pro 7 barev  
    switch (barva) {                                             // nastavení složek aktuální barvy
      case 0: {zelena = 255; cervena = 0  ; modra = 0  ; break;}
      case 1: {zelena = 255; cervena = 255; modra = 0  ; break;} 
      case 2: {zelena = 0  ; cervena = 255; modra = 0  ; break;}
      case 3: {zelena = 0  ; cervena = 255; modra = 255; break;}
      case 4: {zelena = 0  ; cervena = 0  ; modra = 255; break;} 
      case 5: {zelena = 255; cervena = 0  ; modra = 255; break;}
      case 6: {zelena = 255; cervena = 255; modra = 255; break;}
      }
    for (int i=0; i<pocet; i++){                                 // nalití barvy do všech LED
      LED.setPixelColor(i, zelena, cervena, modra);              // nastavení jedné LED     
      LED.show();                                                // přenesení dat do fyzických LED 
      delay(50);                                                 // zpomalení nalití
      }
    for (int i=255; i>=0; i--){                                  // stmívání všech LED současně 
      LED.setBrightness(i);                                      // nastavení jasu
      delay(3);                                                  // zpomalení stmívání
      LED.show();                                                // přenesení dat do fyzických LED 
      }    
    LED.setBrightness(255);                                      // vrácení jasu na plnou hodnotu
  }                                                              // konec cyklu pro jednu barvu 
}                                                                // konec cyklu všech barev  

Na uspořádání LED prakticky nezáleží, kruhy i pásky jsou z hlediska zapojení totožné, dokonce jde řetězce rozvětvit (větve se chovají identicky). Knihovna dovoluje střídavě ovládat více řetězců připojených na různé piny. Omezení počtu ovládaných LED vyplývá z nutnosti vyhradit 3 byty RAM na každou a omezené kapacity paměti. Arduino UNO zvládne až kolem 600 LED, Arduino Mega zhruba 4x víc. Kvůli využívání stejného přerušení respektive zakazování přerušení nemůže obsluha NeoPixel pracovat současně s některými jinými knihovnami, například s programovou obsluhou modelářských serv. Tento problém lze při omezeném počtu serv řešit přepojením na generování signálu pro serva časovači (PWM generátorem). Obecně lze NeoPixel ovládat dostatečně rychlými mikrokontroléry, které jsou schopné zaručit pravidelný proud dat. Tuto podmínku bez HW doplňků bohužel nesplňuje například Raspberry Pi a další počítače schopné multitaskingu s výjimkou platformy BeagleBone Black.

IMGP0589b

Připojení kruhu s 12 LED na Arduino

K čemu se dají pásky a matice NeoPixel použít? Především k vytváření světelných efektů, které by dosud vyžadovaly nepřiměřeně velké „prodrátování“ i složitou řídící elektroniku. Na internetových stránkách výrobce jsou uvedeny příklady jako třeba efekty běžícího světla kolem brýlí, osvětlení podrážek bot reagující na došlápnutí, podsvícení skateboardu nebo soupravy bicích reagující na zvuk, lem basketbalového koše reagující na průlet míče, svítící doplňky oblečení nebo velké barevné indikátory vybuzení. Možností je mnoho a jde jen o další krok směrem k „inteligentním“ součástkám, což se už delší dobu projevuje jako obecnější trend. U nás lze jak pásky, tak kruhy i matice LED NeoPixel najít v nabídce internetového obchodu http://www.snailshop.cz .

anim-thumb

Zobrazení hodnoty polohou serva a současně LED (animace z internetových stránek výrobce)

Seznam klíčových slov:

#######################################
# Syntax Coloring Map For Adafruit_NeoPixel
#######################################
# Class
#######################################
Adafruit_NeoPixel KEYWORD1
#######################################
# Methods and Functions
#######################################
setPixelColor KEYWORD2
setPin KEYWORD2
setBrightness KEYWORD2
numPixels KEYWORD2
getPixelColor KEYWORD2
Color KEYWORD2
#######################################
# Constants
#######################################
NEO_GRB LITERAL1
NEO_COLMASK LITERAL1
NEO_KHZ800 LITERAL1
NEO_SPDMASK LITERAL1
NEO_RGB LITERAL1
NEO_KHZ400 LITERAL1