This is an old revision of the document!
Proiectul consta in realizarea unei telecomenzi universale hibride, capabila sa invete, sa stocheze si sa reproduca semnale de control atat in Infrarosu (IR), cat si in Radiofrecventa (RF 433 MHz). Dispozitivul este construit in jurul microcontrollerului ATmega328P (Arduino Nano), beneficiind de un ecran OLED pentru interfata grafica si un encoder rotativ pentru navigare.
Sistemul este impartit in patru module functionale principale care interactioneaza cu unitatea centrala de procesare (ATmega328P):
Flux de functionare:
MENU_MAIN, MENU_LEARN, MENU_LEARN_SLOT, LEARN_WAITING, LEARN_SUCCESS, MENU_SEND_SLOT, SENDING_CMD, MENU_DELETE_SLOT.| Componenta | Model / Specificatii | Rol in sistem |
|---|---|---|
| Microcontroller | Arduino Nano (ATmega328P-AU, 16 MHz, 5V) | Unitate centrala de procesare |
| Afisaj | OLED 0.96” I2C, Controller SSD1306, 128×64 px | Interfata vizuala / meniuri |
| Encoder rotativ | KY-040 (cu buton integrat) | Navigare meniuri + confirmare |
| Buton suplimentar | Buton tactil (KEY / Inapoi) | Revenire in meniu anterior |
| Receptor IR | KY-022 (VS1838B, 38 kHz) | Capturare semnale IR de la telecomenzi |
| Emitator IR | KY-005 (LED IR 5mm) + Tranzistor NPN 2N2222 | Emitere semnale IR modulate la 38 kHz |
| Receptor RF | SYN480R 433 MHz (4 pini, cu antena 17.3 cm) | Capturare semnale RF de la telecomenzi |
| Emitator RF | SYN115 433 MHz (3 pini) | Emitere semnale RF |
| Acumulator | Li-ion 523450 (3.7V, ~1000 mAh) | Sursa de energie portabila |
| Modul incarcare | TP4056 (Micro-USB sau Type-C) | Incarcare acumulator Li-ion cu protectie |
| Modul Step-Up | MT3608 (ajustabil, setat la 5V) | Ridicare tensiune 3.7V → 5V pentru sistem |
| Periferic | Pin Arduino Nano | Functie hardware utilizata |
|---|---|---|
| OLED SDA | A4 (PC4) | TWI/I2C - linie date |
| OLED SCL | A5 (PC5) | TWI/I2C - linie ceas |
| Receptor IR (KY-022) | D11 (PB3) | Intrare digitala (polling IRremote) |
| Emitator IR (KY-005) | D3 (PD3) | PWM Timer 2 / GPIO (IRremote) |
| Receptor RF (SYN480R) | D2 (PD2) | INT0 - Intrerupere externa HW |
| Emitator RF (SYN115) | D10 (PB2) | GPIO digital output |
| Encoder A (click) | D8 (PB0) | PCINT0 - Pin Change Interrupt |
| Encoder B (directie) | D6 (PD6) | GPIO - citit in ISR PCINT0 |
| Buton PUSH | D4 (PD4) | PCINT20 - Pin Change Interrupt |
| Buton KEY (Inapoi) | D5 (PD5) | PCINT21 - Pin Change Interrupt |
Note de proiectare:
Firmware-ul este scris in C++ pentru Arduino (bare-metal ATmega328P) si structurat ca o masina de stari finita (FSM) cu 8 stari. Bucla principala ``loop()`` citeste starea curenta si executa logica aferenta, inclusiv actualizarea afisajului OLED.
enum AppState { MENU_MAIN, // Meniu principal (Emite / Invata / Sterge) MENU_LEARN, // Sub-meniu: alege IR sau RF MENU_LEARN_SLOT, // Alege slotul EEPROM de salvat (0-9) LEARN_WAITING, // Asteapta semnal IR/RF de la telecomanda originala LEARN_SUCCESS, // Confirmare vizuala (stare tranzitorie) MENU_SEND_SLOT, // Alege slotul de emis (0-9) SENDING_CMD, // Control activ: encoderul modifica comanda IR MENU_DELETE_SLOT // Sterge un slot din EEPROM };
Toate intrarile utilizatorului sunt gestionate exclusiv prin intreruperi, fara polling in ``loop()``:
// Configurare PCINT (fara librarii externe) void setupPCINT() { cli(); PCICR |= (1 << PCIE0) | (1 << PCIE2); // Activare grupuri PCINT0 si PCINT2 PCMSK0 |= (1 << PCINT0); // D8 = PB0 (Encoder A) PCMSK2 |= (1 << PCINT20) | (1 << PCINT21) | (1 << PCINT22); // D4, D5, D6 lastPortB = PINB; lastPortD = PIND; sei(); }
Comunicarea cu ecranul OLED SSD1306 se realizeaza prin magistrala I2C hardware a ATmega328P (TWI), via biblioteca U8g2 in modul 1-page buffer (``_1_``), pentru a minimiza consumul de RAM:
// Mod 1-page: foloseste ~128 bytes RAM in loc de ~1 KB (full-frame buffer) U8G2_SSD1306_128X64_NONAME_1_HW_I2C display(U8G2_R0, U8X8_PIN_NONE);
Desenarea se face cu pattern-ul ``firstPage()`` / ``nextPage()``, care itereaza prin paginile ecranului una cate una, economisind memorie SRAM.
Sistemul poate stoca 10 profiluri de dispozitiv (sloturi 0-9) direct in EEPROM-ul intern al ATmega328P (1 KB disponibil). Fiecare profil este o structura de 12 bytes:
struct DeviceProfile { bool isUsed; // Slot ocupat? bool isIR; // true = IR, false = RF uint16_t protocol; // Protocol IR (NEC, SAMSUNG, etc.) sau RF uint32_t address; // Adresa dispozitivului IR / Codul RF uint16_t command; // Comanda IR (valoarea butonului) uint16_t bitLength; // Lungimea codului RF in biti }; // 10 sloturi x 12 bytes = 120 bytes din 1024 bytes EEPROM
La pornire, daca un slot contine valori de ``0xFF`` (EEPROM proaspat/sters), este marcat automat ca ``isUsed = false``.
Biblioteca IRremote este configurata sa decodifice si sa emita 9 protocoale:
Comanda IR este emisa cu ``IrSender.write(&irData, 0)`` unde ``irData`` contine protocolul, adresa si comanda decodificate la receptie si salvate in EEPROM.
Gestionat de biblioteca RCSwitch, care suporta prize inteligente, intrerupatoare wireless si alte dispozitive cu cod fix OOK (On-Off Keying). La receptie, se salveaza: valoarea codului (32-bit), lungimea in biti si protocolul RF. La emisie, se reproduce identic cu ``mySwitch.send()``.
| Biblioteca | Versiune (PlatformIO) | Utilizare |
|---|---|---|
| U8g2 | olikraus/U8g2 | Driver OLED SSD1306 (I2C, 1-page buffer) |
| IRremote | z3t0/IRremote | Receptie si emisie multi-protocol IR (38 kHz) |
| RCSwitch | sui77/rc-switch | Receptie si emisie RF 433 MHz (OOK, cod fix) |
| EEPROM | Built-in Arduino | Persistenta profilelor de dispozitiv |
| Wire | Built-in Arduino | Initializare magistrala I2C (utilizat de U8g2) |
Proiectul demonstreaza cu succes integrarea mai multor tehnologii de comunicatie fara fir si a tehnicilor de programare bare-metal pe un microcontroller de 8 biti cu resurse limitate: