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 | SSD1306 0.96” SPI | 1 |
| Modul RTC | DS3231 I2C | 1 |
| MOSFET | LR7843 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 | 12V 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 |
-P usb -c xplainedmini (protocolul standard din PlatformIO nu functioneaza cu ATmega328P-XMINI)| Biblioteca | Scop |
|---|---|
Wire.h | Comunicatie I2C cu DS3231 |
RTClib | Citire ora si data de la DS3231 |
SPI.h | Comunicatie SPI hardware cu OLED |
Adafruit_GFX | Biblioteca grafica de baza pentru display |
Adafruit_SSD1306 | Driver display OLED 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 SSD1306 0.96” SPI (D13/D11/D10/D7/D4)
Display-ul este controlat prin SPI hardware. Actualizat o data pe secunda cu ora curenta, valoarea LDR, modul activ si tripletul RGB curent.
I2C - DS3231 RTC (A4/A5)
Comunicatia cu RTC-ul se face prin TWI la adresa 0x68. La primul pornire sau dupa pierderea alimentarii bateriei, ora 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 INPUT_PULLUP. Debouncing software: apasarea e valida doar daca pinul e LOW cel putin 30ms si au trecut cel putin 300ms de la ultima apasare.
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 pentru control precis fara overhead Arduino.
| Laborator | Periferal | Utilizare in proiect |
|---|---|---|
| Lab 0 - GPIO | DDRD, PORTD | Configurare pini PWM ca OUTPUT, buton ca INPUT_PULLUP, control direct registri |
| Lab 1 - UART | Serial, USART | Comunicatie cu HC-06 la 9600 baud, parsare comenzi text, debug serial |
| Lab 2 - Intreruperi | INT0, D2 | Detectie apasare buton, debouncing software cu millis() |
| Lab 3 - Timere / PWM | Timer0, Timer2, OCR | Generare PWM pe 3 canale independente pentru MOSFET-urile RGB |
| Lab 4 - ADC | ADC, A0 | Citire fotorezistor LDR, conversie 10-bit la factor 0–255 |
| Lab 5 - SPI | SPI hardware | Comunicatie cu display OLED, actualizare ecran la fiecare secunda |
| Lab 6 - I2C | TWI, A4/A5 | Citire ora de la DS3231, detectie pierdere alimentare baterie |
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 oledSetup(); // Init OLED prin SPI } 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); updateOLED(cr, cg, cb, ...); }
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 t = 0 => culoare RECE (dimineata/zi) t = 255 => culoare CALD (seara/noapte)
Factorul t in MODE_AUTO:
t = 255 - ADC_value // lumina puternica => RECE, intuneric => CALD
Factorul t in MODE_TIME:
ora 06:00-18:00 => t = 0 ora 18:00-22:00 => t = (h - 18) * 255 / 4 ora 22:00-06:00 => t = 255
Limitare luminozitate globala:
val_finala = val_calculata * MAX_BRIGHT / 255 MAX_BRIGHT = 160 // ~63% din maxim
Curentul prin LED-uri:
I = (VCC - Vf) / R_serie I_R = (5V - 2.0V) / 220 = 13.6 mA (OK, sub 20mA) I_G = (5V - 2.1V) / 100 = 29 mA (la limita, acceptabil) I_B = (5V - 3.2V) / 220 = 8 mA (OK)
analogWrite() pentru control independent al Timer0 si Timer2millis() fara delay(), nu blocheaza UART sau butonulTest 1 - Buton: Apasa butonul de pe D2. Display-ul cicleza: AUTO, CALD, RECE, ALB, TIME, OPRIT. LED-urile isi schimba culoarea la fiecare apasare.
Test 2 - Bluetooth: Conecteaza telefonul la HC-06 (PIN: 1234) cu o aplicatie serial Bluetooth. Trimite comenzile:
WARM ⇒ LED-uri galben-portocaliuCOOL ⇒ LED-uri alb-albastruiWHITE ⇒ LED-uri alb purOFF ⇒ LED-uri stinse200 50 10 ⇒ culoare custom RGBTest 3 - LDR: Acopera fotorezistorul cu mana. In modul AUTO LED-urile vireze spre cald (galben). Descopera LDR, LED-urile vireze spre rece (alb-albastru).
Test 4 - RTC: In modul TIME, ora de pe OLED determina culoarea. Intre 06:00-18:00 culoarea e rece, intre 18:00-22:00 face tranzitie, dupa 22:00 e calda.
Test 5 - Debug serial: Deschide Serial Monitor la 9600 baud. La fiecare 2 secunde:
HH:MM:SS | L:xxx | R:xxx G:xxx B:xxx