This shows you the differences between two versions of the page.
|
pm:prj2025:vstoica:stefania.manea [2025/05/14 12:22] stefania.manea |
pm:prj2025:vstoica:stefania.manea [2025/05/22 12:14] (current) stefania.manea |
||
|---|---|---|---|
| Line 34: | Line 34: | ||
| * [[https://sigmanortec.ro/modul-microfon-max4466-cu-amplificare-castig-reglabil-23-5vdc?SubmitCurrency=1&id_currency=2&gad_source=1&gad_campaignid=22174019478&gbraid=0AAAAAC3W72Mtzy7jY3q2IvRJJL2399kKi&gclid=CjwKCAjw_pDBBhBMEiwAmY02NjoiHoMMp2m7MvMgD5IMIKWO3YSxMbl3gWkBP3i0PlqeKFrk4SYHbhoCJd4QAvD_BwE|Modul microfon MAX4466 cu amplificare si castig reglabil]] | * [[https://sigmanortec.ro/modul-microfon-max4466-cu-amplificare-castig-reglabil-23-5vdc?SubmitCurrency=1&id_currency=2&gad_source=1&gad_campaignid=22174019478&gbraid=0AAAAAC3W72Mtzy7jY3q2IvRJJL2399kKi&gclid=CjwKCAjw_pDBBhBMEiwAmY02NjoiHoMMp2m7MvMgD5IMIKWO3YSxMbl3gWkBP3i0PlqeKFrk4SYHbhoCJd4QAvD_BwE|Modul microfon MAX4466 cu amplificare si castig reglabil]] | ||
| * [[https://sigmanortec.ro/modul-amplificator-miniatura-pam8403-22-5v?SubmitCurrency=1&id_currency=2&gad_source=1&gad_campaignid=22174019478&gbraid=0AAAAAC3W72Mtzy7jY3q2IvRJJL2399kKi&gclid=CjwKCAjw_pDBBhBMEiwAmY02Nv4Kh82h7hM4exmOleI9l1nKFCEOkJXp0H4xaOj1xKOyClULKjlmchoCRUEQAvD_BwE|Modul Mini Amplificator in Clasa D Stereo PAM8403 de 3 W]] | * [[https://sigmanortec.ro/modul-amplificator-miniatura-pam8403-22-5v?SubmitCurrency=1&id_currency=2&gad_source=1&gad_campaignid=22174019478&gbraid=0AAAAAC3W72Mtzy7jY3q2IvRJJL2399kKi&gclid=CjwKCAjw_pDBBhBMEiwAmY02Nv4Kh82h7hM4exmOleI9l1nKFCEOkJXp0H4xaOj1xKOyClULKjlmchoCRUEQAvD_BwE|Modul Mini Amplificator in Clasa D Stereo PAM8403 de 3 W]] | ||
| - | * [[https://www.emag.ro/difuzor-mini-3-wati-8-ohmi-pentru-arduino-diy-gd-0135/pd/DSSX18YBM/#opensearch|Difuzor Mini]] | + | * [[https://www.emag.ro/difuzor-mini-3-wati-8-ohmi-pentru-arduino-diy-gd-0135/pd/DSSX18YBM/|Difuzor Mini]] |
| * [[https://sigmanortec.ro/display-oled-096-i2c-iic-alb?SubmitCurrency=1&id_currency=2&gad_source=1&gad_campaignid=22174019478&gbraid=0AAAAAC3W72Mtzy7jY3q2IvRJJL2399kKi&gclid=CjwKCAjw_pDBBhBMEiwAmY02Nkg1IQK_EUcACBMSpldrDa0FIDTmlGddDwTUg6q6EU_xLhcgTZfY4RoCxKYQAvD_BwE|Ecran OLED 0.96”]] | * [[https://sigmanortec.ro/display-oled-096-i2c-iic-alb?SubmitCurrency=1&id_currency=2&gad_source=1&gad_campaignid=22174019478&gbraid=0AAAAAC3W72Mtzy7jY3q2IvRJJL2399kKi&gclid=CjwKCAjw_pDBBhBMEiwAmY02Nkg1IQK_EUcACBMSpldrDa0FIDTmlGddDwTUg6q6EU_xLhcgTZfY4RoCxKYQAvD_BwE|Ecran OLED 0.96”]] | ||
| * [[https://www.optimusdigital.ro/en/potentiometers/1887-100k-mono-potentiometer.html?gad_source=1&gad_campaignid=19615979487&gbraid=0AAAAADv-p3BfEEZZl7O_k8PCbMoE1d4yA&gclid=CjwKCAjw_pDBBhBMEiwAmY02Np0TkkPLCOFwRPMUOY6n5pKcIBN2whddkB2a2r2Mub2G8ekJFebs3BoCaBEQAvD_BwE|Potențiometru rotativ]] | * [[https://www.optimusdigital.ro/en/potentiometers/1887-100k-mono-potentiometer.html?gad_source=1&gad_campaignid=19615979487&gbraid=0AAAAADv-p3BfEEZZl7O_k8PCbMoE1d4yA&gclid=CjwKCAjw_pDBBhBMEiwAmY02Np0TkkPLCOFwRPMUOY6n5pKcIBN2whddkB2a2r2Mub2G8ekJFebs3BoCaBEQAvD_BwE|Potențiometru rotativ]] | ||
| Line 54: | Line 54: | ||
| |Buton 1 | D2 | Start înregistrare | | |Buton 1 | D2 | Start înregistrare | | ||
| |Buton 2 | D3 | Oprire și revenire la starea inițială | | |Buton 2 | D3 | Oprire și revenire la starea inițială | | ||
| + | |||
| + | |||
| + | {{ :pm:prj2025:vstoica:sch.png?600 | | center }} | ||
| Line 59: | Line 62: | ||
| {{ :pm:prj2025:vstoica:schema_stetoscop.png?600 | | center }} | {{ :pm:prj2025:vstoica:schema_stetoscop.png?600 | | center }} | ||
| | | ||
| + | ===Software Design=== | ||
| + | |||
| + | ==Flow-ul programului== | ||
| + | |||
| + | Programul funcționează pe o mașină de stări (`State currentState = BEGIN/RECORD`), în care logica principală este împărțită în două stări esențiale: **BEGIN** și **RECORD**. | ||
| + | |||
| + | * Starea **BEGIN** – Așteptare | ||
| + | |||
| + | Această stare este activă imediat după pornirea sistemului. În acest moment, dispozitivul se află în repaus și așteaptă interacțiunea utilizatorului. LED-ul roșu este aprins pentru a semnala starea pasivă, iar LED-ul verde este stins. Speaker-ul este dezactivat. Pe ecranul OLED este afișat un mesaj care îi spune utilizatorului cum să înceapă înregistrarea: //Apasă B1 pentru înregistrare//. | ||
| + | |||
| + | La apăsarea butonului 1, sistemul inițiază tranziția către starea de înregistrare (RECORD). În acest moment sunt resetate variabilele relevante: //beatCount// este setat la 0, iar //beatDetected// este resetat pentru a permite o detecție corectă a următoarelor bătăi. Se pornește cronometrul intern (recordStartTime = time_millies()), iar ecranul este curățat pentru a începe afișarea semnalului cardiac. | ||
| + | |||
| + | * Starea **RECORD** – Înregistrare activă | ||
| + | |||
| + | În această stare, dispozitivul începe efectiv procesul de monitorizare a bătăilor inimii. LED-ul verde este stins, în timp ce LED-ul roșu clipește la fiecare 500ms, indicând activitatea înregistrării. | ||
| + | |||
| + | În bucla principală a acestei stări, sistemul citește valoarea analogică de la microfonul conectat pe pinul ADC0. Această valoare este convertită într-o poziție verticală y, utilizată pentru desenarea unui grafic asemănător unei electrocardiograme. Dacă valoarea semnalului depășește pragul //PEAK_THRESHOLD//, sistemul consideră că a fost detectată o bătaie a inimii și incrementează //beatCount//, cu condiția să nu fi fost deja detectată o bătaie în momentul anterior (evitând astfel detecțiile duble). | ||
| + | |||
| + | Semnalul este desenat în timp real pe display, iar coloanele sunt curățate și desenate continuu. | ||
| + | |||
| + | Înregistrarea poate fi oprită prin apăsarea butonului 2. În acest caz, dispozitivul revine în starea **BEGIN**. Speaker-ul este dezactivat, iar sistemul calculează automat durata înregistrării și valoarea ritmului cardiac exprimată în BPM, folosind formulele: | ||
| + | |||
| + | * duration = (time_millies() - recordStartTime) / 1000 | ||
| + | |||
| + | * BPM = (beatCount * 60) / duration | ||
| + | |||
| + | Datele obținute sunt transmise funcției result_screen(bpm, duration, beatCount), care se ocupă de afișarea rezultatelor și animația cu inima care pulsează. | ||
| + | |||
| + | ==Structura și rolul fiecărui fișier== | ||
| + | |||
| + | |||
| + | Proiectul este structurat în mai multe fișiere sursă, fiecare având un rol specific în funcționarea generală a sistemului. În continuare voi descrie în detaliu fiecare fișier: | ||
| + | |||
| + | ==main.cpp - Fluxul programului și logica de bază== | ||
| + | Acesta este punctul de intrare al programului. Are rolul de a inițializa hardware-ul și de a coordona logica programului bazată pe stări. | ||
| + | |||
| + | Apelează funcțiile de inițializare: | ||
| + | |||
| + | * //gpio_init()//, //adc_init()//, //timer0_init()// | ||
| + | Configurează ecranul OLED cu //display.begin()// | ||
| + | Rulează o buclă //while(1)// care alternează între două stări: | ||
| + | |||
| + | * **BEGIN**: Așteaptă butonul 1 pentru a începe înregistrarea. | ||
| + | * **RECORD**: Citește semnalul de la microfon, detectează bătăi, desenează semnalul pe ecran și calculează BPM la oprirea înregistrării (prin butonul 2). | ||
| + | Integrează controlul LED-urilor și speaker-ului în funcție de starea aplicației. | ||
| + | Gestionează afișarea semnalului de puls și menține numărul de bătăi. | ||
| + | |||
| + | == init.hpp – Inițializarea componentelor hardware == | ||
| + | Acest fișier definește funcții pentru a configura perifericele microcontroller-ului. | ||
| + | |||
| + | **Funcții definite:** | ||
| + | |||
| + | //gpio_init()// | ||
| + | |||
| + | Configurează: | ||
| + | |||
| + | * Butoane ca intrări cu pull-up | ||
| + | * LED-uri ca ieșiri (inițial stinse) | ||
| + | * Pinul pentru speaker ca ieșire (alimentare controlată) | ||
| + | //adc_init()// | ||
| + | |||
| + | * Setează ADC-ul pentru citirea valorii analogice de la microfon. | ||
| + | * Selectează referința AVCC și un prescaler de 64 pentru un echilibru între viteză și precizie. | ||
| + | //timer0_init()// | ||
| + | |||
| + | * Inițializează Timer0 în mod CTC pentru a genera o întrerupere la fiecare 1 ms, necesară pentru măsurarea timpului în aplicație. | ||
| + | |||
| + | == vars.hpp – Configurări globale și definiri == | ||
| + | Fișierul definește variabile și constante globale necesare în întregul proiect. | ||
| + | |||
| + | **Include:** | ||
| + | |||
| + | * Dimensiunile ecranului OLED: //SCREEN_WIDTH//, //SCREEN_HEIGHT// | ||
| + | * Obiectul global //display// pentru controlul OLED-ului (Adafruit SSD1306) | ||
| + | * Maparea pinilor: pentru microfon, LED-uri, butoane și speaker. | ||
| + | * Praguri de detecție pentru sunetul pulsului: //PEAK_THRESHOLD// – prag pentru a detecta o bătaie; //MIC_THRESHOLD// – pentru a desena sau nu semnalul. | ||
| + | * Variabila //volatile uint32_t systicks//: Contor de milisecunde incrementat prin întrerupere (folosit pentru temporizări). | ||
| + | |||
| + | == screen.hpp – Afișare grafică și gestionare LED-uri == | ||
| + | Acest fișier conține funcțiile de afișare și de interpretare a rezultatelor măsurării. | ||
| + | |||
| + | **Funcții principale** | ||
| + | |||
| + | //ISR(TIMER0_COMPA_vect)// | ||
| + | |||
| + | * Rutină de întrerupere la fiecare 1 ms → incrementează `systicks`. | ||
| + | //time_millies()// | ||
| + | |||
| + | * Returnează timpul curent în milisecunde (bazat pe `systicks`) | ||
| + | //begin_screen()// | ||
| + | |||
| + | * Afișează ecranul de start cu instrucțiuni pentru utilizator | ||
| + | //result_screen(bpm, duration, beatCount)// | ||
| + | |||
| + | Afișează rezultatele înregistrării: | ||
| + | |||
| + | * BPM | ||
| + | * Durata | ||
| + | * Numărul de bătăi | ||
| + | * Arată o animație cu o inimioară care pulsează | ||
| + | Setează LED-urile în funcție de nivelul ritmului cardiac: | ||
| + | |||
| + | * Verde: normal (60–100 BPM) | ||
| + | * Portocaliu: alertă moderată (40–60 sau 100–120 BPM) | ||
| + | * Roșu: critic (sub 40 sau peste 120 BPM) | ||
| + | |||
| + | == libs.hpp – Include-uri și biblioteci == | ||
| + | Fișier folosit pentru a centraliza toate bibliotecile necesare. | ||
| + | |||
| + | **Include ** | ||
| + | |||
| + | //AVR standard// (pentru control hardware): | ||
| + | |||
| + | * //avr/io.h// – acces la registre | ||
| + | * //avr/interrupt.h// – permite lucrul cu întreruperi | ||
| + | * //util/delay.h// – întrârziere în milisecunde sau microsecunde | ||
| + | * //stdint.h//, //stdbool.h// | ||
| + | //Display OLED:// | ||
| + | |||
| + | * //Wire.h// – comunicare I2C | ||
| + | * //Adafruit_GFX.h// – interfață grafică pentru desenare (linii, text, bitmap-uri) | ||
| + | * //Adafruit_SSD1306.h// – suport specific pentru display-ul SSD1306 | ||
| + | |||
| + | == heart.hpp – Resurse grafice (bitmap-uri inimă) == | ||
| + | Conține două array-uri `PROGMEM` (plasate în memoria flash) cu bitmap-uri: | ||
| + | |||
| + | * //heartSmall[]// – inimă mică | ||
| + | * //heartBig[]// – inimă mare | ||
| + | |||
| + | Acestea sunt desenate alternativ pe ecran în //result_screen()// pentru a simula o inimă care pulsează. | ||
| + | |||
| + | ===Rezultate obținute=== | ||
| + | |||
| + | [[https://www.youtube.com/watch?v=QOGykQ_T8kw|Demo proiect]] | ||
| + | |||
| + | |||
| + | Rezultatele obținute în urma testării arată că proiectul simulează detectarea bătăilor inimii și le contorizează în timp real. Informațiile afișate pe ecranul OLED, mai exact BPM-ul, durata înregistrării și numărul de bătăi, sunt clare și ușor de înțeles, iar animația inimii contribuie la o experiență interactivă și intuitivă pentru utilizator. | ||
| + | Aceste elemente fac ca proiectul să fie nu doar funcțional, ci și accesibil și prietenos pentru utilizatori. | ||
| + | |||
| + | {{ :pm:prj2025:vstoica:poza1.jpg?300|}} | ||
| + | {{ :pm:prj2025:vstoica:poza2.jpg?300|}} | ||
| + | {{ :pm:prj2025:vstoica:poza3.jpg?300|}} | ||
| + | {{ :pm:prj2025:vstoica:poza4.jpg?300|}} | ||
| + | {{ :pm:prj2025:vstoica:poza5.jpg?450 || center}} | ||
| + | |||
| + | |||
| + | |||
| + | ===Concluzie=== | ||
| + | |||
| + | Proiectul **Stetoscop Digital** pune în evidență un mod practic și eficient de a construi un sistem embedded care răspunde la interacțiuni reale. Utilizarea resurselor hardware precum ADC, GPIO, timer și interfața I2C pentru display-ul OLED a permis construirea unei aplicații care combină interacțiunea fizică (butoane, LED-uri, speaker) cu o interfață grafică intuitivă. Această combinație de componente oferă un rezultat vizual și funcțional. | ||
| + | |||
| + | Codul este clar structurat, iar funcționalitatea este împărțită logic, ceea ce face ca proiectul să fie ușor de înțeles și de testat. | ||
| + | |||