Cum se configurează smartphone-uri și PC-uri. Portal informativ
  • Acasă
  • Știri
  • Arduino citește senzorii de la primele stații meteo. Stație meteo de acasă pe Arduino și trimiterea datelor către „Monitorizarea oamenilor”

Arduino citește senzorii de la primele stații meteo. Stație meteo de acasă pe Arduino și trimiterea datelor către „Monitorizarea oamenilor”

Continuăm să ne dezvoltăm stația meteo.

Înainte de a trece la actualizare, vreau să clarific puțin.

Unul dintre colegii noștri mi-a scris întrebând de ce a fost introdus cronometrul de supraveghere?

Cronometrul de supraveghere este activat în caz de urgență. După cum arată practica, ENC28J60 nu gestionează mai mult de (cu excepția cazului în care memoria eșuează) 4 conexiuni simultane. Având în vedere câte conexiuni de serviciu apar în mod constant pentru a menține funcționarea rețelei în sine și doar a lăsat traficul creat de tot felul de jucării de uz casnic (de exemplu, televizoare moderne, scanați gazdele disponibile în rețea și porturile lor deschise) designul pur și simplu intră în stupoare. ENC28J60 nu poate funcționa independent cu protocoale de rețeași totul este implementat în biblioteci. Poate că sunt doar ei.
A verificat toate bibliotecile disponibile și module diferite(deodată căsătorie), dar pentru a realiza funcționare stabilă Nu am putut să o fac multă vreme. Termen maxim a fost cam 3-4 saptamani.
Acesta este motivul pentru care „câinele” se învârte acolo și, dacă se întâmplă ceva, trage controlerul. După aceasta problema a dispărut.
De asemenea, nu neg că este posibil în mine rețeaua de acasă există anumite nuanțe sau probleme. Dar din moment ce am avut o problemă, s-ar putea să o aibă și o altă persoană. Pana acum am gasit doar aceasta solutie.
Din câte știu, cipurile de la Wiznet (W5100 și superioare) nu au acest lucru sau pur și simplu nu arătau suficient de bine.

Să trecem la actualizare

Cel mai important, ne îndepărtăm de cip ENC28J60și du-te la W5100. Am încercat să implementez totul pe vechiul cip, dar nu există suficientă memorie pentru microcontroler din cauza bibliotecilor foarte mari pt ENC28J60. Când utilizați un cip nou, standard biblioteci de la dezvoltator și toate modificările făcute, rămân și mai multe 20% memorie libera microcontroler ATMega328. Și acestea sunt chifle noi!

În această versiune (să o numim a doua) capacitatea de a transmite citiri de la senzori prin intermediul comunicații fără fir folosind frecvența 433 MHz. Am luat modulele în sine de la chinezi, marcaje XY-MK-5V. Aș dori să remarc că calitatea transmisiei este departe de a fi perfectă. Posibilă pierdere de semnal, zgomot, incapacitate de a transmisie simultană etc. Dar prețul lor (mai puțin de 1 USD pe set) compensează aceste neajunsuri. Vă voi spune un secret pentru care aceste (cele mai ieftine) module se găsesc în multe stații meteo de marcă pentru uz casnic. Wow, neașteptat?

Să începem cu stația de bază

Ne mutam la Arduino UNO Și Scut Ethernet(prima versiune) bazată pe cip W5100. Acesta este un sandviș și nu are rost să-l descriu. Voi descrie doar contactele implicate suplimentar pentru module XY-MK-5V.

Modulul transmițător folosește energie 5V, GND(unde ar fi fără mamă) și D2 pin pe controler. Editați contactul D2 (DATE) puteți folosi funcția vw_set_tx_pin din biblioteca vw.

Spre deosebire de schița anterioară, aceasta implică două biblioteci suplimentare:

#include #include

Schița în sine

Text ascuns

#include #include #include #include #include #include #include #include #define DHTTYPE DHT22 #define DHTPIN 5 DHT dht(DHTPIN, DHTTYPE); octet mac = (0x54, 0x34, 0x31, 0x31, 0x31, 0x31); char server = "narodmon.ru"; int port = 8283; IPAddress ip(192,168,0,201); Client EthernetClient; BMP085 dps = BMP085(); lung Temperatura = 0, Presiune = 0; float H, dP, dPt; interval bool = adevărat; EasyTransferVirtualWire ET; struct SEND_DATA_STRUCTURE( byte ID; // Device ID int Temperature; // Temperature float Presiune; // Pressure float Umiditate; // Umiditate float dewPoint; // Roua/punct de îngheț ); SEND_DATA_STRUCTURE difuzat; void setup() ( // Inițializați cronometrul Watchdog wdt_disable(); delay(8000); wdt_enable(WDTO_8S); // Inițializați consola Serial.begin(9600); // Inițializați senzorul DHT dht.begin(); / / Inițializarea modulului de 433 MHz ET.begin(details(broadcast)); vw_set_ptt_inverted(vw_set_tx_pin(2); 1-Wire Wire.begin(); // Inițializarea BMP180 cu ajustarea înălțimii // dps.init (MODE_STANDARD, 3200, true // Inițializare BMP180 dps.init(Ethernet.localIP()); // Trimite primele date imediat după pornirea dispozitivului send_info(true) // dewPoint function NOAA / / reference (1) : http://wahiduddin.net/calc/density_algorithms.htm // reference (2) : http: //www.colorado.edu/geography/weather_station/Geog_site/about.htm Punct de rouă dublu (celsius dublu, umiditate dublă) ( // (1) Presiunea vaporilor de saturație = ESGG(T) RATIO dublu = 373,15 / (273,15 + celsius) ; dublu RHS = -7,90298 * (RATIO - 1); RHS += 5,02808 * log10(RATIO); RHS += -1,3816e-7 * (pow(10, (11,344 * (1 - 1/RATIO))) - 1) ; RHS += 8,1328e-3 * (pow(10, (-3,49149 * (RAPPORT - 1))) - 1) ; RHS += log10(1013,246); // factorul -3 este de a regla unitățile - Presiunea de vapori SVP * umiditate dublu VP = pow(10, RHS - 3) * umiditate; // (2) DEWPOINT = F(Presiune de vapori) dublu T = log(VP/0,61078); // retur var temp (241,88 * T) / (17,558 - T); ) void send_info(bool eth) ( bool fail = true; while(fail) ( // Încercăm să citim datele de la senzorul de umiditate DHT până când obținem // un rezultat. În 90% din cazuri totul funcționează bine, dar avem nevoie 100 % if((H = dht.readHumidity()) >= 0) ( // Obținerea umidității și temperaturii de la senzorul BMP180 dps.getPressure(&Pressure); dps.getTemperature(&Temperature); // Calculați punctul de rouă dacă temperatura exterioară este peste 0 grade Celsius // și așteptați un rezultat peste 0, altfel ieșire 0. Acest lucru este necesar // pentru a nu induce în eroare în timpul sezonului de iarnă. // dP = Temperatură>0?((dPt=punct de rouă(Temperatura*0,1, H))<0?0:dPt):0; dP = dewPoint(Temperature*0.1, H); // Отправляем данные в эфир 433 мГц broadcast.ID = 1; broadcast.Temperature = floor(Temperature*0.1); broadcast.Pressure = floor(Pressure/133.3*10)/10; broadcast.Humidity = floor(H*10)/10; broadcast.dewPoint = floor(dP*10)/10; ET.sendData(); delay(250); if(eth) { // Подключаемся к серверу "Народный мониторинг" if(client.connect(server, port)) { // Начинаем передачу данных // адрес_устройства_в_проекте, имя_устройства, GPS широта, GPS долгота client.print(F("#fe-31-31-0e-5a-3b#Arduino Uno#71.344699#27.200014\n")); // Температура client.print(F("#T0#")); client.print(Temperature*0.1); client.print(F("#Температура\n")); // Давление client.print("#P1#"); client.print(Pressure/133.3); client.print(F("#Давление\n")); // Влажность client.print("#H1#"); client.print(H); client.print(F("#Влажность\n")); // Точка росы\инея client.print("#T1#"); client.print(dP); client.print((dP <= 0)? F("#Точка инея\n"):F("#Точка росы\n")); //client.print(F("#Точка росы\n")); // Отправляем конец телеграммы client.print("##"); // Даем время отработать Ethernet модулю и разрываем соединение delay(250); client.stop(); } } // Останавливаем цикл, если передача завершена fail = !fail; break; } delay(250); } } void loop() { // Каждые 4 секунды сбрасываем сторожевой таймер микроконтроллера // Каждые 6 минут отправляем данные на "Народный мониторинг" // Каждые 30 секунд отсылаем данные в эфир 433 if(!(millis()%1000)) wdt_reset(); if(!(millis()%360000)) send_info(true); if(!(millis()%30000)) send_info(false); }

O antenă trebuie adăugată modulelor în sine. Pentru 433 MHz Un fir de cupru lung obișnuit este suficient 17 cm. Fără antenă, puteți uita de funcționarea normală.

Să trecem la cea mai importantă parte a acestei actualizări - stația locală wireless

Pentru a o implementa (pe genunchi) am folosit un analog Arduino NANO(pe bază ATMega328) Și TFT afișare pe un cip ST7735S cu permisiunea 128 x 160

Text ascuns



Afișaj pinout -> controler

============================ LED | 3.3V SCK | SCK (13) SDA | MOSI(11)A0 | DC (9) RESET | RST(8)CS | CS (10) GND | GND VCC | 5V =============================

Modulul receptor este conectat doar la fel ca un transmițător DATE pentru a fixa D7.

Câteva poze cu cum arată:

Text ascuns

Schița receptorului

Text ascuns

#include #include #include #include int x, y; int w = 128, h = 160; dimensiune int; // 433 EasyTransferVirtualWire ET; struct SEND_DATA_STRUCTURE( byte ID; // Device ID int Temperature; // Temperature float Presiune; // Pressure float Umiditate; // Umiditate float dewPoint; // Roua/punct de îngheț ); SEND_DATA_STRUCTURE difuzat; int Log_Temperature = -1; float Log_Presiunea = -1; float Log_Humidity = -1; float Log_dewPoint = -1; // TFT #define cs 10 #define dc 9 #define rst 8 char Temperatură, Presiune, Umiditate, Punct de rouă; Informații șir; TFT TFTscreen = TFT(cs, dc, rst); void setup())( Serial.begin(9600); // Inițializarea modulului de 433 MHz ET.begin(detalii(difuzare)); vw_set_ptt_inverted(true); vw_set_rx_pin(7); vw_setup(2000); vw_rx_start(); // Inițializarea și configurarea inițială a afișajului TFTscreen.begin(); TFTscreen.setRotation(2), TFTscreen.background(0, 0, 0); , 255); TFTscreen.setTextSize(1)(" ", 10, 10); „%”, w/2+5, 100; ; ) void loop())( if(ET.receiveData())( if(broadcast.ID == 1) TFTPrint(); /* Serial.println(broadcast.Temperature); Serial. println(broadcast.Pressure); Serial.println(broadcast.dewPoint); */ ) void modificări (int size, int y, bool up, bool clear = false) ( if(clear) TFTscreen.stroke(0, 0, 0); else ( modifică (dimensiune, x, y, !sus, adevărat); TFTscreen.stroke((sus)?0:255, 0, (sus)?255:0); ) if((size%2) == 0 ) dimensiune++; while(dimensiune > 0) ( TFTscreen.line(x, y, x+(size--), y); ++x, (sus)?--y:++y, --size; ) /* while( dimensiune > 0) ( TFTscreen.line(x, y, (sus)?x+size-1:x (sus)?y:y+size-1); ++x, ++y, --size; ) */ ) int x_center(int w, int lungime, int dimensiune) ( return floor((w-lungime*(dimensiune*5)+size*2)/2); ) int x_alignment_right(int w, int lungime, int dimensiune) ( return ceil(w-lungime*(dimensiune*5)+dimensiune*2); ) void TFTPrint() (dimensiune = 3; // ================= ==================================================== === =============== // Afișează valorile temperaturii // ========================== ============================================== dacă (difuzare. Temperature != Log_Temperature) ( TFTscreen.setTextSize(size); // Suprascrie datele învechite String info = String(Log_Temperature); info.concat(" C"); if(Log_Temperature > 0) info = "+"+info; info .toCharArray (Temperatura, info.length()+1); Temperatura); = Log_dewPoint) ( TFTscreen.setTextSize(size); // Suprascrie datele învechite info = String(Log_dewPoint); info.toCharArray(dewPoint, info.length()); TFTscreen.stroke(0, 0, 0); TFTscreen.text (dewPoint, x_alignment_right(w/2-5, info.length(), size), 120 // Iesire citiri noi = String(broadcast.dewPoint(info.toCharArray(dewPoint, info.length());); TFTscreen.stroke(255, 255, 255); Log_dewPoint)?true:false); else ( modificări (10, 106, 125, true, true); modificări (10, 106, 125, false, true); ) // Actualizați valorile în jurnalele ulterioare compararea citirilor Log_Temperature = difuzare.Temperatura; Log_Pressure = difuzare.Presiune; Log_Humidity = difuzare.Umiditate; Log_dewPoint = broadcast.dewPoint; )

Citirile sunt afișate destul de compact, dar așa cum arată practica (și sfaturile camarazilor mei) - „gust și culoare, nici măcar soția nu este o prietenă”. Am ascultat o mulțime de sfaturi și sugestii, dar se contrazic. Prin urmare, fă-o după gustul tău.

Mi s-a părut că designul este partea din proiect care ocupă cel mai mult timp!

Text ascuns

Unele dintre date sunt fabricate pentru a reflecta unele elemente de design.

Artefactele de pe afișaj sunt praf și alte murdărie care s-au acumulat de-a lungul timpului în care a fost afișat... undeva acolo,... ei bine, acolo, nu-mi amintesc de unde l-am luat! Lasă-mă în pace!

Schița are funcții de poziționare. Sunt destul de primitive, dar vă permit să obțineți anumite efecte.

  1. x_center
  2. x_alignment_right

Primul centrează textul, iar al doilea îl aliniază în partea dreaptă a zonei specificate. Toate calculele se fac referitor la dimensiuni textul dat, pe baza expresiei 1 dimensiune = 1PX x 1PX segment de font.

Afișajul afișează, de asemenea, elemente corespunzătoare unei creșteri sau scăderi a unei anumite valori de citire. Ele sunt afișate sub formă de triunghiuri. Dar în codul funcției schimbări Există un afișaj alternativ sub formă de triunghiuri rotite cu 45 de grade. Dacă citirile cresc, elementul este roșu, în caz contrar, albastru.

Apropo, culoarea și nuanța temperaturii principale se schimbă în funcție de temperatura în sine. O decizie destul de controversată, dar după părerea mea, confortabilă vizual. M-am luptat cu el o vreme și mi-am dat seama că valorile din funcție accident vascular cerebral, obiect Ecran TFT, sunt listate în ordine greșită. BGR loc RGB. Aceasta este o eroare a dezvoltatorului sau nu înțeleg ceva.

PS: Totul este destul de interesant, dar după părerea mea merită dezvoltare ulterioară. Asta vom face după ceva timp.

Recent, un coleg de-al meu a organizat o mică expoziție științifică.
Profesorul meu mi-a cerut să prezint un proiect de electronică studenților din facultate. Am avut două zile să vin cu ceva interesant și destul de simplu.



Deoarece condițiile meteo de aici sunt destul de schimbătoare, iar temperatura fluctuează în intervalul 30-40°C, am decis să fac o stație meteo acasă.

Care sunt funcțiile unei stații meteo de acasă?
Stație meteo pe Arduino cu afișaj - un dispozitiv care colectează date despre vreme și condiții mediu inconjurator folosind mulți senzori.

De obicei, aceștia sunt următorii senzori:

  • vânt
  • umiditate
  • ploaie
  • temperatura
  • presiune
  • înălțimi

Scopul meu este să fac o stație meteo portabilă de birou cu propriile mele mâini.

Ar trebui să poată determina următorii parametri:

  • temperatura
  • umiditate
  • presiune
  • înălţime

Pasul 1: Cumpărați componentele necesare







  • DHT22, senzor de temperatură și umiditate.
  • BMP180, senzor de presiune.
  • Lipire
  • Conector de ieșire cu un singur rând 40

Echipamentul de care veți avea nevoie:

  • Ciocan de lipit
  • Clești pentru plăcuțe
  • Fire

Pasul 2: Senzor de temperatură și umiditate DHT22







Pentru măsurarea temperaturii sunt utilizați diferiți senzori. DHT22, DHT11, SHT1x sunt populare

Voi explica cum diferă unele de altele și de ce am folosit DHT22.

Utilizează senzorul AM2302 semnal digital. Acest senzor funcționează sistem unic tehnologia de codificare și senzori, astfel încât datele sale sunt de încredere. Elementul său senzor este conectat la un computer cu un singur cip pe 8 biți.

Fiecare senzor al acestui model este compensat de temperatură și calibrat cu precizie, coeficientul de calibrare este localizat într-o memorie programabilă unică (memorie OTP). La citirea citirilor, senzorul va reaminti coeficientul din memorie.

Dimensiuni mici, consum redus de energie, distanta lunga angrenajele (100 m) permit AM2302 să se potrivească aproape tuturor aplicațiilor, iar 4 ieșiri la rând fac instalarea foarte simplă.

Să ne uităm la avantajele și dezavantajele celor trei modele de senzori.

DHT11

Pro: nu necesită lipire, cel mai ieftin dintre cele trei modele, rapid semnal stabil, rază peste 20 m, interferență puternică.
Contra: Biblioteca! Nu există opțiuni de rezoluție, eroarea de măsurare a temperaturii este de +/- 2°C, eroarea de măsurare a nivelului de umiditate relativă este de +/- 5%, intervalul inadecvat de temperaturi măsurate (0-50°C).
Domenii de aplicare: grădinărit, agricultură.

DHT22

Avantaje: nu necesită lipire, cost redus, curbe netezite, erori mici de măsurare, gamă mare de măsurare, rază mai mare de 20 m, interferență puternică.
Contra: sensibilitatea ar putea fi mai mare, urmărirea lentă a schimbărilor de temperatură, necesită o bibliotecă.
Domenii de aplicare: studii de mediu.

SHT1x

Avantaje: nu necesită lipire, curbe netede, erori mici de măsurare, răspuns rapid, consum redus de energie, mod auto somn, stabilitate ridicată și consistență a datelor.
Contra: două interfata digitala, eroare în măsurarea nivelului de umiditate, interval de temperatură măsurat 0-50°C, bibliotecă necesară.
Domenii de aplicare: operare în medii dure și în instalații pe termen lung. Toți cei trei senzori sunt relativ ieftini.

Compus

  • Vcc – 5V sau 3,3V
  • Gnd - cu Gnd
  • Date – la al doilea pin Arduino

Pasul 3: Senzor de presiune BMP180



BMP180 – senzor barometric presiune atmosferică cu interfață I2C.
Senzorii de presiune barometrică măsoară valoarea absolută a aerului ambiental. Acest indicator depinde de specific conditiile meteoși de la altitudine deasupra nivelului mării.

Modulul BMP180 avea un stabilizator de 3.3V 662kOhm, pe care eu, din propria mea prostie, l-am explodat accidental. A trebuit să direcționez sursa de alimentare direct la cip.

Din cauza lipsei unui stabilizator, sunt limitat în alegerea sursei de alimentare - o tensiune peste 3,3V va distruge senzorul.
Este posibil ca alte modele să nu aibă un stabilizator, asigurați-vă că verificați prezența acestuia.

Schema de conectare a senzorului și a magistralei I2C cu Arduino (nano sau uno)

  • SDA-A4
  • SCL - A5
  • VCC - 3,3 V
  • GND - GND

Să vorbim puțin despre presiune și relația acesteia cu temperatura și altitudinea.

Presiunea atmosferică în orice punct nu este constantă. Interacțiune complexăîntre rotația Pământului, înclinarea axei Pământului, duce la apariția multor zone de înaltă și joasă presiune, care, la rândul lor, duce la schimbări zilnice ale condițiilor meteorologice. Observând schimbările de presiune, puteți face prognoze meteo pe termen scurt.

De exemplu, o scădere a presiunii înseamnă de obicei vreme ploioasă sau apropierea unei furtuni (apropierea zonei de joasă presiune, ciclon). Creșterea presiunii înseamnă, de obicei, vreme uscată și senină (o zonă care trece peste tine presiune ridicata, anticiclon).

Presiunea atmosferică se modifică și odată cu altitudinea. Presiunea absolută la tabăra de bază Everest (5400 m deasupra nivelului mării) este mai mică decât presiunea absolută la Delhi (216 m deasupra nivelului mării).

Deoarece valorile presiunii absolute variază în fiecare locație, ne vom referi la presiunea relativă sau presiunea la nivelul mării.

Măsurarea înălțimii

Presiunea medie la nivelul mării este de 1013,25 GPa (sau milibari). Dacă te ridici deasupra atmosferei, această valoare scade la zero. Curba acestei căderi este destul de clară, așa că puteți calcula singur înălțimea deasupra nivelului mării folosind următoarea ecuație: alti=44330*

Dacă luați presiunea la nivelul mării de 1013,25 GPa ca p0, soluția ecuației este a dvs. altitudinea actuală deasupra nivelului mării.

Masuri de precautie

Rețineți că senzorul BMP180 are nevoie de acces la atmosfera înconjurătoare pentru a putea citi presiunea aerului, nu așezați senzorul într-o carcasă închisă. Mic aerisire va fi destul. Dar nu-l lăsa prea deschis - vântul va încurca citirile de presiune și altitudine. Luați în considerare protecția împotriva vântului.

A se proteja de căldură. Măsurarea presiunii necesită citiri precise ale temperaturii. Încercați să protejați senzorul de schimbările de temperatură și nu îl lăsați în apropierea surselor de temperaturi ridicate.

A se proteja de umiditate. Senzorul BMP180 este sensibil la nivelurile de umiditate, încercați să împiedicați posibila intrare de apă în senzor.

Nu orbi senzorul. Ceea ce a fost neașteptat a fost sensibilitatea siliconului din senzor la lumină, care putea ajunge la el printr-o gaură din capacul cipului. Pentru maxim măsurători preciseÎncercați să protejați senzorul de lumina ambientală.

Pasul 4: Asamblarea dispozitivului







Instalarea conectorilor pe un singur rând pentru Arduino Nano. De fapt, le-am redus la dimensiunea potrivităși le-a șlefuit puțin, astfel încât să pară ca și cum ar fi acolo. Apoi le lipim. După aceea, instalăm conectori pe un singur rând pentru senzorul DHT22.

Instalăm un rezistor de 10 kOhm de la ieșirea de date la masă (Gnd). Lipim totul.
Apoi instalăm conectorul pe un singur rând pentru senzorul BMP180 exact în același mod, făcând sursa de alimentare 3.3V. Conectăm totul la magistrala I2C.

În cele din urmă, conectăm afișajul LCD la aceeași magistrală I2C ca și senzorul BMP180.
(Plănuiesc să conectez ulterior un modul RTC (ceasul în timp real) la al patrulea conector, astfel încât dispozitivul să arate și ora).

Pasul 5: Codare




Descărcați biblioteci

Pentru a instala biblioteci pe Arduino, urmați linkul

#include
#include #include #include „DHT.h” #include

SFE_BMP180 presiune;

#define ALTITUDE 20.56 #define I2C_ADDR 0x27 //<<- Add your address here. #define Rs_pin 0 #define Rw_pin 1 #define En_pin 2 #define BACKLIGHT_PIN 3 #define D4_pin 4 #define D5_pin 5 #define D6_pin 6 #define D7_pin 7

#define DHTPIN 2 // la ce pin digital suntem conectați

// Anulați comentariile indiferent de tipul pe care îl folosiți! //#define DHTTYPE DHT11 // DHT 11 #define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321 DHT dht(DHTPIN, DHTTYPE); LiquidCrystal_I2C lcd(I2C,_ADDRw,En_pin,ADDRw, Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin float t1,t2);

void setup() ( Serial.begin(9600); lcd.begin(16,2); //<<-- our LCD is a 20x4, change for your LCD if needed // LCD Backlight ON lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE); lcd.setBacklight(HIGH); lcd.home (); // go home on LCD lcd.print("Weather Station"); delay(5000); dht.begin(); pressure.begin(); } void loop() { char status; double T,P,p0,a; status = pressure.startTemperature(); if (status != 0) { delay(status);

status = pressure.getTemperature(T); dacă (starea != 0) ( Serial.print("1"); lcd.clear(); lcd.setCursor(0,0); lcd.print("Temperatura Baro: "); lcd.setCursor(0,1); ); lcd.print(T,2);

status = pressure.startPressure(3); if (status != 0) ( // Așteptați finalizarea măsurătorii: întârziere(stare);

status = pressure.getPressure(P,T); dacă (starea != 0) (lcd.clear(); lcd.setCursor(0,0); lcd.print("presiunea abslt: "); lcd.setCursor(0,1); lcd.print(P,2); ); lcd.print("mb");

p0 = presiune.nivel de etanșare(P,ALTITUDINE); // suntem la 1655 de metri (Boulder, CO)

a = presiune.altitudine(P,p0); lcd.clear(); lcd.setCursor(0,0); lcd.print("Altitudine: "); lcd.setCursor(0,1); lcd.print(a,0); lcd.print("metri"); întârziere (3000); ) ) ) ) float h = dht.readHumidity(); // Citiți temperatura ca Celsius (implicit) float t = dht.readTemperature(); t2=t; lcd.clear(); lcd.setCursor(0,0); // mergeți la începutul liniei a doua lcd.print("Umiditate: "); lcd.setCursor(0,1);lcd.print(h); lcd.print(" %"); întârziere (3000); lcd.clear(); lcd.setCursor(0,0); // merge la începutul liniei a doua lcd.print("Temperatura DHT: "); lcd.setCursor(0,1); lcd.print(t); lcd.print("grad C "); întârziere (3000); lcd.clear(); lcd.setCursor(0,0); // merge la începutul liniei a doua lcd.print("Temperatura medie: "); lcd.setCursor(0,1); lcd.print((t1+t2)/2); lcd.print("grad C"); întârziere (3000); )

Am folosit Arduino versiunea 1.6.5, codul i se potrivește exact și s-ar putea să se potrivească și cu cele ulterioare. Dacă codul nu este potrivit dintr-un motiv oarecare, utilizați versiunea 1.6.5 ca bază.

Într-o zi, în timp ce mă plimbam prin oraș, am văzut un nou magazin de electronice radio care se deschisese. După ce am intrat în el, am găsit un număr mare de scuturi pentru Arduino pentru că... Am avut acasă un Arduino Uno și un Arduino Nano și imediat mi-a venit ideea să mă joc cu transmițătoare de semnal la distanță. Am decis să cumpăr cel mai ieftin emițător și receptor la 433 MHz:

Transmițător de semnal.


Receptor de semnal.

După ce a scris o schiță simplă a transmisiei de date (un exemplu luat de aici), s-a dovedit că dispozitivele de transmisie pot fi destul de potrivite pentru transmiterea de date simple, cum ar fi temperatura, umiditatea.

Transmițătorul are următoarele caracteristici:
1. Model: MX-FS - 03V
2. Raza de actiune (in functie de prezenta obiectelor de blocare): 20-200 de metri
3. Tensiune de operare: 3,5 -12V
4. Dimensiuni modul: 19 * 19 mm
5. Modulația semnalului: AM
6. Putere emițător: 10mW
7. Frecventa: 433 MHz
8. Lungimea necesară a antenei externe: 25cm
9. Ușor de conectat (doar trei fire): DATE ; VCC; Pământ.

Caracteristicile modulului de recepție:
1. Tensiune de funcționare: DC 5V
2. Curent: 4mA
3. Frecventa de operare: 433,92 MHz
4. Sensibilitate: - 105dB
5. Dimensiuni modul: 30 * 14 * 7 mm
6. Antena externă necesară: 32 cm.

Internetul spune că raza de transmisie a informațiilor la 2Kb/sec poate ajunge până la 150m. Nu l-am verificat eu, dar într-un apartament cu două camere este acceptat peste tot.

Hardware pentru stația meteo de acasă

După mai multe experimente, am decis să conectez un senzor de temperatură, umiditate și transmițător la Arduino Nano.


Senzorul de temperatură DS18D20 este conectat la Arduino după cum urmează:

1) GND la minusul microcontrolerului.
2) DQ printr-un rezistor de tragere la masă și la pinul D2 al Arduino
3) Vdd la +5V.

Modulul transmițător MX-FS - 03V este alimentat de 5 volți, ieșirea de date (ADATA) este conectată la pinul D13.

Am conectat un display LCD și un barometru BMP085 la Arduino Uno.


Schema de conectare la Arduino Uno

Receptorul de semnal este conectat la pinul D10.

Modul BMP085 - senzor digital de presiune atmosferică. Senzorul vă permite să măsurați temperatura, presiunea și altitudinea deasupra nivelului mării. Interfață de conectare: I2C. Tensiune de alimentare senzor 1,8-3,6 V

Modulul este conectat la Arduino în același mod ca și alte dispozitive I2C:

  • VCC - VCC (3,3 V);
  • GND - GND;
  • SCL - la pinul analogic 5;
  • SDA - la pinul analogic 4.
  • Cost foarte mic
  • Putere și I/O 3-5 V
  • Determinarea umidității 20-80% cu o precizie de 5%.
  • Detectare temperatura 0-50 grade. cu o precizie de 2%.
  • Frecvența de interogare nu mai mult de 1 Hz (nu mai mult de o dată la fiecare 1 secundă)
  • Dimensiuni 15,5 mm x 12 mm x 5,5 mm
  • 4 pini cu distanță de 0,1 inch

DHT are 4 pini:

  1. Vcc (sursa de alimentare 3-5V)
  2. Data out - Ieșire date
  3. Nefolosit
  4. General

Se conectează la D8 din Arduino.

Parte software a unei stații meteo de acasă

Modulul de transmisie măsoară și transmite temperatura la fiecare 10 minute.

Mai jos este programul:

/* Schiță versiunea 1.0 Trimiteți temperatura la fiecare 10 minute. */ #include #include #include #define ONE_WIRE_BUS 2 //Pin pentru conectarea senzorului Dallas OneWire oneWire(ONE_WIRE_BUS); DallasSenzori de temperatură(&oneWire); DispozitivAdresa interiorTermometru; void setup(void) ( //Serial.begin(9600); vw_set_ptt_inverted(true); // Necesar pentru DR3100 vw_setup(2000); // Setați viteza de transmisie (bit/s) sensors.begin(); if (! senzori .getAddress(insideThermometer, 0)); printAddress(insideThermometer); //Serial.print; : "); //Serial.println(tempC); //Formarea datelor pentru trimiterea numărului int = tempC; simbolul char = "c"; //Simbolul serviciului pentru a determina că acesta este un senzor String strMsg = "z"; strMsg += simbol; strMsg += " "; ; j<= 6; j++) { sensors.requestTemperatures(); printTemperature(insideThermometer); delay(600000); } } //Определение адреса void printAddress(DeviceAddress deviceAddress) { for (uint8_t i = 0; i < 8; i++) { if (deviceAddress[i] < 16); //Serial.print("0"); //Serial.print(deviceAddress[i], HEX); } }

Dispozitivul de recepție primește date, măsoară presiunea și temperatura din cameră și le transmite pe afișaj.

#include #include LiquidCrystal lcd(12, 10, 5, 4, 3, 2); #include senzor dht11; #define DHT11PIN 8 #include #include BMP085 dps = BMP085(); lung Temperatura = 0, Presiune = 0, Altitudine = 0; void setup() ( Serial.begin(9600); vw_set_ptt_inverted(true); // Necesar pentru DR3100 vw_setup(2000); // Setați viteza de recepție vw_rx_start(); // Începeți monitorizarea difuzării lcd.begin(16, 2) ; Wire.begin(); delay(1000); //lcd.write(0)() (uint8_t buflen; ; // Lungimea tamponului if (vw_get_message(buf, &buflen)) // Dacă mesajul este primit ( // Începeți analizarea int i; // Dacă mesajul nu ni se adresează, ieșiți dacă (buf != "z") ( return; ) char command = buf // Comanda este la indexul 2 // Parametrul numeric începe la indexul 4 i = 4 // Deoarece transmiterea este caracter cu caracter, atunci trebuie să convertiți setul; de caractere într-un număr while (buf[i] != " ") (număr *= 10; număr += buf[i] - "0"; i++; ) dps.getPressure(&Altitudine); getTemperature(&Temperatura //Serial.print(comandă); lcd.print("T="); lcd.setCursor(2,0); lcd.print(numar); lcd.setCursor(5,0); lcd.print("P="); lcd.print(Presiune/133,3); lcd.print("mmH"); lcd.setCursor(0,1); lcd.print("T="); lcd.print(Temperatura*0,1); lcd.print("H="); lcd.print(senzor.umiditate); lcd.home(); //întârziere(2000); int chk = senzor.read(DHT11PIN); comutați (chk) (case DHTLIB_OK: //Serial.println("OK"); pauză; caz DHTLIB_ERROR_CHECKSUM: //Serial.println("Eroare de sumă de verificare"); pauză; caz DHTLIB_ERROR_TIMEOUT: //Serial.println("Time out eroare"); break; default: //Serial.println ("Eroare necunoscută"); break; ) ) )

P.S. Pe viitor am de gând să adaug următoarele:
- senzor de umiditate la transmițător, reluați algoritmul de transmitere a datelor
- senzor pentru măsurarea vitezei și direcției vântului.
- adăugați un alt afișaj la dispozitivul receptor.
- transferați receptorul și transmițătorul pe un microcontroler separat.

Mai jos este o fotografie cu ceea ce s-a întâmplat:

Lista radioelementelor

Desemnare Tip Denumirea Cantitate NotăMagazinBlocnotesul meu
Piesa de transmitere.
Placa Arduino

Arduino Nano 3.0

1 La blocnotes
senzor de temperatura

DS18B20

1 La blocnotes
Rezistor

220 ohmi

1 La blocnotes
Modul transmițătorMX-FS-03V (433 MHz)1 La blocnotes
Partea de recepție radio.
Placa Arduino

Arduino Uno

1 La blocnotes
Rezistor trimmer 1 La blocnotes
Rezistor

Ca bază se ia proiectul stației meteo din cartea lui V. Petin „Proiecte folosind controlerul Arduino”, ediția a II-a (proiectul 5, anexa 2). Folosit Arduino IDE 1.8.5 pe Windows 10.
A fost generată o eroare la rularea schiței

Pe Internet puteți descărca biblioteci pentru Arduino care au aceleași nume, dar conținut diferit. Schița poate să nu funcționeze dacă utilizați biblioteca greșită. Se pare că am dat peste biblioteci greșite. Am adăugat un senzor BMP180 la proiect pentru a măsura presiunea atmosferică și am reluat schița.

Schema de conectare

Scanarea adreselor

Mai întâi, conectați senzorul BMP180 și indicatorul LCD1602 la Arduino. Compilați schița scanerului I2C și rulați-o pentru a determina adresele dispozitivelor de pe magistrala I2C.

La fiecare 5 secunde, programul scanează dispozitivele și emite adrese pe portul COM. Am găsit două dispozitive cu adrese 0x3F și 0x77. BMP180 are în mod implicit adresa 0x77, ceea ce înseamnă că indicatorul LCD are adresa 0x3F.
În unele dintre circuitele cărții, locurile în care semnalele SDA și SCL sunt conectate la placa Arduino sunt amestecate. Ar trebui să fie: SDA - la A4, SCL - la A5. Dacă modulul BMP180 are cinci pini, atunci pinul VIN este furnizat +5 volți.

Schema de conexiuni

Acum asamblați complet circuitul. Am folosit un LED RGB catod comun montat pe placă împreună cu rezistențe de 150 ohmi. Catodul comun este conectat la pinul GND, pinii rămași sunt conectați conform diagramei. Nu este nevoie să faceți modificări schiței, deoarece luminozitatea LED-urilor se modifică conform unei legi ciclice.
Diagrama arată conectarea unui LED RGB cu un anod comun, ca în carte.
Dacă nu sunt vizibile caractere pe ecranul LCD1602, rotiți butonul de control al luminozității. Lumina de fundal a indicatorului consumă destul de mult curent, așa că folosește o sursă de alimentare cu un curent de minim 2 A. Am folosit un hub USB cu o sursă de alimentare externă de 2 A.
Circuitul a folosit un sonerie piezo ZP-22. Rezistorul conectat la sonerie este de 100 ohmi. Frecvența sunetului poate fi modificată în program. Am ales o frecventa de 1000 Hz. Dacă întâlniți un sonerie cu o frecvență fixă ​​a sunetului, atunci îl puteți porni și opri pur și simplu prin aplicarea și eliminarea tensiunii, ca un LED obișnuit. Când începe schița, se aude un scurt bip. Puteți activa semnalizarea periodică în timp ce programul rulează prin decomentarea liniei //bzz(100); în schiță.
În proiect am folosit un senzor DHT11 sub formă de modul cu o rezistență de 4,7 kOhm deja montată. Rezistența poate fi de la 4,7 la 10 kOhm.
Conectați pinul Vcc al modulului de ceas DS1302 la magistrala de +5 volți. În acest fel, veți reduce consumul de energie al bateriei, în esență, va funcționa numai atunci când alimentarea Arduino este oprită.

Program (schiță)

Biblioteca bmp085 este folosită pentru deservirea BMP180. Valoarea presiunii depinde de altitudinea zonei. Pentru valoarea corectă a presiunii atmosferice, trebuie să selectați altitudinea. Pentru a face acest lucru, editați linia dps.init(MODE_STANDARD, 10000, true); Înălțimea mea este de 100 m (10000 cm). Fragmentul de calcul al presiunii este preluat din exemplul BMP085_test2.ino al bibliotecii bmp085.

Schița meteo_P

#include
#include
#include
#include „DHT.h”
#include
BMP085 dps = BMP085();
lung Presiune = 0, Altitudine = 0;
nesemnat lung time1 = 0;

#definiți DHTPIN 10
#define DHTTYPE 11 // 11 - DHT11, 22 - DHT22
DHT dht(DHTPIN, DHTTYPE);

int kCePin = 4; // RST DS1302
int kIoPin = 3; // Date DS1302
int kSclkPin = 2; //CLK DS1302
DS1302 rtc(kCePin, kIoPin, kSclkPin);

int REDpin = 9;
int GREENpin = 6;
int BLUEpin = 11;

LiquidCrystal_I2C lcd(0x3f, 16, 2); // introduceți adresa dvs. 0x20...0xff adresa
memTime lung nesemnat;
int bzzPin = 8;

void HumTempRead() (
float hum = dht.readHumidity();
float temp = dht.readTemperature();
if (isnan(hum) || isnan(temp)) (
Serial.println("Nu s-a putut citi de la senzorul DHT!");
lcd.setCursor(0, 1);
lcd.print("H=--% T=---");
lcd.setCursor(11, 1);
lcd.print((char)223);
lcd.setCursor(12, 1);
lcd.print("C");
) altfel (
lcd.setCursor(0, 1);
lcd.print("H=");
lcd.setCursor(2, 1);
lcd.print(hum);
lcd.setCursor(4, 1);
lcd.print("% T=+");
lcd.setCursor(9, 1);
lcd.print(temp);
lcd.setCursor(11, 1);
lcd.print((char)223);
lcd.setCursor(12, 1);
lcd.print("C ") ;
}
}

void setup_bzz() (
pinMode(bzzPin, OUTPUT);
}

void bzz(int _bzzTime) (
ton (bzzPin, 1000 , _bzzTime); // frecventa 1000 Hz
}

void setup() (
Serial.begin(9600);
Wire.begin();
întârziere (1000);

dps.init(MODE_STANDARD, 10000, adevărat); // 100 de metri (înălțimea deasupra nivelului mării în cm)

dht.begin();
setup_bzz();
bzz(100);

Lcd.init();
lcd.backlight();
lcd.home();
// lcd.setCursor(0, 0);

rtc.halt(fals);
rtc.writeProtect(false);

//rtc.setDOW(VINERI); // Setați Ziua săptămânii la VINERI setați ziua săptămânii
//rtc.setTime(4, 58, 0); // Setați ora la 12:00:00 (format 24 de ore)
//rtc.setDate(6, 8, 2010); // Setați data la 6 august 2010 setați data (zi, lună, an)
}

lcd.setCursor(8, 0);
lcd.print(rtc.getTimeStr());

dacă ((millis() - memTime > 2000) sau (millis()< memTime)) { // DHT11/22 1 time each 2 seconds
HumTempRead();
memTime = milis();
}
întârziere (100);

dacă (((milis() - time1) / 1000.0) >= 1.0) (
dps.calcTrueTemperature();
timp1 = milis();
}
dps.getPressure(&Presiunea);
Serial.print(" Presiune (Pa):");
Serial.println(Presiune);

lung p2;
int pi;
p2 = (Presiune / 133,3224); // Pa în mmHg.
pi = trunc(p2); // eliminând partea fracționară a numărului

lcd.setCursor(0, 0);
lcd.print("P=");
lcd.setCursor(2, 0);
lcd.print(pi); // ieșire atm. presiune pe LCD
lcd.setCursor(5, 0);
lcd.print("mm");
// întârziere(3000);
//bzz(100); // anulați comentariul dacă doriți să ascultați semnale
{
pentru (valoare int = 0; valoare<= 255; value += 1) {
analogWrite(REDpin, valoare);
analogWrite(GREENpin, 255 - valoare);
analogWrite(BLUEpin, 255);
întârziere(5);
}

pentru (valoare int = 0; valoare<= 255; value += 1) {
analogWrite(REDpin, 255);
analogWrite(GREENpin, valoare);
analogWrite(BLUEpin, 255 - valoare);
întârziere(5);
}

pentru (valoare int = 0; valoare<= 255; value += 1) {
analogWrite(REDpin, 255 - valoare);
analogWrite(GREENpin, 255);
analogWrite(BLUEpin, valoare);
întârziere(5);
}
}
}

În Catalogul de fișiere puteți descărca schița și bibliotecile care au fost utilizate în proiect.

Importați bibliotecile LiquidCrystal_I2C.zip, bmp085.zip, DS1302.zip și DHT.zip din arhiva descărcată în Arduino IDE. Accesați meniul Schiță Conectați biblioteca Adăugați o bibliotecă .ZIP... iar în fereastră selectați arhiva zip a bibliotecii.
Încărcați schița meteo_P. Înlocuiți adresa LCD1602 din schiță cu valoarea obținută prin scanarea magistralei I2C. Compilați și rulați schița.
Dacă schița funcționează, deschideți monitorul portului și vizualizați mesajele afișate. Ajustați înălțimea în instrucțiunea dps.init(MODE_STANDARD, 10000 , true); pentru a obține valori reale ale presiunii.
Setează-ți ceasul. Decomentează linia //rtc.setTime(4, 58, 0); iar în paranteze indicați ora curentă (ora, minutele și secundele separate prin virgule) și reîncărcați schița în controler. După setarea orei, comentați din nou această linie și rulați din nou schița.
Dacă sunteți enervat de iluminarea luminii de noapte, o puteți regla schimbând lungimea întârzierii în buclele for de la sfârșitul schiței. Cu întârziere(2); ciclul durează 2-3 secunde, cu întârziere(5); — de la 4 la 5 secunde, cu întârziere(30); - până la 15-16 secunde. Informațiile de pe indicator vor fi actualizate la același interval.
Când se utilizează stația meteo în mod autonom, de ex. fără a vă conecta la portul USB al computerului, comentați liniile din schiță cu cuvintele Serial ... pentru a dezactiva ieșirea informațiilor către monitorul portului COM.

PS. În schița cărții și în exemplele pentru biblioteca DHT este indicată linia de definiție #definiți DHTTYPE DHT 11. Schița începe, dar se blochează după câteva ore. Ceasul se oprește, afișajul nu se schimbă. Pe monitorul portului apare un mesaj vag, care conține un link către dht.
În acest rând am eliminat literele DHT, adică. făcut #define DHTTYPE 11. După aceasta, schița a început să funcționeze stabil.

Articol actualizat la 25 iunie 2018

Resurse folosite
1. Petin V.A. Proiecte care utilizează controlerul Arduino (Electronică) ediția a 2-a, Sankt Petersburg. BHV-Petersburg, 2015 464 p.
2. Petin V. A., Binyakovsky A. A. Enciclopedia practică a Arduino. - M., DMK Press, 2017. - 152 p.
3. http://arduinolearning.com/code/i2c-scanner.php
4. http://arduino.ru/forum/programmirovanie/ds1302lcd1602
5. http://robotehnika18.rf/how-to-connect-lcd-1602-to-arduino-via-i2c/
6. exemplu BMP085_test2.ino din biblioteca bmp085.zip
7. http://proginfo.ru/round/
8. http://homes-smart.ru/index.php?id=14&Itemid=149&option=com_content&view=article
9. http://iarduino.ru/lib/datasheet%20bmp180.pdf
10. http://it-donnet.ru/hd44780_dht11_arduino/

Am testat părți individuale ale sistemului pe Arduino UNO. Acestea. Am conectat modulul ESP la uno si l-am studiat, l-am deconectat, apoi am conectat nRF24 etc. Pentru implementarea finală a senzorului de fereastră, am ales Arduino Pro Mini ca cea mai apropiată miniatură de Uno.



În ceea ce privește consumul de energie, Arduino Pro Mini arată și bine:

  • nu există un convertor USB-TTL, care în sine „mâncă” mult,
  • LED-ul este conectat printr-un rezistor de 10k.

Pentru economisirea avansată a energiei a fost planificat:

  • scoateți LED-ul - indicatorul de alimentare de pe Arduino Pro Mini (am regretat, nu am deteriorat placa)
  • sau utilizați un ansamblu „gol” pe un microprocesor Atmel ATmega328 (nu a fost folosit)
  • utilizați Biblioteca de putere redusă sau JeeLib.

Din bibliotecile pe care le-am ales Low Power Library, este simplu și conține doar ceea ce este necesar.


Pentru unitatea centrală, deoarece era planificată conectarea a numeroase periferice la aceasta, a fost aleasă placa Arduino Mega. În plus, este pe deplin compatibil cu UNO și are mai multă memorie. Privind în perspectivă, voi spune că această alegere a fost complet justificată.


Puteți cumpăra un Arduino Mega pentru aproximativ 8 USD.

Putere și consum de energie

Acum despre puterea și consumul de energie.


Arduino Pro Mini vine în două tipuri:

  • pentru tensiunea de alimentare 5V si frecventa 16MHz
  • pentru o tensiune de alimentare de 3,3V și o frecvență de 8MHz.

Deoarece modulul radio nRF24L01+ necesită 3,3 V pentru alimentare, iar viteza nu este importantă aici, atunci cumpărați un Arduino Pro Mini cu 8 MHz și 3,3 V.


În acest caz, intervalul de tensiune de alimentare al Arduino Pro Mini este:

  • 3,35-12 V pentru modelul de 3,3 V
  • 5-12V pentru modelul 5V.

Aveam deja un Arduino Pro Mini la 5V, de aceea l-am folosit. Puteți cumpăra un Arduino Pro Mini pentru aproximativ 4 USD.


Unitatea centrală va fi alimentată de la o rețea de 220 V printr-o sursă de alimentare mică care oferă o ieșire de 12 V, 450 mA, 5 W. Așa pentru 5 USD. Există, de asemenea, un pin separat de 5V.



Și dacă acest lucru nu este suficient, atunci puteți instala ceva mai puternic. Cu alte cuvinte, economisirea energiei pentru unitatea centrală nu are prea mult sens. Dar pentru un senzor wireless de la distanță, economia de energie este cea mai importantă parte. Dar nici nu aș vrea să pierd funcționalitatea.


Prin urmare, Arduino Pro Mini și modulul radio nRF24 vor fi alimentate de o grămadă de 4 baterii Ni-Mh.


Si amintesteti capacitatea maximă a unei baterii moderne aproximativ 2500-2700mAh, orice altceva este fie trucuri de marketing (Ansmann 2850) sau înșelăciune (UltraFire 3500).


Nu folosesc baterii Li-Ion din mai multe motive:

  • foarte scump
  • când temperatura ambientală scade sub 0°C, puterea bateriei litiu-ion scade la 40-50%
  • cele care sunt ieftine sunt produse fără protecție și sunt nesigure (în timpul unui scurtcircuit sau a unei descărcări pot exploda și arde, vezi o grămadă de videoclipuri pe YouTube)
  • îmbătrânesc, chiar dacă nu sunt folosite (totuși, asta se poate spune despre toate elementele chimice), după 2 ani bateria Li-Ion își pierde aproximativ 20% din capacitate.

Pentru prototip, este foarte posibil să te descurci cu baterii Ni-MH AA sau AAA de înaltă calitate. Mai mult, nu avem nevoie de curenți mari. Singurul dezavantaj al bateriilor Ni-MH este timpul lung de încărcare.

Schema generală a stației meteo

Să rezumam. Iată o diagramă generală a modului în care funcționează totul.



Va urma.

Etichete: Adăugați etichete

Cele mai bune articole pe această temă