Si të konfiguroni telefonat inteligjentë dhe PC. Portali informativ
  • në shtëpi
  • Gabimet
  • Stacion i brendshëm i motit me platformën harduerike të orës arduino. Stacioni i motit në Arduino me sensor të temperaturës me valë

Stacion i brendshëm i motit me platformën harduerike të orës arduino. Stacioni i motit në Arduino me sensor të temperaturës me valë

Ne vazhdojmë të zhvillojmë stacionin tonë të motit.

Para se të kalojmë në përditësimin, dua të sqaroj pak.

Një nga kolegët tanë më shkroi duke pyetur pse u prezantua kohëmatësi i rojes?

Kohëmatësi i rojes është në vend në rast urgjence. Siç tregon praktika, ENC28J60 nuk zgjat më shumë (nëse kujtesa nuk dështon) 4 lidhjet e njëkohshme. Duke marrë parasysh se sa lidhje shërbimesh ndodhin vazhdimisht për të ruajtur funksionimin e vetë rrjetit dhe trafiku i mbetur i krijuar nga të gjitha llojet e lodrave shtëpiake (për shembull, televizorë modernë, skanoni hostet e disponueshëm në rrjet dhe portat e tyre të hapura) dizajni thjesht shkon në hutim. ENC28J60 nuk mund të punojë në mënyrë të pavarur me protokollet e rrjetit dhe gjithçka zbatohet në biblioteka. Ndoshta janë vetëm ata.
Kontrolloi të gjitha bibliotekat e disponueshme dhe module të ndryshme(papritmas martesë), por për të arritur funksionim të qëndrueshëm Nuk mund ta bëja për një kohë të gjatë. Afati maksimal ishte rreth 3-4 javë.
Kjo është arsyeja pse "qeni" rrotullohet atje dhe, nëse ndodh diçka, tërheq kontrolluesin. Pas kësaj problemi u largua.
Unë gjithashtu nuk e mohoj që është e mundur në mua rrjeti i shtëpisë ka disa nuanca apo probleme. Por meqë unë kisha një problem, mund ta ketë edhe një person tjetër. Deri tani kam gjetur vetëm këtë zgjidhje.
Me sa di unë, çipat nga Wiznet (W5100 dhe më i lartë) nuk e kanë këtë, ose thjesht nuk dukeshin mjaft mirë.

Le të kalojmë te përditësimi

Më e rëndësishmja, ne po largohemi nga çipi ENC28J60 dhe shkoni në W5100. Unë u përpoqa të zbatoja gjithçka në çipin e vjetër, por nuk ka memorie të mjaftueshme të mikrokontrolluesit për shkak të bibliotekave shumë të mëdha për ENC28J60. Kur përdorni një çip të ri, standard bibliotekat nga zhvilluesi dhe të gjitha ndryshimet e bëra, mbeten edhe më shumë 20% memorie të lirë mikrokontrollues ATMega328. Dhe këto janë simite të reja!

Në këtë version (le ta quajmë të dytin) aftësia për të transmetuar lexime nga sensorët nëpërmjet komunikimi pa tel duke përdorur frekuencën 433 MHz. Unë i mora vetë modulet nga kinezët, shenjat XY-MK-5V. Do të doja të theksoja se cilësia e transmetimit është larg të qenit perfekt. Humbje e mundshme e sinjalit, zhurmë, pamundësi për të transmetuar njëkohësisht, etj., etj. Por çmimi i tyre (më pak se 1 dollarë për grup) kompenson këto mangësi. Unë do t'ju tregoj një sekret që këto module (më të lira) gjenden në shumë stacione meteorologjike të markave përdorim shtëpiak. Wow, e papritur?

Le të fillojmë me stacionin bazë

Ne po lëvizim në Arduino UNO Dhe Mburoja Ethernet(versioni i parë) i bazuar në çip W5100. Ky është një sanduiç dhe nuk ka kuptim ta përshkruajmë atë. Unë do të përshkruaj vetëm kontaktet e përfshira shtesë për modulet XY-MK-5V.

Moduli i transmetuesit përdor energji 5 V, GND(ku do të ishim pa nënën) dhe D2 pin në kontrollues. Redakto kontaktin D2 (TË DHËNAT) mund të përdorni funksionin vw_set_tx_pin nga biblioteka e vw.

Ndryshe nga skica e mëparshme, kjo përfshin dy biblioteka shtesë:

#përfshi #përfshi

Vetë skica

Teksti i fshehur

#përfshi #përfshi #përfshi #përfshi #përfshi #përfshi #përfshi #përfshi #define DHTTYPE DHT22 #define DHTPIN 5 DHT dht(DHTPIN, DHTTYPE); byte mac = (0x54, 0x34, 0x31, 0x31, 0x31, 0x31); server char = "narodmon.ru"; porta int = 8283; IPadresa ip (192,168,0,201); Klienti EthernetClient; BMP085 dps = BMP085(); gjatë Temperatura = 0, Presioni = 0; noton H, dP, dPt; interval bool = e vërtetë; EasyTransferVirtualWire ET; struct SEND_DATA_STRUCTURE( ID e bajtit; // ID e pajisjes int Temperatura; // Presioni i notimit të temperaturës; // Lagështia e notimit me presion; // float e lagështisë në pikën e vesës; // Pika e vesës/ ngrirjes); SEND_DATA_STRUCTURE transmetim; void setup() ( // Inicializoni kohëmatësin Watchdog wdt_disable(); vonesë(8000); wdt_enable(WDTO_8S); // Inicializoni konsolën Serial.begin(9600); // Inicializoni sensorin DHT dht.begin(); / / Inicializimi i modulit 433 MHz ET.begin(detajet(transmetim)); vw_set_ptt_inverted(true); vw_set_tx_pin(2); vw_setup(2000); // Nisni rrjetin, nëse nuk kemi pritur për të dhëna nga serveri DHCP, atëherë // i caktojmë vetes një adresë nëse (Ethernet.begin(mac) == 0) Ethernet.begin(mac, ip); // Inicializimi i 1-Wire Wire.begin(); vonesë (200); // Inicializimi i BMP180 me rregullim të lartësisë // dps.init (MODE_STANDARD, 3200, e vërtetë); // Inicializoni BMP180 dps.init(); Serial.println(Ethernet.localIP()); // Dërgoni të dhënat e para menjëherë pasi të keni ndezur pajisjen send_info (e vërtetë); ) // funksioni i pikës së vesës NOAA / / referencë (1): http://wahiduddin.net/calc/density_algorithms.htm // referencë (2) : http://www.colorado.edu/geography/weather_station /Geog_site/about.htm dyfishi i pikës së vesës(dofish celsius , lagështi e dyfishtë) ( // (1) Presioni i avullit të ngopjes = ESGG(T) RAPORTI i dyfishtë = 373,15 / (273,15 + celsius); dyfishtë RHS = -7,90298 * (RATIO - 1); RHS += 5,02808 * log10(RAPORTI); RHS += -1,3816e-7 * (pow(10, (11,344 * (1 - 1/RATIO))) - 1) ; RHS += 8,1328e-3 * (pow(10, (-3,49149 * (RATIO - 1))) - 1) ; RHS += log10 (1013.246); // faktori -3 është për të rregulluar njësitë - Presioni i avullit SVP * lagështia e dyfishtë VP = pow(10, RHS - 3) * lagështia; // (2) DEWPOINT = F (Presioni i avullit) dyfishi T = log (VP/0.61078); // kthimi temp var (241,88 * T) / (17,558 - T); ) void send_info(bool eth) ( bool fail = true; while(fail) ( // Ne përpiqemi të lexojmë të dhëna nga sensori i lagështisë DHT derisa të marrim // një rezultat. Në 90% të rasteve gjithçka funksionon mirë, por na duhet 100 % if((H = dht.read Humidity()) >= 0) ( // Marrja e lagështisë dhe temperaturës nga sensori BMP180 dps.getPressure(&Pressure); dps.getTemperature(&Temperature); // Llogaritni pikën e vesës nëse temperatura është jashtë mbi 0 gradë Celsius // dhe prisni një rezultat mbi 0, përndryshe prodhimi 0. Kjo është e nevojshme // për të mos qenë mashtruese gjatë stinës së dimrit. // dP = Temperatura>0?((dPt=pika e vesës(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); }

Një antenë duhet t'i shtohet vetë moduleve. Për 433 MHz Mjafton një tel i zakonshëm i gjatë bakri 17 cm. Pa një antenë, mund të harroni funksionimin normal.

Le të kalojmë te pjesa më e rëndësishme e këtij përditësimi - stacioni lokal me valë

Për ta zbatuar atë (në gju) përdora një analog Arduino NANO(në bazë ATMega328) Dhe TFT shfaqja në një çip ST7735S me leje 128 x 160

Teksti i fshehur



Ekrani i pikës -> kontrolluesi

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

Moduli i marrësit është i lidhur vetëm në të njëjtën mënyrë si një transmetues TË DHËNAT për të fiksuar D7.

Disa foto se si duket:

Teksti i fshehur

Skica e marrësit

Teksti i fshehur

#përfshi #përfshi #përfshi #përfshi int x, y; int w = 128, h = 160; madhësia int; // 433 EasyTransferVirtualWire ET; struct SEND_DATA_STRUCTURE( ID e bajtit; // ID e pajisjes int Temperatura; // Presioni i notimit të temperaturës; // Lagështia e notimit me presion; // float e lagështisë në pikën e vesës; // Pika e vesës/ ngrirjes); SEND_DATA_STRUCTURE transmetim; int Log_Temperatura = -1; float Log_Pressure = -1; float Log_Lagështia = -1; float Log_dewPoint = -1; // TFT #define cs 10 #define dc 9 #define rst 8 char Temperatura, Presioni, Lagështia, Pika e vesës; Informacioni i vargut; TFT TFTekran = TFT(cs, dc, rst); void setup())( Serial.begin(9600); // Inicializimi i modulit 433 MHz ET.begin(details(transmet)); vw_set_ptt_inverted(true); vw_set_rx_pin(7); vw_setup(2000); vw_rx_st); // Inicializimi dhe konfigurimi fillestar i ekranit TFTscreen.begin(); TFTscreen.setRotation(2); TFTscreen.background(0, 0, 0); // Vizatimi i elementeve statike // 1. Ejani të na vizitoni TFTscreen.stroke(255, 255 , 255); TFTscreen.setTextSize(1); TFTscreen.text(" ", 10, 10); // 2. Përshkrimi i leximeve nga sensorët TFTscreen.text("mmHg", w/2+5, 80); TFTekran .text ("%", w/2+5, 100); TFTscreen.text("C", w/2+5, 120); transmetim. Temperatura = 0; transmetim. Presioni = 0; transmetim. Lagështia = 0 ; transmetim .dewPoint = 0; TFTPrint(); ) void loop())( if(ET.receiveData())( if(transmetim.ID == 1) TFTPrint(); /* Serial.println(transmetim.Temperatura) ; Serial. println(transmetim. Presion); Serial.println(transmetim. Lagështia); Serial.println(broadcast.dewPoint); Serial.println(); */ ) ) ndryshimet e zbrazëta(madhësia int, int x, int y, bool up, bool qartë = false) ( if(e qartë) TFTscreen.stroke(0, 0, 0); else (ndryshimet(madhësia, x, y, !lart, e vërtetë); TFTscreen.stroke((lart)?0:255, 0, (lart)?255:0); ) if((madhësia%2) == 0 ) madhësia ++; ndërsa(madhësia > 0) ( TFTscreen.line (x, y, x+(madhësia--), y); ++x, (lart)?--y:++y, --madhësia; ) /* ndërsa( madhësia > 0) ( TFTscreen.line (x, y, (lart)?x+madhësia-1:x, (lart)?y:y+madhësia-1); ++x, ++y, --madhësia; ) */ ) int x_center(int w, gjatësia int, madhësia int) (kati i kthimit ((w-gjatësia*(madhësia*5)+madhësia*2)/2); ) int x_alignment_right(int w, gjatësia int, int madhësia) ( tavani i kthimit (gjatësia w * (madhësia * 5) + madhësia * 2); ) i pavlefshëm TFTPrint () (madhësia = 3; // ================ ================================================== === =============== // Shfaq leximet e temperaturës // ========================= ============================================== nëse (transmetohet. Temperatura != Log_Temperature) ( TFTscreen.setTextSize(madhësia); // Mbishkruani të dhënat e vjetëruara String info = String(Log_Temperature); info.concat("C"); if(Log_Temperature > 0) info = "+"+info; info .toCharArray(Temperatura, info.length()+1); TFTscreen.stroke(0, 0, 0); TFTscreen.text(Temperatura, x_center(w, info.length()+1, madhësia), 35); / / Shfaq informacionin e leximeve të reja = String (transmetim. Temperatura); info.concat ("C"); if(transmetim.Temperatura > 0) info = "+"+info; info.toCharArray(Temperatura, info.length()+1); // Ndrysho ngjyrën e vlerës së temperaturës në varësi të vetë temperaturës int r, g = 0, b; if (transmetim. Temperatura > 0) ( r = harta (transmetim. Temperatura, 0, 40, 255, 150); // E kuqe b = harta (transmetim. Temperatura, 0, 40, 30, 0); // Ndrysho nuancë për një kalim më vizual përmes zeros ) tjetër ( r = harta (transmetim. Temperatura, -40, 0, 0, 30); // Ndrysho ngjyrën për një kalim më vizual përmes zeros b = harta (transmetimi. Temperatura, - 40, 0, 150, 255); // Blu ) TFTekran.stroke(b, g, r); // KUJDES: pozicionet e ngjyrave në bibliotekë janë të përziera, vendi RGB përdoret nga BGR! TFTscreen.text(Temperatura, x_center(w, info.length()+1, madhësia), 35); ) madhësia = 1; // ================================================ ==== ====================================// Leximet e presionit të daljes // === ====== ============================================ ========= ================================ if(transmetim. Presioni != Log_Pressure) ( TFTscreen.setTextSize(size); / / Mbishkruani informacionin e vjetëruar të të dhënave = String(Log_Pressure); info.toCharArray(Pressure, info.length()); TFTscreen.stroke(0, 0, 0); TFTscreen.text(Pressure, x_alignment_right(w/2-5, info .length (), madhësia), 80); // Nxjerr informacionin e leximeve të reja = String (transmetim. Presion); info.toCharArray (Pressure, info.length ()); TFTscreen.stroke (255, 255, 255); TFTekran .text(Pressure, x_alignment_right (w/ 2-5, info.length(), madhësia), 80); ndryshime (10, 106, 85, (transmetim. Presioni > Log_Pressure)?true:false); ) other (ndryshime (10, 106, 85, e vërtetë, e vërtetë); ndryshimet (10, 106, 85, e rreme, e vërtetë); ) // ===================== ================================================== =========== = // Leximet e lagështisë në dalje // =============================== ================================================== ================== if(transmetim. Lagështia != Log_Humidity) ( TFTscreen.setTextSize(size); // Mbishkruani informacionin e vjetëruar të të dhënave = String(Log_Humidity); info.toCharArray(Lagështia, info.length()); TFTscreen.stroke(0, 0, 0); TFTscreen.text(Lagështia, x_radhitja_djathtas (w/2-5, info.length(), madhësia), 100); // Shfaq informacionin e leximeve të reja = String (transmetim. Lagështia); info.toCharArray(Lagështia, info.length()); TFTscreen.stroke(255, 255, 255); TFTscreen.text(Lagështia, x_radhitja_djathtas (w/2-5, info.length(), madhësia), 100); ndryshimet(10, 106, 105, (transmetim. Lagështia > Regjistri_Lagështia)? e vërtetë: e gabuar); ) else ( ndryshime (10, 106, 105, e vërtetë, e vërtetë); ndryshime (10, 106, 105, e rreme, e vërtetë); ) // ================== ================================================== === ============== // Dalja e pikës së vesës/leximet e pikës së ngrirjes // ===================== ================================================== if(transmetim.dewPoint ! = Log_dewPoint) ( TFTscreen.setTextSize(madhësia); // Mbishkruani informacionin e vjetëruar të të dhënave = String(Log_dewPoint); info.toCharArray(dewPoint, info.length()); TFTscreen.stroke(0, 0, 0); TFTscreen.text (Pika e vesës, x_alignment_right (w/2-5, info.length (), madhësia), 120); // Nxjerr informacione të reja për leximet = String (broadcast.dewPoint); info.toCharArray (pika e vesës, info.length ()); TFTscreen.stroke(255, 255, 255); TFTscreen.text (dewPoint, x_alignment_right (w/2-5, info.length(), madhësia), 120); ndryshime (10, 106, 125, (transmetim.dewPoint > Log_dewPoint)?true:false); ) else (ndryshime(10, 106, 125, e vërtetë, e vërtetë); ndryshime (10, 106, 125, false, e vërtetë); ) // Përditëso vlerat në regjistrat për të mëvonshme krahasimi i leximeve Log_Temperature = transmetim.Temperatura; Log_Pressure = transmetim.Presion; Log_Humidity = transmetim.Lagështia; Log_dewPoint = transmetim.dewPoint; )

Leximet shfaqen mjaft kompakte, por siç tregon praktika (dhe këshillat e shokëve të mi) - "shije dhe ngjyra, edhe gruaja nuk është shoqe". Kam dëgjuar shumë këshilla dhe sugjerime, por ato kundërshtojnë njëra-tjetrën. Prandaj, bëjeni sipas shijes tuaj.

Më dukej se dizajni është pjesa e projektit që merr shumicën e kohës!

Teksti i fshehur

Disa nga të dhënat janë krijuar për të pasqyruar disa elementë të dizajnit.

Artefaktet në ekran janë pluhuri dhe papastërtitë e tjera që janë grumbulluar gjatë kohës së gjatë që ekrani ishte brenda... diku atje,... mirë, atje, nuk më kujtohet nga e kam marrë! Më lini të qetë!

Skica ka funksione pozicionimi. Ato janë mjaft primitive, por ju lejojnë të arrini efekte të caktuara.

  1. x_qendra
  2. x_drejtimi_djathtas

E para e përqendron tekstin dhe e dyta e rreshton atë në anën e djathtë të zonës së specifikuar. Të gjitha llogaritjet bëhen në lidhje me dimensionet teksti i dhënë, bazuar në shprehjen 1 madhësi = 1PX x 1PX segmenti i fontit.

Ekrani shfaq gjithashtu elementë që korrespondojnë me një rritje ose ulje të një vlere të caktuar leximi. Ato shfaqen në formën e trekëndëshave. Por në kodin e funksionit ndryshimet Ekziston një ekran alternativ në formën e trekëndëshave të rrotulluar me 45 gradë. Nëse leximet rriten, elementi është i kuq, përndryshe, blu.

Nga rruga, ngjyra dhe hija e temperaturës kryesore ndryshon në varësi të vetë temperaturës. Një vendim mjaft i diskutueshëm, por për mendimin tim, vizualisht i rehatshëm. Kam luftuar me të për një kohë dhe kuptova se vlerat në funksion goditje në tru, Objekt Ekran TFT, janë renditur në rendin e gabuar. BGR vend RGB. Ky është një gabim zhvilluesi, ose nuk kuptoj diçka.

PS: Gjithçka është mjaft interesante, por për mendimin tim e meriton zhvillimin e mëtejshëm. Kjo është ajo që ne do të bëjmë pas një kohe.

Kohët e fundit, një kolegu im organizoi një ekspozitë të vogël shkencore.
Mësuesi im më kërkoi t'u prezantoj një projekt elektronik studentëve në kolegj. Kisha dy ditë për të gjetur diçka interesante dhe mjaft të thjeshtë.



Meqenëse kushtet e motit këtu janë mjaft të ndryshueshme, dhe temperatura luhatet në intervalin 30-40 ° C, vendosa të bëj një stacion moti në shtëpi.

Cilat janë funksionet e një stacioni meteorologjik në shtëpi?
Stacioni i motit në Arduino me ekran - një pajisje që mbledh të dhëna për motin dhe kushtet mjedisi duke përdorur shumë sensorë.

Zakonisht këta janë sensorët e mëposhtëm:

  • era
  • lagështia
  • shiu
  • temperatura
  • presioni
  • lartësitë

Qëllimi im është të bëj një stacion portativ të motit desktop me duart e mia.

Ai duhet të jetë në gjendje të përcaktojë parametrat e mëposhtëm:

  • temperatura
  • lagështia
  • presioni
  • lartësia

Hapi 1: Bleni komponentët e nevojshëm







  • DHT22, sensori i temperaturës dhe lagështisë.
  • BMP180, sensor presioni.
  • Saldim
  • Lidhës i daljes me një rresht 40

Pajisjet që do t'ju nevojiten:

  • Makine per ngjitjen e metalit
  • Pincë jastëk hunde
  • Tela

Hapi 2: Sensori i temperaturës dhe lagështisë DHT22







Për matjen e temperaturës përdoren sensorë të ndryshëm. DHT22, DHT11, SHT1x janë të njohura

Unë do të shpjegoj se si ndryshojnë nga njëri-tjetri dhe pse kam përdorur DHT22.

Përdor sensorin AM2302 sinjal dixhital. Ky sensor funksionon sistem unik teknologjia e kodimit dhe sensorit, kështu që të dhënat e tij janë të besueshme. Elementi i tij sensor është i lidhur me një kompjuter 8-bit me një çip.

Çdo sensor i këtij modeli kompensohet me temperaturë dhe kalibrohet saktësisht; koeficienti i kalibrimit ndodhet në një memorie të programueshme një herë (OTP memorie). Gjatë leximit të leximeve, sensori do të kujtojë koeficientin nga kujtesa.

Madhësia e vogël, konsumi i ulët i energjisë, distancë e madhe ingranazhet (100 m) lejojnë që AM2302 t'i përshtatet pothuajse të gjitha aplikacioneve dhe 4 dalje në një rresht e bëjnë instalimin shumë të thjeshtë.

Le të shohim të mirat dhe të këqijat e tre modeleve të sensorëve.

DHT11

Pro: nuk kërkohet saldim, më i lirë nga të tre modelet, i shpejtë sinjal i qëndrueshëm, varg mbi 20 m, interferencë e fortë.
Kundër: Biblioteka! Nuk ka opsione rezolucioni, gabimi i matjes së temperaturës është +/- 2°C, gabimi i matjes së nivelit të lagështisë relative është +/- 5%, diapazoni joadekuat i temperaturave të matura (0-50°C).
Fushat e aplikimit: kopshtari, bujqësi.

DHT22

Pro: nuk kërkon saldim, kosto të ulët, kthesa të lëmuara, gabime të vogla në matje, diapazon të madh matjeje, diapazon më të madh se 20 m, ndërhyrje të forta.
Kundër: ndjeshmëria mund të jetë më e lartë, gjurmimi i ngadaltë i ndryshimeve të temperaturës, kërkon një bibliotekë.
Fushat e aplikimit: studime mjedisore.

SHT1x

Pro: nuk kërkon saldim, kthesa të lëmuara, gabime të vogla në matje, përgjigje të shpejtë, konsum të ulët të energjisë, modaliteti automatik gjumë, stabilitet të lartë dhe konsistencë të të dhënave.
Kundër: dy ndërfaqe dixhitale, gabim në matjen e niveleve të lagështisë, diapazoni i matur i temperaturës 0-50°C, nevojitet bibliotekë.
Fushat e aplikimit: funksionimi në mjedise të vështira dhe në instalime afatgjatë. Të tre sensorët janë relativisht të lirë.

Kompleksi

  • Vcc - 5V ose 3.3V
  • Gnd - me Gnd
  • Të dhënat - në pinin e dytë Arduino

Hapi 3: Sensori i presionit BMP180



BMP180 - sensor barometrik presioni atmosferik me ndërfaqe I2C.
Sensorët barometrikë të presionit matin vlerën absolute të ajrit të ambientit. Ky tregues varet nga specifika Kushtet e motit dhe nga lartësia mbi nivelin e detit.

Moduli BMP180 kishte një stabilizues 3.3V 662 kOhm, të cilin unë, nga marrëzia ime, e shpërtheva aksidentalisht. Më duhej ta drejtoja furnizimin me energji direkt në çip.

Për shkak të mungesës së një stabilizuesi, unë jam i kufizuar në zgjedhjen e burimit të energjisë - një tension mbi 3.3 V do të shkatërrojë sensorin.
Modelet e tjera mund të mos kenë një stabilizues, sigurohuni që të kontrolloni praninë e tij.

Diagrami i lidhjes së sensorit dhe autobusit I2C me Arduino (nano ose uno)

  • SDA-A4
  • SCL - A5
  • KQV - 3.3V
  • GND - GND

Le të flasim pak për presionin dhe marrëdhënien e tij me temperaturën dhe lartësinë.

Presioni atmosferik në çdo pikë nuk është konstant. Ndërveprim kompleks ndërmjet rrotullimit të Tokës, animi i boshtit të Tokës, çon në shfaqjen e shumë zonave me presion të lartë dhe të ulët, gjë që çon në ndryshime ditore të kushteve të motit. Duke vëzhguar ndryshimet në presion, mund të bëni parashikime afatshkurtra të motit.

Për shembull, një rënie e presionit zakonisht nënkupton mot me shi ose afrimin e një stuhie (duke iu afruar zonës me presion të ulët, ciklonit). Rritja e presionit zakonisht nënkupton mot të thatë dhe të kthjellët (një zonë që kalon mbi ju shtypje e lartë, anticiklon).

Presioni atmosferik gjithashtu ndryshon me lartësinë. Presioni absolut në kampin bazë të Everestit (5400 m mbi nivelin e detit) është më i ulët se presioni absolut në Delhi (216 m mbi nivelin e detit).

Meqenëse leximet e presionit absolut ndryshojnë në çdo vend, ne do t'i referohemi presionit relativ ose presionit të nivelit të detit.

Matja e lartësisë

Presioni mesatar në nivelin e detit është 1013.25 GPa (ose milibar). Nëse ngriheni mbi atmosferën, kjo vlerë bie në zero. Kurba e kësaj rënieje është mjaft e qartë, kështu që ju mund të llogarisni vetë lartësinë mbi nivelin e detit duke përdorur ekuacionin e mëposhtëm: alti=44330*

Nëse e merrni presionin e nivelit të detit prej 1013,25 GPa si p0, zgjidhja e ekuacionit është e juaja lartësia aktuale mbi nivelin e detit.

Masat paraprake

Mos harroni se sensori BMP180 ka nevojë për qasje në atmosferën përreth për të qenë në gjendje të lexojë presionin e ajrit, mos e vendosni sensorin në një strehë të mbyllur. I vogël ndenja do të jetë mjaft e mjaftueshme. Por mos e lini shumë të hapur - era do të ngatërrojë leximet e presionit dhe lartësisë. Merrni parasysh mbrojtjen e erës.

Mbroni nga nxehtësia. Matja e presionit kërkon lexime të sakta të temperaturës. Mundohuni të mbroni sensorin nga ndryshimet e temperaturës dhe mos e lini pranë burimeve të temperaturave të larta.

Mbroni nga lagështia. Sensori BMP180 është i ndjeshëm ndaj niveleve të lagështisë, përpiquni të parandaloni hyrjen e mundshme të ujit në sensor.

Mos e verboni sensorin. Ajo që ishte e papritur ishte ndjeshmëria e silikonit në sensor ndaj dritës, e cila mund ta arrinte atë përmes një vrime në kapakun e çipit. Për maksimumin matje të sakta Mundohuni të mbroni sensorin nga drita e ambientit.

Hapi 4: Montimi i pajisjes







Instalimi i lidhësve me një rresht për Arduino Nano. Në fakt, ne i shkurtojmë ato madhësinë e duhur dhe i lamë pak me rërë që të duken sikur të ishin aty. Pastaj i bashkojmë ato. Më pas, ne instalojmë lidhës me një rresht për sensorin DHT22.

Ne instalojmë një rezistencë 10 kOhm nga dalja e të dhënave në tokë (Gnd). Ne bashkojmë gjithçka.
Pastaj ne instalojmë lidhësin me një rresht për sensorin BMP180 në të njëjtën mënyrë, duke e bërë furnizimin me energji 3.3V. Ne lidhim gjithçka me autobusin I2C.

Së fundi, ne e lidhim ekranin LCD me të njëjtin autobus I2C si sensori BMP180.
(Unë planifikoj të lidh më vonë një modul RTC (orë në kohë reale) me lidhësin e katërt në mënyrë që pajisja të tregojë gjithashtu kohën).

Hapi 5: Kodimi




Shkarkoni bibliotekat

Për të instaluar bibliotekat në Arduino, ndiqni lidhjen

#përfshi
#include #include #include "DHT.h" #include

Presioni SFE_BMP180;

#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 // me cilin pin dixhital jemi lidhur

// Uncomment Whatdo lloj lloji që ju "të përdorni! // #përcaktoni dhttype dht11 // dht 11 #define dhttype dht22 // dht 22 (am2302), am2321 dht dht (dhtpin, dhtttype); likuidcrystal_i2c lcd (i2c_addr, en_pin, rw_pin, rw_pin, rw_pin, rw_pin, rw_pin, rw_pin 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 = presion.getTemperature(T); if (statusi != 0) ( Serial.print ("1"); lcd.clear (); lcd.setCursor (0,0); lcd.print ("Temperatura Baro: "); lcd.setCursor(0,1 lcd.print(T,2);lcd.print("gradë C");t1=T; vonesë(3000);

status = presion.startPressure(3); nëse (statusi != 0) ( // Prisni që matja të përfundojë: vonesë(status);

status = presion.getPressure(P,T); nëse (statusi != 0) (lcd.clear(); lcd.setCursor(0,0); lcd.print("presion abslt: "); lcd.setCursor(0,1); lcd.print(P,2 lcd.print(" mb "); vonesë (3000);

p0 = presion.nivel vulosje(P,ALTITUDE); // jemi në 1655 metra (Boulder, CO)

a = presioni.lartësia (P,p0); LCD.clear(); lcd.setCursor(0,0); lcd.print("Lartësia: "); lcd.setCursor(0,1); LCD.print(a,0); lcd.print("metra"); vonesë (3000); ) ) ) ) float h = dht.lexo Lagështia(); // Lexoni temperaturën si Celsius (e parazgjedhur) float t = dht.readTemperature(); t2=t; LCD.clear(); lcd.setCursor(0,0); // shkoni te fillimi i rreshtit të dytë lcd.print("Lagështia: "); lcd.setCursor(0,1);lcd.print(h); lcd.print(" %"); vonesë (3000); LCD.clear(); lcd.setCursor(0,0); // shkoni te fillimi i rreshtit të dytë lcd.print("Temperatura DHT: "); lcd.setCursor(0,1); LCD.print(t); lcd.print (" gradë C "); vonesë (3000); LCD.clear(); lcd.setCursor(0,0); // shkoni te fillimi i rreshtit të dytë lcd.print("Temperatura mesatare: "); lcd.setCursor(0,1); lcd.print((t1+t2)/2); lcd.print (" gradë C "); vonesë (3000); )

Kam përdorur versionin 1.6.5 të Arduino, kodi i përshtatet saktësisht dhe mund të përshtatet edhe me ato të mëvonshme. Nëse kodi nuk është i përshtatshëm për ndonjë arsye, përdorni versionin 1.6.5 si bazë.

Ashtu si shumica e njerëzve që punojnë, ndjekja e projekteve tuaja kërkon të vetmen kohë të lirë që ju ka mbetur. Kjo është arsyeja pse unë nuk kam krijuar asgjë për një kohë të gjatë dhe isha kruar për të bërë diçka. Mjaft e çuditshme, kjo mundësi u shfaq në universitet. Është shtator jashtë dritares, viti i 4-të dhe një kurs i ardhshëm mbi dizajnin e qarkut. Na u tha se lëndët mund të kryheshin në dy variante: letër dhe pajisje.

Për 5 vjet, lëndët në letër në universitetin tonë kryheshin sipas parimit "merr të vjetrat dhe bashkoji". Kjo qasje nuk më përshtatet për shkak të rutinës së saj, kështu që menjëherë zgjodha lëndët në harduer. Mikrokontrolluesi Arduino u propozua si zemra e lëndës për shkak të lehtësisë së të mësuarit. Pas përcaktimit të llojit të lëndës, mbeti një pyetje tjetër: çfarë saktësisht duhet bërë. Meqenëse nuk kisha përvojë në programimin e mikrokontrolluesve, hapa menjëherë Google dhe fillova të studioj projektet ekzistuese. Ka shumë projekte, disa prej tyre janë mjaft të thjeshta, disa janë gjeniale (skaneri 3D, për shembull), por shumica dërrmuese nuk kishte asnjë aplikim praktik. Dhe unë thjesht doja diçka që nuk do të shtrihej në raft dhe nuk do të mblidhte pluhur. Pas një ekskursioni gjysmë ore në botën e Arduino, u interesova për temën e stacioneve të motit në shtëpi, dhe projektet nuk më dukeshin shumë të vështira për t'u zbatuar (gjë që tërhoqi kryesisht të sapoardhurin).

Kështu u zgjodh tema për lëndën dhe me kalimin e kohës dukej se nuk kishte probleme.

Përzgjedhja e komponentëve

Duke parë projekte të ndryshme, kuptova se do të më mjaftonte një Nano apo edhe një Pro Mini, por megjithatë zgjodha Arduino Uno me shpresën se do të doja të programoja për Arduino dhe do të zbatoja disa projekte të tjera në të ardhmen. Unë kurrë nuk kisha mbajtur një hekur saldimi në duar më parë, kështu që për zhvillim më të lehtë vendosa të blej edhe Sensor Shield v4.

Më shumë detaje

Pllaka lehtëson lidhjen e shpejtë të sensorëve, moduleve, servo motorëve, ndërfaqeve Serial dhe I2C, dhe gjithashtu shfaq të gjitha portat e kontrolluesit të faktorit të formës Duemilanova/Uno (mund të lidhet edhe me serinë mega, por me kufizime dhe pasoja që pasojnë) . Mbështet mburojat e tjera mbi vete.


Zgjodha sensorët e mëposhtëm si burime për të dhënat meteorologjike:


Kam vendosur për sensorët. Por çfarë të bëjmë me të dhënat që vijnë nga sensorët? Vendosa ta shfaq. Doja një foto me ngjyra, kështu që hodha menjëherë zgjidhjet pikturë njëngjyrëshe. Pas disa minutash kërkimi, u zgjodh ekrani TFT 1,8 inç ST7735.

Më shumë detaje

Meqenëse ekrani përdor një protokoll SPI me 4 tela për komunikim dhe ka buferin e vet të kornizës me adresë pikselësh, ai mund të përdoret me çdo lloj mikrokontrollues. Ekrani 1.8 inç ka 128x160 piksele ngjyrash. Ekziston gjithashtu një fole për kartën microSD, kështu që mund të ngarkoni lehtësisht imazhe bitmap me ngjyra të plota nga sistemi i skedarëve të kartës microSD FAT16/FAT32.

Karakteristikat:

  • Diagonalja e ekranit - 1,8 inç, rezolucion 128x160 piksele, ngjyra 18-bit (262,144 ngjyra)
  • Kontrolluesi me adresimin e integruar të pikselit të tamponit të kujtesës video
  • Slot i integruar për microSD - përdor më shumë se 2 linja dixhitale
  • E përputhshme me 3.3 dhe 5V
  • Përmasat: 34 mm x 56 mm x 6.5 m


Programimi i kontrolluesit Arduino

Pasi të kemi vendosur për komponentët për stacionin e motit, do të fillojmë të programojmë kontrolluesin. Arduino IDE u përdor për të ndezur firmware-in Arduino. Përdoren gjithashtu biblioteka nga Adafruit.

Para se të kalojmë në skicë, le të shohim funksionalitetin:

  • Leximet merren nga sensorët çdo 10 sekonda dhe vetëm ata tregues që kanë ndryshuar në krahasim me matjen e mëparshme përditësohen në ekran.
  • Transferimi i të dhënave i zbatuar përmes portit COM

Skicë

#përfshi // bibliotekë për komunikim me pajisjet I2C #include // Biblioteka thelbësore për të gjithë sensorët #include // biblioteka për BMP180 #include // Biblioteka kryesore grafike #include // Biblioteka specifike për harduerin #include // biblioteka për komunikim me pajisjet SPI #përfshi "dht.h" // bibliotekë për DHT #define DHT22_PIN 2 // lidh pinin e të dhënave të DHT22 me 2 pin dixhital #define TFT_CS 10 // lidh pinin CS të TFT me 10 pin dixhital #define TFT_RST 9 // lidhni pinin RST të TFT me 9 pin dixhital // mund ta lidhni këtë edhe me rivendosjen e Arduino // në këtë rast, vendosni këtë pin #define në 0! #define TFT_DC 8 // lidh pinin DC të TFT me 8 kunja dixhitale Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST); //initialize TFT #define TFT_SCLK 13 // lidh pinin SCLK të TFT me 13 pin dixhital #define TFT_MOSI 11 // lidh pinin MOSI të TFT me 11 pin dixhital dht DHT; Adafruit_BMP085_Unified bmp = Adafruit_BMP085_Unified(10085); //initalizo BMP180 int bmpFlag = 0; struct ( uint32_t total; uint32_t ok; uint32_t crc_error; uint32_t time_out; uint32_t lidh; uint32_t ack_l; uint32_t ack_h; uint32_t i panjohur; ) statistika = ( 0,0,0,0,0,0); // struktura për konfigurimin e pavlefshëm të statusit dht (void) ( Serial.begin (9600); Serial.println ("Testi Meteo"); Serial.println (""); if(!bmp.begin()) // kontrolloni lidhjen për BMP180 ( Serial.print("Oops, nuk u zbulua BMP180 ... Kontrollo instalimet elektrike ose I2C ADDR!"); bmpFlag = 1; ) tft.initR(INITR_BLACKTAB); // Inicializoni TFT dhe mbushni me ngjyrë të zezë tft.fillScreen (ST7735_BLACK); tft.setRotation(tft.getRotation() + 1); tft.setTextSize(1.5); vonesë (500); // vonesë për të siguruar që TFT ishte inicializuar) // notimi i fundit i të dhënave të matura e vjetërTemperatura = 0 , Lartësia e vjetër = 0, Presioni i vjetër = 0, Lagështia e vjetërDHTH = 0, temperatura e vjetërDHTT; bool wasUpdate = false; void loop(void) ( if(Serial.available() > 0) // kemi të dhëna është porta serike ( Serial.read(); // lexo bajtin nga porta serike dhe dërgo të dhënat e fundit të matura printValue("Pressure", OldPressure , " hPa", false); printValue ("Temperatura", e vjetërTemperaturë, " C", false); printValue ("Lartësia", e vjetërAltitude, " m", false); printValue ("Lagështia", lagështia e vjetërDHTH, "%", false); printValue("temperatura_DHT", temperatura e vjetërDHTT, " C", false); Serial.println("END_TRANSMISSION"); ) ngjarja sensors_event_t; temperatura notuese, lartësia; if(bmpFlag == 0)(bmp.getEvent(&event) ; // merrni të dhëna nga BMP180 nëse (ngjarje.presioni) ( bmp.getTemperature(&temperaturë); noton seaLevelPressure = SENSORS_PRESSURE_SEALEVELHPA; lartësia = bmp.pressureToAltitude(presioni i nivelit të detit, ngjarja.presioni, temperatura.Sornl) gabim"); ) ) uint32_t start = mikros(); int chk = DHT.read22(DHT22_PIN); // merr të dhëna nga DHT22 uint32_t stop = micros(); stat.total++; switch (chk) // kontrollo statusin e DHT22 (rasti DHTLIB_OK: stat.ok++; pushim; rasti DHTLIB_ERROR_CHECKSUM: stat.crc_error++; Serial.print("Gabim kontrollues,\t"); pushim; rasti DHTLIB_ERROR_TIMEOUT: stat.time_out++; Serial.print ("Gabimi i skadimit të kohës,\t"); pushim; rasti DHTLIB_ERROR_CONNECT: stat.connect++; Serial.print("Gabimi i lidhjes,\t"); pushim; rasti DHTLIB_ERROR_ACK_L: stat.ack_l++; Serial.print ("Ack Low error,\t"); pushim; rasti DHTLIB_ERROR_ACK_H: stat.ack_h++; Serial.print ("Ack High error,\t"); pushim; default: stat.unknown++; Serial.print("Gabim i panjohur,\t"); pushim; ) if(bmpFlag ! = 0 || !event.pressure) // përditësoni të dhënat ( tft.fillRect(0, 30, 160, 6, ST7735_BLACK); tft.setCursor(0, 30); tft.setTextColor(ST7735_RED); printValue("GABIM BMP INITIALIZATION", 0 , "", true); ) other ( if(event.pressure != OldPressure) (tft.fillRect(0, 30, 160, 7, ST7735_BLACK); tft.setCursor(0, 30); tft.setTextColor(ST7735_RED) ; printValue("Presion", event.presioni, "hPa", e vërtetë); oldPressure = ngjarje.presioni; ishteUpdate = e vërtetë; ) if(temperatura != OldTemperature) ( tft.fillRect(0, 38, 160, 7, ST7735_BLACK ); tft.setCursor (0, 38); tft.setTextColor (ST7735_WHITE); printValue ("Temperatura", temperatura, "C", e vërtetë); e vjetërTemperatura = temperatura; ishte Përditësuar = e vërtetë; ) if(lartësia !=lartësia e vjetër) ( tft.fillRect(0, 46, 160, 7, ST7735_ZEZE); tft.setCursor(0, 46); tft.setTextColor(ST7735_BLUE); printValue("Lartësia", lartësia, "m", e vërtetë); oldAltitude = lartësi; wasUpdate = true; ) ) if(DHT.lagështia != vjetërDHTHlagështia) (tft.fillRect(0, 54, 160, 7, ST7735_BLACK); tft.setCursor(0, 54); tft.setTextColor(ST7735_GREEN); printValue("Lagështia", DHT.lagështia, "%", e vërtetë); vjetërDHTHlagështia = DHT.lagështia; wasUpdate = e vërtetë; ) if(DHT.temperaturë != e vjetërDHTTtemperatura) (tft.fillRect(0, 80, 160, 7, ST7735_BLACK); tft.setCursor(0, 80); tft.setTextColor(ST7735_YELLOW); Vlera e printimit("DHT_temperaturë"DHT_temperaturë. temperatura, "C", e vërtetë); e vjetërDHTTtemperatura = DHT.temperatura; ishtePërditësuar = e vërtetë; ) if(wasUpdate) ( Serial.println("END_TRANSMISSION"); ) wasUpdate = false; vonesë (10000); ) void printValue(titulli char*, vlera e dyfishtë, masa char*, bool tftPrint) ( if(tftPrint) // printoni të dhënat në TFT ( tft.print(title); tft.print(": "); tft.print( vlera); tft.println(masë); ) Serial.print(titulli); // dërgoni të dhëna te porta serike Serial.print(": "); Serial.print(vlera); Serial.println(masë); )

Është koha për të montuar trupin

Kushti kryesor i kursit ishte një prototip pune në një formë të paraqitshme. Prandaj, më duhej të blija një banesë dhe, të armatosur me një skedar, të fusja stacionin e motit në banesë në çfarëdo mënyre.

Rasti është blerë nga një dyqan lokal radio elektronik.

Kornizë

(Rasti në foto është pak më ndryshe. Unë kam një kapak transparent)



Më pas, duke përdorur një skedar, u bënë vrima për të nxjerrë sensorët dhe për të furnizuar energjinë. Vendosa t'i zhvendos sensorët jashtë, sepse gjatë testimit të sistemit pa kasë, vura re se pjesa e pasme e ekranit u nxeh shumë, gjë që do të ndikonte në temperaturën brenda kasës.

Strehimi me hapje për sensorë dhe energji elektrike



Meqenëse më është dashur të bashkoj këmbët në 2 sensorë dhe kam djegur pistën në njërin prej tyre, vendosa të mos tundoj fatin dhe të mos bashkoj telat në sensorë (do të praktikoj diçka tjetër), por në mënyrë që të lidhet për të qenë pak a shumë i besueshëm, vendosa të mbështjella shiritin elektrik.

Sistemi përpara se të "mbushet" në strehim



Meqenëse kasa është shumë më e madhe se Arduino (nuk kishte më të vogël), më duhej të krijoja një mbështetje në mënyrë që bordi të mos lëvizte brenda kasës. Gjithashtu, nga shkuma ishte prerë një figurë dhe në të kishte një drejtkëndësh për ekranin për të fshehur pjesët e brendshme të kasës. Nuk kisha ngjitës në dorë, kështu që më duhej të përdorja shirit të dyanshëm.

Miracle-yuda peshk-balenë



Vidhni kapakun, lidhni rrymën dhe prisni.

Stacioni i kompletuar meteorologjik në ndërtesë



Pas shfaqjes së rezultateve në ekran, ne identifikojmë një gabim të pakëndshëm në matjen e lagështisë: DHT22 prodhon me zell shifrën 99,90% (1,00% është jashtëzakonisht e rrallë). Le të fillojmë të kuptojmë se cili është problemi. Gjëja e parë që bëjmë është të shikojmë daljen e vlerave në portin COM. Ndihet mire. Pas disa rimbushjeve, çmontimit dhe rimontimit të kasës, më vjen në mendje ideja për të kërkuar përgjigjen në Google. Siç pritej, Google rus nuk tha asgjë të dobishme. NE RREGULL. Fillojmë të kërkojmë në anglisht dhe në një nga forumet hasim djem me një problem të ngjashëm. Katër faqet e para të diskutimit nuk japin asgjë të dobishme, por në faqen e pestë gjejmë përgjigjen e pyetjes sonë:
Sensorët e lagështisë mund të ndikohen lehtësisht nga gazrat e gabuar ose ekspozimi shumë i gjatë ndaj lagështisë së lartë IIRC. Në fletën e të dhënave ekziston një procedurë se si të "rivendosni" sensorin, mund ta provoni.

E vetmja pyetje që mbeti ishte kur dhe si arrita të dëmtoj DHT22. Por po afrohej koha për të ndjekur lëndët dhe kështu zgjidhjen e këtij problemi e lashë për më vonë.

Pasthënie

Kursi u kalua. Stacioni meteorologjik është shtyrë për një kohë të pacaktuar deri në mbylljen e të gjitha mbetjeve në universitet. Megjithatë, na u desh të ktheheshim në stacionin e motit më herët se sa mendova. Ndodhi që në mes të nëntorit ndryshova vendin tim të punës dhe në ekipin e ri takova njerëz që janë të interesuar për platformën Arduino dhe të ngjashme. Prandaj, interesimi im për këtë platformë, pa pasur kohë për t'u qetësuar, u ndez përsëri. Nxora stacionin tim të motit, e lidha me kompjuterin dhe u kujtova se kam zbatuar transferimin e të dhënave nga Arduino përmes portit COM. Dhe më pas më lindi ideja për të shkruar një program që merr të dhëna përmes portit COM nga Arduino dhe i transmeton këto të dhëna në monitorimin publik, por kjo është një histori krejtësisht e ndryshme.

Unë gjithashtu do të doja të kisha sensorë me valë dhe ende të zbatoja një stacion moti në Arduino Pro Mini. Prandaj, porosita 4 Arduino Pro Mini me furnizim me energji 3.3V, 4 module radio nRF24L01+ dhe disa sensorë shtesë, për të cilët do të përpiqem të flas edhe herën tjetër. Ndërkohë, jam duke pritur për parcelën, ka plane për të zbatuar lidhjen e një ore në kohë reale për të ruajtur kohën e përditësimit të të dhënave dhe vetë të dhënat në një kartë microSD, me kusht që të mos ketë lidhje me klient përmes portit COM.

Ju mund të ndihmoni dhe transferoni disa fonde për zhvillimin e faqes



Një ditë, duke shëtitur nëpër qytet, pashë një dyqan të ri radio elektronike që ishte hapur. Pasi hyra në të, gjeta një numër të madh mburojash për Arduino sepse... Në shtëpi kisha një Arduino Uno dhe një Arduino Nano dhe menjëherë lindi ideja për të luajtur me transmetuesit e sinjalit në distancë. Vendosa të blej transmetuesin dhe marrësin më të lirë në 433 MHz:

Transmetuesi i sinjalit.


Marrës sinjalesh.

Pasi regjistroi një skicë të thjeshtë të transmetimit të të dhënave (një shembull i marrë nga këtu), doli që pajisjet transmetuese mund të jenë mjaft të përshtatshme për transmetimin e të dhënave të thjeshta, si temperatura, lagështia.

Transmetuesi ka karakteristikat e mëposhtme:
1. Modeli: MX-FS - 03V
2. Gama (në varësi të pranisë së objekteve bllokuese): 20-200 metra
3. Tensioni i funksionimit: 3.5 -12V
4. Përmasat e modulit: 19 * 19 mm
5. Modulimi i sinjalit: AM
6. Fuqia e transmetuesit: 10mW
7. Frekuenca: 433 MHz
8. Gjatësia e kërkuar e antenës së jashtme: 25cm
9. Lehtë për t'u lidhur (vetëm tre tela): DATA ; KQV ; Toka.

Karakteristikat e modulit të marrjes:
1. Tensioni i funksionimit: DC 5V
2. Rryma: 4mA
3. Frekuenca e funksionimit: 433.92 MHz
4. Ndjeshmëria: - 105dB
5. Përmasat e modulit: 30 * 14 * 7 mm
6. Kërkohet antenë e jashtme: 32 cm.

Interneti thotë se diapazoni i transmetimit të informacionit me 2 Kb/sek mund të arrijë deri në 150 m. Unë nuk e kam kontrolluar vetë, por në një apartament me dy dhoma pranohet kudo.

Pajisjet e stacionit të motit në shtëpi

Pas disa eksperimenteve, vendosa të lidh një sensor të temperaturës, lagështisë dhe transmetuesit me Arduino Nano.


Sensori i temperaturës DS18D20 është i lidhur me Arduino si më poshtë:

1) GND në minus të mikrokontrolluesit.
2) DQ përmes një rezistence tërheqëse në tokë dhe në pin D2 të Arduino
3) Vdd në +5V.

Moduli i transmetuesit MX-FS - 03V mundësohet nga 5 Volt, dalja e të dhënave (ADATA) është e lidhur me pinin D13.

Kam lidhur një ekran LCD dhe një barometër BMP085 me Arduino Uno.


Diagrami i lidhjes me Arduino Uno

Marrësi i sinjalit është i lidhur me pinin D10.

Moduli BMP085 - sensor dixhital i presionit atmosferik. Sensori ju lejon të matni temperaturën, presionin dhe lartësinë mbi nivelin e detit. Ndërfaqja e lidhjes: I2C. Tensioni i furnizimit të sensorit 1.8-3.6 V

Moduli është i lidhur me Arduino në të njëjtën mënyrë si pajisjet e tjera I2C:

  • KQV - KQV (3.3 V);
  • GND - GND;
  • SCL - në pinin analog 5;
  • SDA - në pinin analog 4.
  • Kosto shumë e ulët
  • Fuqia dhe I/O 3-5 V
  • Përcaktimi i lagështisë 20-80% me saktësi 5%.
  • Zbulimi i temperaturës 0-50 gradë. me saktësi 2%.
  • Frekuenca e votimit jo më shumë se 1 Hz (jo më shumë se një herë në 1 sekondë)
  • Dimensionet 15.5mm x 12mm x 5.5mm
  • 4 kunja me hapësirë ​​0,1" të kunjave

DHT ka 4 kunja:

  1. Vcc (furnizimi me energji 3-5V)
  2. Dalja e të dhënave - Dalja e të dhënave
  3. I pa perdorur
  4. Gjeneral

Lidhet me D8 të Arduino.

Softueri pjesë e një stacioni meteorologjik në shtëpi

Moduli transmetues mat dhe transmeton temperaturën çdo 10 minuta.

Më poshtë është programi:

/* Sketch version 1.0 Dërgo temperaturën çdo 10 minuta. */ #include #include #include #define ONE_WIRE_BUS 2 //Pin për lidhjen e sensorit të Dallas OneWire oneWire(ONE_WIRE_BUS); Sensorët e temperaturës në Dallas (&oneWire); Adresa e pajisjes brenda Termometrit; void setup(void) (//Serial.begin(9600); vw_set_ptt_inverted(true); // Nevojshme për DR3100 vw_setup(2000); // Cakto shpejtësinë e zhurmës (bit/s) sensorë.begin(); nëse (! sensorë .getAddress(brendaTermometer, 0)); printAddress(brenda Termometri); sensors.setResolution(brenda Termometri, 9); ) printim i pavlefshëm(Adresa e pajisjes së Adresës) (float tempC = sensors.getTempC(deviceAddressprint);/"emp. C : "); //Serial.println(tempC); //Formimi i të dhënave për dërgimin e numrit int = tempC; simboli char = "c"; //Simboli i shërbimit për përcaktimin se ky është një sensor String strMsg = "z" ; strMsg += simbol; strMsg += " "; strMsg += numër; strMsg += " "; char msg; strMsg.toCharArray(msg, 255); vw_send ((uint8_t *)msg, strlen(msg)); vw_prit_ (); / / Prisni derisa transferimi të përfundojë vonesë(200); ) void loop(void) (për (int j=0; 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); } }

Pajisja marrëse merr të dhëna, mat presionin dhe temperaturën në dhomë dhe i transmeton ato në ekran.

#include #include LCD Crystal Liquid(12, 10, 5, 4, 3, 2); #përfshi sensorin dht11; #define DHT11PIN 8 #include #include BMP085 dps = BMP085(); gjatë Temperatura = 0, Presioni = 0, Lartësia = 0; void setup() ( Serial.begin(9600); vw_set_ptt_inverted(true); // E nevojshme për DR3100 vw_setup(2000); // Cakto shpejtësinë e marrjes vw_rx_start(); // Fillo monitorimin e transmetimit lcd.begin(16, 2) ; Wire.begin(); vonesë(1000); dps.init(); //lcd.setCursor(14,0); //lcd.write(byte(0)); //lcd.home(); ) void loop() ( uint8_t buf; // Buffer për mesazhin uint8_t buflen = VW_MAX_MESSAGE_LEN; // Gjatësia e buferit nëse (vw_get_message(buf, &buflen)) // Nëse mesazhi është marrë ( // Filloni analizimin int i; // Nëse mesazhi nuk na drejtohet neve, dilni nëse (buf != "z") (kthim; ) komanda char = buf; // Komanda është në indeksin 2 // Parametri numerik fillon në indeksin 4 i = 4; numri int = 0; // Meqenëse transmetimi është karakter pas karakteri, atëherë duhet të konvertoni grupin e karaktereve në një numër ndërsa (buf[i] != " ") (numri *= 10; numri += buf[i] - "0"; i++; ) dps.getPressure(&Pressure); dps.getAltitude (&Altitude); dps.getTemperature(&Temperature); //Serial.print(command); Serial.print(" "); Serial.println( numri); lcd.print("T="); lcd.setCursor(2,0); lcd.print(numri); lcd.setCursor(5,0); lcd.print("P="); lcd.print(Presion/133.3); lcd.print("mmH"); lcd.setCursor(0,1); lcd.print("T="); lcd.print(Temperatura*0.1); lcd.print("H="); LCD.print(sensor.lagështia); LCD.home(); //vonesa (2000); int chk = sensor.lexo(DHT11PIN); ndërprerësi (chk) (rasti DHTLIB_OK: //Serial.println("OK"); pushim; rasti DHTLIB_ERROR_CHECKSUM: //Serial.println("Gabim i shumës së kontrollit"); ndërprerje; rasti DHTLIB_ERROR_TIMEOUT: //Serial.println("Përfundoi koha gabim"); pushim; parazgjedhje: //Serial.println("Gabim i panjohur"); pushim; ) ) )

P.S. Në të ardhmen planifikoj të shtoj sa vijon:
- Sensori i lagështisë në transmetues, ripërpunoni algoritmin e transmetimit të të dhënave
- sensor për matjen e shpejtësisë dhe drejtimit të erës.
- shtoni një ekran tjetër në pajisjen marrëse.
- transferoni marrësin dhe transmetuesin në një mikrokontrollues të veçantë.

Më poshtë keni një foto të asaj që ndodhi:

Lista e radioelementeve

Emërtimi Lloji Emërtimi sasi shënimDyqanblloku im i shënimeve
Pjesa transmetuese.
Pllaka Arduino

Arduino Nano 3.0

1 Në bllokun e shënimeve
sensor temperature

DS18B20

1 Në bllokun e shënimeve
Rezistencë

220 Ohm

1 Në bllokun e shënimeve
Moduli i transmetuesitMX-FS-03V (433 MHz)1 Në bllokun e shënimeve
Pjesë marrëse e radios.
Pllaka Arduino

Arduino Uno

1 Në bllokun e shënimeve
Rezistencë prerëse 1 Në bllokun e shënimeve
Rezistencë

Projekti i stacionit të motit nga libri i V. Petin "Projektet duke përdorur kontrolluesin Arduino", botimi i dytë (projekti 5, shtojca 2) është marrë si bazë. Përdorur Arduino IDE 1.8.5 në Windows 10.
U shfaq një gabim gjatë ekzekutimit të skicës

Në internet mund të shkarkoni biblioteka për Arduino që kanë të njëjtat emra, por përmbajtje të ndryshme. Skica mund të mos funksionojë nëse po përdorni bibliotekën e gabuar. Me sa duket kam hasur në bibliotekat e gabuara. Shtova një sensor BMP180 në projekt për të matur presionin atmosferik dhe ripërpunova skicën.

Diagrami i lidhjes

Skanimi i adresave

Së pari, lidhni sensorin BMP180 dhe treguesin LCD1602 me Arduino. Përpiloni skicën e skanerit I2C dhe ekzekutoni atë për të përcaktuar adresat e pajisjeve në autobusin I2C.

Çdo 5 sekonda programi skanon pajisjet dhe adresat e problemeve në portën COM. Gjeta dy pajisje me adresat 0x3F dhe 0x77. BMP180 si parazgjedhje ka adresën 0x77, që do të thotë se treguesi LCD ka adresën 0x3F.
Në disa qarqe të librit, vendet ku sinjalet SDA dhe SCL janë të lidhura me tabelën Arduino janë të përziera. Duhet të jetë: SDA - në A4, SCL - në A5. Nëse moduli BMP180 ka pesë kunja, atëherë +5 Volt i jepet pinit VIN.

Diagrami i instalimeve elektrike

Tani montoni plotësisht qarkun. Kam përdorur një katodë të zakonshme RGB LED të montuar në tabelë së bashku me rezistorë 150 ohm. Katoda e zakonshme është e lidhur me pinin GND, kunjat e mbetura janë të lidhura sipas diagramit. Nuk ka nevojë të bëni ndryshime në skicë, pasi shkëlqimi i LED-ve ndryshon sipas një ligji ciklik.
Diagrami tregon lidhjen e një LED RGB me një anodë të zakonshme, si në libër.
Nëse asnjë karakter nuk është i dukshëm në ekranin LCD1602, ktheni kontrollin e ndriçimit. Drita e prapme e treguesit konsumon mjaft rrymë, prandaj përdorni një furnizim me energji elektrike me një rrymë prej të paktën 2 A. Kam përdorur një shpërndarës USB me një furnizim të jashtëm 2 A.
Qarku përdori një zile piezo ZP-22. Rezistenca e lidhur me zilen është 100 ohms. Frekuenca e zërit mund të ndryshohet në program. Zgjodha një frekuencë prej 1000 Hz. Nëse hasni një sinjalizues me një frekuencë fikse tingulli, atëherë mund ta ndizni dhe fikni thjesht duke aplikuar dhe hequr tensionin, si një LED i rregullt. Kur fillon skica, bie një bip i shkurtër. Mund të aktivizoni sinjalizimin periodik ndërkohë që programi është duke u ekzekutuar duke mos komentuar linjën //bzz(100); në skicë.
Në projekt përdora një sensor DHT11 në formën e një moduli me një rezistencë 4.7 kOhm të montuar tashmë. Rezistenca mund të jetë nga 4.7 në 10 kOhm.
Lidhni kutinë Vcc të modulit të orës DS1302 me autobusin +5 Volt. Në këtë mënyrë ju do të zvogëloni shkarkimin e baterisë, në thelb ajo do të funksionojë vetëm kur energjia e Arduino është e fikur.

Programi (skica)

Biblioteka bmp085 përdoret për të shërbyer BMP180. Vlera e presionit varet nga lartësia e zonës. Për vlerën e saktë të presionit atmosferik, duhet të zgjidhni lartësinë. Për ta bërë këtë, modifikoni rreshtin dps.init(MODE_STANDARD, 10000, true); Lartësia ime është 100 m (10000 cm). Fragmenti i llogaritjes së presionit është marrë nga shembulli BMP085_test2.ino i bibliotekës bmp085.

Skica meteo_P

#përfshi
#përfshi
#përfshi
#përfshi "DHT.h"
#përfshi
BMP085 dps = BMP085();
Presioni i gjatë = 0, Lartësia = 0;
kohë e gjatë e panënshkruar1 = 0;

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

int kCePin = 4; // RST DS1302
int kIoPin = 3; // Të dhënat 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); // shkruani adresën tuaj 0x20...0xff adresën
memTime e gjatë e panënshkruar;
int bzzPin = 8;

void HumTempRead() (
float hum = dht.lexo Lagështia();
float temp = dht.lexoTemperature();
nëse (isnan(hum) || isnan(temp)) (
Serial.println("Dështoi të lexohej nga sensori DHT!");
lcd.setCursor(0, 1);
lcd.print("H=--% T=---");
lcd.setCursor(11, 1);
lcd.print((char)223);
lcd.setCursor(12, 1);
lcd.print("C");
) tjeter (
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); // frekuenca 1000 Hz
}

konfigurimi i zbrazët () (
Seriali.fillim(9600);
Wire.begin();
vonesë (1000);

dps.init (MODE_STANDARD, 10000, e vërtetë); // 100 metra (lartësia mbi nivelin e detit në cm)

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

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

rtc.ndalt(false);
rtc.writeProtect(false);

//rtc.setDOW(E Premte); // Cakto ditën e javës në FRIDAY cakto ditën e javës
//rtc.setTime(4, 58, 0); // Cakto orën në 12:00:00 (format 24 orë)
//rtc.setDate(6, 8, 2010); // Cakto datën në 6 gusht 2010, cakto datën (ditën, muajin, vitin)
}

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

nëse ((millis() - memTime > 2000) ose (millis()< memTime)) { // DHT11/22 1 time each 2 seconds
HumTempRead();
memTime = millis();
}
vonesë (100);

nëse (((millis() - koha1) / 1000.0) >= 1.0) (
dps.calcTrueTemperature();
koha1 = millis();
}
dps.getPressure(&Pressure);
Serial.print(" Presioni (Pa):");
Serial.println(Presion);

i gjatë p2;
int pi;
p2 = (Presioni / 133.3224); // Pa në mmHg.
pi = trunc(p2); // duke hedhur poshtë pjesën thyesore të numrit

lcd.setCursor(0, 0);
lcd.print("P=");
lcd.setCursor(2, 0);
LCD.print(pi); // atm dalje. presioni në LCD
lcd.setCursor(5, 0);
lcd.print("mm");
// vonesë (3000);
//bzz(100); // ankokomento nëse dëshiron të dëgjosh sinjale
{
për (vlera int = 0 ; vlera<= 255; value += 1) {
analogWrite (REDpin, vlera);
analogWrite(GREENpin, 255 - vlera);
analogWrite (Bluepin, 255);
vonesë (5);
}

për (vlera int = 0; vlera<= 255; value += 1) {
analogWrite (REDpin, 255);
analogWrite(GREENpin, vlera);
analogWrite(Bluepin, 255 - vlera);
vonesë (5);
}

për (vlera int = 0; vlera<= 255; value += 1) {
analogWrite(REDpin, 255 - vlera);
analogWrite(GREENpin, 255);
analogWrite(Bluepin, vlera);
vonesë (5);
}
}
}

Në Katalogun e skedarëve mund të shkarkoni skicën dhe bibliotekat që janë përdorur në projekt.

Importoni bibliotekat LiquidCrystal_I2C.zip, bmp085.zip, DS1302.zip dhe DHT.zip nga arkivi i shkarkuar në Arduino IDE. Shkoni te menyja Skicë Lidh bibliotekën Shto bibliotekën .ZIP... dhe në dritare zgjidhni arkivin zip të bibliotekës.
Ngarko skicën meteo_P. Zëvendësoni adresën LCD1602 në skicë me vlerën e marrë duke skanuar autobusin I2C. Përpiloni dhe ekzekutoni skicën.
Nëse skica funksionon, hapni monitorin e portit dhe shikoni mesazhet e shfaqura. Rregulloni lartësinë në deklaratën dps.init(MODE_STANDARD, 10000, true); për të marrë vlerat reale të presionit.
Vendosni orën tuaj. Çkomentoni rreshtin //rtc.setTime(4, 58, 0); dhe në kllapa tregoni kohën aktuale (orë, minuta dhe sekonda të ndara me presje) dhe ringarkoni skicën në kontrollues. Pasi të caktohet koha, komentoni përsëri këtë rresht dhe riprodhoni skicën përsëri.
Nëse ndriçimi i dritës së natës ju bezdis, mund ta rregulloni duke ndryshuar gjatësinë e vonesës në sythe për në fund të skicës. Me vonesë (2); cikli zgjat 2-3 sekonda, me vonesë(5); — nga 4 deri në 5 sekonda, me vonesë (30); - deri në 15-16 sekonda. Informacioni mbi treguesin do të përditësohet në të njëjtin interval.
Kur përdorni stacionin e motit në mënyrë autonome, d.m.th. pa u lidhur me portën USB të kompjuterit, komentoni linjat në skicë me fjalët Serial ... për të çaktivizuar daljen e informacionit në monitorin e portës COM.

PS. Në skicën e librit dhe në shembujt për bibliotekën DHT, tregohet linja e përkufizimit #define DHTTYPE DHT 11. Skica fillon, por rrëzohet pas disa orësh. Ora ndalon, ekrani nuk ndryshon. Një mesazh i paqartë shfaqet në monitorin e portit, i cili përmban një lidhje me dht.
Në këtë rresht hoqa shkronjat DHT, d.m.th. bëri #define DHTTYPE 11. Pas kësaj, skica filloi të funksionojë në mënyrë të qëndrueshme.

Artikulli u përditësua më 25 qershor 2018

Burimet e përdorura
1. Petin V.A. Projekte duke përdorur kontrolluesin Arduino (Elektronikë) Edicioni i dytë, Shën Petersburg. BHV-Petersburg, 2015 464 f.
2. Petin V. A., Binyakovsky A. A. Enciklopedia praktike e Arduino. - M., DMK Press, 2017. - 152 f.
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. shembull BMP085_test2.ino nga biblioteka 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/

Artikujt më të mirë mbi këtë temë