100% au considerat acest document util (2 voturi)
493 vizualizări73 pagini

Arduino

Aplicația măsoară temperatura și umiditatea relativă utilizând senzori analogici, calculează indicele de confort termic și afișează valorile pe un ecran LCD. Componentele hardware includ o placă Arduino Uno, un breadboard, un modul LCD shield, senzori de temperatură și umiditate, firuri de legătură.

Încărcat de

Dumitru George
Drepturi de autor
© © All Rights Reserved
Respectăm cu strictețe drepturile privind conținutul. Dacă suspectați că acesta este conținutul dumneavoastră, reclamați-l aici.
Formate disponibile
Descărcați ca DOCX, PDF, TXT sau citiți online pe Scribd
100% au considerat acest document util (2 voturi)
493 vizualizări73 pagini

Arduino

Aplicația măsoară temperatura și umiditatea relativă utilizând senzori analogici, calculează indicele de confort termic și afișează valorile pe un ecran LCD. Componentele hardware includ o placă Arduino Uno, un breadboard, un modul LCD shield, senzori de temperatură și umiditate, firuri de legătură.

Încărcat de

Dumitru George
Drepturi de autor
© © All Rights Reserved
Respectăm cu strictețe drepturile privind conținutul. Dacă suspectați că acesta este conținutul dumneavoastră, reclamați-l aici.
Formate disponibile
Descărcați ca DOCX, PDF, TXT sau citiți online pe Scribd

ARDUINO UNO

Descriere teoretică

Introducere

Arduino Uno R3 este o placă open-source de dezvoltare ce folosește un microcontroler


ATMEL pe 8 biți de tip ATmega328. Cu ajutorul ei se pot realiza nenumărate proiecte
electronice cu aplicații în aproape orice domeniu, beneficiind și de suport din partea unei
comunități online din ce în ce mai mare.

Caracteristicile unei plăci Arduino sunt următoarele :

- Tensiune de operare: 5 V
- Tensiune de alimentare recomandată: 7-12 V
- Port USB 2.0
- Pini intrare/ieșire digitală: 14 (dintre care 6 pot funcționa în mod
PWM)
- Pini intrare analogică: 6
- Curent de ieșire pentru un pin digital: 40 mA
- Curent de ieșire pentru pinul de 3,3 V: 50 mA
- Memorie flash (ATmega328): 32 KB (0,5KB pentru boot loader)

- Memorie SRAM (ATmega328): 2 KB


- Memorie EEPROM (ATmega328): 1 KB
- Frecvența ceasului: 16 MHz

Placa poate fi alimentată fie prin portul USB, fie dintr-o sursă externă prin conectorul de
alimentare. Poziționarea și denumirea tuturor porturilor și pinilor plăcii se pot vedea în figura
următoare.
Placa de dezvoltare Arduino Uno R3

Porturi ale plăcii de dezvoltare Arduino Uno R3

Placa Arduino poate fi extinsă prin atașarea unor module numite shield ce se pot conecta
direct la pinii externi ai plăcii (module GPS, Wi-Fi, LCD - Figura 4, touchscreen, control
motoare, etc.), aceștia putând fi accesați în continuare deoarece majoritatea modulelor shield au
extensii ale lor.
Utilizarea unui shield LCD pe o placă de tip Arduino Uno R3

Pentru realizarea montajelor electronice ce necesită componente externe (și dacă nu se


dorește utilizarea componentelor montate pe un cablaj, de exemplu în cazurile prototipurilor) se
poate folosi o placă de testare numită breadboard (Figura 5 – în partea din dreapta sunt
simbolizate legăturile electrice între pini).

Breadboard-ul și conexiunile interne

Programarea microcontrolerului se face într-un limbaj derivat din C++. Programul


necesar se numește Arduino IDE și se poate descărca de pe web-situl producătorului [3]. După
conectarea plăcii și instalarea și lansarea programului asigurați-vă că este selectată placa
Arduino și portul corespunzător (în meniul Tools, sub-meniurile Board și Port).
Interfața grafică a programului Arduino IDE

Cele mai utilizate butoane din aplicația software vor fi butonul de compilare (verificarea
de erori a programului), butonul de încărcare (încărcarea programului în microcontrolerul plăcii
Arduino) și butonul pentru Serial Monitor (afișarea datelor trimise de placă către calculator).

Butoane și meniuri ale programului Arduino IDE


LED clipitor

5.1. Realizarea montajului electronic

Figura 14. Schema de principiu pentru aplicația 2

Figura 15. Realizarea conexiunilor electrice pentru aplicația 2

Se realizează următoarele conexiuni:

- Pinul digital 8 de pe placa Arduino se conectează cu un fir la pinul IN al modulului


LED;
- Pinul GND (digital) de pe placa Arduino se conectează cu un fir la pinul GND al
modulului LED.

5.2. Schema logică și secvența de cod

Definire port led

Aprindere led

Păstrare led aprins un timp t

Stingere led

Păstrare led stins un timp t

const int led = 8;


//definirea variabilei led corespunzătoare portului digital 8 unde va fi conectat pinul IN
al modulului LED
void setup() {
pinMode(led, OUTPUT);
//se declară pinul led ca fiind de ieșire
}

void loop() {
digitalWrite(led, HIGH);
//scrie valoarea 1 logic pe pinul led (aprinde led) delay(1000);
//întârzie 1000ms (păstrează led aprins 1 secundă) digitalWrite(led, LOW);
//scrie valoarea 0 logic pe pinul led (stinge led) delay(1000);

//întârzie 1000ms (păstrează led stins 1 secundă)


}
Măsurarea parametrilor mediului
înconjurător utilizând senzori analogici

Descrierea lucrării

Obiectivele lucrării

- Crearea și testarea de circuite de complexitate medie ce utilizează senzori și


traductoare.
- Utilizarea de module electronice tip shield.
- Realizarea unei aplicații practice de măsurare a valorilor temperaturii și umidității
relative, de calcul al indicelui de confort termic și afișarea lor pe un ecran LCD.

Descriere teoretică

Introducere

Temperatura este o mărime fizică ce caracterizează starea termică a unui mediu sau a
unui corp. Cele mai utilizate scări de măsurare a temperaturii sunt scara Celsius (punctul de
îngheț al apei este 0 °C, punctul de fierbere este 100 °C) și scara Fahrenheit (punctul de îngheț al
apei este 32 °F, punctul de fierbere este 212 °F). Relația între cele două este următoarea: tC[°F] =
tF[°C] × 1,8 + 32.

Umiditatea atmosferică reprezintă cantitatea de vapori de apă din aer. Umiditatea


relativă a aerului este relația proporțională dintre umiditatea momentană la o temperatură
anume și umiditatea maximă posibilă la aceeași temperatură și se măsoară în procente. Ea nu
poate depăși 100% deoarece surplusul se elimină prin condensare. Atunci când cantitatea
vaporilor de apă este constantă, scăderea temperaturii determină creșterea valorii umidității
relative (aerul devine mai umed), iar creșterea temperaturii determină scăderea valorii
umidității relative (aerul devine mai uscat).
Descrierea aplicației

Scopul acestei aplicații este de a realiza un circuit electronic care să măsoare temperatura
și umiditatea relativă a mediului înconjurător utilizând senzori analogici, să realizeze calculul
indicelui de confort termic și să le afișeze numeric pe un ecran LCD.

Pentru măsurarea temperaturii se va folosi un traductor bazat pe un circuit integrat


specializat, de precizie, LM50. Traductorul furnizează la ieșire o tensiune analogică ce va fi
aplicată uneia din intrările analogice ale plăcii Arduino, având avantajul unei caracteristici
liniare a variației tensiunii de ieșire în raport cu temperatura. Pe baza tensiunii analogice de la
intrare placa va furniza o valoare digitală corespunzătoare, valoare ce va fi folosită pentru a
calcula și afișa temperatura măsurată.

Pentru măsurarea umidității se va folosi un senzor rezistiv SYH-2R (rezistența la bornele


acestuia variază în funcție de umiditate) împreună cu un rezistor fix, pentru a forma un divizor
rezistiv de tensiune care să furnizeze plăcii Arduino o tensiune analogică ce variază în funcție de
umiditatea măsurată. Pe baza tensiunii analogice de la intrare placa va furniza o valoare digitală
corespunzătoare, valoare ce va fi folosită pentru a determina și afișa umiditatea măsurată.

Componente hardware
Componentele și modulele electronice utilizate în cadrul lucrării sunt cele din următorul
tabel:

Componentă sau Număr


Caracteristici Imagine
modul bucăți
Arduino Uno 1
Breadboard 82x52x10 1
mm

Afișare pe 2
LCD Shield rânduri a câte 1
16 caractere

Fir de legătură Tată-Tată 8


Modul traductor
LM50 1
de temperatură

Modul traductor
SYH-2R 1
de umiditate

Observații

În această lucrare, pentru realizarea montajului electronic folosind componente externe se


va utiliza o placă de testare de tip breadboard (Figura 1 – în partea din dreapta sunt simbolizate
legăturile electrice între pini).

Breadboard-ul și conexiunile interne

Traductorul de temperatură măsoară temperatura mediului ambiant, bazându-se pe


utilizarea unui senzor de temperatură de precizie (LM50). Senzorul poate măsura temperaturi
între −40 °C și +125 °C, tensiunea de ieșire fiind proporțională cu temperatura în grade Celsius
și variind cu pași de 10 mV/°C. Având în vedere că senzorul măsoară și temperaturi negative,
fără să fie necesară o sursă de tensiune negativă, pentru temperatura de 0 °C tensiunea de la
ieșire NU este 0 V, ci are valoarea de 500 mV [2]. Pe baza variației acestei tensiuni (ideal între
0,1 și 1,75 V), aplicată unuia din porturile analogice, placa Arduino furnizează o valoare digitală
ce variază între 21 și 359 (103 pentru temperatura de 0 °C). Precizia senzorului este de ±3 °C la
temperatura camerei și de ±4 °C de-a lungul întregii game de măsurare.

Traductor de temperatură realizat cu senzorul LM50

Traductorul se va alimenta cu tensiunea VCC = 5 V.

Traductorul de umiditate măsoară umiditatea mediului ambiant, bazându-se pe utilizarea


unui senzor de umiditate rezistiv. Senzorul poate măsura umiditatea relativă între 10 % și 95 %
iar variația rezistenței de ieșire în funcție de umiditate (măsurate la temperatura de 25 °C) este
cea din Figura 4.

Traductorul de umiditate conține, pe lângă senzor, și un rezistor conectat între pinul de


ieșire al modulului (OUT) și VCC. Acesta formează, împreună cu senzorul, un divizor rezistiv de
tensiune (Figura 3).

Divizor rezistiv de tensiune


Traductor de umiditate realizat cu senzorul SYH-2R și caracteristica acestuia

Traductorul se va alimenta cu tensiunea VCC = 5 V.

Măsurarea umidității

Deoarece producătorul senzorului nu oferă o formulă de calcul pentru umiditate în funcție


de rezistența senzorului, determinarea valorii umidității măsurate se va face printr-o metodă mai
puțin precisă dar cu rezultate acceptabile pentru o lucrare de laborator demonstrativă. Metoda
constă în utilizarea unui program de calculator capabil să digitalizeze grafice aflate sub formă de
imagine (în cazul de față a fost utilizat Plot Digitizer ). Astfel, prin calibrarea inițială a axelor X
și Y, se pot citi valorile caracteristicii digitizate dând clic cu mausul pe fiecare punct în parte.

Valorile preluate din grafic se regăsesc în tabelul de mai jos, în coloanele Rezistență și
Umiditate. S-a ales afișarea umidității măsurate cu un pas de 5 % pentru simplificarea secvenței
de cod.

Shield-ul LCD permite afișarea de caractere pe un ecran cu cristale lichide, cu iluminare


LED. Acesta se montează peste placa Arduino și are conectorii de așa natură încât pinii plăcii
vor fi în continuare accesibili.

Ecranul LCD este format din 2 linii a câte 16 caractere, fiecare caracter fiind compus din
5x8 pixeli. Numerotarea coloanelor (caracterelor) se face de la 0 la 15 (de la stânga la dreapta),
iar al rândurilor de la 0 la 1 (de sus în jos).
Important! Pentru a funcționa, shield-ul utilizează pinii digitali ai plăcii Arduino de la 2
până la 7 astfel: pinul 2 – d7, pinul 3 – d6, pinul 4 – d5, pinul 5 – d4, pinul 6 – enable, pinul 7 –
rs.

Componente software

LiquidCrystal.h este biblioteca ce conține comenzile pentru shield-ul LCD.

LiquidCrystal lcd(rs, enable, d4, d5, d6, d7) creează o variabilă lcd specificându-se pinii digitali
folosiți pentru a comanda shield-ul LCD.

int variabilă = valoare stabilește o valoare pentru o variabilă de tip


întreg pe 16 biți, cu semn (de la -32.768 până la 32.767).

const are semnificația de constantă modificând comportamentul unei variabile. Variabila


va deveni de tip Read-only adică valoarea ei nu va putea fi schimbată.

float variabilă = valoare stabilește o valoare pentru o variabilă de tip real în virgulă
mobilă pe 32 de biți, cu semn (de la -3.4028235E+38 până la 3.4028235E+38). Numărul total de
digiți afișați cu precizie este 6 – 7 (include toți digiții, nu doar cei de după virgulă).

void setup() este o funcție (care nu returnează date și nu are parametri) ce rulează o
singură dată la începutul programului. Aici se stabilesc instrucțiunile generale de pregătire a
programului (setare pini, activare porturi seriale, etc.).

void loop() este principala funcție a programului (care nu returnează date și nu are
parametri) și este executată în mod continuu atâta timp cât placa funcționează și nu este resetată.

analogRead(pin) citește valoarea pinului analogic specificat.

for(inițializare, condiție, increment) {instrucțiune/ instrucțiuni } repetă un bloc de


instrucțiuni până la îndeplinirea condiției.
switch(variabilă) / case(valoare/domeniu de valori): instrucțiune / break compară valoarea
unei variabile cu valorile specificate în condițiile case și execută instrucțiunea atunci când există
o potrivire. Comanda break determină ieșirea din instrucțiunea switch.
lcd.begin(coloane, rânduri) inițializează interfața cu ecranul LCD și specifică numărul de
rânduri și de coloane al acestuia.
lcd.setCursor(coloană, rând) stabilește poziția cursorului LCD. Pentru LCD-ul folosit în
această aplicație numărul coloanelor este de la 0 la 15, iar al rândurilor de la 0 la 1.

lcd.clear() șterge ecranul LCD și poziționează cursorul în colțul din stânga sus.
lcd.print() afișează pe ecranul LCD datele (valori ale unor variabile)/textul dintre
paranteze. Pentru a afișa un text este necesar ca acesta să fie plasat între ghilimele (”text”).
Pentru a afișa valoarea unei variabile de tip char, byte, int, long, sau string se scrie numele
variabilei și, opțional, baza de numerație a acesteia (variabilă, BIN sau DEC sau OCT sau
HEX). Pentru a afișa valoarea unei variabile de tip float sau double se scrie numele variabilei iar
după virgulă, numărul de zecimale dorit a se afișa (variabilă, nr. zecimale).

delay(ms) pune în pauză programul pentru o durată de timp specificată în milisecunde.

++ este folosit pentru a incrementa o variabilă

Crearea de caractere personalizate pentru a fi afișate pe LCD

byte variabilă[nr. valori] = {valori} stabilește o valoare pentru o variabilă de tip octet,
fără semn. În această aplicație variabila definită nu are o singură valoare ci o matrice de valori,
care are rolul de a stabili ce pixeli vor fi aprinși (valoare 1) și ce pixeli vor fi stinși (valoare 0) în
compoziția unui caracter personalizat (un caracter de pe LCD este format din 5x8 pixeli).

lcd.createChar(număr, variabilă) creează un caracter personalizat căruia i se alocă un


număr între 0 și 7, având distribuția pixelilor conform variabilei.

lcd.write(număr) afișează caracterul din poziția specificată (număr).


Caracter personalizat

Măsurarea temperaturii și a umidității relative

Realizarea montajului electronic

Schema de principiu
Realizarea conexiunilor
electrice

Se realizează următoarele conexiuni:

- Pinul GND (power) de pe placa Arduino se conectează cu un fir la bara de minus a


breadboard-ului;
- Pinul 5V (power) de pe placa Arduino se conectează cu un fir la bara de plus a
breadboard-ului;
- Pinul analogic A0 de pe placa Arduino se conectează cu un fir la pinul OUT al
modulului traductor de temperatură;
- Pinul analogic A1 de pe placa Arduino se conectează cu un fir la pinul OUT al
modulului traductor de umiditate;
- Pinii GND ai traductoarelor se conectează cu un fir la bara de minus a breadboard-
ului;
- Pinii Vcc ai traductoarelor se conectează cu un fir la bara de plus
a breadboard-ului.
Schema logică și secvența de cod

DefinireLC
D

Definire variabile

Inițializare LCD

Creare caracter personalizat

Citire 500 valori digitale temperatură

Citire 500 valori digitale umiditate

Calcul valoare digitală medie temperatură

Calcul valoare digitală medie umiditate

Calcul temperatură

Calcul umiditate

Calcul ICT

Afișaretemperatură

Afișare umiditate

Afișare ICT

#include <LiquidCrystal.h>
//includerea în program a bibliotecii comenzilor pentru LCD
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);
//inițializarea bibliotecii și a variabilei lcd cu numerele pinilor utilizați de shield-ul LCD
byte grad[8] = {
//definirea variabilei grad de tip byte, ca fiind o matrice cu 8 rânduri ce au valorile din
acolade
B01000,
B10100,
B01000,
B00011,
B00100,
B00100,
B00011,
B00000
};

const int portTemperatura = 0;


//definirea variabilei portTemperatura corespunzătoare portului analogic
A0 unde va fi conectat pinul OUT al senzorului de temperatură const int
portUmiditate = 1;
//definirea variabilei portUmiditate corespunzătoare portului analogic A1 unde va fi
conectat pinul OUT al senzorului de umiditate
float temp = 0.0;
//definirea variabilei pentru temperatură
int umid = 0.0;
//definirea variabilei pentru umiditate
float val_dig_temp = 0.0;
//definirea variabilei val_dig_temp ce va avea valoarea digitală
corespunzătoare temperaturii citite
int val_dig_umid = 0.0;
//definirea variabilei val_dig_umid ce va avea valoarea digitală corespunzătoare
umidității citite
float U_temp = 0.0;
//definirea variabilei pentru tensiunea analogică furnizată de traductorul de temperatură
float ICT = 0.0;
//definirea variabilei pentru ICT (indicele de confort termic) float Vcc = 5.0;
//definirea variabilei pentru tensiunea Vcc ce va avea valoarea inițială 5V

void setup(){ lcd.begin(16, 2);


//inițializarea interfeței cu ecranul LCD și specificarea numărului de rânduri și de
coloane al acestuia
lcd.createChar(1, grad);
//crearea caracterului personalizat ce va avea conținutul matricei grad și alocarea poziției
1
}

void loop(){ for (int i=0;i<500;i++) {


val_dig_temp = val_dig_temp + analogRead(portTemperatura);
//citirea valorii digitale corespunzătoare temperaturii de 500 de ori și însumarea tuturor
valorilor
val_dig_umid = val_dig_umid + analogRead(portUmiditate); //citirea valorii digitale
corespunzătoare umidității de 500 de ori și însumarea tuturor valorilor
delay(1);
//întârziere 1 milisecundă
}
val_dig_temp = val_dig_temp/500;
//calculul valorii digitale medii a temperaturii val_dig_umid =
val_dig_umid/500;
//calculul valorii digitale medii a umidității
U_temp = (val_dig_temp * Vcc)/1023;
//calculul tensiunii analogice echivalentă valorii digitale citite – formula
(2) temp = (U_temp - 0.5)/0.01;
//calculul temperaturii – formula (3)
switch (val_dig_umid) {
//determinarea valorii umidității în funcție de valoarea digitală citită
case 0 ... 1: umid = 95; break;
case 2: umid = 90; break;
case 3 ... 4: umid = 85; break;
case 5 ... 7: umid = 80; break;
case 8 ... 11: umid = 75; break;
case 12 ... 19: umid = 70; break;
case 20 ... 32: umid = 65; break;
case 33 ... 52: umid = 60; break;
case 53 ... 92: umid = 55; break;
case 93 ... 148: umid = 50; break;
case 149 ... umid = 45; break;
261:
case 262 ... umid = 40; break;
387:
case 388 ... umid = 35; break;
559:
case 560 ... 721: umid = 30; break; case 722 ... 852:
umid = 25; break; case 853 ... 1023: umid = 20; break;
}
ICT = (temp * 1.8 + 32) - (0.55 - 0.0055 * umid)*((temp * 1.8 + 32) - 58);
//calculul Indicelui de Confort Termic – formula (1)
lcd.clear();
//ștergere conținut ecran LCD și poziționare cursor în colțul din stânga sus
lcd.print("t=");
//afișează pe ecranul LCD textul dintre ghilimele lcd.print(temp,1);
//afișează pe ecranul LCD valoarea variabilei temp, cu o zecimală după virgulă
lcd.write(1);
//afișează pe ecranul LCD caracterul personalizat având poziția 1 lcd.print(" h=");
//afișează pe ecranul LCD textul dintre ghilimele
lcd.print(umid);
//afișează pe ecranul LCD valoarea variabilei umid
lcd.print("%");
//afișează pe ecranul LCD textul dintre ghilimele lcd.setCursor(0, 1);
//mutare cursor pe coloana 1, rândul 2 lcd.print("ICT=");
//afișează pe ecranul LCD textul dintre ghilimele lcd.print(ICT,1);
//afișează pe ecranul LCD valoarea variabilei ICT, cu o zecimală după virgulă
}

Deoarece valorile reale diferă de cele teoretice, este necesară o calibrare a circuitului
electronic de măsurare realizat, prin modificări în partea de software:

Tensiunea Vcc are valoarea teoretică de 5 V. Se va măsura tensiunea reală cu ajutorul


unui voltmetru, iar valoarea măsurată se va scrie în program la declararea variabilei Vcc.

Evaluare
1. Să se modifice secvența de cod astfel încât afișarea temperaturii să se facă în grade
Fahrenheit.
2. Să se modifice programul astfel încât să se afișeze mesajele „Stare de confort” pentru
ICT ≤ 65, „Stare de alertă” pentru 65 < ICT < 80 și „stare de disconfort” pentru ICT ≥
80.
3. Să se modifice programul astfel încât să se afișeze mesajele „Cod roșu” pentru ICT ≥
80 și temperatură mai mare de 30 °C.
4. Să se modifice programul astfel încât în afară de afișarea temperaturii și umidității
instantanee să se calculeze și afișeze valorile medii ale temperaturii și umidității pentru
diferite intervale de timp (ex. 30 sec., 1 min, 12 ore, 24 ore, etc.).

Traductoarele au rolul de a converti o variație a unei mărimi fizice în semnal electric.


Astfel, la ieșirea traductorului de temperatură se va regăsi o tensiune a cărei valoare este
proporțională cu temperatura măsurată. Plaja de variație a tensiunii la ieșirea traductorului este
recomandat a fi identică cu cea a intrării analogice a plăcii de achiziție, în general, sau a plăcii
de dezvoltare Arduino, în acest caz particular. Acest lucru este important pentru a păstra
rezoluția plăcii de dezvoltare, respectiv variația minimă de tensiune sesizată de intrarea
analogică a plăcii de dezvoltare. Adaptarea plajei de variație a tensiunii de la ieșirea
traductorului la plaja de variație acceptată de către intrarea plăcii de dezvoltare se face prin
intermediul unor circuite de condiționare a semnalelor. Această adaptare este necesară numai în
cazul în care se dorește menținerea rezoluției plăcii de dezvoltare.
O rezoluție de 10 biți pentru o intrare analogică corespunde unui număr de 210 (1024 sau
1K) niveluri de tensiune diferite care pot fi sesizate de către intrarea respectivă. Pentru o variație
a tensiunii între 0 și 10 V, la o intrare analogică ce este caracterizată de o rezoluție de 10 biți, se
pot obține 1024 de niveluri distincte între 0 V și 10 V ceea ce înseamnă o variație minimă
detectabilă de 9,765 mV.

Toate aparatele și instrumentele de măsură au nevoie de o calibrare inițială și de calibrare


periodică. Această calibrare se efectuează cu ajutorul unui aparat sau instrument de măsură
etalon sau prin generarea mărimii măsurate în sistem etalon.

Afișarea informațiilor pe dispozitive LCD este limitată de rezoluția afișorului (sau de


numărul de pixeli pe unitatea de suprafață a afișorului), de memoria disponibilă, de viteza de
scriere și de alți parametri, în funcție de aplicațiile la care sunt utilizate aceste afișoare LCD.

Măsurarea parametrilor mediului

înconjurător utilizând senzori digitali


Descrierea lucrării

Obiectivele lucrării

- Crearea și testarea de circuite de complexitate medie ce utilizează senzori și


traductoare.
- Utilizarea de module electronice tip shield.
- Realizarea unei aplicații practice de măsurare a valorilor temperaturii, umidității
relative, presiunii atmosferice și afișarea lor pe un ecran LCD.

Descriere teoretică

Introducere
Temperatura este o mărime fizică ce caracterizează starea termică a unui mediu sau a
unui corp. Cele mai utilizate scări de măsurare a temperaturii sunt scara Celsius (punctul de
îngheț al apei este 0 °C, punctul de fierbere este 100 °C) și scara Fahrenheit (punctul de îngheț
al apei este 32 °F, punctul de fierbere este 212 °F). Relația între cele două este următoarea:
tC[°F] = tF[°C] × 1,8 + 32.

Umiditatea atmosferică reprezintă cantitatea de vapori de apă din aer. Umiditatea


relativă a aerului este relația proporțională dintre umiditatea momentană la o temperatură
anume și umiditatea maximă posibilă la aceeași temperatură și se măsoară în procente. Ea nu
poate depăși 100% deoarece surplusul se elimină prin condensare. Atunci când cantitatea
vaporilor de apă este constantă, scăderea temperaturii determină creșterea valorii umidității
relative (aerul devine mai umed), iar creșterea temperaturii determină scăderea valorii
umidității relative (aerul devine mai uscat).

Presiunea atmosferică reprezintă forța cu care aerul apasă pe o unitate de suprafață a


pământului. Presiunea se măsoară în Newton/metru2 sau Pascal (1 N/m2 = 1 Pa). În cazul
presiunii atmosferice, cele mai utilizate unități de măsură sunt Milibarul (1 mb = 100 Pa = 100
N/m2) și Milimetrul coloană de mercur (presiunea exercitată de o coloană de mercur cu
înălțimea de 1 mm, 1 mm Hg = 133,3 N/m2).

Descrierea aplicațiilor

Scopul acestor aplicații este de a realiza în final un circuit electronic complex care să
măsoare temperatura, umiditatea relativă și presiunea atmosferică din mediul înconjurător
utilizând senzori digitali, să realizeze calculul altitudinii și să le afișeze numeric pe un ecran
LCD.

De reținut! Pentru realizarea unei stații meteo se poate adăuga ceasul descris în Lucrarea
8 și se recomandă utilizarea unui ecran LCD mai mare.

1.Măsurarea umidității și temperaturii


Pentru măsurarea umidității se va folosi traductor (DHT22) ce conține un senzor de
umiditate de tip capacitiv dar și un senzor de temperatură, datorită necesității de compensare în
raport cu temperatura. Valorile umidității relative și a temperaturii măsurate vor fi transmise
către placa Arduino printr-o comunicație serială, folosind unul din pinii de intrare/ieșire
digitală.

2.Măsurarea presiunii atmosferice și temperaturii

Pentru măsurarea presiunii atmosferice se va folosi un traductor (BMP180) ce conține un


senzor de presiune de tip piezo-rezistiv dar și un senzor de temperatură, datorită necesității de
compensare în raport cu temperatura. Valorile presiunii atmosferice și a temperaturii măsurate
vor fi transmise către placa Arduino printr-o comunicație serială de tip I2C, folosind pinii de date
SCL și SDA disponibili pe placa Arduino.

De reținut! Comunicația serială I2C (Inter Integrated Circuit) este un tip de comunicație
multi-master, multi-slave inventată de Philips Semiconductor special pentru transmiterea de
date între circuite integrate de viteză mică și procesoare sau microcontrolere. Magistrala de
comunicație este formată din două linii, una pentru transmiterea/recepționarea datelor, SDA
(Serial Data Line) și una pentru transmiterea/recepționarea semnalului de ceas, SCL (Serial
Clock Line). Este obligatorie montarea câte unui rezistor de ridicare la 1 pe fiecare dintre cele
două linii de date, iar fiecare circuit conectat la o magistrală I2C trebuie să aibă o adresă
proprie.

2. Componente hardware
Componentele și modulele electronice utilizate în cadrul lucrării sunt cele din următorul
tabel:
Componentă sau Caracteristic Număr
Imagine
modul i bucăți
Arduino Uno 1
82x52x10
Breadboard 1
mm
Afișare pe 2
LCD Shield rânduri a câte 1
16 caractere

Fir de legătură Tată-Tată 7

Rezistor 10kΩ 1

Traductor de
DHT22 1
umiditate

Traductor de
BMP180 1
presiune

Observații

În această lucrare, pentru realizarea montajului electronic folosind componente externe


se va utiliza o placă de testare de tip breadboard (Figura 1 – în partea din dreapta sunt
simbolizate legăturile electrice între pini).

Breadboard-ul și conexiunile interne


Shield-ul LCD permite afișarea de caractere pe un ecran cu cristale lichide, cu
iluminare LED. Acesta se montează peste placa Arduino și are conectorii de așa natură încât
pinii plăcii vor fi în continuare accesibili.

Ecranul LCD este format din 2 linii a câte 16 caractere, fiecare caracter fiind compus
din 5x8 pixeli. Numerotarea coloanelor (caracterelor) se face de la 0 la 15 (de la stânga la
dreapta), iar al rândurilor de la 0 la 1 (de sus în jos).

Important! Pentru a funcționa, shield-ul utilizează pinii digitali ai plăcii Arduino de la 2


până la 7 astfel: pinul 2 – d7, pinul 3 – d6, pinul 4 – d5, pinul 5 – d4, pinul 6 – enable, pinul 7 –
rs.

Traductorul de umiditate măsoară umiditatea relativă dar și temperatura mediului


ambiant, bazându-se pe utilizarea unui senzor de precizie (DHT22) calibrat și compensat în
raport cu temperatura. Senzorul este de tip capacitiv și poate măsura umiditatea între 0-100% și
temperatura între −40 °C și +80 °C, furnizând la ieșire un semnal de date digital printr-o
conexiune serială. Precizia senzorului este de ±0,5 °C pentru temperatură și de ±2% pentru
umiditate [2]. Semnificația pinilor este prezentată în Figura 2 (NC semnifică NeConectat).

Traductor de umiditate realizat cu senzorul DHT22

Traductorul necesită utilizarea unui rezistor de 10 kΩ între pinul de date și VCC, cu rol
de rezistor de ridicare la 1 (engl. Pull up [3], vezi Figura 3). Acesta are rolul de a păstra
valoarea logică 1 la pinul de date al traductorului atunci se comută între modurile de intrare sau
ieșire, sau când nu există un semnal pe acest pin. Stabilirea unui nivel logic sigur (1 în acest
caz) împiedică apariția aleatorie a unei valori 0 sau 1 la intrarea digitală a plăcii Arduino
datorită unor eventuale zgomote electrice [4].
Utilizarea rezistorului de ridicare la 1

Traductorul se va alimenta cu tensiunea VCC = 5 V.

Măsurarea umidității și a temperaturii

Fiind vorba de un traductor digital, măsurarea și determinarea valorilor umidității și


temperaturii se face în mod automat de către acesta, iar pentru afișarea lor este necesară citirea
semnalului de date, fără a fi nevoie de alte formule de calcul. Modalitatea de citire a acestuia se
poate implementa în secvența de cod folosind instrucțiunile din foaia de catalog a traductorului
[2], aceasta necesitând însă mai mult timp și cunoștințe avansate de programare.

Există totuși o variantă mai rapidă de a obține valorile pentru umiditate și temperatură,
profitând de faptul că este un senzor foarte des utilizat, prin utilizarea în secvența de cod a unei
biblioteci dezvoltate special pentru acest tip de senzor [5], numită DHT.h (trebuie descărcate de
pe Internet două biblioteci - Adafruit_Sensor și DHT-sensor-library - și importate în Arduino
IDE folosind tab-ul Skecth -> Import Library… -> Add Library…). Avantajul îl reprezintă
implementarea în secvența de cod a numai câțiva pași:

- Stabilirea tipului de senzor.


- Stabilirea pinului digital unde este conectat pinul de date.
- Definirea senzorului.
- Inițializarea senzorului.
- Citirea valorii umidității cu comanda nume_senzor.readHumidity() și alocarea ei unei
variabile.
- Citirea valorii temperaturii cu comanda
nume_senzor.readTemperature() și alocarea ei unei variabile.
De reținut! DHT22 este un senzor ”lent”, adică nu va reacționa instantaneu la schimbări
bruște de temperatură sau umiditate, o citire a acestora putând dura până la 2 secunde sau mai
mult [2].

Traductorul de presiune măsoară presiunea atmosferică și temperatura mediului


ambiant, bazându-se pe utilizarea unui senzor de înaltă precizie și liniaritate (BMP180).
Senzorul este de tip piezo-rezistiv și poate măsura presiunea între 300-1100 mb și temperatura
între 0-65 °C, furnizând la ieșire un semnal de date digital printr-o conexiune serială de tip I2C.
Precizia absolută tipică a senzorului este de ±1 °C pentru temperatură și de ±1 mb pentru
presiune [1].

Traductorul de presiune conține și două rezistoare de 4,7 kΩ conectate între fiecare


dintre pinii de date SCL și SDA, și VCC, cu rol de rezistoare de ridicare la 1 (vezi Figura 4).
Atunci când o magistrală I2C este împărțită de mai multe module, fiecare având câte un set de
rezistoare de ridicare la 1, se va păstra un singur set, de exemplu prin eliminarea fludorului de
pe jumper-ul SJ1, încercuit cu verde în Figura 4.

Utilizarea rezistoarelor de ridicare la 1

Pinul VDDIO se utilizează numai în cazul conectării traductorului la microcontrolere


care funcționează cu tensiuni mai mici de 3,3 V.

Având în vedere că se utilizează magistrala I2C, va trebui ca în secvența de cod să fie


inclusă și biblioteca Wire.h, disponibilă deja în pachetul de biblioteci preinstalate în Arduino
IDE.

ATENȚIE! Traductorul se va alimenta cu tensiunea VCC = 3,3V.


Măsurarea presiunii atmosferice și a temperaturii

La fel ca și la traductorul de umiditate, măsurarea și determinarea valorilor presiunii


atmosferice și temperaturii se face în mod automat de către acesta, iar pentru afișarea lor este
necesară citirea semnalului de date.

Și pentru acest traductor se poate utiliza în secvența de cod o bibliotecă dezvoltată


special [6], numită SFE_BMP180.h (biblioteca trebuie descărcată de pe Internet și importată în
Arduino IDE folosind tab-ul Skecth -> Import Library… -> Add Library…).

Trebuie reținut că mai întâi se măsoară temperatura și după aceea presiunea, pentru a
putea realiza compensarea în raport cu temperatura. Măsurarea presiunii se poate face în patru
moduri (n = 0, 1, 2, 3), în funcție de acuratețea dorită, prin preluarea a 1, 2, 4, sau 8 eșantioane,
timpul de conversie variind între 4,5 și 25,5 ms.

Pașii necesari pentru obținerea valorilor presiunii și temperaturii sunt:

- Definirea senzorului.
- Inițializarea senzorului.
- Începerea măsurării temperaturii cu comanda nume_senzor.startTemperature().
- Citirea valorii temperaturii cu comanda
nume_senzor.getTemperature(variabilă_temp).
- Începerea măsurării presiunii cu comanda nume_senzor.startPressure(n).
- Citirea valorii presiunii cu comanda
nume_senzor.getPressure(variabilă_pres,variabilă_temp).

Calculul altitudinii

Altitudinea este calculată în mod automat dacă se utilizează biblioteca SFE_BMP180.h,


citirea valorii acesteia realizându-se cu comanda nume_senzor.altitude(variabilă_pres,p0).

De reținut! Pentru presiunea la nivelul mării p0 se poate utiliza valoarea standard de


1013 mb. Se recomandă totuși folosirea valorii reale, corelată cu condițiile atmosferice (valoare
cunoscută de institute meteorologice și uneori disponibilă pe Internet, vezi [7] pentru
București).
3. Componente software

Funcții, comenzi și simboluri utilizate:

LiquidCrystal.h este biblioteca ce conține comenzile pentru shield-ul LCD.

DHT.h este biblioteca ce conține comenzile pentru senzorul de umiditate.

Wire.h este biblioteca ce conține comenzile pentru magistrala I2C.

SFE_BMP180.h este biblioteca ce conține comenzile pentru senzorul de presiune.

LiquidCrystal lcd(rs, enable, d4, d5, d6, d7) creează o variabilă lcd specificându-se pinii
digitali folosiți pentru a comanda shield-ul LCD.

const are semnificația de constantă modificând comportamentul unei variabile.


Variabila va deveni de tip Read-only adică valoarea ei nu va putea fi schimbată.

int variabilă = valoare stabilește o valoare pentru o variabilă de tip întreg pe 16 biți, cu
semn (de la -32.768 până la 32.767).
float variabilă = valoare stabilește o valoare pentru o variabilă de tip real în virgulă
mobilă pe 32 de biți, cu semn (de la -3.4028235E+38 până la 3.4028235E+38). Numărul total
de digiți afișați cu precizie este 6 – 7 (include toți digiții, nu doar cei de după virgulă).

double variabilă = valoare stabilește o valoare pentru o variabilă de tip real în virgulă
mobilă cu dublă precizie față de variabila de tip float.
char variabilă = valoare stabilește o valoare pentru o variabilă de tip caracter
void setup() este o funcție (care nu returnează date și nu are parametri) ce rulează o
singură dată la începutul programului. Aici se stabilesc instrucțiunile generale de pregătire a
programului (setare pini, activare porturi seriale, etc.).

void loop() este principala funcție a programului (care nu returnează date și nu are
parametri) și este executată în mod continuu atâta timp cât placa funcționează și nu este
resetată.

if(condiție) {instrucțiune/i} else {instrucțiune/instrucțiuni} testează îndeplinirea sau nu a


unei condiții. != are semnificația diferit de.
senzor_umiditate.begin() este o funcție ce inițializează senzorul de umiditate.
senzor_umiditate.readHumidity() este o funcție ce citește și oferă valoarea umidității
măsurate.
senzor_umiditate.readTemperature() este o funcție ce citește și oferă valoarea
temperaturii măsurate.
Wire.begin() este o funcție care inițializează magistrala I2C.

senzor_presiune.begin() este o funcție ce inițializează senzorul de presiune.


senzor_presiune.startTemperature() este o funcție ce comandă începerea măsurării
temperaturii și returnează timpul necesar pentru efectuarea acestei măsurări.

senzor_presiune.getTemperature(variabilă) este o funcție ce citește de la traductor, și


oferă variabilei, valoarea temperaturii măsurate.
senzor_presiune.startPressure(n) este o funcție ce comandă începerea măsurării presiuni
și returnează timpul necesar acestei măsurări. n poate lua valori între 0 și 3, semnificând modul
de măsurare care stabilește numărul de eșantioane.

senzor_presiune.getPressure(variabilă_pres,variabilă_temp) este o funcție ce citește și


oferă variabilei valoarea presiunii măsurate, compensată cu temperatura specificată prin
variabilă_temp.

senzor_presiune.altitude(variabilă_pres,variabilă_p0) este o funcție ce citește valoarea


altitudinii calculată în funcție de cele două variabile. lcd.begin(coloane, rânduri) inițializează
interfața cu ecranul LCD și specifică numărul de rânduri și de coloane al acestuia.
lcd.setCursor(coloană, rând) stabilește poziția cursorului LCD. Pentru LCD-ul folosit în
această aplicație numărul coloanelor este de la 0 la 15, iar al rândurilor de la 0 la 1.

lcd.clear() șterge ecranul LCD și poziționează cursorul în colțul din stânga sus.
lcd.print() afișează pe ecranul LCD datele (valori ale unor variabile)/textul dintre
paranteze. Pentru a afișa un text este necesar ca acesta să fie plasat între ghilimele (”text”).
Pentru a afișa valoarea unei variabile de tip char, byte, int, long, sau string se scrie numele
variabilei și, opțional, baza de numerație a acesteia (variabilă, BIN sau DEC sau OCT sau
HEX). Pentru a afișa valoarea unei variabile de tip float sau double se scrie numele variabilei
iar după virgulă, numărul de zecimale dorit a se afișa (variabilă, nr. zecimale).
delay(ms) pune în pauză programul pentru o durată de timp specificată în milisecunde.

Crearea de caractere personalizate pentru a fi afișate pe LCD

byte variabilă[nr. valori] = {valori} stabilește o valoare pentru o variabilă de tip octet,
fără semn. În această aplicație variabila definită nu are o singură valoare ci o matrice de valori,
care are rolul de a stabili ce pixeli vor fi aprinși (valoare 1) și ce pixeli vor fi stinși (valoare 0)
în compoziția unui caracter personalizat (un caracter de pe LCD este format din 5x8 pixeli).

lcd.createChar(număr, variabilă) creează un caracter personalizat căruia i se alocă un


număr între 0 și 7, având distribuția pixelilor conform variabilei.

lcd.write(număr) afișează caracterul din poziția specificată (număr).

În cadrul acestei lucrări, caracterul personalizat va fi cel din Figura, reprezentând simbolul
pentru grad Celsius.

Caracter personalizat
Măsurarea umidității și temperaturii

Realizarea montajului electronic

Schema de principiu pentru aplicația 1

Realizarea conexiunilor electrice pentru aplicația 1


Se realizează următoarele conexiuni:

- Pinul GND (power) de pe placa Arduino se conectează cu un fir la pinul GND al


traductorului de umiditate DHT22;
- Pinul 5V (power) de pe placa Arduino se conectează cu un fir la pinul V CC al
traductorului de umiditate DHT22;
- Pinul digital 8 de pe placa Arduino se conectează cu un fir la pinul DATE al
traductorului de umiditate DHT22;
- Între pinii VCC și DATE ai traductorului de umiditate DHT22 se conectează un
rezistor, cu rol de ridicare la 1, având valoarea de 10 kΩ.

Schema logică și secvența de cod

Definire senzor

Definire variabile

Definire LCD

Inițializare senzor

Inițializare LCD

Creare caracter personalizat

Citire valoare umiditate

Citire valoare temperatură

Afișare umiditate

Afișare temperatură
#include <DHT.h>
//includerea în program a bibliotecii comenzilor pentru senzorul de umiditate
char tip_senzor = DHT22;
//definirea tipului de senzor const int pin_senzor =8;
//definirea variabilei pin_senzor corespunzătoare portului digital 8 unde va fi conectată
ieșirea de date a senzorului de umiditate
DHT senzor_umiditate(pin_senzor, tip_senzor);
//definirea senzorului de umiditate
float umid;
//definirea variabilei umiditate
float temp;
//definirea variabilei temperatură
#include <LiquidCrystal.h>
//includerea în program a bibliotecii comenzilor pentru LCD
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);
//inițializarea bibliotecii și a variabilei lcd cu numerele pinilor utilizați de shield-ul LCD
byte grad[8] = {
//definirea variabilei grad de tip byte, ca fiind o matrice cu 8 rânduri ce au valorile din
acolade
B01000,
B10100,
B01000,
B00011,
B00100,
B00100,
B00011,
B00000
};

void setup(){
senzor_umiditate.begin();
//inițializarea senzorului de umiditate
lcd.begin(16, 2);
//inițializarea interfeței cu ecranul LCD și specificarea numărului de rânduri și de
coloane al acestuia
lcd.createChar(1, grad);
//crearea caracterului personalizat ce va avea conținutul matricei grad și alocarea poziției
1
}

void loop(){
umid = senzor_umiditate.readHumidity();
//citirea valorii umidității temp =
senzor_umiditate.readTemperature();
//citirea valorii temperaturii
lcd.clear();
//ștergere conținut ecran LCD lcd.print("Umid = ");
//afișează pe ecranul LCD textul dintre ghilimele lcd.print(umid,1);
//afișează pe ecranul LCD valoarea variabilei umid, cu o zecimală după virgulă
lcd.print("% ");
//afișează pe ecranul LCD textul dintre ghilimele lcd.setCursor(0, 1);
//mutare cursorul pe coloana 1, rândul 2 lcd.print("Temp = ");
//afișează pe ecranul LCD textul dintre ghilimele lcd.print(temp,1);
//afișează pe ecranul LCD valoarea variabilei temp, cu o zecimală după virgulă
lcd.write(1);
//afișează pe ecranul LCD caracterul personalizat având poziția 1 delay(1000);

//întârzie 1 secundă
}
Măsurarea presiunii atmosferice și temperaturii

Realizarea montajului electronic

Schema de principiu pentru aplicația 2

Se realizează următoarele conexiuni:

- Pinul GND (power) de pe placa Arduino se conectează cu un fir la pinul GND al


traductorului de presiune BMP180;
- Pinul 3.3V (power) de pe placa Arduino se conectează cu un fir la pinul VDD al
traductorului de presiune BMP180;
- Pinul SCL de pe placa Arduino se conectează cu un fir la pinul SCL al traductorului
de presiune BMP180;
- Pinul SDA de pe placa Arduino se conectează cu un fir la pinul SDA al traductorului
de presiune BMP180.
Realizarea conexiunilor electrice pentru aplicația 2
Schema logică și secvența de cod

Definire senzor

Definire variabile

Definire
LCD
2
Inițializare magistrală
C I

Inițializare senzor

Inițializare
LCD
Creare caracter personalizat

Începere măsurare temperatură

Citire e temperatură
valoar
Începere măsurare presiune

Citire valoare presiune

Citire valoare
altitudine

Afișare temperatură

Afișare presiune

Afișare
altitudine

#include <Wire.h>
//includerea în program a bibliotecii comenzilor pentru magistrala I2C
#include <SFE_BMP180.h>
//includerea în program a bibliotecii comenzilor pentru senzorul de presiune
SFE_BMP180 senzor_presiune;
//definirea senzorului de presiune double pres, temp, alt;
//definirea variabilelor pentru presiune, temperatură și altitudine double p0 = 1013;
//definirea variabilei p0, presiunea la nivelul mării, vezi secțiunea 2 a lucrării
#include <LiquidCrystal.h>
//includerea în program a bibliotecii comenzilor pentru LCD
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);
//inițializarea bibliotecii și a variabilei lcd cu numele pinilor utilizați de shield-ul LCD
byte grad[8] = {
//definirea variabilei grad de tip byte, ca fiind o matrice cu 8 rânduri ce au valorile din
acolade
B01000,
B10100,
B01000,
B00011,
B00100,
B00100,
B00011,
B00000
};

void setup(){
Wire.begin();
//inițializarea magistralei I2C senzor_presiune.begin();
//inițializarea senzorului de presiune
lcd.begin(16, 2);
//inițializarea interfeței cu ecranul LCD și specificarea numărului de rânduri și de
coloane al acestuia
lcd.createChar(1, grad);
//crearea caracterului personalizat ce va avea conținutul matricei grad și alocarea poziției
1
}

void loop(){
int status;
//se definește variabila status de tip întreg status =
senzor_presiune.startTemperature();
//începerea măsurării temperaturii, funcția returnând timpul necesar if (status !=
0) {
//dacă timpul necesar măsurării este diferit de zero delay(status);
//se așteaptă timpul respectiv senzor_presiune.getTemperature(temp);
//se alocă variabilei temp valoarea temperaturii măsurate
}
status = senzor_presiune.startPressure(3);
//începerea măsurării presiunii (se specifică numărul de eșantioane dorit), funcția
returnând timpul necesar
if (status != 0) {
//dacă timpul necesar măsurării este diferit de zero delay(status);
//se așteaptă timpul respectiv senzor_presiune.getPressure(pres,temp);
//se alocă variabilei pres valoarea presiunii măsurate, compensată cu temperatura temp
}
alt = senzor_presiune.altitude(pres,p0);
//se alocă variabilei alt valoarea altitudinii calculate în funcție de presiunea măsurată și
de p0
lcd.clear();
//ștergere conținut ecran LCD lcd.print(temp,1);
//afișează pe ecranul LCD valoarea variabilei temp, cu o zecimală după virgulă
lcd.write(1);
//afișează pe ecranul LCD caracterul personalizat având poziția 1 lcd.print(" ");

//afișează pe ecranul LCD textul dintre ghilimele lcd.print(pres,1);


//afișează pe ecranul LCD valoarea variabilei pres, cu o zecimală după virgulă
lcd.print("mb");
//afișează pe ecranul LCD textul dintre ghilimele lcd.setCursor(0, 1);
//mutare cursorul pe coloana 1, rândul 2 lcd.print("Alt=");
//afișează pe ecranul LCD textul dintre ghilimele
lcd.print(alt,1);
//afișează pe ecranul LCD valoarea variabilei alt, cu o zecimală după virgulă
lcd.print("m");
//afișează pe ecranul LCD textul dintre ghilimele
delay(1000);
//întârzie 1 secundă
}

Măsurarea distanței și a proximității


Descrierea lucrării

Obiectivele lucrării

- Crearea și testarea de circuite de complexitate medie ce utilizează senzori și


traductoare.
- Utilizarea de module electronice tip shield.
- Realizarea unei aplicații practice de măsurare a distanței sau a proximității față de un
obiect.

Descriere teoretică

Introducere

Ultrasunetele sunt unde sonore având frecvența mai mare decât limita superioară a
domeniului de sensibilitate a urechii umane (20 Hz … 20 KHz), adică mai mare de 20kHz.
Măsurarea distanței cu ajutorul ultrasunetelor presupune generarea unor valuri de unde sonore
de către un emițător. Prezența unui obstacol în calea undelor duce la reflectarea acestora către
senzor (Figura 1).
Măsurarea distanței cu ajutorul ultrasunetelor

Traductorul folosit pentru emiterea și recepționarea undelor ultrasonice măsoară durata


de timp scursă de la emiterea până la recepția unei unde sonore, durată ce este proporțională cu
distanța până la obstacol.

Cei mai utilizați senzori pentru astfel de dispozitive sunt cei bazați pe efectul
piezoelectric:

- Efectul direct: aplicarea unei vibrații (unde sonore) pe suprafața unui material
piezoceramic are ca efect apariția unei tensiuni electrice pe aceasta.
- Efectul invers: aplicarea unei tensiuni electrice pe suprafața unui material
piezoceramic are ca efect dilatarea sau contractarea acestuia, ducând la emisia unor
unde sonore.

Modul de construcție al unui astfel de dispozitiv este ilustrat în Figura următoare.

Structura unui senzor ultrasonic

Elementul piezoelectric este format dintr-o placă de metal și o placă piezoceramică, iar
pâlnia are dublu rol, de a radia eficient undele generate de elementul piezoelectric și de a
concentra undele recepționate către partea centrală a acestuia.
Obiectele realizate din sticlă, metal, lemn, hârtie, beton, etc. reflectă aproape în totalitate
undele ultrasonice, făcând ușoară detectarea lor, pe când materialele absorbante precum textile,
lână, etc. fac mai dificilă detectarea. De asemenea, mai greu de detectat sunt și obiectele cu
forme neregulate, undele fiind reflectate în alte direcții și nu spre senzor [1].

O altă problemă a măsurării distanțelor cu ajutorul ultrasunetelor este atenuarea puterii


undelor proporțional cu distanța parcursă de acestea și în funcție de frecvența undelor
ultrasonice (cu cât frecvența este mai mare, cu atât undele sunt atenuate mai rapid).

Utilizarea undelor infraroșii pentru a măsura distanțe se bazează pe același procedeu,


emiterea unei unde luminoase și măsurarea timpului până când aceasta ajunge înapoi la
traductor datorită reflectării de către un obstacol.

Traductorul este format din două componente, un LED care emite lumină în spectrul
infraroșu și o fotodiodă care recepționează undele reflectate (Figura 3). Pentru a evita
interferențele cu alte surse de lumină externe, semnalul luminos emis de către LED este
modulat.

Măsurarea distanțelor cu ajutorul undelor infraroșii

La fel ca și în cazul măsurării distanțelor cu ultrasunete, și măsurarea cu ajutorul undelor


infraroșii este afectată atenuarea puterii undelor în funcție de distanța parcursă de acestea și de
proprietățile reflectante ale obstacolelor detectate (obiectele deschise la culoare reflectă lumina
mai mult decât cele închise la culoare).
Avantaje și dezavantaje:

- Traductoarele ce utilizează unde infraroșii permit măsurarea de distanțe mici (spre


deosebire de cele ce utilizează unde ultrasonice, care nu pot măsura distanțe sub
anumită valoare minimă), dar au precizie mai mică.
- Traductoarele ce utilizează unde infraroșii au preț mai mic decât cele ce utilizează
unde ultrasonice.
- Traductoarele ce utilizează unde infraroșii au timpi de răspuns
mai mici decât cele ce utilizează unde ultrasonice.

Descrierea aplicațiilor

Scopul acestor aplicații este de a realiza circuite electronice care să măsoare


distanța/proximitatea până la un obstacol prin diferite metode și să o afișeze numeric pe un ecran
LCD.

Măsurarea distanței utilizând un traductor cu unde ultrasonice

Pentru măsurarea distanței cu ajutorul ultrasunetelor se va folosi un traductor (LV-


MaxSonar-EZ0) bazat pe un senzor de tip piezoceramic. Traductorul furnizează la ieșire mai
multe tipuri de semnale, dintre care vor fi utilizate doar două, unul de tip PWM și unul analogic.

Semnalul digital de ieșire, de tip PWM, va fi aplicat uneia din intrările digitale ale plăcii
Arduino. Pe baza factorului de umplere al acestuia se va calcula și afișa valoarea măsurată a
distanței.

Semnalul analogic de ieșire va fi aplicat uneia din intrările analogice ale plăcii Arduino.
Pe baza tensiunii analogice de la intrare placa va furniza o valoare digitală corespunzătoare,
valoare ce va fi folosită pentru a calcula și afișa distanța măsurată.
Componente hardware

Componentele și modulele electronice utilizate în cadrul lucrării sunt cele din următorul
tabel:

Componentă sau Număr


Caracteristici Imagine
modul bucăți
Arduino Uno 1
Breadboard 82x52x10 1
mm

Afișare pe 2
LCD Shield rânduri a câte 1
16 caractere

Fir de legătură Tată-Tată 10

Traductor
LV-
ultrasonic de 1
MaxSonarEZ0
distanță

Traductor de
proximitate și VCNL-4000 1
ambient

Observații

În această lucrare, pentru realizarea montajului electronic folosind componente externe


se va utiliza o placă de testare de tip breadboard.
Breadboard-ul și conexiunile interne

Traductorul ultrasonic de distanță măsoară distanța până la obiectele aflate în fața


acestuia folosind unde ultrasonice cu frecvența de 42 kHz, fiind bazat pe un senzor de tipul LV-
MaxSonar-EZ0. Senzorul poate măsura distanțe între 0 și 6,45 m (254 inch), cu o rezoluție de
2,54 cm (1 inch). Deși senzorul poate detecta obiecte între 0 și 15 cm (6 inch), datorită unor
constrângeri de natură fizică distanța nu poate fi măsurată cu exactitate iar indicația senzorului
pentru toată această plajă de valori va fi de 15 cm [2].

Traductor ultrasonic de distanță realizat cu senzorul LV-MaxSonarEZ0


Traductorul dispune de trei tipuri de ieșiri de date:

- O ieșire de tip PWM (Pulse-Width Modulation, pinul PW) ce presupune variația


controlată a formei tensiunii de ieșire prin schimbări rapide ale valorii logice din 1 în
0, în funcție de un factor de umplere (durata de timp cât semnalul are valoarea 1
logic). Distanța poate fi calculată ținând cont că factorul de umplere variază cu 147
µs/inch.
- O ieșire analogică (pinul AN) a cărei tensiune variază cu V CC/512 per inch, adică 9,8
mV/inch dacă traductorul este alimentat cu o tensiune de 5 V.
- O ieșire serială (pinul TX) ce furnizează date în mod asincron în formatul RS232.

Ceilalți pini au următoarele roluri:

- Pinul BW activează ieșirea serială TX dacă i se aplică 0 logic sau dacă este
neconectat. Dacă i se aplică 1 logic pinul TX trimite un puls în loc de date seriale (util
pentru înserierea mai multor traductoare atunci când senzorii sunt prea apropiați și pot
apărea interferențe).
- Pinul RX este folosit pentru a comanda o măsurare a distanței, dacă i se aplică 1 logic
sau dacă este neconectat. Dacă i se aplică 0 logic, traductorul va opri măsurarea.

Traductorul măsoară distanța începând de la partea din față a senzorului, așa cum este
reprezentat în Figura 6.

Măsurarea distanței cu traductorul LV-MaxSonar-EZ0

Traductorul se va alimenta cu tensiunea VCC = 5 V.


Traductorul de proximitate măsoară proximitatea până la obstacolele din apropierea
acestuia, până la maxim 200 mm cu o rezoluție de 16 biți, fiind bazat pe un senzor de tipul
VCNL4000 [3]. Datele de ieșire sunt puse la dispoziție printr-o magistrală de tip I2C.

Traductorul nu poate fi utilizat pentru măsurarea exactă a distanței datorită faptului că


citirea acesteia nu este liniară, precum și din cauza reflectării diferite a undelor de către obiecte
de culori diferite aflate la aceeași distanță de senzor. Astfel, traductorul poate fi utilizat numai
pentru a determina gradul de apropiere sau depărtare a unui obiect față de acesta.

Lungimea de undă a luminii emise are o valoare de vârf de 890 nm, iar pentru modulația
acesteia se poate alege între patru valori ale frecvenței purtătoarei: 390,625 kHz, 781,25 kHz,
1,5625 MHz sau 3,125 MHz.

Curentul prin dioda LED poate fi stabilit la valoarea optimă prin programare între 10 mA
și 200 mA, cu pas de 10 mA, în funcție de distanța necesară a fi măsurată.

Traductor de proximitate realizat cu senzorul VCNL4000

Pini traductorului au următoarele roluri:

- Pinul IR+ este folosit pentru alimentarea diodei LED, fiind necesară o tensiune de 5
V.
- Pinii SDA și SCL sunt utilizați pentru conectarea la magistrala I2C.
- Pinul GND este folosit pentru legătura la masă.
- Pinului 3.3 este utilizat pentru alimentarea traductorului, fiind
necesară o tensiune de 3,3 V.

În ceea ce privește necesitatea utilizării rezistoarelor de ridicare la 1 pe fiecare dintre cele două
linii de date, dacă se utilizează un singur dispozitiv pe magistrală atunci nu sunt necesare
rezistoare externe, cele incluse (și activate automat) în microcontrolerul de pe placa Arduino
fiind suficiente.

Atenție! Traductorul se va alimenta cu tensiunea VCC = 3,3 V.

Componente software

LiquidCrystal.h este biblioteca ce conține comenzile pentru shield-ul LCD.

Wire.h este biblioteca ce conține comenzile pentru magistrala I2C.

LiquidCrystal lcd(rs, enable, d4, d5, d6, d7) creează o variabilă lcd specificându-se pinii
digitali folosiți pentru a comanda shield-ul LCD.

const are semnificația de constantă modificând comportamentul unei variabile. Variabila


va deveni de tip Read-only adică valoarea ei nu va putea fi schimbată.

int variabilă = valoare stabilește o valoare pentru o variabilă de tip întreg pe 16 biți, cu
semn (de la -32.768 până la 32.767).
unsigned int variabilă = valoare stabilește o valoare pentru o variabilă de tip întreg pe 16
biți, fără semn (de la 0 până la 65.535).
byte variabilă stabilește o variabilă de tip octet, fără semn.

float variabilă = valoare stabilește o valoare pentru o variabilă de tip real în virgulă
mobilă pe 32 de biți, cu semn (de la -3.4028235E+38 până la 3.4028235E+38). Numărul total de
digiți afișați cu precizie este 6 – 7 (include toți digiții, nu doar cei de după virgulă).

void setup() este o funcție (care nu returnează date și nu are parametri) ce rulează o
singură dată la începutul programului. Aici se stabilesc instrucțiunile generale de pregătire a
programului (setare pini, activare porturi seriale, etc.).

void loop() este principala funcție a programului (care nu returnează date și nu are
parametri) și este executată în mod continuu atâta timp cât placa funcționează și nu este resetată.

pinMode(pin, mode) configurează pinul digital specificat ca intrare


sau ca ieșire.
Wire.begin() este o funcție care inițializează magistrala I2C.

Wire.beginTransmission(adresă) este o funcție care deschide magistrala I2C în modul de


transmitere/primire de date către/de la circuitul cu adresa specificată.

Wire.endTransmission() este o funcție care încheie


transmiterea/primirea de date.

Wire.write(byte(pointer_registru)) este o funcție care stabilește registrul de unde se va


începe operația de citire de date.

Wire.requestFrom(adresă, n) este o funcție care deschide magistrala I2C în modul de


citire de date (un număr de n registre) de la circuitul cu adresa specificată.

Wire.read() este o funcție care citește datele registru cu registru și le oferă ca rezultat.

analogRead(pin) citește valoarea pinului analogic specificat.

pulseIn(pin, valoare, expirare) este o funcție ce returnează durata de timp în


microsecunde a unui impuls logic, de valoare 0 (LOW) sau de valoare 1 (HIGH), recepționat pe
un pin. Se poate stabili și un timp de expirare în microsecunde pentru a evita măsurarea
impulsurilor prea lungi.

for(inițializare, condiție, increment) {instrucțiune/ instrucțiuni }


repetă un bloc de instrucțiuni până la îndeplinirea condiției.

while(expresie) este o buclă executată în mod continuu și infinit


până când expresia devine falsă.

lcd.begin(coloane, rânduri) inițializează interfața cu ecranul LCD și


specifică numărul de rânduri și de coloane al acestuia.

lcd.setCursor(coloană, rând) stabilește poziția cursorului LCD. Pentru LCD-ul folosit în


această aplicație numărul coloanelor este de la 0 la 15, iar al rândurilor de la 0 la 1.

lcd.clear() șterge ecranul LCD și poziționează cursorul în colțul din


stânga sus.
lcd.print() afișează pe ecranul LCD datele (valori ale unor variabile)/textul dintre
paranteze. Pentru a afișa un text este necesar ca acesta să fie plasat între ghilimele (”text”).
Pentru a afișa valoarea unei variabile de tip char, byte, int, long, sau string se scrie numele
variabilei și, opțional, baza de numerație a acesteia (variabilă, BIN sau DEC sau OCT sau
HEX). Pentru a afișa valoarea unei variabile de tip float sau double se scrie numele variabilei iar
după virgulă, numărul de zecimale dorit a se afișa (variabilă, nr. zecimale).

return valoare are rolul de a termin execuția unei funcții și de a


returna o valoare.

delay(ms) pune în pauză programul pentru o durată de timp specificată în milisecunde.

variabilă << n este un operator care mută biții variabilei cu un număr


de n poziții spre stânga.

++ este folosit pentru a incrementa o variabilă

& este operatorul ȘI logic.

| este operatorul SAU logic.

/ este operatorul de împărțire care, în cazul împărțirii a două numere întregi, oferă
rezultatul fără rest.

! este operatorul boolean NU (negație).


Măsurarea distanței utilizând un traductor cu unde ultrasonice

Realizarea montajului electronic

Schema de principiu pentru aplicația 1


Realizarea conexiunilor electrice pentru aplicația 1

Se realizează următoarele conexiuni:

- Pinul GND (power) de pe placa Arduino se conectează cu un fir la pinul GND al


traductorului ultrasonic;
- Pinul 5V (power) de pe placa Arduino se conectează cu un fir la pinul +5 al
traductorului ultrasonic;
- Pinul analogic A0 de pe placa Arduino se conectează cu un fir la pinul AN al
traductorului ultrasonic;
- Pinul digital 9 de pe placa Arduino se conectează cu un fir la
pinul PW al traductorului ultrasonic.
Schema logică și secvența de cod

DefinireLC
D

Definire variabile

Inițializare LCD

Inițializare pin digital

Citire semnal PW

Citire semnal AN

Alegere valoare mediană PW)


(

Calcul valoare distanță măsurată (PW)

Alegere valoare mediană (AN)

Calcul valoare distanță măsurată (AN)

Afișare distanță (PW)

Afișare distanță (AN)

Definire funcțiefiltru median

//Autor al programului de bază: Bruce Allen, 23.07.2009


#include <LiquidCrystal.h>
//includerea în program a bibliotecii comenzilor pentru LCD
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);
//inițializarea bibliotecii și a variabilei lcd cu numerele pinilor utilizați de shield-ul
LCD const int pwPin = 9;
//definirea variabilei pwPin corespunzătoare portului digital 9 unde va fi conectată
ieșirea PW a traductorului
const int anPin = 0;
//definirea variabilei anPin corespunzătoare portului analogic A0 unde va fi conectată
ieșirea AN a traductorului
unsigned int durata_impuls, val_inch;
//definirea variabilelor pentru durata unui puls și pentru valoarea distanței în inch
float distanta_an, distanta_pw;
//definirea variabilelor pentru distanțele calculate
int dim_matrice = 5;
//definirea variabilei ce stabilește numărul de elemente al unei matrice
int element_median;
//definirea variabilei elementului median al unei matrice
int valoare_pw[] = {0, 0, 0, 0, 0};
//definirea unei matrice cu 5 elemente pentru valorile transmise prin semnal digital
int valoare_an[] = {0, 0, 0, 0, 0};
//definirea unei matrice cu 5 elemente pentru valorile transmise prin semnal analogic

void setup() { lcd.begin(16, 2);


//inițializarea interfeței cu ecranul LCD și specificarea numărului de rânduri și de
coloane al acestuia
pinMode(pwPin, INPUT);
//se declară pinul pwPin ca fiind de intrare element_median =
dim_matrice/2;
//calculul valorii poziției elementului median al matricei
}

void loop() {
//Citirea semnalelor de date
for(int i = 0; i < dim_matrice; i++) {
//buclă cu ajutorul căreia se populează cu valori cele două matrice valoare_pw[i] =
pulseIn(pwPin, HIGH);
//citirea valorii unui puls și stocarea ei ca element al matricei valoare_pw
valoare_an[i] = analogRead(anPin);
//citirea valorii digitale a semnalului analogic și stocarea ei ca element al matricei
valoare_an
delay(10);
}

//Calculul distanței utilizând semnalul digital sortare(valoare_pw,


dim_matrice);
//se sortează valorile consecutive ale matricei ce conține duratele
pulsurilor recepționate de la traductor
durata_impuls = valoare_pw[element_median];
//se extrage din matrice valoarea corespunzătoare elementului median distanta_pw =
((durata_impuls/147)*2.54)/100;
//se calculează distanța măsurată în metri, în funcție de valoarea mediană a duratei unui
puls – formula (2)

//Calculul distanței utilizând semnalul analogic


sortare(valoare_an, dim_matrice);
//se sortează valorile consecutive ale matricei ce conține valorile digitale ale semnalului
recepționat de la traductor
val_inch = valoare_an[element_median]/2;
//se extrage din matrice valoarea corespunzătoare elementului median și
se împarte la 2 pentru a obține distanța măsurată în inch – formula (3)
distanta_an = (val_inch*2.54)/100;
//se calculează distanța măsurată în metri – formula (4)

//Afișarea valorilor distanțelor măsurate


lcd.clear();
//ștergere conținut ecran LCD lcd.print("Dist_pw = ");
//afișează pe ecranul LCD textul dintre ghilimele lcd.print(distanta_pw,3);
//afișează pe ecranul LCD valoarea variabilei distanta_pw, cu 3 zecimale după virgulă
lcd.print("m");
//afișează pe ecranul LCD textul dintre ghilimele
lcd.setCursor(0, 1);
//mutare cursor pe coloana 1, rândul 2 lcd.print("Dist_an = ");
//afișează pe ecranul LCD textul dintre ghilimele lcd.print(distanta_an,3);
//afișează pe ecranul LCD valoarea variabilei distanta_an, cu 3 zecimale după virgulă
lcd.print("m");
//afișează pe ecranul LCD textul dintre ghilimele delay(500);
}

//Filtru median creat de Bill Gentles, 12.11.2010


//Sortează elementele unei matrice în ordinea crescătoare a valorilor lor void
sortare(int *a, int n) { for (int i = 1; i < n; ++i)
{ int j = a[i];
int k; for (k = i - 1; (k >= 0) && (j < a[k]); k--)
{
a[k + 1] = a[k];
} a[k + 1] = j;
}
}

Laravel
Laravel este un framework PHP flexibil pentru web-development modern, care face
procesul de creare, intretinere si modifiare a site-urilor mai usor si rapid. Foloseste sistemul
MVC (model–view–controller).

Ca toate framework-urile PHP populare cum ar fi Symfony, Yii, Codeigniter si altele, Laravel


este un framework MVC (Model-View-Controller). Este un model de arhitectura care separa o
aplicatie in trei componente logice:

 Model - Aceasta componenta se ocupa de toata logica aplicatiei.


 View - Se ocupa de Interfata cu utilizatorul si elemente de prezentare ale aplicatiei.
 Controller - Aceasta componenta actioneaza ca o legatura intre Model si View.
Controleaza interactiunile dintre Model si View.

Structura de baza a directoarelor


Directorul app in Laravel contine componentele Models si Controllers.
"Models" sunt create direct in directorul app/, pe cand Controllers si Middlewares sunt creat in
directoarele lor respective in directorul Http.
"Views" in Laravel (template-urile rendate ca HTML) sunt create in directorul resources/views/.

Directorul resources contine fisiere pentru diferite resurse, cum ar fi: LESS si Sass, fisierele de
limba si localizare, si Template-uri care sunt rendate ca HTML.
Directorul storage contine depozitul aplicatiei (cum ar fi fisiere uploadate), depozitul
Framework-ului (in 'framework/') fisiere cache si logs.
Routing-ul pt. controllers este gestionat de fisierul web.php aflat in directorul routes.
Directorul vendor contine dependentele pt. composer.
In fisierul .env se pot adauga datele pentru conectare la o baza de date mysql (DB_DATABASE,
DB_USERNAME, DB_PASSWORD).
"locale-ul", time zone, si alte configuratii se pot seta in fisierul config/app.php.
Directorul public este documentul root al aplicatiei in browser. Contine activele pt. pagina in
browser, cum ar fi JavaScript, CSS, Imagini, etc.

- Pentru a rula aplicatia Laravel, se acceseaza in browser directorul public.

Afisarea continutului dorit

Odata ce cunoastem arhitectura Laravel si structura directoarelor si fisierelor, putem edita si crea
fisiere pentru a afisa in browser continutul pe care il vrem.
Deschide interfata Command Line (CMD in Windows), navigheaza catre directorul unde este
instalat framework-ul

Functia esentiala a oricarei aplicatii web este de a primi cereri de la utilizator si livra raspunsuri,
de obicei prin HTTP(S).
Routing este un sistem destinat sa trimita cererea catre un controller.
"Rutele" pot fi definite in fisierul "routes/web.php". Daca deschizi acest fisier cu un editor de
text veti vedea un cod ca acesta:
Route::get('/', function(){
return view('welcome');
});

Aici 'Route' este o clasa care are o metoda statica get() ce returneaza o metoda view() care
prezinta o pagina web creata in directorul 'resources/views/'.
Cand un utilizator visiteza prima pagina, va fi afisat continutul din 'welcome.blade.php' (stocat in
directorul views).
Poti trimite un alt respuns in loc de view(). De exemplu:
Route::get('/', function(){
return 'welcome';
});
Folosind metoda Route::get(), poti afisa continut pe pagina in functie de adresa URL.
Sa cream inca o ruta pentru o pagina "test".

Parametri Route

Daca adresa URI are parametri, acestia pot fi preluati in functia "callback" definita la Route.
- Exemplu: Preia si afiseaza ID-ul "paginii" adaugat in URL.

Route::get('page-{id}', function($id){
return 'Page id: '. $id;
});

Daca adaugi codul de mai sus in "routes/web.php", orice argument adaugat dupa "public/page-"
in URL va fi retinut in $id, si putem folosi acel parametru pentru procesare in continuare. Aici
doar il afisam.

Se pot folosi si parametri Route optionali, adaugand semnul "?" dupa numele parametrului:

Route::get('page{id?}', function($id ='noid'){


return 'Page id: '. $id;
});

Se pot folosi expresii Regexp pentru a executa un route doar daca un parametru indeplineste
anumite cerinte; adaugand metoda where().

Route::get('page-{name}', function($name){
return 'Page name: '. $name;
})->where('name', '[A-z-]+');

De asemenea, se pot defini mai multi parametri la un route:

Route::get('/{name}/{id?}', function($name, $id=1){


return 'Page name: '. $name .', id: '. $id;
})->where(['name'=>'[A-z-]+', 'id'=>'[0-9]+']);
Numire Rute

Laravel permite sa denumesti fiecare route cu un nume care va permite sa faci referire la acel
Route fara sa adaugi in mod explicit adresa URL. Astfel, poti da nume simple unor rute
complexe, apoi se pot crea link-uri simplu folosind direct numele definit, si de asemenea, nu e
nevoie sa rescrii link-ul paginii daca adresa URI se schimba.
- Poti defini numele route-ului folosind metoda name().

Route::name(name_id)->get('/{name}/{id?}', function($name, $id=1){


return 'Page name: '. $name .', id: '. $id;
})->where(['name'=>'[A-z-]+', 'id'=>'[0-9]+']);

Pentru a crea o adresa URL pentru acest route (numit 'name_id'), se foloseste functia route(), cu
numele si parametri necesari intr-un array.
De exemplu, intr-un fisier view poti adauga acest cod pentru a crea doua link-uri pentru route-ul
"name_id":

<?php
$url1 = route('name_id', ['name'=>'test']); //here id is not specified because it is optional
$url2 = route('name_id', ['name'=>'tutorial', 'id'=>2]);
?>
<a href='{{$url1}}' title='test'>Test</a>
<a href='{{$url2}}' title='tutorial'>Tutorial</a>

Controller e o clasa care organizeaa logica unuia sau mai multor Rute intr-un loc.
Treaba principala a unui controller este sa preia cererea HTTP si sa prelucreze datele pentru
restul aplicatiei. Astfel, se poate crea logica pentru route-urile tuturor paginilor intr-o singura
clasa.

Crearea unui Controller

Pentru a crea un controller poti folosi comanda 'artisan' in CLI. In interfata Command Line
navigheaza catre directorul cu proiectul Laravel si executa aceasta comanda:
php artisan make:controller MyController

Aceasta va crea un nou fisier numit "MyController.php" in


directorul app/Http/Controllers/ cu un cod de baza (care extinde clasa Controller de baza
inclusa cu Laravel):

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;

class MyController extends Controller {


//
}

- De asemenea, poti crea manual fisierul "MyController.php" (in


directorul app/Http/Controllers/) cu codul de mai sus.

Pentru a vedea o lista de comenzi "artisan" valabile, scrieti in interfata Command Line:

php artisan –list

Folosire Rute cu Controller

In clasa MyController putem crea metode care pot fi folosite in rute (in "web.php").

Middleware actioneaza ca un intermediar intre cerere si raspuns, asigura un mecanism pentru


filtrare cereri HTTP.
Spre exemplu Laravel include un middleware care verifica daca utilizatorul aplicatiei este
autentificat sau nu. Daca utilisatorul este autentificat, el va fi redirectionat catre homepage, altfel
va fi redirectionat catre pagina de login.

Exista cateva middleware incluse in framework-ul Laravel, inclusiv middleware pentru


autentificare si protectie CSRF. Toate aceste middleware-uri sunt localizate in
directorul app/Http/Middleware/.
Definire Middleware

Poti crea propriul middleware pentru a filtra si a prelucra cererile inainte de a returna raspunsuri.
Pentru a crea un Middleware poti folosi comanda 'artisan make:middleware' in CLI.

php artisan make:middleware MiddlewareName

- Exemplu, in interfata Command Line, navigheaza catre directorul cu proiectul Laravel si


executa aceasta comanda pentru a crea un middleware CheckAge:

php artisan make:middleware CheckAge

Aceasta va crea un nou fisier numit "CheckAge.php" in directorul app/Http/Middleware/ cu o


clasa CheckAge si o metoda handle():

namespace App\Http\Middleware;

use Closure;

class CheckAge {
//Handle an incoming request.
//@param \Illuminate\Http\Request $request
//@param \Closure $next
//@return mixed
public function handle($request, Closure $next){
if($request->age <=200) echo $request->age; //added for tests
return $next($request);
}
}

- Am adaugat linia de cod "if($request->age <=200)" pentru a o folosi pentru testare.

Metoda middleware handle() este executata inaintea controller-ului.


Inregistrare Middleware

Inainte de a folosi un middleware, trebuie sa il inregistrezi in clasa app/Http/Kernel.php.


Aceasta clasa contine trei proprietati: $middleware, $routeMiddleware, $middlewareGroups.
Exista doua tipuri de Middleware in Laravel: Global Middleware si Route Middleware.

Global Middleware

Global Middleware va rula automat la fiecare cerere HTTP a aplicatiei.


Pentru a inregistra un Global Middleware, adauga clasa la sfarsitul proprietatii $middleware,
cum e in codul de mai jos.

- Aici aveti un exemplu pentru testare.


1. Adauga clasa CheckAge in proprietatea $middleware' (in clasa app/Http/Kernel.php).

protected $middleware =[
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
\App\Http\Middleware\TrustProxies::class,
\App\Http\Middleware\CheckAge::class //-for test
];

2. Acum, acceseaza aceste adrese URL in browser:

Aceasta adresa va afisa 99; datorita: "if($request->age <=200) echo $request->age;" in


CheckAge middleware
//localhost:8000/?age=99

Acest URL nu afisaza 299; deoarece age e mai mare de 200


//localhost:8000/?age=299
Route Middleware

Route Middleware va fi alocat unui route specific.


Pentru a inregistra un Route Middleware, adauga-l in lista proprietatii $routeMiddleware, si
atribuie-i un index care doresti, ca in codul de mai jos.
De exemplu:

protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'age'=> \App\Http\Middleware\CheckAge::class //-for test
];

Dupa ce middleware-ul a fost adaugat in proprietatea $routeMiddleware, poti folosi metoda


middleware pentru a atribui middleware-ul unui route (cu indexul care a fost inregistrat):

Route::get('admin/profile', function(){
//
})->middleware('auth');

- De asemenea, poti folosi mai multe middleware-uri la un Route:

Route::get('/', function(){
//
})->middleware('auth', 'age');

Poti de asemenea folosi o clasa middleware fara a o inregistra in Kernel.php, incluzand-o cu


"use" in "routes/web.php".
Apoi, trece ClassName::class in metoda middleware() in Route:

use App\Http\Middleware\CheckAge;
Route::get('admin/profile', function(){
//
})->middleware(CheckAge::class);

Grupe de Middleware

Grupe de Middleware (Middleware Groups) se foloseste pentru a grupa mai multe middleware-


uri in acelasi nume (index).
Pentru a crea un grup de middleware, se foloseste proprietatea $middlewareGroups in
Kernel.php.
- Laravel vine cu grupurile de middleware "web" si "api" care contin middleware-uri comune pe
care ai vrea poti sa le aplici la web UI si Rutele API:

protected $middlewareGroups = [
'web' =>[
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class
],

'api' =>[
'throttle:60,1',
'bindings'
],

//for exemplification
'group_name'=>[
\App\Http\Middleware\Middleware::class,
\App\Http\Middleware\OtherMiddleware::class,
]
];

Grupul middleware 'web' este aplicat automat la fisierul routes/web.php de


catre RouteServiceProvider.

Grupele middleware pot fi folosite la Route si actiuni catre controller folosind aceasi sintaxa ca
si la middleware-uri individuale:

//assign middleware group_name to this route


Route::get('/', 'MyController@index')->middleware('group_name');

//assign group_name to a group of routes


Route::group(['middleware' => ['group_name']], function () {
//here you can add several routes
});

Parametri Middleware

Middleware poate de asemenea primi parametri aditionali. Poti adauga parametri dupa
argumentul $next in metoda middleware.
- De exemplu putem seta un parametru $role in metoda handle() a clasei middleware pe care am
creat-o.

public function handle($request, Closure $next, $role){


echo $role;
return $next($request);
}

Parametri Middleware poti fi specificati cand se defineste route-ul prin separarea numelui de
inregistrare middleware si parametrilor cu ":"
//pass 'role_value' for the first additional parameter ($role) to middleware registered with the key
'age' in $routeMiddleware (in Kernel.php) Route::name('home')->get('/', 'MyController@index')-
>middleware('age:role_value');

- Acum daca accesezi "//localhost:8000/", va arata sirul "role_value".

Middleware Terminabil

Middleware terminabil (Terminable middleware) executa anumite instructiuni dupa


ce raspunsul a fost trimis catre browse.
- Metoda handle() a clasei middleware este executata inainte de a trimite Request-ul la
controller.
Pentru a efectua anumite instructiuni dupa ce raspunul a fost trimis browser-ului, defineste o
metoda terminate() in clasa middleware.
Metoda terminate() trebuie sa primeasca argumentele $request si $response.

namespace App\Http\Middleware;

use Closure;

class CheckAge {
//Handle an incoming request.
//@param \Illuminate\Http\Request $request
//@param \Closure $next
//@return mixed
public function handle($request, Closure $next){
if($request->age <=200) echo $request->age;
return $next($request);
}

//executed after the response has been sent to browser


public function terminate($request, $response){
echo '<br>Executing statements of terminate method of CheckAge.';
}
}

- Middleware-ul terminabil trebuie inregistrat in lista


proprietatilor $middleware sau $routeMiddleware in app/Http/Kernel.php.
Metoda terminate() va fi apelata automat dupe ce raspunsul este trimis catre browser.

Pentru a obtine o instanta a HTTP accesarii curente intr-un controller, se foloseste


clasa Illuminate\Http\Request in controller si parametrul Request $request in metoda
controller-ului.
Daca metoda controller foloseste si date de la parametri Route, se adauga parametri route dupa
parametrul $request.
- De exemplu, daca un route "test" este definit asa:
Route::name('test')->get('test/{id}', 'TestController@index');
O clasa TestController intr-un fisier "TestController.php" (in
directorul app/Http/Controllers/ ) ar arata asa:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;

class TestController extends Controller {

//Responds to requests to /test


//receives the $request instane, $id from URI
//returns view() response
public function index(Request $request, $id){
return view('test');
}
}

Metode si adrese Request


Obiectul $request furnizeaza o varietate de metode pentru examinarea cererii HTTP.

 $request->fullUrl() - returneaza URL-ul intreg, incluzand sirul "query" (cu '?...').


 $request->method() - Va returna HTTP tipul de request.
 $request->path() - va returna adresa URI.
 $request->is() - permite sa verifici daca adresa accesat se potriveste cu un model dat.
Poti folosi caracterul "*" ca un wildcard: is('test/*')
 $request->isMethod() - pentru a verifica ca tipul HTTP se potriveste cu un tip dat
 $request->url() - returneaza URL-ul intreg, fara sirul query.
Bibliografie

 Arduino Uno, Senzori si traductoare, Iordache Valentin


 https://laravel.com/
Universitatea “Valahia” din Targoviste
Facultatea de Inginerie Electrică, Electronică și Tehnologia Informației
Specializarea: Automatică și infromatică aplicată

Proiect
Măsurări și traductoare

Profesor Coordonator:
Mâinea Marin
Studenți:
Tița Constantin Sebastian
Dumitru George
Oancea Ciprian
Milca Florin Leonard

S-ar putea să vă placă și