This is an old revision of the document!
Punctul de plecare a fost observatia ca lumina albastra seara afecteaza calitatea somnului. Majoritatea oamenilor stau la birou sau in camera cu aceeasi lumina alba tot timpul, indiferent de ora din zi. O lampa care isi adapteaza singura temperatura de culoare rezolva aceasta problema fara nicio interventie din partea utilizatorului.
Proiectul consta intr-o lampa RGB controlata de un microcontroler ATmega328P-XMINI. Lampa trece automat de la lumina rece (albastru-alb) ziua la lumina calda (galben-portocaliu) seara, in functie de luminozitatea ambientala citita de un fotorezistor si de ora curenta furnizata de un modul RTC. Pe langa modul automat, lampa poate fi controlata manual printr-un buton fizic sau de pe telefon prin Bluetooth. Un display OLED afiseaza in timp real modul activ, culoarea setata si ora curenta.
Proiectul este util pentru confortul vizual zilnic si pentru prevenirea durerilor de ochi cauzate de expunerea prelungita la lumina albastra seara. In acelasi timp, acopera practic toate periferalele studiate in laboratoarele PM: GPIO, UART, intreruperi externe, PWM, ADC, SPI si I2C.
Sistemul are urmatoarele module principale:
| Componenta | Model / Specificatii | Cantitate |
|---|---|---|
| Placa microcontroller | ATmega328P-XMINI | 1 |
| Modul Bluetooth | HC-06 UART | 1 |
| Display OLED | SH1106 1.3” SPI | 1 |
| Modul RTC | DS3231 I2C | 1 |
| MOSFET | IRLZ44N N-Channel Logic Level | 3 |
| LED rosu | LED 5mm rosu | 1 |
| LED verde | LED 5mm verde | 1 |
| LED albastru | LED 5mm albastru | 1 |
| Fotorezistor | GL5528 LDR | 1 |
| Buton | Push tactil | 1 |
| Regulator tensiune | L7805CV | 1 |
| Rezistor | 220Ω | 3 |
| Rezistor | 10kΩ | 2 |
| Rezistor | 1kΩ | 1 |
| Rezistor | 2kΩ | 1 |
| Breadboard | 830 puncte | 1 |
| Fire jumper | Male-to-male | ~30 |
| Cablu USB | Micro-USB | 1 |
| Sursa alimentare | 24V externa | 1 |
| Pin MCU | Conectat la | Functie |
|---|---|---|
| D0 (RX) | HC-06 TX | UART receptie Bluetooth |
| D1 (TX) | HC-06 RX via 1kΩ+2kΩ | UART transmisie (protejat 3.3V) |
| D2 | Buton + pull-up 10kΩ | Intrerupere externa INT0 |
| D3 (PWM) | Gate MOSFET Rosu | PWM canal R |
| D4 | OLED RST | SPI Reset |
| D5 (PWM) | Gate MOSFET Verde | PWM canal G |
| D6 (PWM) | Gate MOSFET Albastru | PWM canal B |
| D7 | OLED DC | SPI Data/Command |
| D10 | OLED CS | SPI Chip Select |
| D11 (MOSI) | OLED SDA | SPI Date |
| D13 (SCK) | OLED SCK | SPI Clock |
| A0 | Nod LDR + 10kΩ | ADC citire luminozitate |
| A4 (SDA) | DS3231 SDA | I2C date RTC |
| A5 (SCL) | DS3231 SCL | I2C clock RTC |
Github: https://github.com/CovaliuStefan/LampaRGB
Video Demo: https://drive.google.com/file/d/1rH4AE9yBBfuPUU4mn2AI_eMcyocapCyA/view?usp=sharing
-P usb -c xplainedmini (protocolul standard xplainedmini din PlatformIO nu functioneaza cu ATmega328P-XMINI si returneaza eroare de port)| Biblioteca | Versiune | Scop |
|---|---|---|
Wire.h | built-in Arduino | Comunicatie I2C (TWI) cu DS3231 |
RTClib | Adafruit | Citire ora/data de la DS3231 in format lizibil |
SPI.h | built-in Arduino | Comunicatie SPI hardware cu OLED |
Adafruit_GFX | Adafruit | Biblioteca grafica de baza pentru display |
Adafruit_SSD1306 | Adafruit | Driver display OLED SSD1306/SH1106 prin SPI |
UART — HC-06 Bluetooth (D0/D1)
HC-06 functioneaza ca bridge serial wireless la 9600 baud. Microcontrolerul citeste caractere din Serial pana la \n, apoi parseaza comanda. Comenzile suportate sunt WARM, COOL, AUTO, WHITE, TIME, OFF si format numeric R G B (ex: 200 50 10). Pinul RX al modulului este protejat printr-un divizor 1kΩ+2kΩ deoarece HC-06 lucreaza la 3.3V logic iar ATmega transmite la 5V.
SPI — OLED SH1106 (D13/D11/D10/D7/D4)
Display-ul este controlat prin SPI hardware. Se foloseste biblioteca Adafruit_SSD1306 care este compatibila si cu controller-ul SH1106. Display-ul este actualizat o data pe secunda cu: ora curenta (HH:MM), valoarea LDR, modul activ si tripletul RGB curent. Pinii folositi: SCK=D13, MOSI=D11, CS=D10, DC=D7, RST=D4.
I2C — DS3231 RTC (A4/A5)
Comunicatia cu modulul RTC se face prin protocolul TWI la adresa implicita 0x68. Biblioteca RTClib abstractizeaza citirea registrilor BCD ai DS3231. La primul pornire (sau dupa pierderea alimentarii bateriei), RTC-ul se seteaza automat cu ora compilarii prin rtc.adjust(DateTime(F(DATE), F(TIME))).
ADC — LDR GL5528 (A0)
LDR-ul este conectat intr-un divizor de tensiune cu 10kΩ la GND. Valoarea ADC (0–1023) este mapata la intervalul 0–255 si folosita ca factor de interpolare pentru temperatura de culoare.
GPIO + Intrerupere — Buton (D2)
Butonul este conectat la D2 cu pull-up intern activat (INPUT_PULLUP). Debouncing-ul este realizat software: se valideaza apasarea doar daca pinul e LOW cel putin 30ms si au trecut cel putin 300ms de la ultima apasare valida.
PWM — MOSFETs RGB (D3/D5/D6)
Cele trei canale sunt controlate prin Timer0 (D5=OC0B, D6=OC0A) si Timer2 (D3=OC2B). PWM-ul este configurat direct prin registrii hardware TCCR0A, TCCR2A, OCR0A, OCR0B, OCR2B, fara a folosi analogWrite, pentru control precis al timerelor.
| Laborator | Periferal | Utilizare in proiect |
|---|---|---|
| Lab 0 — GPIO | GPIO, DDRD, PORTD | Configurare pini PWM ca OUTPUT, buton ca INPUT_PULLUP, control direct registri |
| Lab 1 — UART | Serial, USART | Comunicatie cu HC-06 Bluetooth la 9600 baud, parsare comenzi text, debug serial |
| Lab 2 — Intreruperi | INT0, D2 | Detectie apasare buton pe front descrescator, debouncing software cu millis() |
| Lab 3 — Timere / PWM | Timer0, Timer2, OCR | Generare PWM pe 3 canale independente pentru controlul MOSFET-urilor RGB |
| Lab 4 — ADC | ADC, A0 | Citire fotorezistor LDR, conversie 10-bit la factor de interpolare 0–255 |
| Lab 5 — SPI | SPI hardware, D13/D11 | Comunicatie cu display OLED SH1106, actualizare ecran la fiecare secunda |
| Lab 6 — I2C | TWI, A4/A5 | Citire ora de la DS3231 RTC, detectie pierdere alimentare baterie |
// ── Setup ────────────────────────────────────────── void setup() { Serial.begin(9600); // UART pentru HC-06 si debug pwmSetup(); // Configurare Timer0 si Timer2 pentru PWM RGB setRGB(0, 0, 0); // Pornire cu LED-urile stinse pinMode(PIN_BTN, INPUT_PULLUP); Wire.begin(); rtcSetup(); // Init DS3231, seteaza ora daca RTC a pierdut alimentarea oledSetup(); // Init OLED SSD1306/SH1106 prin SPI } // ── Loop principal ───────────────────────────────── void loop() { parseBT(); // 1. Citeste comenzi UART de la HC-06 checkButton(); // 2. Verifica buton cu debouncing software // 3. Calcul culoare in functie de mod activ switch (currentMode) { case MODE_AUTO: // LDR determina caldura culorii case MODE_TIME: // RTC determina caldura culorii case MODE_WARM: // Fix CALD (R=255, G=180, B=80) case MODE_COOL: // Fix RECE (R=200, G=220, B=255) case MODE_WHITE: // Alb pur (R=255, G=255, B=255) case MODE_BT: // Culoare primita prin Bluetooth case MODE_OFF: // Stins (R=0, G=0, B=0) } setRGB(cr, cg, cb); // Aplica PWM pe Timer0/Timer2 updateOLED(cr, cg, cb, ...); // Actualizeaza display SPI }
Interpolare liniara temperatura culoare:
R = RECE_R + (CALD_R - RECE_R) * t / 255
G = RECE_G + (CALD_G - RECE_G) * t / 255
B = RECE_B + (CALD_B - RECE_B) * t / 255
unde t = 0 → culoare RECE (dimineata/zi)
t = 255 → culoare CALD (seara/noapte)
Factorul t in MODE_AUTO — determinat de LDR:
t = 255 - ADC_value // lumina puternica = RECE, intuneric = CALD
Factorul t in MODE_TIME — determinat de ora RTC:
ora 06:00–18:00 → t = 0 (RECE) ora 18:00–22:00 → t = (h - 18) * 255 / 4 (tranzitie liniara) ora 22:00–06:00 → t = 255 (CALD)
Limitare luminozitate globala:
val_finala = val_calculata * MAX_BRIGHT / 255 MAX_BRIGHT = 160 // ~63% din maxim, protectie LED-uri si MOSFET-uri
Curentul prin LED-uri (verificare siguranta):
I_LED = (VCC - Vf) / R_serie I_R = (5V - 2.0V) / 220Ω ≈ 13.6 mA ✓ (sub limita de 20mA) I_G = (5V - 2.1V) / 100Ω ≈ 29 mA ⚠ (la limita, acceptabil) I_B = (5V - 3.2V) / 220Ω ≈ 8 mA ✓
analogWrite() — evita overhead-ul Arduino si permite control independent al Timer0 si Timer2 fara conflictemillis()) in loc de delay() — nu blocheaza parsarea UART sau citirea butonului\n — previne blocaje daca HC-06 trimite date corupteTest 1 — Buton: Apasa butonul fizic de pe D2. Display-ul trebuie sa cicleze prin modurile: AUTO → CALD → RECE → ALB → TIME → OPRIT → AUTO. LED-urile isi schimba culoarea la fiecare apasare.
Test 2 — Bluetooth: Conecteaza telefonul la HC-06 (PIN: 1234) cu o aplicatie serial Bluetooth (ex: Serial Bluetooth Terminal). Trimite comenzile:
WARM → LED-uri galben-portocaliuCOOL → LED-uri alb-albastruiWHITE → LED-uri alb purOFF → LED-uri stinse200 50 10 → culoare custom RGBTest 3 — ADC / LDR: Acopera fotorezistorul cu mana. In modul AUTO, LED-urile trebuie sa vireze spre culori calde (galben). Descopera LDR — LED-urile vireze spre rece (alb-albastru).
Test 4 — RTC: In modul TIME, ora afisata pe OLED determina culoarea. Intre 06:00–18:00 culoarea e rece, intre 18:00–22:00 face tranzitie spre cald, dupa 22:00 e culoare calda.
Test 5 — Debug serial: Deschide Serial Monitor la 9600 baud. La fiecare 2 secunde se printeaza:
HH:MM:SS | L:xxx | R:xxx G:xxx B:xxx