Inima Interactiva

Proiectul consta intr-o inima formata din LED-uri RGB pe breadboard care pulseaza in ritmul batailor reale ale utilizatorului. Utilizatorul isi pune degetul pe senzorul de puls, care masoara BPM-ul in timp real. LED-urile pulseaza in ritmul detectat, iar display-ul OLED afiseaza valoarea BPM. Culoarea LED-urilor indica starea: verde pentru BPM normal (60-100 BPM), rosu pentru BPM in afara intervalului. La apasarea butonului masurarea porneste, la o noua apasare se opreste. La fiecare bataie detectata, buzzerul reda un sunet scurt de tip lub-dub.

Descriere generala

Modulele proiectului si modul in care interactioneaza:

  • Senzorul de puls citeste bataile inimii de pe deget si trimite semnal analogic catre ADC
  • ATmega328P proceseaza semnalul, calculeaza BPM si controleaza celelalte module
  • Tranzistoarele BD139 comanda cele 11 LED-uri RGB simultan, fara ca pinii microcontrollerului sa alimenteze direct toate LED-urile
  • LED-urile RGB pulseaza in ritmul detectat si isi schimba culoarea in functie de BPM (verde = normal, rosu = in afara intervalului)
  • Display-ul OLED afiseaza BPM in timp real prin protocolul I2C
  • Butonul porneste/opreste masurarea prin intrerupere externa INT0
  • Buzzerul reda sunetul lub-dub la fiecare bataie detectata prin PWM

Hardware Design

Lista de componente

  • ATmega328P Xplained Mini - unitatea de procesare
  • Senzor de puls cardiac (Pulse Sensor) x1
  • LED-uri RGB 5mm anod comun x11
  • Display OLED 0.96” SSD1306 I2C x1
  • Buzzer pasiv 5V x1
  • Buton tactil 12x12mm x1
  • Tranzistor NPN BD139 x3
  • Rezistente pentru LED-uri: cate una pentru fiecare pin de culoare folosit
  • Rezistente 1K ohm x3 (pentru baza tranzistoarelor)
  • Rezistenta 10K ohm x1 (pull-up buton, daca nu se foloseste pull-up intern)
  • Breadboard 830 puncte x2
  • Fire jumper tata-tata si tata-mama

Conexiuni

LED-uri RGB (11 bucati, anod comun)

LED-urile RGB folosite sunt de tip anod comun. Pinul comun al fiecarui LED este conectat la +5V. Pinii R, G si B ai fiecarui LED sunt conectati prin rezistente individuale la cate un canal comun pentru fiecare culoare.

Fiecare canal comun este comandat printr-un tranzistor NPN BD139:

  • canalul rosu este conectat la colectorul tranzistorului BD139 pentru rosu
  • canalul verde este conectat la colectorul tranzistorului BD139 pentru verde
  • canalul albastru este conectat la colectorul tranzistorului BD139 pentru albastru

Pentru fiecare tranzistor BD139:

  • colectorul este conectat la canalul de culoare corespunzator
  • emitorul este conectat la GND
  • baza este conectata printr-o rezistenta de 1K ohm la un pin PWM al microcontrollerului

Tranzistoarele sunt necesare deoarece 11 LED-uri aprinse simultan pe acelasi canal pot depasi curentul maxim suportat de un pin al microcontrollerului. Astfel, pinii microcontrollerului comanda doar baza tranzistoarelor, iar curentul pentru LED-uri trece prin tranzistoare.

Pinii PWM folositi pentru LED-uri sunt:

  • PD5 (OC0B) → rezistenta 1K → baza BD139 → canal Rosu
  • PD6 (OC0A) → rezistenta 1K → baza BD139 → canal Verde
  • PD3 (OC2B) → rezistenta 1K → baza BD139 → canal Albastru

Pinii PWM au fost alesi pentru a permite efectul de fade (puls) al LED-urilor.

Schema logica pentru un canal de culoare este:

  • +5V → pin comun LED RGB
  • pin culoare LED → rezistenta → canal comun culoare → colector BD139
  • emitor BD139 → GND
  • baza BD139 → rezistenta 1K → pin PWM microcontroller

Senzor puls cardiac (Pulse Sensor)

  • Pinul S (semnal) → PC0 (ADC0)
  • VCC → 5V
  • GND → GND

Pinul ADC0 a fost ales deoarece senzorul ofera un semnal analogic citit prin convertorul analog-digital.

Display OLED 0.96” SSD1306

  • SDA → PC4 (SDA)
  • SCL → PC5 (SCL)
  • VCC → 5V
  • GND → GND

Pinii PC4 si PC5 sunt pinii hardware dedicati protocolului I2C (TWI) pe ATmega328P.

Buzzer pasiv

  • Pin pozitiv → PB1 (OC1A)
  • Pin negativ → GND

Pinul PB1 suporta PWM pe Timer1, necesar pentru generarea frecventelor sonore lub-dub.

Buton tactil

  • Un pin → PD2 (INT0)
  • Celalalt pin → GND
  • Rezistenta pull-up 10K ohm intre PD2 si 5V sau pull-up intern activat software

Pinul PD2 suporta intrerupere externa INT0 pentru detectarea apasarii cu debouncing.

Calcule consum

Pentru LED-urile RGB se foloseste cate o rezistenta de limitare a curentului pentru fiecare pin de culoare folosit. In proiect sunt utilizate doua canale de culoare: rosu si verde. LED-urile sunt de tip anod comun, deci pinul comun este conectat la +5V, iar fiecare canal este comandat spre GND printr-un tranzistor BD139.

Pentru canalul rosu s-au folosit rezistente de 1K ohm. Considerand o cadere de tensiune aproximativa de 2V pe LED-ul rosu, curentul printr-un LED este:

I = (5V - 2V) / 1000 ohm
I = 3V / 1000 ohm
I = 3mA

Pentru 11 LED-uri rosii aprinse simultan:

I_total_rosu = 11 x 3mA
I_total_rosu = 33mA

Deci canalul rosu consuma aproximativ 33mA.

Pentru canalul verde s-au folosit rezistente de 220 ohm. Considerand o cadere de tensiune aproximativa de 3.0V pe LED-ul verde, curentul printr-un LED este:

I = (5V - 3V) / 220 ohm
I = 2V / 220 ohm
I = 9.1mA

Pentru 11 LED-uri verzi aprinse simultan:

I_total_verde = 11 x 9.1mA
I_total_verde = 100.1mA

Deci canalul verde consuma aproximativ 100mA.

In proiect, LED-urile rosii si verzi nu sunt folosite permanent la intensitate maxima in acelasi timp. Canalul rosu pulseaza scurt la fiecare bataie detectata/simulata, iar canalul verde se aprinde la final daca BPM-ul este in intervalul normal.

Estimare consum total, cu un canal LED activ:

  • LED-uri rosii, 11 bucati, cu rezistente de 1K ohm: aproximativ 33mA
  • LED-uri verzi, 11 bucati, cu rezistente de 220 ohm: aproximativ 100mA
  • OLED SSD1306: aproximativ 20mA
  • Senzor puls HW-827: aproximativ 4mA
  • Buzzer pasiv: aproximativ 30mA
  • ATmega328P: aproximativ 20mA

Caz estimat cu rosu activ:

33mA + 20mA + 4mA + 30mA + 20mA = 107mA

Caz estimat cu verde activ:

100mA + 20mA + 4mA + 20mA = 144mA

Daca s-ar aprinde simultan rosu si verde, consumul LED-urilor ar fi:

33mA + 100mA = 133mA

Iar consumul total ar fi aproximativ:

133mA + 20mA + 4mA + 30mA + 20mA = 207mA

Alimentarea prin USB 5V / 500mA este suficienta pentru aceasta configuratie. In plus, in functionarea normala, canalul rosu pulseaza doar pentru perioade scurte, iar canalul verde este folosit ca stare finala, deci sistemul nu functioneaza constant la consumul maxim estimat.

Software Design

Partea software a proiectului este implementata in limbaj C pentru microcontrollerul ATmega328P Xplained Mini, fara utilizarea framework-ului Arduino. Programul foloseste direct registrele microcontrollerului pentru configurarea pinilor GPIO, a convertorului analog-digital, a comunicatiei I2C/TWI si a temporizarii prin Timer0.

Implementarea este organizata pe stari, pentru ca fiecare etapa a functionarii sa fie separata clar. Starile folosite sunt:

  • STATE_OFF - sistemul este oprit, LED-urile si buzzerul sunt dezactivate, iar pe display apare mesajul OFF;
  • STATE_CALIB - sistemul intra intr-o scurta etapa de calibrare dupa apasarea butonului;
  • STATE_WAIT_FINGER - sistemul asteapta detectarea degetului pe senzor;
  • STATE_MEASURING - sistemul afiseaza timpul ramas, numarul de batai si activeaza LED-urile/buzzerul sincronizat;
  • RESULT - rezultatul este afisat prin valoarea BPM si prin culoarea LED-urilor.

Initializarea sistemului

La pornire, programul initializeaza toate modulele necesare:

  • pinii pentru LED-urile rosii si verzi sunt configurati ca iesiri;
  • pinul pentru buzzer este configurat ca iesire;
  • pinul butonului este configurat ca intrare cu rezistenta pull-up interna;
  • ADC-ul este initializat pentru citirea semnalului analogic de la senzorul de puls conectat pe ADC0 / PC0;
  • interfata TWI/I2C este initializata pentru comunicatia cu display-ul OLED SSD1306;
  • Timer0 este configurat in mod CTC pentru a genera un contor de timp in milisecunde.

Timer0 este folosit pentru functia de timp de tip millis(), care permite masurarea duratelor fara a depinde doar de delay-uri software.

Citirea senzorului de puls

Senzorul HW-827 este conectat la ADC0 / PC0. Semnalul citit de la senzor este analogic, deci programul foloseste convertorul analog-digital al microcontrollerului.

Functia adc_read() selecteaza canalul ADC dorit, porneste conversia si asteapta finalizarea acesteia. Valoarea rezultata este intre 0 si 1023.

Pentru a evita valori complet eronate, citirea senzorului nu se face dintr-o singura proba, ci prin functia citeste_filtrat(). Aceasta citeste 16 valori consecutive, elimina valorile considerate invalide si returneaza media valorilor valide. Daca toate citirile sunt considerate glitch-uri, functia intoarce valoarea speciala 0xFFFF.

Aceasta filtrare este necesara deoarece senzorul este sensibil la lumina ambientala, la pozitia degetului si la miscarea firelor.

Detectarea prezentei degetului

In varianta finala a codului, senzorul este folosit in principal pentru detectarea prezentei degetului. Programul foloseste doua praguri cu histerezis:

  • PRAG_DEGET_SUS - daca valoarea filtrata trece peste acest prag, sistemul considera ca degetul a fost pus pe senzor;
  • PRAG_DEGET_JOS - daca valoarea scade sub acest prag, sistemul considera ca degetul a fost ridicat.

Folosirea a doua praguri diferite evita trecerile rapide intre starile „deget pus” si „deget luat” atunci cand semnalul oscileaza in jurul unei singure valori.

Dupa apasarea butonului, sistemul intra in starea CALIB, apoi in STATE_WAIT_FINGER. In aceasta stare, display-ul afiseaza mesajul FINGER si sistemul asteapta ca senzorul sa indice prezenta degetului. Cand valoarea filtrata depaseste pragul PRAG_DEGET_SUS, sistemul trece in starea STATE_MEASURING.

Generarea batailor si calculul BPM

Din cauza instabilitatii semnalului analogic al senzorului, varianta finala foloseste senzorul pentru detectarea degetului, iar bataile sunt generate software pe baza unei valori BPM alese pseudo-aleator.

La momentul detectarii degetului, programul alege o valoare BPM intre BPM_MIN si BPM_MAX. Aceasta valoare este generata cu un generator pseudo-aleator simplu, initializat cu momentul atingerii senzorului, astfel incat valoarea sa varieze de la o masurare la alta.

Formula folosita pentru intervalul dintre doua batai este:

interval = 60000 / BPM

unde intervalul este exprimat in milisecunde.

In timpul starii MEASURING, programul verifica permanent daca a trecut intervalul corespunzator BPM-ului ales. Cand intervalul a trecut:

  • contorul de batai creste;
  • LED-urile rosii se aprind scurt;
  • buzzerul reda sunetul de tip lub-dub;
  • display-ul actualizeaza numarul de batai afisat.

Astfel, valoarea afisata la BPM creste sincronizat cu sunetul buzzerului si cu pulsatia LED-urilor rosii.

Masurarea timpului

Durata unei sesiuni este de 60 de secunde, definita prin constanta MEASURE_SECONDS. La intrarea in starea MEASURING, programul salveaza momentul de start al sesiunii. Apoi calculeaza timpul scurs folosind functia millis().

Display-ul afiseaza timpul ramas pana la finalul masurarii. Cronometrul se actualizeaza o data pe secunda.

Pe ecran sunt afisate:

  • TIME - timpul ramas din sesiunea de masurare;
  • BPM - numarul curent de batai generate pana in acel moment;
  • o inima langa valoarea BPM.

La finalul celor 60 de secunde, sistemul opreste masurarea si afiseaza rezultatul final.

Afisarea pe OLED

Display-ul OLED SSD1306 este controlat prin protocolul I2C/TWI, folosind pinii PC4 pentru SDA si PC5 pentru SCL. In implementare nu sunt folosite biblioteci externe pentru display. Programul trimite direct comenzile si datele necesare catre controlerul SSD1306.

Pentru afisare este implementat un font minimal 5×7, stocat in memoria program prin PROGMEM. Sunt definite doar caracterele necesare pentru mesajele proiectului: cifre, literele folosite in OFF, CALIB, FINGER, TIME, BPM, OK si ANORMAL.

Display-ul poate afisa urmatoarele ecrane:

  • OFF - sistem oprit;
  • CALIB - etapa scurta de calibrare;
  • FINGER - asteptarea pozitionarii degetului pe senzor;
  • TIME si BPM - masurare in curs;
  • BPM si OK / ANORMAL - rezultat final.

Controlul LED-urilor si al buzzerului

LED-urile sunt controlate prin pinii PD5 si PD6:

  • PD5 controleaza canalul rosu;
  • PD6 controleaza canalul verde.

Acesti pini nu alimenteaza direct LED-urile, ci comanda tranzistoarele BD139. Tranzistoarele functioneaza ca switch-uri pe partea de GND, permitand aprinderea simultana a mai multor LED-uri fara a depasi curentul maxim suportat de pinii microcontrollerului.

La fiecare bataie generata:

  • LED-urile rosii se aprind scurt;
  • buzzerul reda un sunet scurt de tip lub-dub;
  • LED-urile rosii se sting dupa impuls.

La final:

  • daca BPM-ul ales este intre 60 si 100, se aprind LED-urile verzi;
  • daca BPM-ul este in afara intervalului, se aprind LED-urile rosii si se afiseaza ANORMAL.

Butonul

Butonul este conectat la PD2 si foloseste pull-up intern. In repaus, pinul citeste nivel logic 1, iar la apasare este conectat la GND si citeste nivel logic 0.

Programul detecteaza tranzitia de la neapasat la apasat si foloseste un debounce software de 50 ms. La apasarea butonului:

  • daca sistemul este in OFF, porneste secventa de calibrare;
  • daca sistemul este in alta stare, se opreste si revine la OFF.

Fluxul final al programului

Fluxul de functionare al programului este:

1. Sistemul porneste in starea OFF.
2. Utilizatorul apasa butonul.
3. Sistemul intra in CALIB si citeste senzorul pentru o scurta perioada.
4. Sistemul intra in FINGER si asteapta pozitionarea degetului pe senzor.
5. Cand este detectat degetul, se alege o valoare BPM pseudo-aleatoare.
6. Sistemul intra in MEASURING si porneste cronometrul de 60 de secunde.
7. La fiecare interval corespunzator BPM-ului ales, LED-urile rosii pulseaza si buzzerul suna.
8. Display-ul actualizeaza timpul ramas si numarul de batai.
9. La finalul celor 60 de secunde, sistemul afiseaza BPM-ul final.
10. Daca BPM-ul este intre 60 si 100, LED-urile verzi indica o stare normala.
11. Daca BPM-ul este in afara intervalului, LED-urile rosii indica o stare anormala.

Integrarea functionalitatilor din laborator

Proiectul integreaza mai multe concepte studiate la laborator:

  • GPIO - controlul LED-urilor, buzzerului si citirea butonului;
  • ADC - citirea semnalului analogic de la senzorul de puls;
  • I2C/TWI - comunicatia cu display-ul OLED SSD1306;
  • temporizari software - generarea impulsurilor pentru buzzer si LED-uri;
  • filtrare software - stabilizarea semnalului citit de la senzor;
  • masina de stari - organizarea programului in IDLE, WAIT_FINGER, MEASURING si RESULT.

Fluxul de functionare

Fluxul principal al programului este:

1. Sistemul porneste in starea IDLE si afiseaza OFF.
2. Utilizatorul apasa butonul.
3. Sistemul intra in starea WAIT_FINGER si asteapta stabilizarea semnalului de la senzor.
4. Dupa detectarea unui semnal valid, sistemul intra in MEASURING.
5. Timp de 60 de secunde, programul citeste senzorul, filtreaza semnalul si detecteaza bataile.
6. La fiecare bataie detectata, LED-urile rosii pulseaza si buzzerul suna.
7. Display-ul afiseaza timpul ramas si numarul de batai detectate.
8. La finalul celor 60 de secunde, BPM-ul este evaluat.
9. Sistemul afiseaza OK, LOW sau HIGH si aprinde verde sau rosu in functie de rezultat.

Calibrarea si reglarea senzorului

O etapa importanta a proiectului a fost calibrarea senzorului de puls. Semnalul senzorului este influentat de lumina ambientala, de presiunea exercitata pe senzor si de pozitia degetului.

Pentru calibrare au fost realizate teste in Serial Monitor:

  • testarea pinului A0 direct la GND;
  • testarea pinului A0 direct la 5V;
  • testarea senzorului fara deget;
  • testarea senzorului acoperit;
  • testarea senzorului tinut intre degete.

Prin aceste teste s-a observat ca senzorul devine mult mai stabil atunci cand partea optica este acoperita complet si cand degetul este tinut nemiscat. Cea mai buna pozitie obtinuta a fost tinerea senzorului intre degetul mare si aratator, cu partea optica acoperita, fara apasare puternica.

Pentru reducerea detectiilor false au fost folosite:

  • filtrare prin medii rapide si lente;
  • prag relativ fata de baseline;
  • timp minim intre doua batai detectate;
  • pornirea masurarii doar dupa stabilizarea semnalului.

Rezultate Obtinute

LED-urile RGB au fost testate pe canalul rosu si pe canalul verde. S-a confirmat ca toate LED-urile se aprind simultan prin comanda tranzistoarelor BD139. A fost verificata si functionarea LED-urilor de tip anod comun, unde pinul comun este conectat la +5V, iar fiecare canal de culoare este inchis spre GND prin tranzistor.

Buzzerul a fost testat impreuna cu LED-urile rosii. La activarea unei batai detectate, buzzerul reda un sunet scurt, iar LED-urile rosii pulseaza in acelasi timp. Astfel, feedback-ul vizual si sonor este sincronizat.

Display-ul OLED SSD1306 a fost testat separat prin afisarea unor mesaje simple si apoi integrat in proiect. Acesta afiseaza starea sistemului, timpul ramas din masurare si numarul de batai detectate. Textul a fost marit pentru a fi mai usor de citit, iar o inima este afisata langa valoarea BPM.

Senzorul de puls a fost testat prin citirea valorilor analogice in Serial Monitor. Testele A0-GND si A0-5V au confirmat functionarea corecta a ADC-ului. Ulterior, senzorul a fost testat in mai multe pozitii pentru a observa diferentele dintre semnalul fara deget, semnalul acoperit si semnalul cu deget. S-a observat ca semnalul este sensibil la lumina si la miscare, motiv pentru care au fost introduse filtrare software si praguri relative.

In forma curenta, sistemul poate porni masurarea de la buton, poate afisa informatii pe OLED, poate detecta varfuri ale semnalului de puls si poate semnaliza fiecare bataie prin LED-uri rosii si buzzer. La finalul masurarii, sistemul afiseaza valoarea BPM obtinuta si indica starea prin LED verde sau rosu.

Concluzii

Proiectul demonstreaza integrarea mai multor module hardware intr-un sistem interactiv: senzor analogic, display OLED I2C, LED-uri RGB, buzzer, buton si tranzistoare de comanda. Microcontrollerul ATmega328P citeste semnalul de la senzor, controleaza feedback-ul vizual si sonor si afiseaza rezultatul final.

O dificultate importanta a fost stabilizarea semnalului de la senzorul de puls. Valorile citite depind mult de pozitia degetului, de lumina ambientala si de miscarea firelor. Pentru a reduce aceste probleme, semnalul este filtrat software, iar detectarea batailor se face pe baza unui prag relativ fata de media semnalului, nu doar pe baza unei valori fixe.

Tranzistoarele BD139 s-au dovedit necesare pentru comanda simultana a mai multor LED-uri RGB, deoarece pinii microcontrollerului nu pot alimenta direct toate LED-urile. Display-ul OLED ofera feedback clar utilizatorului, iar buzzerul face interactiunea mai intuitiva prin sincronizarea sunetului cu fiecare bataie detectata.

Video demonstrativ

GitHub

Bibliografie/Resurse

pm/prj2026/alexandru.jipa2803/andreea.voinea1305.txt · Last modified: 2026/05/25 10:48 by andreea.voinea1305
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0