LAKI PINGVINI<>
042017<><>

Arduino: Meteorološka merenja

Elektronska čula u akciji

U prethodnim brojevima „Sveta kompjutera” obrađivali smo ispisivanje podataka na displejima, kao i neke varijante bežičnog prenosa podataka. U pitanju su važne stvari za realizaciju praktičnih projekata, međutim, sve to malo vredi bez postojanja ulaznih uređaja koji će prikupljati informacije i slati ih na dalju obradu. Tu dolazimo do senzora, naprava koje omogućavaju očitavanje vrednosti iz realnog sveta. Tih „elektronskih čula” ima dosta, a mi ćemo za početak da se osvrnemo na senzore zadužene za prikupljanje meteoroloških podataka, tačnije, jednog njihovog dela.

DHT11

 
Reč je o jeftinom senzoru koji daje podatke o temperaturi i relativnoj vlažnosti vazduha. Zbog niske cene (modul 90,a senzor 80 centi) se vrlo često koristi u hobističkim projektima. Za dobijanje podataka o temperaturi koristi termistor (temperaturni otpornik), dok je za relativnu vlažnost zadužen kapacitivni senzor, kome se rad zasniva na merenju električnog kapaciteta, koji se menja u zavisnosti od delovanja vlažnosti vazduha na hemijski supstrat. Unutar senzora se nalaze elektrode koje formiraju oblik češlja. Važnu ulogu u funkcionisanju igra hidrofilni sloj, koji se najčešće pravi od celuloznog acetata (CA), amonijum tetrafluoroborata (NH4BF4) i polietilen glikola (PEG600), što se u kombinovanoj formi označava kao CA-NH4BF4-PEG600.. Sa donje strane nalazi se keramički supstrat, dok je na vrhu smešten zaštitni sloj. U pitanju je najjeftiniji tip senzora i glavna im je mana što su dosta osetljivi i ne naročito precizni. Računa se da im je rok upotrebe oko pet godina, pošto u međuvremenu gube preciznost usled slabljenja svojstava korišćenog hemijskog supstrata pod dejstvom toplote, UV zračenja i hemijskih uticaja.

Sa druge strane senzora nalazi se 14-pinski osmobitni mikrokontroler (nije moguće pronaći oznaku, niti tehničke podatke), čija je funkcija da prikupljene informacije obradi i pošalje do korisnika.

 
Senzor ima četiri nožice, od kojih se jedna ne koristi. U slučaju da koristimo modul, radimo sa tri pina, uz pogodnost da ne moramo koristiti dodatni otpornik. Inače, u oba slučaja razmak između nožica iznosi 2,54 milimetra, pa su senzori pogodni za smeštanje na prototipsku ploču.

Kao što vidimo iz tabele, DHT11 nije šampion preciznosti. Po specifikaciji je moguće odstupanje od stvarnih veličina u opsegu +- dva stepena Celzijusa, što nije mala vrednost. Prilikom merenja relativne vlažnosti, greška iznosi +-pet posto, što je još nekako i moguće trpeti. Može da vam zasmeta i ograničenost merenja na temperaturni opseg 0-50 stepeni Celzijusa, kao i opseg relativne vlažnosti do 85 posto. Sve vrednosti relativne vlažnosti veće od toga će biti prikazane sa greškom, pošto senzor jednostavno ne može da napravi razliku između, na primer, 85 i 100 posto.

Konstruktori se često odlučuju na njihovo kombinovanje kako bi se usrednjavanjem dobila preciznija vrednost merenja. Pa, da pogledamo jedan takav scenario.

# include <DHT_U.h>

DHT senz1(4, DHT11); // pin prvog senzora

DHT senz2(6, DHT11); // pin drugog senzora

void setup() {

Serial.begin(9600);

senz1.begin(); // aktiviramo senzore

senz2.begin();

Serial.println("Merenje temperature");

Serial.println("===================");

}

void loop() {

// ocitavanje temperature

float t1 = senz1.readTemperature();

float t2 = senz2.readTemperature();

// ocitavanje relativne vlaznosti

float rv1 = senz1.readHumidity();

float rv2 = senz2.readHumidity();

if ((isnan(t1)||isnan(rv1))||(isnan(t2)||isnan(rv2))) {

Serial.println("Nepravilno ocitavanje podataka!");

} else {

Serial.print("Temperatura: ");

Serial.print((t1+t2)/2);

Serial.print(" *C\t"); // ’\t’ je tabulator

Serial.print("Relativna vlaznost: ");

Serial.print((rv1+rv2)/2);

Serial.print(" %\t"); // znak ’%’

Serial.println(); // na novi red

delay(1000);

}

}

Prvo dodajemo unifikovanu Adafruit DHT biblioteku (goo.gl/GEVGJy), koja pravi najmanje problema u radu sa ovom vrstom senzora. U sledeće dve linije inicijalizujemo dve instance klase DHT, pod nazivima senz1 i senz2. U oba slučaja prvi prosleđeni argument predstavlja digitalni pin Arduino uređaja preko koga ćemo primati informacije od senzora. Drugi argument precizira tip korišćenog senzora. Unutar bloka Setup(), prvo inicijalizujemo serijski monitor, a zatim aktiviramo rad sa oba senzora. Najvažniji deo koda je, kao i uvek, smešten u okviru bloka Loop(), gde na početku definišemo četiri varijable tipa float, kojima odmah dodeljujemo vrednosti putem metoda readTemperature() i readHumidity(). Putem funkcije isnan (is not a number), u okviru naredbe If ispitujemo da li su očitane vrednosti validni brojevi. Ukoliko neki od njih nije, ispisujemo poruku da podaci nisu pravilno očitani. Ako je sa brojevima sve u redu, prelazi se na deo koji ispisuje podatke preko serijskog monitora. Vrednosti temperature i relativne vlažnosti se konsekventno sabiraju i dele sa dva.

DHT 22

 
Videli smo da prethodni senzor pruža dosta neprecizne podatke merenja, što u pojedinim situacijama može biti smetnja njegovoj upotrebi. Generalno, DHT11 je dobar kada je potrebno ugrubo izmeriti temperaturu i relativnu vlažnost (recimo, da li je napolju hladno, umereno toplo ili toplo, da li je vlažnost vazduha visoka, srednja ili niska) i na osnovu tih podataka preduzeti određenu akciju. Za slučajeve kada su potrebna dosta preciznija merenja, na raspolaganju nam je modul DHT22, odnosno, senzor pod nazivom AM2302, koji čini osnovu modula. Kućište senzora je vizuelno dosta slično onome kod DHT11, samo što je bele boje i što na vrhu ima maleni otvor za fiksiranje.

Kao što se to vidi iz prateće tabele, preciznost je sada mnogo bolja i seže do pola Celzijusovog stepena, dok pri merenju relativne vlažnosti varira u opsegu 2-5 posto. Opseg merenja je mnogo širi i kreće se od -40 do +80 stepeni Celzijusa (na nekoliko mesta se može naći podatak da je moguće merenje i do +125 stepeni Celzijusa, ali to nismo proveravali). Isto tako, moguće je merenje celog dijapazona relativne vlažnosti vazduha.

 
Jedan od retkih minusa ovog senzora, u odnosu na DHT11, je to da sporije očitava vrednosti, i to čini u intervalima od dve sekunde. Cene ovih uređaja (kako za modul, tako i za senzor) su oko tri puta veće od onih koje smo pominjali u vezi modula DHT11.

Za razliku od prethodnog primera, ovde ćemo koristiti senzor umesto modula. Jedina bitna razlika odnosi se na uvođenje otpornika od deset kilooma, koji povezuje napajanje sa linijom za prenos podataka.

Programski deo je skoro isti kao na modulu DHT11.

#include <DHT_U.h> // Unifikovana biblioteka

DHT senzor(3, DHT22); // treci data pin Arduina

void setup() {

Serial.begin(9600);

senzor.begin();

Serial.println("Merenje temperature");

Serial.println("===================");

}

void loop() {

float temp = senzor.readTemperature();

float rv = senzor.readHumidity();

if (isnan(temp) || isnan(rv)) {

Serial.println("Nepravilno ocitavanje podataka!");

} else {

Serial.print("Temperatura = ");

Serial.print(temp);

Serial.print(" *C ");

Serial.print("*** Rel. vlaznost = ");

Serial.print(rv);

Serial.println("%");

delay(2000); // pauza 2 sekunde

}

}

Često se dešava da ovi senzori nakon priključivanja daju neprecizne podatke, pa je u pojedinim situacijama potrebno da prođe desetak minuta kako bi počeli da dobijaju stvarne vrednosti.

Još jedna napomena koja se odnosi na module DHT11 i DHT22 – prilikom korišćenja napona od 3,3 volta, potrebno je koristiti što kraći kabl za napajanje. Specifikacija govori da je maksimalna dužina za DHT22 100 centimetara, dok je kod DHT11 do 25 centimetara. Pri napajanju od pet volti kod DHT11 žice mogu da budu dugačke do 30 metara, a kod DHT22 i do 100 metara.

LM35 / TMP35

Ovaj temperaturni senzor najčešće dolazi u kućištu TO-92 tipa, koje je karakteristično za tranzistore (postoji i SOIC i još neke TO-xx varijante), pa zbog toga neodoljivo podseća na njih. Za razliku od prethodnih, namenjen je isključivo merenju temperature. Reč je o uređaju koji vraća analogne vrednosti proporcionalne temperaturi u Celzijusima. Radi u širokom opsegu temperatura, a hermetičko kućište u kome se nalazi ga dobro štiti od atmosferskih uticaja. Preciznost mu se, u zavisnosti od temperature, kreće u opsegu ±0,25-0,7 stepeni Celzijusa. U tabeli vidimo da senzor podržava zavidan temperaturni opseg od -55 do 150 stepeni, ali u praksi se najčešće ograničavamo na raspon od 0 do 110 stepeni Celzijusa, pošto merenje u negativnom opsegu umnogome komplikuje posao, mada nije nemoguće.

 
Za pisanje skeča koji koristi LM35 nam nisu potrebne nikakve dodatne biblioteke. Jedan prost primer upotrebe bi mogao izgledati ovako:

void setup()

{

Serial.begin(9600);

pinMode(A0, INPUT); //A0 ima funkciju analognog ulaza

analogReference(INTERNAL); // ref. napon je 1,1 V

}

void loop()

{

float tem = (analogRead(0) / 9.31);

Serial.print("Trenutna temperatura = ");

Serial.print(tem);

Serial.print("*C");

Serial.println();

delay(1000);

}

Koncentrišemo se samo na stvari koje nismo obrađivali do sada. Naredba pinMode(A0, INPUT) govori Arduinu da će analogni pin A0 imati funkciju ulaza. U stvari, i bez ove naredbe pin A0 inicijalno ima funkciju analognog ulaza, ali je preciziranje takvih stvari u kodu dobra praksa, pošto se mogu izbeći naknadne zabune. Potom, dolazimo do zanimljive funkcije analogReference(INTERNAL). Njen zadatak je da postavi napon koji se koristi kao referenca za očitavanje analognog ulaza pomoću komande analogRead(). Može imati sledeće vrednosti:

Iz prošlih brojeva znamo da Arduinov ADC (analogno-digitalni konverter) ima rezoluciju od deset bita (210), što je ekvivalentno decimalnoj vrednosti 1024. Tačnije, analogni ulaz može imati neku vrednost od 0 do 1023. To opet znači da je svaka od 1024 vrednosti analognog ulaza pri naponu od 5 volti jednaka koraku od 0,004883 Volti, tj. 4,883 milivolti (5 V / 1024).

Postavljanjem vrednosti INTERNAL govorimo Arduinu (Uno) da koristi napon od 1,1 volt kao vrednost za 1023, a ostale vrednosti se dobijaju proporcionalnim deljenjem opsega. Na taj način ga prilagođavamo vrednostima koje dobijamo od senzora LM35 i koje se kreću u rasponu 0-1000 milivolti. Deljenjem 1100 na 1024 dela, dobijamo vrednost 1.07421 milivolta. Pošto je deset milivolti ekvivalentno jednom stepenu Celzijusa, deljenjem deset sa 1.07421 dobijamo 9,3091, što je približno 9,31.

Prva naredba u bloku Loop() dodeljuje promenljivoj tem količnik jedne od 1024 ADC vrednosti i pomenutog broja 9,31. U slučaju da je vrednost ulaza analognog pina 0 jednaka nuli, temperatura će biti nula. U slučaju da ADC daje vrednost 100, temperatura će biti 10,74 stepena Celzijusa, dok će pri maksimalnoj vrednosti 1023 iznositi 109.88 stepeni Celzijusa.

Dodatno je moguće unaprediti preciznost uvođenjem For..Next petlje koja, recimo, u roku od deset sekundi deset puta očitava vrednosti temperatura i zatim zbir tih vrednosti deli sa deset i dobija se temperatura filtrirana od eventualnog šuma.

Imajte u vidu da nakon promene referentnog napona nekoliko narednih očitavanja ulaza analognog porta daje netačne rezultate.

BME280 i BMP280

Bosch je velika firma sa velikim proizvodnim asortimanom, u kome se našlo mesta i za elektronske senzore. Ovde obrađujemo dva slična modela pod nazivima BME280 i BMP280. Osnovna razlika je u tome što BME („E” znači „environmental”) meri atmosferski pritisak, temperaturu i relativnu vlažnost vazduha, dok BMP („P” znači „pressure”) ne može meriti relativnu vlažnost. I još da napomenemo, dodatni plus ovog senzora je što omogućuje posredno računanje nadmorske visine preko atmosferskog pritiska.

BMP280 je znatno unapređena verzija svog prethodnika pod nazivom BMP180 i donosi velika poboljšanja po pitanju opsega merenja, brzine očitavanja, preciznosti, veće rezolucije, smanjenja šuma i manje potrošnje struje. Ceo sistem je spakovan u sićušni čip dimenzija 2x2,5 milimetara i namenjen je prvenstveno ugradnji u mobilne uređaje kao što su telefoni, GPS navigatori, pametni časovnici ili fitnes narukvice.

Postoji priličan broj modula koji su dizajnirani na sličan, ali ipak različit način. Recimo, modul pod nazivom BME/BMP280 ima na sebi samo četiri pina i omogućuje povezivanje putem I2C interfejsa. Veoma su popularni (ali i višestruko skuplji) moduli SparkFun BME280 i Adafruit BME280. Treba obratiti pažnju i na to da većina modula radi sa naponom od 3,3 volta, ali postoje i oni koji podržavaju pet volti. Prodaju se i moduli koji osim pomenutih funkcija pružaju i dodatne mogućnosti, kao na primer 10DOF – GY-91, koji još nudi kompas, žiroskop i akcelerometar.

Ovde ćemo obraditi jeftini (oko 1,4 evra) modul pod nazivom GY-BM E/P 280. koji na sebi ima šest rupica za pinove konektora i omogućuje povezivanje kako putem I2C, tako i preko SPI interfejsa (varijanta sa tri i četiri žice):

Za demonstraciju koristimo jednostavniji metod uz pomoć I2C interfejsa. Za to nam je potrebno da povežemo pinove SCL i SDA sa odgovarajućim pinovima na Arduinu. Oni koji su pratili prethodne nastavke znaju da se taj interfejs na modelu Arduino Uno R3 nalazi na dva mesta. Prvo mesto je na pinovima A4 i A5, dok se drugi I2C interfejs nalazi na kraju reda digitalnih pinova i nosi naziv TWI. Potrebno je da povežemo konektore na sledeći način:

SDA <--> A4, SCL <--> A5

Kod korišćenja I2C interfejsa potencijalno postoji problem vezan za adresu uređaja. Pošto sama biblioteka ne poseduje funkciju kojom bi se ta adresa promenila, potrebno je u fajlu Adafruit_BMP280.h, u liniji koda #define BMP280_ADDRESS, promeniti 0x77 na 0x76. U broju SK 12/2016, kada smo govorili o upotrebi displeja povezanih putem I2C magistrale, prikazali smo mali program koji skenira adresni prostor tog interfejsa i pronalazi adrese uređaja, koje prikazuje u heksadecimalnom obliku. Alternativno je moguće koristiti biblioteku pod nazivom cactus_io_BME280_I2C, koju možemo preuzeti sa lokacije goo.gl/x8bLiU. Osim što omogućuje zadavanje adrese I2C uređaja, ona nudi još nekoliko dodatnih funkcija.

Arduino skeč izgleda ovako:

#include "Adafruit_BMP280.h"

#include <Wire.h> //I2C biblioteka

//#include "SPI.h" //ako koristimo SPI

Adafruit_BMP280 bmp280; // koristimo I2C

void setup() {

//inicijalizujemo senzor

if (!bmp280.begin()) {

Serial.println("Uredjaj nije pronadjen");

while (1); //blokiraj rad Arduina do reseta

} // ako je u redu, aktiviramo serijski monitor

Serial.begin(9600);

}

void loop() {

float atmprit = bmp280.readPressure();//pritisak (Pa)

float tem = bmp280.readTemperature(); //temperatura

//nivo mora

float nadmvis = bmp280.readAltitude (1013.25);

// prikazivanje informacija

Serial.print(F("Atm. pritisak: "));

Serial.print(atmprit);

Serial.print(" Pa");

Serial.print("\t"); //tabulacija

Serial.print(("Temp: "));

Serial.print(tem);

Serial.print(" *C");

Serial.print("\t");

Serial.print("Nadm. Visina: ");

Serial.print(nadmvis);

Serial.println(" m");

delay(2000);

}

Opet je pred nama jednostavan kod, kojeg ne treba nešto naročito komentarisati. Senzor inicijalizujemo naredbom bmp280.begin() i istovremeno putem petlje If..Then proveravamo da li je taj proces završen uspešno. Ako nije, ispisuje se poruka o grešci. To je znak da nešto nismo povezali kako treba ili je ukazana nepravilna adresa I2C uređaja. Zanimljiva je neobična komanda while (1), koju embedded programer koristi da bi obustavio rad sistema (petlja se neprekidno vrti u krug) do pojave reset signala.

U okviru petlje loop(),koristeći pomenutu biblioteku funkcija, program poziva metode readPressure(), readTemperature() i bmp280.readAltitude() za dobijanje podataka o temperaturi, atmosferskom pritisku i nadmorskoj visini. Jedino ova poslednja stavka zaslužuje dodatno objašnjenje.

Kao što samo ime govori, vazdušni pritisak je pritisak koji ostvaruje masa vazduha na površinu zemlje. On je najveći nad površinom mora, dok pri povećanju visine opada jer se vazduh razređuje. Standardni atmosferski (vazdušni) pritisak se definiše na 101325 Paskala (N/m2), odnosno 1013,25 milibara, odnosno 760 milimetara živinog stuba (jedan milimetar živinog stuba = 133,3 Paskala).

Da bi se dobila tačna informacija o nadmorskoj visini, potrebno je poznavati podatke o takozvanom pritisku na nivou mora, koji se računa projekcijom pritiska sa neke lokacije na površinu mora. Problem je u tome što je taj podatak varijabilan i poseduju ga samo meteorološke službe. Uglavnom se saznaje putem medija. Pošto se pritisak menja sa promenom temperature i vlažnosti vazduha, menja se i taj podatak, pa odstupanja dovode do grešaka u merenju. Formula za računanje nadmorske visine preko atmosferskog pritiska izgleda ovako:

P je pritisak izmeren senzorima, dok je p0 vrednost srednjeg pritiska na nivou mora. Normalizacijom jednačine dobijamo sledeći kod:

visina = 44330 * (1 – pow((p/p0), 0.190295)

Prateća biblioteka će sama izračunati ove podatke, bez potrebe za intervencijom korisnika. Poznavanjem tačnih podataka je moguće dosta precizno odrediti na kojoj nadmorskoj visini se trenutno nalazimo.

Ako koristimo SPI interfejs, prvo treba da skinemo oznaku komentara sa odgovarajuće direktive #include i, umesto koda za inicijalizaciju I2C interfejsa, dodati sledeće:

//SPI

Adafruit_BMP280 bmp280(10, 11, 12, 13);

Već znamo da se pinovi sa navedenim brojevima digitalnih konektora odnose na hardverski SPI, tako da će shema povezivanja izgledati ovako:

Naravno, potrebno je povezati i GND sa odgovarajućim pinom na Arduinu, kao i pin Vcc sa pinom napajanja od 3,3 Volta. U slučaju da koristimo modul koji nema podršku za napon od pet Volti, biće nam još potreban i modul za bi-direkcionu translaciju napona 3,3 i pet Volti („šifter”), koji se postavlja kao most između I2C/SPI nožica modula i Arduina. Dobar izbor su šifteri bazirani na čipu TXS0108E koji koštaju oko 70 centi i nude osam kanala prenosa podataka.

Igor S. RUŽIĆ

 
Automotive Grade Linux
Abiword 3.0.2
GNOME Commander 1.4.8
FriendlyARM NanoPi M1 i S2
Arduino: Meteorološka merenja
Šta mislite o ovom tekstu?
Home / Novi brojArhiva • Opšte temeInternetTest driveTest runPD kutakCeDetekaWWW vodič • Svet igara
Svet kompjutera Copyright © 1984-2015. Politika a.d. • RedakcijaKontaktSaradnjaOglasiPretplata • Help • English
SKWeb 2.54
Opšte teme
Internet
Test Drive
Test Run
PD kutak
CeDeteka
WWW vodič
Svet igara



Naslovna stranaPrethodni brojeviOpšte informacijeKontaktOglašavanjePomoćInfo in English

Svet kompjutera