RGB LED je hezká součástka. Kombinuje v sobě vlastně hned tři svítivé diody, červená (Red), zelená (Green) a modrá (Blue), které společně umí vytvořit v podstatě jakoukoliv barvu, takže nám vlastně stačí tři diody v jednom pouzdře a máme o zábavu postaráno. Můžeme si naprogramovat jakou barvu jen chceme.

U jednoduché LED, která svítí jenom jednou barvou, máme dva vývody: katodu, tedy zápornou elektrodu, kterou připojujeme zpravidla na GND, a anodu, tedy kladnou elektrodu, kterou připojujeme na + pól, třeba +3,3 V. U RGB LED je to obdobné, avšak zde máme vývody 4, tedy jeden společný, a zbylé tři pro každou jednu barvu. Podle toho, jaká RGB LED se nám dostane do ruky, můžeme mít buď takovou, která bude mít společnou katodu a 3 anody pro jednotlivé barvy (většinou klasická v 5 mm pouzdře) nebo takovou, která bude mít společnou anodu a 3 katody pro jednotlivé barvy (takto jsou osazeny třeba RGB LED pásky). Na obrázku můžeme vidět obě varianty. 

Obrázek 1: typy diod [1]

Vždy je třeba se podívat na konkrétní kus a zjistit, kterou verzi máme, a podle toho zvolit správný postup zapojení. Rezistory připojujeme vždy 3, pro každou barvu zvlášť, hodnoty rezistorů zvolíme odhadem (pak ale reprezentace barev nebude přesná), lépe však výpočtem pomocí Ohmova zákona (je třeba však zjistit úbytky napětí pro konkrétní diody v pouzdře - mělo by odpovídat jednobarevným výkonovým diodám). Ve verzi se společnou katodou (-) zapojujeme katodu na GND a 3 anody přes rezistory na + pól, nebo na digitální piny MCU. Ve verzi se společnou anodou (+) zapojujeme anodu na + pól, v našem případě 3,3V a 3 katody přes rezistory na GND, nebo na digitální piny MCU.

Zkusíme si teda LEDku rozsvítit, nejprve jenom se zdrojem napětí, pak ji připojíme k MCU. S největší pravděpodobností budeme mít koupenou LEDku v 5 mm pouzdře se společnou katodou (-) (dále tedy budeme pracovat pouze s touto verzí, dokud neuvedu jinak).  Jednotlivé elektrody poznáme podle obrázku, nebo jednoduše metodou pokusu. Společná elektroda bude mít zpravidla nejdelší vývod. Tu připojíme na GND. Na ostatní elektrody připojíme rezistory, laboratorně nám stačí pro všechny stejná hodnota, třeba kolem 330 Ω. Pak je připojíme ke kladnému pólu zdroje. Po zapnutí zdroje by LEDka ze vzdálenějšího pohledu měla svítit bílou barvou. Při detailnějším pohledu uvidíme svítit jednotlivé barvy.

Proč svítí zrovna bíle?

Jak jsem již zmínil na začáku, pomocí tří barev jsme schopni reprodukovat takřka všechny možné barvy, které si jen dokážeme představit. A jak to teda funguje? No stejně jako u slunce nebo třeba žárovky. Možná jste se s tím setkali ve fyzice, kdy Vám vyučující ukázal jakýsi zázračný trojhran, na který když posvítil bílým světlem (klidně i žárovkou, ta ve skutečnosti nesvítí žlutě nebo oranžově, jak se může zdát, ale má teplou bílou barvu), tak rozložil toto světlo na jednotlivé barevné složky. Stejně tak je to i v přírodě s duhou, tam prochází sluneční paprsky přes kapky vody a rozkládají se na jednotlivé barevné složky.

Obrázek 2: rozklad světla [2]

RGB LED využívá stejného principu, jenom opačně. Využívá míchání těchto barev, říkáme tomu aditivní míchání barev.

Obrázek 3: aditivní míchání barev [3]

Z obrázku vidíme že smícháním všech tří složek RGB získáme bílou barvu. Vzniká nám jakýsi barevný RGB model, na základě kterého můžeme míchat barvy. Míchání barev je realizování jasem jednotlivých barevných složek. Z obrázku je patrné, že pokud smícháme pouze červenou a zelenou, vznikne žlutá. Modrá složka se nijak nezapojuje, zůstává "vypnutá". Budeme-li postupně přidávat modrou složku, bude původně žlutá barva přecházet do bílé. Podle toho, do jaké míry chceme reprezentovat barvy, podle toho musíme zvolit preciznost reprezentace jednotlivé barvy. U RGB ledky reprezentujeme preciznost úrovní jasu, čím více úrovní, tím lépe. V počítačích se obečně používá 24 bitová reprezentace barev, kdy jsme schopni reprezentovat až 16 milionů barev, avšak pro každou jednotlivou složku nám stačí pouze 256 úrovní jasu. Úrovně jasu se pak zapisují od 0 do 255 v pořadí červená, zelená, modrá. Příklad: 255, 255, 255, to dá ve výsledku bílou barvu. Toto můžeme zapsat také kódem dané barvy, ten se uvádí v 16 soustavě. Bílé barvě odpovídá #FFFFFF. Více viz: https://cs.wikipedia.org/wiki/Wikipedie:Tabulka_barev

Pojdmě si tedy ledku připojit k MCU a zkusíme si s barvami trochu pohrát. Připojme tedy ledku k MCU, piny si zvolte jak se Vám to líbí, jenom je třeba je správně zapsat při definici v kódu. Já jsem zvolil pin GPIO 14, tedy D5 pro červenou, GPIO12, tedy D6 pro zelenou a GPIO13, tedy D7 pro zelenou.

 

//definice pinů
const char redD = 14;
const char greenD = 12;
const char blueD = 13;

void setup() {
  //nastavení pinů jako výstupních
  pinMode(redD, OUTPUT);
  pinMode(greenD, OUTPUT);
  pinMode(blueD, OUTPUT);



}
//metoda pro ovládání jednotlivých barevných složek - usnadní nám volání
//v parametru zadáme barevné složky v rozsahu 0 - 255, použijeme 24 bitový model
//uvnitř metody pak předáme hodnotu jasu z parametru na piny jednotlivých barev.
//protože však ESP8266 nabízí až 1024 možných úrovní, je třeba vynásobit každou hodnotu 4, abychom dosáhli plného jasu LED
void RGBLED(int red, int green, int blue){
  analogWrite(redD, red*4);
  analogWrite(greenD, green*4);
  analogWrite(blueD, blue*4);
}
void loop() {
 //ve smyčce teď voláme predchozí metodu, předáváme jí pouze hodnoty barevných složek
  //červená
  RGBLED(255, 0, 0);
  delay(1000);
  //zelená
  RGBLED(0, 255, 0);
  delay(1000);
  //modrá
  RGBLED(0, 0, 255);
  delay(1000);
  //bílá
  RGBLED(255, 255, 255);
  delay(1000);
  //žádná složka nesvítí, je zhasnuto
  RGBLED(0, 0, 0);
  delay(1000);
  
  
  

}

Po nahrání kódu nám bude ledka opakovaně měnit barvy: červená-zelená-modrá-bílá-žádná. Vždy však daná barva bude svítit v plném jasu. Pokud bychom chtěli nastavit bílou barvu v polovičním jasu, zavoláme RGBLED(128, 128, 128), pak bude LEDka svítit bílou barvou při asi polovičním jasu. A jak to vlastně funguje? MCU periodicky přepíná na pinech logickou 1 a 0, třeba 1000x za sekundu. Pokud nastavíme plný jas, pak je po celou dobu periody nastavena 1, tedy přivedeno kladné napětí 3,3V, nic se nemění, LEDka svítí na maximum. Pokud nastavíme poloviční jas, pak polovinu periody je nastavena 1, druhou polovinu 0, ledka tedy polovinu periody svítí a druhou ne. Takto blikne třeba 1000x za sekundu. Lidské oko však není tuto rychlou změnu schopno zaregistrovat a mozek to reprezentuje jako snížení jasu. Pokud bychom tedy nastavili RGBLED (64, 64, 64), pak bude svítit asi čtvrtinovým jasem, čtvrtinu času bude nastavena 1, zbylé tři čtvrtiny 0. Při RGBLED(0, 0, 0) bude po celou dobu logická 0, pak LEDka svítit nebude. No jo, ale co když vezmu druho variantu, tedy tu se společnou katodou(+)? Bude to fungovat stejně, když bude LEDka zapojena opačně? Tak pojdmě postupně, společná katoda (+) bude připojena na kladný (+) pól zdroje, tedy v podstatě na logickou 1. Na druhé straně, na anodách (-) tedy potřebujeme získat logickou 0, tedy GND, aby nám LEDka svítila. Tudíž potřebujeme, aby na pinech MCU nastavit logickou 0. Bude to fungovat tedy přesně opačně. Pokud tedy nastavíme RGBLED(255, 255, 255), pak bude RGB LED se společnou katodou zhaslá, a naopak pokud nastavíme RGBLED(0, 0, 0), pak bude svítit. To je třeba si uvědomit a vhodně upravit čísla udávající hodnotu jasu.

 

A zkusíme si naprogramovat i něco trochu vychytanějšího. Abychom nemuseli nahrávat znova celý kód, když chceme změnit barvu, uděláme si program, kdy přes sériový vstup zadáme hodnoty R, G, B a ty se pak projeví přímo na LEDce.

Obecně potřebujeme zkombinovat předchozí kód a kód pro čtení ze sériového vstupu (viz Sériový IO), k tomu nějaké lehké úpravy a máme hotovo.

//definice pinů
const char redD = 14;
const char greenD = 12;
const char blueD = 13;

//definujeme si proměnné pro jednotlivé barvy
int red = 0;
int green = 0;
int blue = 0;
void setup() {
  //nastavení pinů jako výstupních
  pinMode(redD, OUTPUT);
  pinMode(greenD, OUTPUT);
  pinMode(blueD, OUTPUT);

  // Inicializace sériového rozhraní
  Serial.begin(9600);
  delay(5000);
  //výpis úvodné informace
  Serial.println("Ovládání RGB LED");
  Serial.println("Zadávejte DEC hodnotu barevnych složek R, G, B");
  Serial.println("Pred zadanim hodnoty pockejte na vyzvání");
  Serial.println("Zadavejte pouze hodnoty v rozsahu 0-255!");
  delay(1000);
  
}

void getRGBFromSerial(){
   //ve smyčce bude v podstatě třikrát to samé, pro každou složku zvlášť
   Serial.println("Zadej uroven cervene slozky.");
   // Vytvoření proměnné
   String prectenaHodnota = "";
   // Cyklus běží dokud se nezmění hodnota proměnné
   while(prectenaHodnota == ""){
    //do proměnné ukládám hodnotu prectenou ze seriového vstupu
    prectenaHodnota = Serial.readString();
   }
   // Program vypíše hodnotu 
   Serial.print("hodnota cervene: ");
   // a vypíše obsah proměnné
   Serial.println(prectenaHodnota);
   red = prectenaHodnota.toInt();

    
   Serial.println("Zadej uroven zelene slozky.");
   //vyprázdnění proměnné
   prectenaHodnota = "";
   // Cyklus běží dokud se nezmění hodnota proměnné
   while(prectenaHodnota == ""){
    //do proměnné ukládám hodnotu prectenou ze seriového vstupu
    prectenaHodnota = Serial.readString();
   }
   // Program vypíše hodnotu 
   Serial.print("hodnota zelene: ");
   // a vypíše obsah proměnné
   Serial.println(prectenaHodnota);
   green = prectenaHodnota.toInt();
  
     
   Serial.println("Zadej uroven modre slozky.");
   //vyprázdnění proměnné
   prectenaHodnota = "";
   // Cyklus běží dokud se nezmění hodnota proměnné
   while(prectenaHodnota == ""){
    //do proměnné ukládám hodnotu prectenou ze seriového vstupu
    prectenaHodnota = Serial.readString();
   }
   // Program vypíše hodnotu 
   Serial.print("hodnota modre: ");
   // a vypíše obsah proměnné
   Serial.println(prectenaHodnota);
   blue = prectenaHodnota.toInt();
}


//metoda pro ovládání jednotlivých barevných složek - usnadní nám volání
//v parametru zadáme barevné složky v rozsahu 0 - 255, použijeme 24 bitový model
//uvnitř metody pak předáme hodnotu jasu z parametru na piny jednotlivých barev.
//protože však ESP8266 nabízí až 1024 možných úrovní, je třeba vynásobit každou hodnotu 4, abychom dosáhli plného jasu LED
void RGBLED(int red, int green, int blue){
  analogWrite(redD, red*4);
  analogWrite(greenD, green*4);
  analogWrite(blueD, blue*4);
}

void loop() {
  //čti hodnoty ze sériového vstupu
  getRGBFromSerial();
  //vypiš do konzole RGB hodnoty
  Serial.println("RGB("+String(red)+", "+String(green)+", "+String(blue)+")");
  Serial.println("");
  //predá hodnoty na LEDku
  RGBLED(red, green, blue);
 

 
}

 

[1] https://hackster.imgix.net/uploads/attachments/697494/common_cathode_and_common_anode_rgb_led_6yyt7t5x44.png?auto=compress%2Cformat&w=680&h=510&fit=max
[2] https://cs.wikipedia.org/wiki/Optick%C3%BD_hranol
[3]https://cs.wikipedia.org/wiki/Aditivn%C3%AD_m%C3%ADch%C3%A1n%C3%AD_barev#/media/Soubor:AdditiveColorMixiing.svg