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
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.
1. Umetni NULA MINI pločicu na breadboard
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.

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.

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

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

5. Dodaj otpornik od 10 kΩ
Otpornik nastavlja lanac prema dolje, iz reda 11 u red 9.

6. Spoji otpornik na masu
Jedna jumper žica iz reda 9 do plave − vodilice.

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 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žica | Red |
|---|---|
| Crvena, krajnja, najdalja od duge nožice | 1 |
| Zelena, između crvene i duge nožice | 2 |
| Zajednička katoda, najdulja nožica | 3 |
| Plava, sama s druge strane duge nožice | 4 |

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.

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

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.
| Kanal | Iz | U |
|---|---|---|
| Crvena | slobodan red crvenog otpornika | j25 (IO2) |
| Zelena | slobodan red zelenog otpornika | j26 (IO3) |
| Plava | slobodan red plavog otpornika | j27 (IO4) |

GND, 3V3, IO5, IO4, IO3, IO2), a ne nagađaj iz sredine.12. Spoji pločicu na računalo

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
IO5raste. - 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 radi | Rezultat |
|---|---|---|
| 0 → 1365 | crvena slabi dok zelena jača | crvena → zelena |
| 1366 → 2730 | zelena slabi dok plava jača | zelena → plava |
| 2731 → 4095 | plava ostaje puna dok crvena i zelena rastu | plava → 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.

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

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čitati | RGB | Boja |
|---|---|---|---|
| Ostavi ga u osvijetljenoj prostoriji | ~2900–3300 | 35, 35, 255 | plava |
| Zasjeni ga prstom | ~1270 | 19, 236, 0 | zelena |
| Čvrsto ga prekrij dlanom | ispod ~300 | 199, 56, 0 | narančasto-crvena |
| Osvijetli ga svjetlom mobitela | blizu 4095 | 255, 255, 255 | bijela |
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:
- 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.
- 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.
- Zamijeni jumper žice na strani pločice. Ako su crvena i plava zamijenjene, zamijeni žice u
j25ij27. Serial Monitor ti kaže koju je boju pločica namjeravala: ako ispisuje255, 0, 0a 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.