ESP32: senzor svetlosti i svetleći prsten (WS2812)
U lekciji o merenju osvetljenja ESP32 je palio jednu LED diodu kada padne mrak. Sada umesto nje koristimo svetleći prsten sa 12 RGB dioda (WS2812, poznat i kao NeoPixel). Svaka dioda na prstenu može da dobije svoju boju, a sve se upravljaju preko samo jednog pina. Pravimo noćno svetlo koje pali više dioda što je mračnije.

Kako radi svetleći prsten
- Svaka dioda u sebi ima tri male LED diode (crvenu, zelenu i plavu) i mali čip koji pamti boju.
- ESP32 šalje niz podataka na ulaz DIN (IN). Prva dioda uzme svoju boju, a ostatak prosledi sledećoj – kao kad se poruka prenosi niz red.
- Boja se zadaje sa tri broja od 0 do 255:
Color(crvena, zelena, plava). Na primerColor(255, 0, 0)je crvena, aColor(255, 255, 255)bela. - Pri punoj jačini jedna dioda troši do 60 mA – 12 dioda skoro 0,75 A. Zato jačinu smanjujemo naredbom
setBrightness().
Povezivanje

| Deo | Priključak | ESP32 |
|---|---|---|
| svetleći prsten | PWR (5V/VCC) | 3V3 (za 12 dioda pri maloj jačini) ili 5V (VIN) |
| svetleći prsten | GND | GND |
| svetleći prsten | IN (DIN) | GPIO4 |
| LDR modul | VCC | 3V3 |
| LDR modul | GND | GND |
| LDR modul | AO (analogni izlaz) | GPIO34 |

Korak 1: test prstena
U Arduino IDE-u instaliraj biblioteku Adafruit NeoPixel (Sketch → Include Library → Manage Libraries). Prvi program samo proverava da li prsten radi – diode se pale redom u tri boje:
// ESP32 – test svetlećeg prstena (WS2812 / NeoPixel)
// Biblioteka: Adafruit NeoPixel (Library Manager)
#include <Adafruit_NeoPixel.h>
const int PRSTEN_PIN = 4; // DIN (IN) prstena na GPIO4
const int BROJ_LED = 12; // broj dioda na prstenu (12, 16 ili 24)
Adafruit_NeoPixel prsten(BROJ_LED, PRSTEN_PIN, NEO_GRB + NEO_KHZ800);
void setup() {
prsten.begin();
prsten.setBrightness(40); // 0–255; mala jačina štedi struju (i oči)
}
void loop() {
// diode se pale jedna po jedna – crveno, zeleno, plavo
uint32_t boje[3] = { prsten.Color(255, 0, 0), prsten.Color(0, 255, 0), prsten.Color(0, 0, 255) };
for (int b = 0; b < 3; b++) {
for (int i = 0; i < BROJ_LED; i++) {
prsten.setPixelColor(i, boje[b]);
prsten.show(); // tek show() šalje boje prstenu
delay(60);
}
}
prsten.clear();
prsten.show();
delay(300);
}
Važno: setPixelColor() samo pamti boju u memoriji ESP32. Prsten se promeni tek kada pozovemo show().
Korak 2: noćno svetlo
Sada čitamo LDR senzor i od broja koji vrati analogRead() računamo koliko dioda treba da svetli. Kod većine LDR modula vrednost raste kada je mračnije; ako je kod tebe obrnuto, zameni vrednosti SVETLO i MRAK.
// ESP32 – noćno svetlo: što je mračnije, to više dioda svetli
#include <Adafruit_NeoPixel.h>
const int LDR_PIN = 34; // AO izlaz LDR modula (ADC1)
const int PRSTEN_PIN = 4;
const int BROJ_LED = 12;
// kalibracija: pročitaj vrednosti u Serial Monitoru i upiši svoje
const int SVETLO = 800; // vrednost kada je svetlo u sobi
const int MRAK = 3500; // vrednost kada je senzor pokriven rukom
Adafruit_NeoPixel prsten(BROJ_LED, PRSTEN_PIN, NEO_GRB + NEO_KHZ800);
void setup() {
Serial.begin(115200);
prsten.begin();
prsten.setBrightness(60);
}
void loop() {
int ldr = analogRead(LDR_PIN); // kod većine modula: veći broj = manje svetla
int upaljeno = map(ldr, SVETLO, MRAK, 0, BROJ_LED);
upaljeno = constrain(upaljeno, 0, BROJ_LED);
for (int i = 0; i < BROJ_LED; i++) {
if (i < upaljeno) {
prsten.setPixelColor(i, prsten.Color(255, 160, 40)); // toplo belo
} else {
prsten.setPixelColor(i, 0); // ugašeno
}
}
prsten.show();
Serial.print("LDR: ");
Serial.print(ldr);
Serial.print(" upaljeno dioda: ");
Serial.println(upaljeno);
delay(100);
}
Kalibracija
- Pokreni program i otvori Serial Monitor (115200).
- Zapiši vrednost LDR pri svetlu u sobi – to je
SVETLO. - Pokrij senzor rukom i zapiši vrednost – to je
MRAK. - Upiši te brojeve u program i pošalji ga ponovo.
map() može da da broj manji od 0 ili veći od 12 (ako je svetlije nego pri kalibraciji), zato posle njega stoji constrain().
Zadaci za vežbu
- Promeni boju noćnog svetla u plavu ili zelenu.
- Neka prsten trepće crveno kada je potpuno mračno (sve diode bi trebalo da svetle).
- Napravi „disanje“ prstena: jačina se polako menja od 10 do 150 i nazad.
- Boja neka zavisi od osvetljenja: žuta na svetlu, plava u mraku, a između – prelaz.
Rešenje: boja zavisi od osvetljenja
// Zadatak – boja zavisi od osvetljenja: plavo u mraku, žuto na svetlu
#include <Adafruit_NeoPixel.h>
const int LDR_PIN = 34;
const int PRSTEN_PIN = 4;
const int BROJ_LED = 12;
Adafruit_NeoPixel prsten(BROJ_LED, PRSTEN_PIN, NEO_GRB + NEO_KHZ800);
void setup() {
prsten.begin();
prsten.setBrightness(50);
}
void loop() {
int ldr = constrain(analogRead(LDR_PIN), 0, 4095);
int t = map(ldr, 0, 4095, 0, 255); // 0 = svetlo, 255 = mrak
// mešamo žutu (255, 200, 0) i plavu (0, 0, 255) srazmerno vrednosti t
int r = map(t, 0, 255, 255, 0);
int g = map(t, 0, 255, 200, 0);
int b = map(t, 0, 255, 0, 255);
prsten.fill(prsten.Color(r, g, b));
prsten.show();
delay(50);
}
Proveri znanje
Otvori kviz
Kviz: senzor svetlosti i svetleći prsten
1. Preko koliko signalnih pinova ESP32 upravlja svim diodama prstena?
2. Šta mora da se pozove da bi prsten prikazao nove boje posle setPixelColor()?
3. Koju boju daje Color(0, 0, 255)?
4. Zašto posle map() stoji constrain()?
