Skip to main content

7.4 RGB LED kontroler

Ovaj projekt tjera RGB LED-icu da mijenja boju sa svjetlom u prostoriji. U tami svijetli crveno; kako svjetlo raste, boja klizi kroz zelenu i plavu, a pod jakim svjetlom postaje bijela.

Spaja dvije stvari koje si već sagradio. Krug s fotootpornikom točno je onaj iz 2.3 Analogno čitanje fotootpornika, a ideja postavljanja svjetline umjesto samo uključivanja i isključivanja pina dolazi iz 3.2 Udaljenost i zatamnjivanje LED-ice. Novo je to što jedna vrijednost senzora sada pobuđuje tri izlaza u isto vrijeme.

U ovoj dokumentaciji naučit ćeš:

  • Kako naći četiri nožice RGB LED-ice i koja je dijeljena.
  • Kako se jedna analogna vrijednost može pomoću map() pretvoriti u tri odvojene svjetline.
  • Kako PWM miješa crvenu, zelenu i plavu u bilo koju boju između.
  • Zašto boja glatko prelazi umjesto da skače.

Potreban hardver:

  • 1x Soldered NULA MINI pločica
  • 1x Breadboard
  • 1x Fotootpornik (LDR)
  • 1x RGB LED-ica
  • 1x otpornik od 10 kΩ
  • 3x otpornika od 330 Ω
  • 8x Jumper žice
  • 1x USB-C kabel
ℹ️
Ovaj primjer koristi dvije različite vrste otpornika, koje rade dva potpuno različita posla. Onaj od 10 kΩ ne štiti ništa. On je polovica mjernog kruga, točno kao u 2.3. Tri od 330 Ω su ograničivači struje, po jedan za svaki kanal boje. RGB LED-ica je tri LED-ice u jednom pakiranju, pa joj trebaju tri.
⚠️
Provjeri prstenove prije nego bilo što utisneš. 10 kΩ se čita smeđi-crni-narančasti, a 330 Ω narančasti-narančasti-smeđi. Lako ih je pomiješati, a njihova zamjena neće ništa oštetiti ali će zaustaviti rad kruga.

Spajanje komponenti

Prati dvanaest koraka ispod. Svaka fotografija snimljena je s istog položaja, pa je možeš usporediti s prethodnom i vidjeti točno što se promijenilo.

ℹ️
Sve u ovom primjeru živi na f–j strani breadboarda, jer je svaki pin koji mu treba na tom rubu pločice: IO2 u redu 25, IO3 u redu 26, IO4 u redu 27, IO5 u redu 28, 3V3 u redu 29 i GND u redu 30. Pločica prekriva većinu tih redova, pa su krajnje rupice (j25 do j30) one do kojih možeš doći.

1. Umetni NULA MINI pločicu na breadboard

ℹ️
Ovaj korak pretpostavlja da znaš kako je breadboard spojen iznutra i što su njegove naponske vodilice (power rails). Za uvod pogledaj stranicu dokumentacije Osnove breadboarda.

Utisni pločicu u jedan kraj breadboarda tako da njezina dva reda pinova sjednu s obje strane središnjeg kanala, s čipom okrenutim prema dolje. Trebala bi zauzeti redove 25 do 30.

NULA MINI pločica postavljena na breadboard
Korak 1: pločica postavljena na breadboard

2. Izvedi masu na vodilicu

Jedna jumper žica iz j30 (GND) do plave vodilice. Ta vodilica postaje dijeljena masa cijelog kruga, i obje se polovice vraćaju na nju.

Jumper žica iz j30 na plavu negativnu vodilicu
Korak 2: GND izveden na plavu − vodilicu

3. Izvedi 3.3 V u red 14

Druga jumper žica, iz j29 (3V3) gore u red 14. To je vrh mjernog kruga.

Jumper žica iz j29 u red 14
Korak 3: 3V3 izveden u red 14

4. Dodaj fotootpornik

Fotootpornik premošćuje red 14, u koji sada dolazi 3.3 V, i red 11.

Fotootpornik premošćuje redove 14 i 11
Korak 4: fotootpornik premošćuje redove 14 i 11
ℹ️
Fotootpornik nema polaritet: bilo koja nožica može ići na bilo koju stranu. To je samo otpornik čija se vrijednost mijenja sa svjetlom.

5. Dodaj otpornik od 10 kΩ

Otpornik nastavlja lanac prema dolje, iz reda 11 u red 9.

Otpornik od 10k premošćuje redove 11 i 9
Korak 5: otpornik od 10 kΩ premošćuje redove 11 i 9

6. Spoji otpornik na masu

Jedna jumper žica iz reda 9 do plave vodilice.

Jumper žica spaja red 9 na negativnu vodilicu
Korak 6: donji kraj otpornika od 10 kΩ spojen na − vodilicu

Lanac je sada potpun: 3.3 V → fotootpornik → 10 kΩ → GND. Struja teče kroz oba dijela serijski.

7. Zahvati sredinu pomoću IO5

Sada samo mjerenje. Povuci jumper žicu iz j28 (IO5) u red 11, red koji dijele donja nožica fotootpornika i gornji izvod otpornika.

IO5 spojen na spoj između fotootpornika i otpornika
Korak 7: IO5 zahvaća spoj u redu 11
ℹ️
Red 11 je cijela svrha ove polovice kruga. On je središnja točka između dva otpora, i njegov se napon mijenja kako se mijenja svjetlo. To je ono što IO5 mjeri. Ako žica sleti u red 14 ili red 9, i dalje ćeš dobivati vrijednost. Samo se neće mijenjati kada se svjetlo mijenja.

8. Dodaj RGB LED-icu

RGB LED-ica je tri LED-ice u jednom pakiranju koje dijele jednu nožicu. Drži je s nožicama okrenutima prema dolje i nađi najdulju. To je dijeljena nožica, zajednička katoda. Na ovoj LED-ici ona je treća po redu, s jednom nožicom s jedne strane i dvjema s druge.

Postavi LED-icu tako da njezine četiri nožice slete u redove 1, 2, 3 i 4, s dugom nožicom u redu 3:

NožicaRed
Crvena, krajnja, najdalja od duge nožice1
Zelena, između crvene i duge nožice2
Zajednička katoda, najdulja nožica3
Plava, sama s druge strane duge nožice4
RGB LED-ica postavljena s četiri nožice u redovima 1 do 4
Korak 8: RGB LED-ica s četiri nožice u redovima 1, 2, 3 i 4
⚠️
To nije redoslijed nožica koji koristi većina RGB LED-ica, i nije redoslijed koji ćeš naći u većini vodiča, koji obično pretpostavljaju crvena–zajednička–zelena–plava s dijeljenom nožicom na drugom mjestu. LED-ica u ovom kitu stvarno ide crvena, zelena, zajednička, plava. Vodi se dužinom nožica, a ne dijagramom, a ako boje na kraju izađu pogrešno, ovo je prva stvar koju treba provjeriti.

9. Spoji zajedničku katodu na masu

Jedna jumper žica iz reda 3 do plave vodilice. Sva tri kanala boje vraćaju se na masu preko te jedne žice.

Jumper žica spaja red zajedničke katode na negativnu vodilicu
Korak 9: zajednička katoda spojena na plavu − vodilicu

10. Dodaj tri otpornika od 330 Ω

Svakom kanalu boje treba vlastiti ograničivač struje. Premosti svaku od tri nožice boje do slobodnog reda dalje duž pločice:

  • iz reda 1 (crvena) u slobodan red
  • iz reda 2 (zelena) u drugi slobodan red
  • iz reda 4 (plava) u treći slobodan red
Tri otpornika od 330 ohma dodana, po jedan za svaki kanal boje
Korak 10: po jedan otpornik od 330 Ω za svaki kanal boje
ℹ️
Nije važno u koje redove sletiš, dokle god je svaki prazan i nijedan otpornik ne dijeli red s drugim. Raširi ih po različitim stupcima da im tijela ne sjede jedno na drugom. Drži red 3 slobodnim, jer je to zajednička katoda, a i red 9, jer on već pripada spoju mase fotootpornika.
⚠️
Otpornik s obje nožice u istom redu ne radi ništa. Svaka rupica u redu je jedan spoj, pa je otpornik koji premošćuje dvije rupice u istom redu jednostavno kratko spojen. Kanal se i dalje pali, često svjetlije od druga dva, ali radi bez ikakvog ograničenja struje. Svaki otpornik mora obuhvatiti dva različita reda.

11. Spoji tri kanala boje na pločicu

Još tri jumper žice, s dalekog kraja svakog otpornika natrag na odgovarajući pin. Koristi tri različite boje žica, jer idu jedna uz drugu i kasnije ćeš ih htjeti razlikovati.

KanalIzU
Crvenaslobodan red crvenog otpornikaj25 (IO2)
Zelenaslobodan red zelenog otpornikaj26 (IO3)
Plavaslobodan red plavog otpornikaj27 (IO4)
Tri obojene jumper žice spajaju otpornike na IO2, IO3 i IO4
Korak 11: tri kanala boje spojena na IO2, IO3 i IO4
⚠️
Redovi 25, 26 i 27 razmaknuti su jednu rupicu i skriveni pod rubom pločice, zbog čega ih je lako pogrešno prebrojiti. Broji unutra od j30 na samom kraju (GND, 3V3, IO5, IO4, IO3, IO2), a ne nagađaj iz sredine.

12. Spoji pločicu na računalo

Gotov krug napajan preko USB-C
Korak 12: gotov krug, napajan preko USB-C

Kako jedan senzor postaje tri boje

Čitanje svjetla

Pločica ne može mjeriti otpor, samo napon. Fotootpornik mijenja svoj otpor sa svjetlom, pa sam za sebe pločici ne daje ništa za čitanje. Spajanje s fiksnim otpornikom od 10 kΩ pravi djelitelj napona, a napon u točki između njih ovisi o odnosu njihovih otpora:

  • Na jakom svjetlu otpor fotootpornika pada, zadržava manje od 3.3 V za sebe, i vrijednost na IO5 raste.
  • U tami njegov otpor raste, zadržava veći dio napona, i vrijednost pada.

analogRead() taj napon pretvara u broj od 0 do 4095, jer NULA MINI ima 12-bitni ADC.

Postavljanje boje

analogWrite() radi obrnuto. Umjesto da pin samo uključi potpuno ili isključi potpuno, uključuje ga i isključuje vrlo brzo, koristeći PWM, ili Pulse Width Modulation, i što pin dulje ostaje uključen unutar svakog ciklusa, to taj kanal izgleda svjetlije. Pisanje svih triju odjednom je ono što miješa boju.

Svaki kanal ovdje prima vrijednost od 0 do 255, a to je zadani izlazni raspon pločice. Sva tri zajedno su samo obična RGB boja: 255, 0, 0 je crvena, 0, 255, 0 je zelena, a 255, 255, 255 je bijela.

Spajanje svega

Raspon svjetla razdijeljen je na tri jednaka dijela. FIRST_THIRD je 1365 a SECOND_THIRD je 2730, jednostavno 4095 podijeljen na trećine, a svaki dio dobiva svoj prijelaz:

LDR vrijednostŠto kod radiRezultat
0 → 1365crvena slabi dok zelena jačacrvena → zelena
1366 → 2730zelena slabi dok plava jačazelena → plava
2731 → 4095plava ostaje puna dok crvena i zelena rastuplava → bijela

U svakom dijelu jedan kanal preslikava se prema gore dok se drugi preslikava prema dolje. To je ono što jednu boju tjera da klizne u sljedeću umjesto da skoči. A budući da svaki dio počinje točno tamo gdje je prethodni završio, granice su nevidljive: na 1365 boja je čista zelena s koje god strane joj pristupiš.


Kod

/**
**************************************************
*
* @file 7.4_RGB_LED_Controller.ino
* @brief Projekt koji pomoću fotootpornika postavlja boju RGB LED-ice. Kako se svjetlo u prostoriji mijenja,
* boja klizi od crvene u tami, kroz zelenu i plavu, sve do bijele na jakom svjetlu.
* Gradi se na fotootporniku iz sekcije 2.3 i upravljanju svjetlinom LED-ice iz sekcije 3.2, i
* pokazuje kako jedna vrijednost senzora može pobuđivati tri izlaza u isto vrijeme.
* Za detalje, shemu spajanja i više, pogledaj dokumentaciju primjera na: <link placeholder>
* @author Soldered
***************************************************
*/

/*
Ovo je varijabla kojoj predajemo broj pina na koji smo spojili izlaz fotootpornika. Budući da ovdje
moramo pročitati cijeli raspon vrijednosti a ne samo HIGH ili LOW, to mora biti pin koji podržava analogni ulaz.
NULA pločica ima logiku imenovanja pinova ovako: IO5, gdje je 5 broj koji dajemo varijabli.

Ovom primjeru također treba otpornik od 10k. Fotootpornik mijenja svoj otpor sa svjetlom, ali pločica može
mjeriti samo napon, pa ta dva spajamo u ono što se naziva djelitelj napona: fiksni otpornik promjenjivi
otpor pretvara u promjenjivi napon koji pločica može pročitati.
*/
const int LDR_PIN = 5;

/*
Ovo su varijable kojima predajemo brojeve pinova na koje smo spojili tri kanala boje
RGB LED-ice. RGB LED-ica je u stvari tri LED-ice u jednom pakiranju, jedna crvena, jedna zelena i jedna plava, a paljenjem
na različitim jačinama možemo pomiješati bilo koju boju koju želimo. Sva tri pina moraju podržavati PWM, a to je ono što nam dopušta da
postavimo svjetlinu umjesto samo uključeno ili isključeno.

Zapamti da svakom od tri kanala boje treba vlastiti otpornik od 330 ohma u seriji s njim. RGB LED-ica se računa kao
tri LED-ice, pa traži tri otpornika, a bez njih kanali vuku više struje nego što su oni ili pinovi
građeni izdržati.
*/
const int RED_PIN = 2;
const int GREEN_PIN = 3;
const int BLUE_PIN = 4;

/*
Ova varijabla čuvat će sirovu analognu vrijednost pročitanu s fotootpornika. Budući da NULA pločica koristi 12-bitni ADC,
vrijednost će ići od 0 u potpunoj tami do 4095 na jakom svjetlu.
*/
int ldrValue = 0;

/*
Ove tri varijable drže svjetlinu svakog kanala boje, od 0 za ugašeno do 255 za potpuno upaljeno.
*/
int r = 0, g = 0, b = 0;

/*
Ove dvije varijable razdjeljuju raspon svjetla na tri jednaka dijela, a to je ono što nam daje naša tri prijelaza boje.
4095 podijeljeno s tri je 1365, pa prvi dio tamo završava a drugi završava na dvostrukom toga. Slobodno
eksperimentiraj s ovim vrijednostima da promjene boje premjestiš na druge razine svjetla.
*/
const int FIRST_THIRD = 1365;
const int SECOND_THIRD = 2730;

void setup() {

/*
Serial.begin() uspostavlja serijsku komunikaciju između tvoje pločice i tvog računala preko USB kabela. Ovdje ga koristimo
da gledamo i razinu svjetla i pomiješanu boju, što čini mnogo lakšim razumjeti što kod radi.
*/
Serial.begin(115200);

/*
pinMode() je funkcija koja konfigurira zadani pin da se ponaša ili kao ulaz ili kao izlaz.
Fotootpornik je nešto što čitamo, pa ide u INPUT mod, dok su tri kanala boje stvari u koje
pišemo, pa idu u OUTPUT mod.
*/
pinMode(LDR_PIN, INPUT);

/*
analogReadResolution() definira koliko se bitova koristi za ADC vrijednosti. NULA MINI podržava 12-bitnu rezoluciju,
što znači da analogRead() vraća vrijednosti od 0 do 4095. To je raspon oko kojeg su rasponi boja ispod izgrađeni,
pa ga navodimo ovdje umjesto da se oslanjamo na zadanu vrijednost.
*/
analogReadResolution(12);

pinMode(RED_PIN, OUTPUT);
pinMode(GREEN_PIN, OUTPUT);
pinMode(BLUE_PIN, OUTPUT);

//Ispiši početnu poruku da znamo da se program uspješno pokrenuo.
Serial.println("RGB LED Controller with full-spectrum color mapping started");
}

void loop() {

/*
analogRead() čita napon na zadanom analognom pinu i pretvara ga u broj. Što više svjetla pada na
fotootpornik, to je njegov otpor manji a ovaj broj veći.
*/
ldrValue = analogRead(LDR_PIN);
Serial.print("LDR value: ");
Serial.println(ldrValue);

/*
Ovdje se boja odlučuje. Raspon svjetla razdjeljujemo na tri dijela i svakom dajemo vlastiti prijelaz,
tako da boja nikada ne skoči: uvijek klizne odakle je bila u sljedeću boju.
map() je funkcija koja uzima broj iz jednog raspona i preskalira ga u drugi raspon, a ovdje je koristimo da razinu
svjetla pretvorimo u svjetlinu. Primijeti kako se u svakom dijelu jedan kanal preslikava prema gore dok se drugi preslikava
prema dolje, a to je točno ono što jednu boju tjera da prelije u sljedeću.
*/
if (ldrValue <= FIRST_THIRD) {

//Najtamnija trećina: prijelaz od crvene (255, 0, 0) do zelene (0, 255, 0).
r = map(ldrValue, 0, FIRST_THIRD, 255, 0);
g = map(ldrValue, 0, FIRST_THIRD, 0, 255);
b = 0;
}
else if (ldrValue <= SECOND_THIRD) {

//Srednja trećina: prijelaz od zelene (0, 255, 0) do plave (0, 0, 255).
r = 0;
g = map(ldrValue, FIRST_THIRD + 1, SECOND_THIRD, 255, 0);
b = map(ldrValue, FIRST_THIRD + 1, SECOND_THIRD, 0, 255);
}
else {

/*
Najsvjetlija trećina: prijelaz od plave (0, 0, 255) do bijele (255, 255, 255). Bijela je jednostavno sva tri kanala uključena
odjednom, i zato crvena i zelena ovdje rastu dok plava ostaje na punoj svjetlini.
*/
r = map(ldrValue, SECOND_THIRD + 1, 4095, 0, 255);
g = map(ldrValue, SECOND_THIRD + 1, 4095, 0, 255);
b = 255;
}

/*
analogWrite() je funkcija koja na pin piše vrijednost "između" umjesto samo HIGH ili LOW. To radi
pomoću PWM-a, što je skraćeno od Pulse Width Modulation: pin se uključuje i isključuje vrlo brzo, i što dulje
ostaje uključen unutar svakog ciklusa, to ta boja izgleda svjetlije. Pisanje svih triju odjednom je ono što miješa boju.
*/
analogWrite(RED_PIN, r);
analogWrite(GREEN_PIN, g);
analogWrite(BLUE_PIN, b);

//Ispiši i pomiješanu boju, da je možemo usporediti s razinom svjetla iznad.
Serial.print("RGB: ");
Serial.print(r); Serial.print(", ");
Serial.print(g); Serial.print(", ");
Serial.println(b);

/*
Kratka pauza između vrijednosti. Držanje male čini promjene boje glatkima.
*/
delay(100);
}

Što bi trebao vidjeti

Prenesi skicu, pa otvori Tools → Serial Monitor i postavi baud rate na 115200. Dvije linije pojavljuju se deset puta u sekundi: sirova vrijednost svjetla i tri svjetline koje je kod iz nje izračunao.

U običnoj osvijetljenoj prostoriji vrijednost sjedi visoko, u gornjoj trećini raspona, pa se LED-ica smjesti na jaku plavu.

RGB LED-ica svijetli plavo na gotovom krugu
Obično svjetlo u prostoriji: LED-ica svijetli plavo
Serial Monitor prikazuje LDR vrijednost oko 2923 i RGB vrijednosti 35, 35, 255
Odgovarajući serijski ispis: 2923 postaje 35, 35, 255

Sada stavi prst preko fotootpornika. Vrijednost pada u srednji pojas i boja prelazi sve do zelene.

Prst zasjenjuje fotootpornik dok RGB LED-ica svijetli zeleno
Zasjenjivanje senzora prstom: LED-ica postaje zelena
Serial Monitor prikazuje LDR vrijednost oko 1266 i RGB vrijednosti 19, 236, 0
Odgovarajući serijski ispis: 1266 postaje 19, 236, 0

Te dvije snimke vrijedi čitati jednu uz drugu, jer računanje koda možeš provjeriti napamet. Na 1266 vrijednost je u prvom pojasu, pa se crvena preslikava dolje od 255 a zelena gore od 0: 255 − 1266 × 255 ÷ 1365 je 18.5, što pločica zaokruži na 19 koji je ispisala. Broj na ekranu i boja pred tobom su ista činjenica, dvaput.

Cijeli raspon

Što radišPribližno što ćeš pročitatiRGBBoja
Ostavi ga u osvijetljenoj prostoriji~2900–330035, 35, 255plava
Zasjeni ga prstom~127019, 236, 0zelena
Čvrsto ga prekrij dlanomispod ~300199, 56, 0narančasto-crvena
Osvijetli ga svjetlom mobitelablizu 4095255, 255, 255bijela
ℹ️
Crvenu je teže dosegnuti nego što bi očekivao. Skupljena ruka vrijednost spusti samo na oko 1300, a to je još zeleno. Svjetlo se probija oko tvog zapešća i između prstiju. Da vidiš crvenu treba ti stvarna tama: ugasi svjetla u prostoriji, ili spusti neprozirnu šalicu ili kutiju preko senzora. Gledaj broj a ne nagađaj, jer je sve ispod oko 300 nedvojbeno crveno.
ℹ️
Tvoji brojevi neće se točno poklapati s ovima. Ovise o svjetlu u tvojoj prostoriji i o samom fotootporniku. Važno je da se vrijednost miče kada se svjetlo mijenja. Ako stoji na fiksnom broju bez obzira što radiš, vrati se na korak 7 i provjeri da IO5 stvarno zahvaća red 11.

Ako boje izađu pogrešno

Ako se LED-ica pali ali prikazuje pogrešnu boju (zelenu gdje očekuješ crvenu, ili jedan kanal koji se nikada ne upali), krug je u redu a preslikavanje nije. Prođi kroz to u ovom redoslijedu:

  1. Provjeri je li duga nožica u redu 3 i spojena na vodilicu. Ako je dijeljena nožica negdje drugdje, kanali se međusobno bore i većinom ostaju tamni.
  2. Provjeri obuhvaća li svaki otpornik dva reda. Kratko spojen otpornik čini svoj kanal daleko svjetlijim od druga dva, što se čita kao da ta boja preuzima.
  3. Zamijeni jumper žice na strani pločice. Ako su crvena i plava zamijenjene, zamijeni žice u j25 i j27. Serial Monitor ti kaže koju je boju pločica namjeravala: ako ispisuje 255, 0, 0 a ti vidiš plavu, dva kanala su prekrižena.

Ta posljednja je korisna navika: linija RGB je vlastita izjava pločice o tome što pokušava prikazati, pa je svako neslaganje između nje i LED-ice pred tobom greška u spajanju, a ne greška u kodu.


Cijeli primjer

Pogledaj cijeli kod primjera na linku ispod:

7.4_RGB_LED_Controller.ino

Projekt koji pomoću fotootpornika upravlja RGB LED-icom, glatko mijenjajući boju od crvene do bijele na temelju jačine okolnog svjetla.