Autor: Grosulescu Despina-Alexandra
Grupa: 333CD
OptiSense este o solutie embedded portabila destinata persoanelor cu deficiente de vedere, care converteste automat textul tiparit din mediul fizic in format audio. Sistemul integreaza o arhitectura hardware dedicata cu servicii cloud de recunoastere optica a caracterelor (OCR), automatizand complet procesul de la capturarea imaginii pana la redarea vocala a continutului.
La baza proiectului se afla doua microcontrolere: ESP32-CAM, ales pentru capacitatile sale integrate de procesare video si conectivitate wireless, si ESP32S NodeMCU, responsabil exclusiv de logica de redare audio. Impreuna, cele doua placi formeaza un sistem distribuit: ESP32-CAM captureaza si transmite imaginea, un server intermediar realizeaza recunoasterea textului, iar NodeMCU descarca rezultatul si il reda printr-un difuzor extern.
Proiectul demonstreaza ca o arhitectura de tip vision-to-audio poate fi implementata intr-un format hardware compact si accesibil, punand accent pe eficienta fluxului de date, simplitatea utilizarii si autonomia dispozitivului. Scopul final este cresterea gradului de independenta a utilizatorilor in activitatile lor de zi cu zi.
Sistemul este complet integrat si functional. ESP32-CAM captureaza imagini stabile si le trimite prin retea catre un server Flask ce ruleaza pe un PC local. Serverul prelucreaza imaginea (corectie geometrica prin rotire si oglindire), apoi o transmite catre un API extern de OCR care returneaza textul identificat. In paralel, NodeMCU executa o bucla de interogare (polling) care descarca textul analizat si controleaza secvential redarea audio prin modulul DFPlayer Mini, gestionand pauzele dintre caractere.
Cele doua placi nu comunica direct intre ele prin fire, ci exclusiv prin intermediul serverului Flask, folosind protocolul HTTP peste WiFi. Aceasta decizie de arhitectura decupleaza complet modulul de captura de cel de redare, facand sistemul mai robust si mai usor de extins.
Protocoale de comunicatie folosite
Motivarea bibliotecilor folosite
Elementul de noutate al proiectului
Noutatea consta in arhitectura distribuita cu server intermediar si decuplarea completa a modulului de captura de cel de redare. Cele doua microcontrolere nu comunica direct intre ele – tot schimbul de date trece prin serverul Flask, care actioneaza ca un broker. Aceasta abordare muta toata puterea de calcul necesara OCR-ului pe un sistem cu resurse suficiente (PC), lasand placile embedded sa indeplineasca exclusiv rolul pentru care sunt optimizate: captura video si redare audio. Sistemul devine astfel scalabil (serverul poate fi inlocuit cu un serviciu cloud), usor de intretinut si extensibil cu noi functionalitati fara modificari hardware.
Justificarea utilizarii functionalitatilor din laborator
Functionarea sistemului este organizata in cinci etape distincte:
1. Captura
Utilizatorul pozitioneaza camera in dreptul unui text (eticheta, panou sau carte) si apasa butonul fizic. ESP32-CAM detecteaza tranzitia HIGH pe GPIO 13, declanseaza aprinderea flash-ului LED (GPIO 4) pentru 500 ms, apoi comanda senzorului OV2640 captarea unui cadru foto. Imaginea este stocata in buffer-ul PSRAM in format JPEG (rezolutie UXGA – 1600×1200, calitate 10 daca PSRAM este disponibil, SVGA altfel).
2. Transmisie
ESP32-CAM initializeaza o sesiune HTTP folosind biblioteca esp_http_client cu metoda POST. Imaginea JPEG din buffer este trimisa catre adresa serverului Flask (http://172.20.10.3:5000/upload) cu header Content-Type: image/jpeg. Conexiunea este mentinuta pana la primirea raspunsului de la server (timeout 60s). Textul returnat de server in corpul raspunsului HTTP este citit prin event handler-ul HTTP si stocat in variabila globala text_primit_global, dupa care este transmis pe Serial1 catre NodeMCU (varianta cu conexiune directa seriala intre placi – alternativa la varianta WiFi).
3. Procesare (pe server)
Imaginea receptionata pe ruta /upload este preluata ca stream de octeti si deschisa cu Pillow. Se aplica corectiile geometrice necesare (rotire si mirror), apoi imaginea corectata este trimisa prin POST catre API-ul extern de OCR. Serviciul OCR returneaza un string cu textul recunoscut. Serverul curata rezultatul (elimina caractere speciale, pastreaza litere A-Z, cifre 0-9 si spatii) si il stocheaza intr-o variabila globala accesibila pe ruta /get_text.
4. Mapare si Interogare
NodeMCU executa la fiecare 1 secunda o cerere HTTP GET catre /get_text. Cand primeste un string nevid, il converteste la majuscule si il parcurge caracter cu caracter. Pentru fiecare caracter, functia getTrackNumber() calculeaza numarul track-ului corespunzator: cifrele 0-9 sunt mapate la track-urile 1-10, literele A-Z sunt mapate la track-urile 11-36. Numarul de track este transmis ca argument catre DFPlayer prin Serial2.
5. Redare
Pentru fiecare cod numeric calculat, comanda player.play(track) este trimisa catre DFPlayer Mini prin Serial2. DFPlayer acceseaza fisierul corespunzator de pe cardul MicroSD prin SPI, il decodeaza si trimite semnalul audio amplificat catre difuzorul de 3W/8Ω. Intre redari, programul asteapta 700 ms pentru a asigura redarea completa inainte de urmatorul caracter, respectiv 1000 ms la intalnirea unui spatiu.
| Componenta | Descriere |
|---|---|
| ESP32-CAM | Unitate centrala captura: procesor dual-core Xtensa LX6, 520KB SRAM, 4MB PSRAM, senzor OV2640, WiFi 802.11 b/g/n integrat Datasheet |
| ESP32S NodeMCU | Unitate centrala audio: procesor dual-core Xtensa LX6, WiFi 802.11 b/g/n integrat, 4MB Flash Datasheet |
| FT232RL | Modul USB-to-UART pentru programarea ESP32-CAM si monitorizare seriala; furnizeaza totodata alimentarea de 5V a placii |
| DFPlayer Mini MP3-TF-16P | Modul MP3 standalone cu decodor audio integrat, citire MicroSD prin SPI intern, amplificator audio 3W, control prin UART Datasheet |
| Difuzor 3W / 8 Ohm | audio pentru redarea fisierelor MP3 Datasheet |
| Card MicroSD 16GB | Stocare fisiere audio MP3; organizat in folderul /01/ cu fisiere numerotate |
| Buton tactil push | Declansare manuala captura foto pe ESP32-CAM |
| Fire jumper M-F si M-M | Conexiuni pe breadboard intre module |
ESP32-CAM
| Componenta | Pin ESP32-CAM | Functie |
|---|---|---|
| FT232RL (TXD) | U0R (RX) | Receptie date seriale – programare si Serial Monitor |
| FT232RL (RXD) | U0T (TX) | Transmisie date seriale – programare si Serial Monitor |
| Buton captură | IO13 | Detectare apasare buton (INPUT_PULLDOWN, activ HIGH) |
| Flash LED | IO4 | Iluminare la captura (OUTPUT, HIGH = pornit) |
| OV2640 – XCLK | IO0 | Clock extern senzor camera (20 MHz) |
| OV2640 – SIOD | IO26 | SCCB/I2C Data – configurare senzor |
| OV2640 – SIOC | IO27 | SCCB/I2C Clock – configurare senzor |
| OV2640 – Y9..Y2 | IO35, IO34, IO39, IO36, IO21, IO19, IO18, IO5 | Date video paralele (8 biti) |
| OV2640 – VSYNC | IO25 | Sincronizare verticala cadru |
| OV2640 – HREF | IO23 | Sincronizare orizontala linie |
| OV2640 – PCLK | IO22 | Pixel clock |
| OV2640 – PWDN | IO32 | Power down senzor |
ESP32S NodeMCU
| Componenta | Pin NodeMCU | Functie |
|---|---|---|
| DFPlayer Mini (RX) | GPIO17 (TX2) | Transmisie comenzi UART Serial2 catre DFPlayer (9600 baud) |
| DFPlayer Mini (TX) | GPIO16 (RX2) | Receptie status UART Serial2 de la DFPlayer (9600 baud) |
| Difuzor | SPK_1 / SPK_2 | Iesire audio amplificata de la DFPlayer catre difuzor |
Nota: DFPlayer Mini acceseaza cardul MicroSD prin SPI intern – aceasta comunicatie este gestionata complet de modul, fara pini suplimentari din NodeMCU.
Schema electrica prezinta doua sectiuni distincte:
Calibrarea camerei
Senzorul OV2640 integrat in ESP32-CAM produce implicit imagini oglindite vertical, ceea ce ar face textul capturat inutilizabil pentru motorul OCR. Calibrarea a fost realizata prin apelarea functiilor set_vflip(1) si set_hmirror(1) pe obiectul sensor_t dupa initializarea camerei. Aceasta corecteaza orientarea direct la nivelul senzorului, eliminand necesitatea procesarii suplimentare a imaginii pe server si reducand latenta totala a sistemului. Ajustarea fina finala (rotire/mirror suplimentara) a ramas in stratul de pre-procesare Pillow de pe server, pentru a acoperi si diferentele de montaj fizic al camerei.
Optimizarea accesului la fisierele audio
O problema majora intalnita a fost latenta ridicata la redarea fisierelor MP3: DFPlayer Mini citeaza lent tabela de alocare a fisierelor (FAT) de pe card, in functie de ordinea copierii fizice a fisierelor. Solutia implementata consta in utilizarea comenzii playLargeFolder(1, cod_ascii) in loc de play(track). Aceasta comanda adreseaza direct folderul numeric /01/ si asociaza imediat codul ASCII primit cu fisierul corespunzator (ex: 065.mp3 pentru 'A'), garantand identificarea instantanee a fisierului indiferent de ordinea copierii pe card.
Utilizarea memoriei PSRAM
ESP32-CAM este echipat cu 4MB de memorie PSRAM externa. Prin detectarea prezentei PSRAM (psramFound()) in faza de initializare, sistemul alege automat rezolutia UXGA (1600×1200) si calitatea JPEG 10, in loc de SVGA cu calitate 12. Aceasta optimizare mareste semnificativ acuratetea extractiei textului de catre motorul OCR, in special pentru texte mici sau cu font subtire.
Debouncing buton
In bucla principala, apasarea butonului este validata prin doua citiri succesive cu un delay de 50 ms intre ele, eliminand semnalele false generate de vibratiile mecanice ale contactului.
Am realizat un scurt videoclip demonstrativ care prezinta functionalitatea completa a sistemului OptiSense. In clip se observa cum, la apasarea butonului, ESP32-CAM face captura textului “APPLE”, il trimite catre serverul Flask, care il proceseaza prin OCR API. Textul extras este descarcat wireless de NodeMCU, care il transforma in sunet redand secvential fiecare litera prin fisierele audio de pe cardul SD.