RGB LED diódy na skúšobnom poli

Zápisník experimentátora

RGB LED diódy vám poskytnú viac možností na experimentovanie s farbou svetla. Je možné ich aj priamo zastrčiť do skúšobného poľa, ale treba sa pripraviť na to, že jedna takáto dióda má štyri vývody a pre každú zložku RGB potrebujete aj predradný rezistor. Ak chcete diód použiť viac, rýchlo narazíte na nedostatok vývodov na Arduine. Tento problém je možné riešiť využitím posuvných registrov. V tomto článku sa zameriame na prípravu takéhoto zapojenia na skúšobnom poli pomocou dvoch navrhnutých dosiek, ktoré celé zapojenie uľahčujú.

Použité dosky

Využijeme dve dosky:

  • 8x RGB LED board - Na tejto doske je pripravených 8 RGB LED diód aj s predradnými rezistormi.
  • 3x 74HC595 board - Na tejto doske sú tri posuvné registre. Obe dosky sa dajú zastrčiť do skúšobného poľa tak, aby tam nebolo nutné používať žiadne ďalšie prepojovacie vodiče.

Celé zapojenie je na nasledovnom obrázku. Vľavo sa nachádza Arduino. Z neho sú vyvedené iba dva piny pre napájanie ostatných súčiastok a tri piny s dátovými signálmi. Kvôli rýchlosti sa používajú piny pre SPI a používame MOSI a CLOCK. Tretí vodič je takzvaný LATCH, ktorý sa používa na presun dát z interných registrov na výstupné piny.

Piny sú prepojené s posuvným registrom 74HC595. Pokiaľ ste ho niekedy zapájali, viete, že je potrebné zapojiť ešte aj ďalšie piny. Tie sa ale obvykle zapájajú stále rovnako a sú pripojené na logickú jednotku alebo nulu. Na tejto doske sú všetky piny interne prepojené s potrebnou úrovňou. Nie je potrebné ich extra pripájať na želanú logickú hodnotu. V prípade potreby sú ale vyvedené a je možné ich použiť aj s inou logickou hodnotou. Na tejto doske sa nachádzajú 3 posuvné registre. To nám dáva 3x8=24 výstupov, čo sa presne hodí na 3x8 RGB LED diód na poslednej doske.

Obe dosky sú navrhnuté tak, aby sa dali zapojiť presne podľa obrázku. Na doske s RGB diódami treba potom pripojiť iba GND.

Programovanie

Poďme sa teraz pozrieť na to, ako je možné RGB LED diódy ovládať. Aby sme mali nejaký vzorový príklad, napísal som kód, ktorý vo funkcii setup zapne pre každú LED inú farbu, počká pár sekund a potom vo funkcii loop animuje pohyb každej farby. Predstavu o funkčnosti môžete získať z nasledovných obrázkov, ale video je hodnotnejšie než množstvo slov a tak si správanie programu pozrite na videu.

Prejdime si jednotlivé časti programu. Najprv sa definujú dátové piny. Z kódu je jasné, že využívame SPI. Potrebujeme aj miesto na 24 bitov a preto mám definované pole buf.

#include <SPI.h>

//Pin connected to ST_CP of 74HC595
// SS
int latchPin = 10;

//Pin connected to SH_CP of 74HC595
// SCK
int clockPin = 13;

// Pin connected to DS of 74HC595
// MOSI
int dataPin = 11;

const uint8_t numreg595=3;
uint8_t buf[numreg595];

Teraz nasleduje niekoľko funkcií na nastavovanie konkrétnych bitov. Aby bol kód flexibilnejší, je možné nastaviť pre každú farbu, v akom poradí sa nachádza na doske. V tomto prípade je to v poradí BGR, ale nič vám v prípade zapojenia na skúšobnom poli nebráni v tom, aby ste si to zapojili podľa potreby. Potom treba len prepnúť v kóde poradie jednotlivých bitov.

Kód funkcie bufSet sa môže javiť zložito, ale je to len hranie sa s bitmi. Prvé tri riadky vypočítajú absolútnu pozíciu konkrétneho bitu pre danú farbu. A následné tri riadky iba určia, či sa bude bit mazať alebo nastavovať a potom sa pomocou celočíselného delenia určí konkrétny bajt a pomocou modula konkrétny bit v bajte, ktorý sa nastaví.

#define RED_BIT 2
#define GREEN_BIT 1
#define BLUE_BIT 0

void bufClear() {
  for(uint8_t i=0;i<3;i++)
    buf[i]=0;
}

void bufSet(uint8_t pos, uint8_t r, uint8_t g, uint8_t b) {
  uint8_t posbitr=pos*3+RED_BIT;
  uint8_t posbitg=pos*3+GREEN_BIT;
  uint8_t posbitb=pos*3+BLUE_BIT;
  r ? bitSet(buf[posbitr/8],posbitr%8) : bitClear(buf[posbitr/8],posbitr%8);
  g ? bitSet(buf[posbitg/8],posbitg%8) : bitClear(buf[posbitg/8],posbitg%8);
  b ? bitSet(buf[posbitb/8],posbitb%8) : bitClear(buf[posbitb/8],posbitb%8);
}

Nasleduje odoslanie trojice bajtov cez SPI. Na začiatku sa LATCH nastaví na logickú nulu, prenesú sa bajty a LATCH sa zase nastaví na logickú jednotku. V tej chvíli sa informácia z interného registra presunie na výstupné piny a príslušné LED diódy sa rozsvietia.

void bufSend() {
  SPI.begin();
  digitalWrite(latchPin, LOW);
  for(uint8_t i=0;i<3;i++)
    SPI.transfer(buf[2-i]);
  digitalWrite(latchPin, HIGH);
}

Konkrétne farby definujeme pomocou štruktúry rgb. V tomto príklade vieme nastavovať iba to, či dióda svieti alebo nesvieti a preto je množstvo farieb limitované.

struct rgb {
  int r;
  int g;
  int b;
};

rgb rgb[7]={
  {1,0,0},
  {0,1,0},
  {0,0,1},
  {1,1,0},
  {0,1,1},
  {1,0,1},
  {1,1,1},
};

Vo funkcii setup iba nastavíme pre každú LED diódu jednu farbu a počkáme niekoľko sekund.

void setup() {
  bufClear();
  for(uint8_t i=0;i<7;i++)
    bufSet(i,rgb[i].r,rgb[i].g,rgb[i].b);  
  bufSend();
  delay(5000);
}

Vo funkcii loop animujeme jednotlivé farby. Prestávka 50 ms nám dáva 20 animácií za sekundu, čiže celý efekt beží dosť rýchlo.

void loop() {
  for(uint8_t i=0;i<7;i++)
    for(uint8_t j=0;j<8;j++) {
      bufClear();
      bufSet(j,rgb[i].r,rgb[i].g,rgb[i].b);  
      bufSend();
      delay(50);
    }  
}

Zdrojový kód

Zdrojový kód sa nachádza na GitHub.

Video

Doplňujúce video sa nachádza na YouTube.


03.11.2016


Menu