This shows you the differences between two versions of the page.
|
pm:prj2026:ciprian.popescu0411:sara.tutuianu [2026/05/16 18:56] sara.tutuianu |
pm:prj2026:ciprian.popescu0411:sara.tutuianu [2026/05/24 10:31] (current) sara.tutuianu |
||
|---|---|---|---|
| Line 2: | Line 2: | ||
| ===== Introducere ===== | ===== Introducere ===== | ||
| - | Proiectul folosește modulul ESP32-CAM pentru a construi un sistem de recunoaștere a imaginilor, capabil să identifice diverse obiecte în timp real. Modulul camera captează imaginea, iar un model de inteligență artificială antrenat pe platforma Edge Impulse o analizează și afișează rezultatul, adică obiectul detectat împreună cu procentul de încredere pe un ecran OLED. Pe lângă afișaj, am adăugat și un servomotor care rotește brațul cu 90° pentru a ridica sau coborî poarta, în funcție de obiectul identificat. | + | Proiectul folosește modulul ESP32-CAM pentru a construi un sistem de recunoaștere a imaginilor, capabil să identifice diverse obiecte în timp real. Modulul camera captează imaginea, iar un model de inteligență artificială antrenat o analizează și afișează rezultatul, adică obiectul detectat împreună cu procentul de încredere pe un ecran OLED. Pe lângă afișaj, am adăugat și un servomotor care rotește brațul cu 90° pentru a ridica sau coborî poarta, în funcție de obiectul identificat. |
| - | Scopul proiectului este să demonstreze că inteligența artificială nu are nevoie de servere puternice pentru a funcționa. Prin edge computing, algoritmii de IA rulează direct pe dispozitive mici și low-power, cum ar fi microcontrollerele, procesând datele local, fără a le trimite în cloud. Astfel, sistemul este rapid, independent de internet și ieftin. | + | Scopul proiectului este implementarea unui sistem automat de sortare a fructelor folosind computer vision. Camera ESP32-CAM capturează imagini în timp real, un model MobileNetV2 antrenat custom clasifică obiectele, iar un servomotor acționează o poartă mecanică în funcție de rezultat. |
| - | Sunt pasionată de inteligența artificială și am vrut să construiesc ceva care să combine IA cu microcontrollerele. Provocarea principală este atât găsirea celui mai bun model care să clasifice corect obiectele, cât și optimizarea acestuia pentru a încăpea în memoria limitată a ESP32-CAM. | + | Sunt pasionată de inteligența artificială și am vrut să construiesc ceva care să combine IA cu microcontrollerele. Provocarea principală este atât găsirea celui mai bun model care să clasifice corect obiectele. |
| Proiectul are aplicații practice variate. Într-un supermarket, de exemplu, poate identifica automat produsul pus pe cântar, eliminând nevoia de a căuta manual codul acestuia și accelerând procesul pentru toți clienții. Pentru persoanele nevăzătoare, este deosebit de util deoarece nu mai trebuie să caute un cod pe un ecran pe care nu îl pot vedea. Mai departe, sistemul poate fi adaptat pentru inventariere și sortare automată în depozite sau clasificarea fructelor și legumelor în agricultură. | Proiectul are aplicații practice variate. Într-un supermarket, de exemplu, poate identifica automat produsul pus pe cântar, eliminând nevoia de a căuta manual codul acestuia și accelerând procesul pentru toți clienții. Pentru persoanele nevăzătoare, este deosebit de util deoarece nu mai trebuie să caute un cod pe un ecran pe care nu îl pot vedea. Mai departe, sistemul poate fi adaptat pentru inventariere și sortare automată în depozite sau clasificarea fructelor și legumelor în agricultură. | ||
| Line 18: | Line 18: | ||
| * ESP32-CAM — microcontrollerul principal al proiectului. Captează imaginea prin camera integrată, rulează modelul AI și controlează toate celelalte componente. | * ESP32-CAM — microcontrollerul principal al proiectului. Captează imaginea prin camera integrată, rulează modelul AI și controlează toate celelalte componente. | ||
| * Servomotor SG90 — conectat la pinul GPIO16 al ESP32-CAM. Primește semnal PWM de la ESP32-CAM și rotește brațul cu 90° pentru a ridica sau coborî poarta, în funcție de obiectul identificat de modelul AI. | * Servomotor SG90 — conectat la pinul GPIO16 al ESP32-CAM. Primește semnal PWM de la ESP32-CAM și rotește brațul cu 90° pentru a ridica sau coborî poarta, în funcție de obiectul identificat de modelul AI. | ||
| - | * Buzzer — conectat la un pin GPIO al ESP32-CAM. Primește semnal de la ESP32-CAM și emite un sunet diferit în funcție de obiectul identificat. | + | * Modul Nano micro servo motor SG90 - servomotor de 9g controlat prin PWM pe GPIO16, folosit pentru acționarea porții mecanice |
| * FTDI Programmer — conectat prin UART la ESP32-CAM. Are dublu rol: încarcă codul pe microcontroller și îl alimentează cu 5V prin USB de la PC. | * FTDI Programmer — conectat prin UART la ESP32-CAM. Are dublu rol: încarcă codul pe microcontroller și îl alimentează cu 5V prin USB de la PC. | ||
| Module software: | Module software: | ||
| - | * Edge Impulse — platforma online unde este antrenat modelul de recunoaștere a obiectelor. Datele de antrenare sunt imagini capturate chiar cu ESP32-CAM, iar modelul rezultat este exportat ca librărie Arduino. | + | * Flask — framework web Python care rulează pe laptop și servește ca intermediar între browser, modelul AI și ESP32-CAM. Gestionează rutele HTTP pentru stream video, clasificare și comunicarea cu ESP32-CAM. |
| - | * Modelul AI — exportat din Edge Impulse și instalat direct pe ESP32-CAM ca librărie. Analizează fiecare cadru capturat de cameră și returnează obiectul detectat împreună cu scorul de încredere. | + | * TensorFlow + MobileNetV2 — modelul de clasificare antrenat custom pe laptop folosind transfer learning. Primește imaginile capturate de ESP32-CAM, le clasifică în categoriile apple, lemon sau empty și returnează label-ul împreună cu scorul de încredere. |
| * Arduino IDE — mediul de programare folosit pentru a scrie codul care leagă toate componentele: camera, modelul AI, ecranul OLED și buzzerul. | * Arduino IDE — mediul de programare folosit pentru a scrie codul care leagă toate componentele: camera, modelul AI, ecranul OLED și buzzerul. | ||
| ===== Hardware Design ===== | ===== Hardware Design ===== | ||
| - | Listă de piese: | + | **Listă de piese**: |
| - | * ESP32-CAM | + | * ESP32-CAM - microcontroller principal cu cameră integrată și modul WiFi/Bluetooth |
| - | * USB to Serial Converter | + | * USB to Serial Converter - convertor FTDI FT232RL folosit pentru programarea ESP32-CAM și alimentarea acestuia prin USB |
| - | * Breadboard | + | * Breadboard - placă de prototipare pentru conectarea componentelor fără lipire |
| - | * 0.96” OLED Display | + | * 0.96" OLED Display - ecran SSD1306 conectat prin I2C care afișează obiectul detectat și procentul de încredere |
| - | * Modul Nano micro servo motor SG90 | + | * Modul Nano micro servo motor SG90 - servomotor de 9g controlat prin PWM pe GPIO16, folosit pentru acționarea porții mecanice |
| - | * Fire de legătură | + | * Fire de legătură - fire jumper pentru realizarea conexiunilor între componente pe breadboard |
| - | * Obiecte pentru antrenare | + | * Obiecte pentru antrenare - obiecte fizice fotografiate și folosite pentru antrenarea modelului AI în Edge Impulse |
| + | **Demonstrație funcționare** | ||
| + | {{:pm:prj2026:ciprian.popescu0411:imagine_hardware.jpeg?500|}} | ||
| + | {{:pm:prj2026:ciprian.popescu0411:video_placuta.gif?500|}} | ||
| + | |||
| + | **Schemă electrică** | ||
| + | {{:pm:prj2026:ciprian.popescu0411:schema_elec_sara.jpeg?900|}} | ||
| + | |||
| + | Schema electrică prezintă sistemul complet al proiectului ESP32-CAM Object Detection, realizată în KiCad 10.0.3. Aceasta include patru componente principale: microcontrollerul ESP32-WROOM-32 în centrul schemei, display-ul OLED conectat prin I2C , convertorul USB-Serial FT232RL conectat prin UART pentru programare și alimentare la 5V, și servomotorul SG90 alimentat separat din baterii 4xAA la 6V. Firele verzi indică conexiunile de semnal și alimentare între componente, iar simbolurile de alimentare (+3.3V, +5V, +6V, GND) sunt distribuite corespunzător fiecărei componente în funcție de tensiunea necesară. | ||
| + | |||
| + | ^ Pin FTDI ^ Semnal ^ Conectat la ^ De ce? ^ | ||
| + | | VCC | Alimentare | ESP32 5V | Furnizează 5V prin USB de la laptop către ESP32 | | ||
| + | | GND | Masă | ESP32 GND | Referință comună de tensiune | | ||
| + | | TX | Transmisie | ESP32 U0R | FTDI trimite date, ESP32 primește - încărcare cod | | ||
| + | | RX | Recepție | ESP32 U0T | ESP32 trimite date, FTDI primește - Serial Monitor | | ||
| + | |||
| + | ^ Pin ESP32 ^ Semnal ^ Conectat la ^ De ce? ^ | ||
| + | | 5V | Alimentare | FTDI VCC | Primește alimentare 5V prin USB | | ||
| + | | GND | Masă | FTDI GND + Baterii GND + OLED GND | Masă comună pentru toate componentele | | ||
| + | | 3.3V | Alimentare | OLED VCC | 3.3V pentru OLED | | ||
| + | | GPIO0 | Boot mode | GND | Conectat la GND, mod programare. Deconectat, rulare normală | | ||
| + | | GPIO14 | I2C SCL | OLED SCL | Clock I2C pentru OLED | | ||
| + | | GPIO15 | I2C SDA | OLED SDA | Date I2C pentru OLED | | ||
| + | | GPIO16 | PWM | Servo semnal | Generează semnal PWM | | ||
| + | |||
| + | ^ Pin OLED ^ Semnal ^ Conectat la ^ De ce? ^ | ||
| + | | GND | Masă | ESP32 GND | Referință comună | | ||
| + | | VCC | Alimentare | ESP32 3.3V | OLED funcționează la 3.3V | | ||
| + | | SCL | I2C clock | ESP32 GPIO14 | Primește clock-ul I2C de la ESP32 | | ||
| + | | SDA | I2C date | ESP32 GPIO15 | Primește datele de afișat de la ESP32 | | ||
| + | |||
| + | ^ Pin Servo ^ Culoare fir ^ Conectat la ^ De ce? ^ | ||
| + | | VCC | Roșu | Baterii +6V | Alimentare separată baterii | | ||
| + | | GND | Maro/Negru | Baterii GND + ESP32 GND | Masă comună | | ||
| + | | Semnal | Portocaliu | ESP32 GPIO16 | Primește semnal PWM | | ||
| ===== Software Design ===== | ===== Software Design ===== | ||
| Line 52: | Line 86: | ||
| </note> | </note> | ||
| + | **Stadiul actual al implementării software** | ||
| + | Proiectul este implementat pe două componente software distincte care comunică prin WiFi. | ||
| + | |||
| + | * ESP32-CAM (Arduino C++) rulează două servere HTTP simultane. Portul 81 găzduiește stream-ul MJPEG video în timp real, implementat prin librăria eloquent_esp32cam. Portul 82 găzduiește un server REST API custom cu trei rute: /jpeg pentru captura unui singur frame, /rezultat pentru primirea predicției și afișarea pe OLED, și /servo pentru controlul servomotorului prin semnal PWM. Camera RHYX transmite date RGB565 raw, iar frame-urile sunt copiate în memorie înainte de trimitere. | ||
| + | * Serverul Python (Flask + TensorFlow) rulează pe laptop și se ocupă de predictie. Primește frame-urile RGB565 raw de la ESP32, aplică conversia de bytes și transformarea în format BGR, după care rulează modelul MobileNetV2 antrenat custom. Rezultatul este trimis înapoi la ESP32 pentru afișare pe OLED și control servo. | ||
| + | |||
| + | **Motivația alegerii bibliotecilor** | ||
| + | * eloquent_esp32cam — oferă stream MJPEG într-un thread separat, fără a bloca execuția principală. | ||
| + | * Adafruit_SSD1306 + Adafruit_GFX — librării pentru display-ul OLED SSD1306 în ecosistemul Arduino. Oferă funcții de nivel înalt pentru text și grafică, abstractizând complet protocolul I2C. | ||
| + | * WebServer (ESP32) — librărie nativă ESP32 pentru server HTTP. Aleasă în locul librăriilor third-party deoarece nu introduce conflicte cu camera sau I2C, și suportă nativ send_P pentru trimiterea datelor binare raw. | ||
| + | * driver/ledc.h (ESP-IDF) — driver direct pentru controlul PWM al servomotorului. Librăria ESP32Servo a cauzat crash-uri prin conflict cu interfața I2S a camerei, deoarece folosea același timer hardware. Prin utilizarea directă a driver-ului LEDC cu LEDC_TIMER_2 și LEDC_CHANNEL_2, conflictul a fost eliminat complet. | ||
| + | * Flask — framework web Python | ||
| + | * TensorFlow + MobileNetV2 — modelul MobileNetV2 pre-antrenat pe ImageNet prin transfer learning a fost ales deoarece oferă acuratețe ridicată cu un dataset mic (240 imagini per clasă). Antrenarea de la zero ar fi necesitat mii de imagini. MobileNetV2 este optimizat pentru dispozitive cu resurse limitate, iar inferența pe laptop durează sub 100ms. | ||
| + | * OpenCV — aleasă pentru conversia RGB565 → BGR și redimensionarea imaginilor. Oferă funcția nativă COLOR_BGR5652BGR care face conversia eficient. | ||
| + | |||
| + | **Scheletul proiectului și interacțiunea dintre funcționalități** | ||
| + | |||
| + | **Arhitectura generala** | ||
| + | Browser (localhost:5000) | ||
| + | ↕ HTTP | ||
| + | Flask Server (Python) | ||
| + | ↕ HTTP WiFi | ||
| + | ESP32-CAM | ||
| + | ↕ I2C | ||
| + | OLED Display | ||
| + | ↕ PWM | ||
| + | Servo SG90 | ||
| + | |||
| + | **Flux clasificare** | ||
| + | 1. Utilizatorul deschide http://localhost:5000 | ||
| + | 2. Browser afișează stream live (refresh la 300ms) | ||
| + | 3. Utilizatorul apasă "Clasifica" | ||
| + | 4. Browser → POST /clasificare → Flask | ||
| + | 5. Flask → GET /jpeg → ESP32 portul 82 | ||
| + | 6. ESP32 flush frame vechi → captură nouă | ||
| + | 7. Trimite 153600 bytes RGB565 raw | ||
| + | 8. Flask swap bytes → conversie RGB565→BGR | ||
| + | 9. MobileNetV2 → predicție label + confidence | ||
| + | 10. Flask → GET /rezultat → ESP32 OLED | ||
| + | 11. Flask → GET /servo?grade=90 (dacă apple) | ||
| + | 12. Flask → sleep(3) → GET /servo?grade=0 | ||
| + | 13. Flask → JSON {detectii, snapshot} → Browser | ||
| + | 14. Browser afișează rezultat + snapshot | ||
| + | |||
| + | **Interacțiunea dintre funcționalități din laborator** | ||
| + | * Lab GPIO | ||
| + | * Lab UART este folosit pentru debug prin Serial.printf() la fiecare eveniment important: inițializare cameră, trimitere frame, primire rezultat. | ||
| + | * Lab PWM este folosit pentru controlul servomotorului prin driverul LEDC cu LEDC_TIMER_2 la 50Hz și rezoluție 12 biți, generând semnalul PWM pe GPIO16. | ||
| + | * Lab I2C este folosit pe două magistrale simultane: GPIO14/GPIO15 pentru OLED SSD1306 la adresa 0x3C, și GPIO26/GPIO27 pentru configurarea internă a camerei prin protocolul SCCB. | ||
| + | |||
| + | **Validarea funcționalităților** | ||
| + | * Camera și conversia RGB565 au fost validate prin salvarea locală a fișierului ultima_captura.jpg după fiecare clasificare și verificarea vizuală că imaginea este corectă și culorile sunt normale. | ||
| + | * Modelul TensorFlow a fost validat prin antrenare cu 100% validation accuracy pe setul de validare, și prin testarea live cu obiecte reale în fața camerei, observând predicțiile în timp real în consolă și pe OLED. | ||
| + | * Comunicația WiFi a fost validată prin monitorizarea log-urilor Flask care confirmă fiecare cerere HTTP: accesarea /jpeg, trimiterea la /rezultat și controlul /servo. | ||
| + | |||
| + | **Optimizări realizate** | ||
| + | * Flush frame vechi — înainte de captură, frame-ul vechi din buffer este aruncat pentru ca clasificarea să folosească mereu imaginea curentă. | ||
| + | * Copiere buffer — buffer-ul camerei este copiat în memorie și camera eliberată imediat, eliminând conflictele cu stream-ul MJPEG. | ||
| + | * Transfer Learning — MobileNetV2 pre-antrenat pe ImageNet cu layerele înghețate, obținând 100% validation accuracy cu doar 240 imagini per clasă. | ||
| + | * Threshold clasificare — predicțiile sub 70% confidence sunt tratate automat ca empty, prevenind activarea greșită a servo-ului. | ||
| + | * Byte-swapping RGB565 — bytes primiți de la camera RHYX sunt reordonați în Python înainte de conversie, corectând culorile imaginilor trimise modelului. | ||
| + | |||
| + | **Link Github:** https://github.com/saratutuianu/UPB-PM-Automatic-object-sorting-using-ML | ||
| + | |||
| + | **Link videoclip functionare:** https://youtu.be/nlO-m5YhCmo | ||
| ===== Rezultate Obţinute ===== | ===== Rezultate Obţinute ===== | ||