This is an old revision of the document!
Proiectul constă în realizarea unui instrument de măsură 2-în-1, portabil, bazat pe un microcontroller ATmega328P standalone. Dispozitivul combină funcționalitatea unei rulete digitale (măsurarea distanței fără contact) cu cea a unei nivele electronice (boloboc digital pentru determinarea gradului de înclinare), oferind date în timp real pe un afișaj LCD și feedback sonor.
Sistemul obține date de la două module senzoriale:
- Senzorul Ultrasonic HC-SR04 - folosit pentru a măsura timpul de zbor al sunetului și a calcula distanța până la un obstacol.
- Senzorul Inerțial MPU-6050 - un modul cu accelerometru și giroscop care comunică prin protocolul I2C, folosit pentru a calcula unghiul de înclinare pe axele X și Y.
Utilizatorul primește informațiile vizual, pe un ecran LCD text 16×2, și auditiv, printr-un buzzer pasiv. Sistemul sonor este dinamic: emite bip-uri a căror frecvență se modifică pe măsură ce dispozitivul se apropie de unghiul de 0 grade (orizontala perfectă), transformându-se într-un ton continuu la nivelare optimă.
Ideea a pornit de la necesitatea de a avea o unealtă de măsură multifuncțională pentru proiecte de bricolaj (DIY), demonstrând totodată capacitatea de a prelucra date brute de la senzori diferiți și de a le transforma în mărimi fizice reale (centimetri și grade).
Laboratoare folosite: GPIO, Timere, PWM, I2C.
1. Flux de funcționare - Modul Ruletă:
ATmega328P trimite un impuls scurt (10µs) pe pinul Trig al HC-SR04.
Senzorul emite un tren de impulsuri ultrasonice și ridică pinul Echo.
Microcontrollerul măsoară lățimea impulsului Echo folosind un Timer/Întrerupere.
Distanța este calculată și actualizată pe ecranul LCD.
2. Flux de funcționare - Modul Nivelă:
Microcontrollerul interoghează constant senzorul MPU-6050 prin magistrala I2C.
Datele brute de accelerație pe axele X, Y, Z sunt preluate și trecute printr-o funcție trigonometrică (atan2) pentru a afla unghiul de înclinare.
Valoarea este afișată pe rândul doi al LCD-ului.
Modulul PWM controlează buzzer-ul pasiv: dacă unghiul este 0°, buzzer-ul emite un semnal continuu; altfel, generează pulsuri cu pauze proporționale cu unghiul de înclinare.
| Componenta | Link | Descriere |
|---|---|---|
| Placă dezvoltare ATmega328P-XMINI | - | Microcontroller principal |
| Senzor ultrasonic HC-SR04+ | din kit Plusivo | Măsurare distanță (funcția ruletă) |
| Modul MPU-6050 (Giroscop/Accel) | Magazin | Măsurare înclinare (funcția nivelă) pe I2C |
| Display LCD 16×2 cu modul I2C | Magazin | Afișaj interfață utilizator |
| Buzzer Pasiv | din kit Plusivo | Feedback sonor dinamic prin semnal PWM |
| 2x Butoane tactile | din kit Plusivo | Schimbare mod afișare și măsurare în mod ruletă |
| Sursă alimentare breadboard HW-131 | din kit Plusivo | Coboară tensiunea bateriei la 5V constanți |
| Baterie 9V + Mufă DC | din kit Plusivo | Alimentare sistem portabil |
| Breadboard 830 puncte + fire | din kit Plusivo | Montaj prototipare |
| Componentă | Pin ATmega328P | Funcție |
|---|---|---|
| LCD (SDA) | PC4 | Linie de date I2C |
| LCD (SCL) | PC5 | Linie de ceas I2C |
| MPU-6050 (SDA) | PC4 | Același bus I2C (paralel cu LCD) |
| MPU-6050 (SCL) | PC5 | Același bus I2C (paralel cu LCD) |
| HC-SR04 (Trig) | PD2 | Semnal de declanșare ultrasonic |
| HC-SR04 (Echo) | PD3 | Măsurare timp de zbor |
| Buzzer | PB1 | Semnal PWM pentru ton variabil |
| Buton 1 | PD4 | Schimbare mod afișare |
| Buton 2 | PD5 | Măsurare în mod ruletă |
LCD-ul și MPU-6050 împart același bus I2C (PC4/PC5) deoarece protocolul I2C permite mai multe dispozitive pe aceleași fire, fiecare identificat printr-o adresă unică (LCD: 0x27, MPU-6050: 0x68). Buzzer-ul este conectat la PB1 deoarece acesta suportă ieșire PWM hardware prin Timer1 (OC1A), permițând generarea de tonuri fără să blocheze procesorul. Butoanele folosesc pull-up intern activat din software, deci nu necesită rezistențe externe.
La momentul actual au fost testate și confirmate funcționale următoarele componente:
Toate componentele active sunt conectate simultan și funcționează fără conflicte pe același breadboard.
Se poate observa că butoanele și display-ul funcționează. Testarea a fost făcută cu un cod simplu
care afișează un mesaj pe display când unul din butoane e observat ca fiind apăsat.
Proiectul este dezvoltat în PlatformIO cu extensia VS Code, folosind toolchain-ul AVR-GCC. Nu sunt folosite librării third-party — tot codul este implementat de la zero, direct pe registrele hardware ale ATmega328P. Această alegere a fost făcută deliberat pentru a înțelege și controla complet comportamentul hardware, fără abstracții care ar putea ascunde probleme de timing sau consum de resurse.
<avr/io.h> — definițiile registrelor hardware ale ATmega328P (TWCR, TCCR1A, PORTD etc.). Folosită în toate modulele.<avr/interrupt.h> — macrourile ISR() și sei() pentru definirea și activarea întreruperilor. Folosită în buzzer.c pentru ISR(TIMER2_COMPA_vect).<util/delay.h> — funcțiile _delay_ms() și _delay_us() pentru delay-uri precise bazate pe F_CPU. Folosită în inițializări, debounce butoane și pulsul Trig al HC-SR04.<math.h> — funcția atan2f() pentru calculul unghiului de înclinare din datele brute ale accelerometrului. Necesită flag-ul de compilare -lm în platformio.ini.<stdlib.h> — funcțiile utoa() și itoa() pentru conversia distanței și unghiului din integer în string pentru afișare pe LCD.<stdint.h> — tipurile fixe uint8_t, uint16_t, int16_t, int32_t pentru control precis al dimensiunii variabilelor pe arhitectura pe 8 biți.Toate bibliotecile folosite sunt parte din avr-libc, distribuită împreună cu toolchain-ul AVR-GCC. Nu sunt folosite librării third-party externe.
src/main.c — bucla principală, logica modurilor, gestionarea butoanelorlib/display/i2c.c — driver I2C hardware (modulul TWI al ATmega328P)lib/display/lcd.c — driver LCD HD44780 în mod 4-bit peste I2C (PCF8574)lib/hcsr04/hcsr04.c — driver senzor ultrasonic HC-SR04lib/mpu6050/mpu6050.c — driver MPU-6050 (citire accelerometru + calcul unghi)lib/buzzer/buzzer.c — driver buzzer PWM non-blocant via Timer1 + Timer2PORTD |= biți). Butoanele folosesc logică inversată: nivel LOW = apăsat. Pinul Trig al HC-SR04 (PD2) e controlat tot prin GPIO ca ieșire digitală.ISR(TIMER2_COMPA_vect)) numără milisecundele pentru durata buzzer-ului, făcându-l non-blocant.ISR(TIMER2_COMPA_vect) decrementează un contor de milisecunde și oprește buzzer-ul automat când durata expiră, fără să blocheze CPU. sei() activează întreruperile globale în main().Proiectul combină două instrumente de măsură independente într-un singur dispozitiv portabil, controlat prin același set de butoane și afișat pe același LCD. Elementul distinctiv este feedback-ul sonor adaptiv: în modul ruletă, frecvența bipului variază cu distanța măsurată; în modul nivelă, buzzer-ul emite un ton de 2000Hz când dispozitivul e la ±3° de orizontală, oferind feedback auditiv fără a privi ecranul — util în situații practice de bricolaj.
Interacțiunea dintre module urmează un flux unidirecțional clar:
main.c detectează apăsarea și comută modul sau declanșează măsurătoareahcsr04_measure_cm() trimite puls Trig (10µs) și măsoară durata Echo prin polling cu buclă calibratămpu6050_get_angle_x() citește accelerometrul prin I2C și calculează unghiul cu atan2f() din <math.h>, cu medie mobilă pe 8 citiri pentru stabilitatelcd_print() afișează rezultatul prin PCF8574 pe bus-ul I2Cbuzzer_tone() setează frecvența pe Timer1 și durata pe Timer2 prin întrerupere, returnând imediat controlul către main()
Implementarea inițială folosea o buclă polling cu _delay_us(1) pentru a măsura durata
pulsului Echo. Această abordare introducea erori sistematice semnificative: la 21cm reali,
senzorul raporta 13cm, iar la 23cm reali raporta 15cm — o eroare de ~38%.
Cauza: overhead-ul instrucțiunilor AVR-GCC în buclă făcea ca fiecare iterație să dureze ~1.45µs în loc de 1µs, distorsionând calculul distanței.
Soluția implementată: calibrare empirică cu factor ajustat și corecție liniară pentru distanțe mari:
uint16_t dist = duration / 40; if (dist > 15) dist += (dist / 15); // corectie ~6% la distante mari return dist;
Factorul /40 a fost determinat prin măsurători la distanțe cunoscute cu riglă.
Rezultat după calibrare: eroare sub 1cm între 5-15cm, sub 2cm între 15-100cm.
_delay_ms() blocant cu Timer2 + întrerupere permite CPU-ului să continue execuția în timp ce buzzer-ul sună. Fără această optimizare, un bip de 200ms ar bloca complet butoanele și LCD-ul.int32_t).lcd_clear() la fiecare iterație (care produce flickering vizibil), se suprascrie doar zona valorii cu spații, păstrând eticheta fixă pe rândul 1.Video demonstrativ — în curs de realizare
Fişierele se încarcă pe wiki folosind facilitatea Add Images or other files. Namespace-ul în care se încarcă fişierele este de tipul :pm:prj20??:c? sau :pm:prj20??:c?:nume_student (dacă este cazul). Exemplu: Dumitru Alin, 331CC → :pm:prj2009:cc:dumitru_alin.