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, Întreruperi, 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 VS Code cu extensia PlatformIO, 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 din cauza overhead-ului instrucțiunilor AVR-GCC în buclă, care făcea ca fiecare iterație să dureze în realitate mai mult de 1µs, distorsionând calculul distanței.
Soluția implementată: Calibrarea empirică a factorului de conversie la valoarea fixă / 36.
factor = 36; uint16_t dist = duration / factor; return dist;
Factorul /36 a fost determinat prin măsurători experimentale succesive la distanțe cunoscute cu o ruletă reală. Această abordare oferă o precizie excelentă (eroare de maximum ±1 cm) în intervalul stabil de operare hardware, cuprins între 0 și 60 cm.
În urma testării pe plaje mai lungi, s-a observat că la distanțe ce depășesc 60-70 cm, din cauza unghiului de dispersie (conului acustic) al senzorului HC-SR04 și a comportamentului semnalului primit, încep să apară ecouri false (reflexii din podea sau masă). Din acest motiv, s-a preferat păstrarea unei funcții matematice curate și liniare, optimizată special pentru distanțe scurte și medii (specifice utilizării de zi cu zi), în detrimentul unor corecții software artificiale care ar fi mascat o instabilitate de natură strict fizică/acustică a senzorului.
_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.Videoclipuri demonstrative:
În urma implementării și calibrării componentelor, s-a realizat un dispozitiv portabil, compact și complet funcțional, care îndeplinește cu succes specificațiile inițiale ale ambelor moduri de funcționare:
Realizarea acestui proiect a reprezentat o oportunitate excelentă de a aprofunda programarea sistemelor embedded la nivel de registru, fără utilizarea unor biblioteci abstracte (third-party), oferind un control direct și total asupra resurselor microcontrolerului ATmega328P.
Implementarea manuală a protocolului I2C (modulul TWI hardware) pentru partajarea bus-ului între ecranul LCD și giroscop a evidențiat avantajele flexibilității protocoalelor seriale industriale. De asemenea, lucrul în paralel cu două timere hardware distincte (Timer1 pentru generarea frecvenței PWM a sunetului și Timer2 pentru întreruperile de durată) a demonstrat importanța sincronizării non-blocante în aplicații în timp real.
Deși senzorul ultrasonic HC-SR04 a prezentat limitări fizice clare cauzate de conul mare de reflexie acustică la distanțe de peste 60 cm în condiții de alimentare portabilă, calibrarea riguroasă a codului a demonstrat cum constrângerile de natură fizică pot fi gestionate corect printr-o abordare software inteligentă. În final, proiectul și-a atins toate obiectivele, transformându-se dintr-o rețea complexă de fire într-un instrument de măsură fiabil și util pentru scenarii practice.
Codul sursa complet este disponibil pe GitHub:
Structura proiectului este cea mentionata mai sus.