Kako postaviti pametne telefone i računala. Informativni portal
  • Dom
  • U kontaktu s
  • Projekti Arduino pro mini meteorološke stanice. BMP085 Modul senzora barometarskog tlaka za arduino (ili kako napraviti meteorološku stanicu vlastitim rukama)

Projekti Arduino pro mini meteorološke stanice. BMP085 Modul senzora barometarskog tlaka za arduino (ili kako napraviti meteorološku stanicu vlastitim rukama)

Kao i većina radnih ljudi, bavljenje vlastitim projektima oduzima jedino slobodno vrijeme koje vam preostaje. Zato dugo nisam ništa stvarao i žudio sam da nešto napravim. Ova prilika pojavio se, začudo, na sveučilištu. Rujan je pred prozorom, 4. godina i nadolazeći kolegij o dizajnu sklopova. Rečeno nam je da se kolegij može raditi u dvije varijante: papirnati i hardverski.

5 godina rad na papiru na našem fakultetu odvijao se po principu “uzmi stare i sastavi ih”. Ovakav pristup mi nije odgovarao zbog svoje rutine pa sam odmah odabrao tečaj iz hardvera. Kao srce tečaja predloženo je Arduino mikrokontroler zbog lakoće učenja. Nakon određivanja vrste kolegija ostalo je još jedno pitanje: što točno treba napraviti. Kako nisam imao iskustva u programiranju mikrokontrolera, odmah sam otvorio Google i počeo proučavati postojeće projekte. Postoji mnogo projekata, neki od njih su prilično jednostavni, neki su genijalni (3D skener, na primjer), ali velika većina nije imala praktična aplikacija. A samo sam htjela nešto što neće ležati na polici i skupljati prašinu. Nakon polusatnog izleta u svijet Arduina, zainteresirala me tema kućnih meteoroloških stanica, a projekti se nisu činili teško izvedivi (što je pridošlicu najviše privuklo).

Tako je odabrana tema za kolegij i s vremenom se činilo da nema problema.

Odabir komponente

Pregledavajući različite projekte, shvatio sam da Nano ili čak Pro Mini, ali sam ipak odabrao Arduino Uno u nadi da ću zavoljeti programiranje za Arduino i da ću u budućnosti realizirati još neke projekte. Nikad prije nisam držao lemilicu u rukama pa sam radi lakšeg razvoja odlučio kupiti i Sensor Shield v4.

Više detalja

Naknada doprinosi brza veza senzore, module, servo motore, serijska i I2C sučelja, a također prikazuje sve portove kontrolera Duemilanova/Uno form faktora (može se spojiti i na mega seriju, ali uz ograničenja i posljedice koje iz toga proizlaze). Podržava druge štitove na sebi.


Kao izvore meteoroloških podataka odabrao sam sljedeće senzore:


Odlučio sam se za senzore. Ali što učiniti s podacima koji dolaze sa senzora? Odlučio sam ga prikazati. Htio sam sliku u boji, pa sam odmah odbacio jednobojna rješenja. Nakon nekoliko minuta traženja odabran je ST7735 1,8-inčni TFT zaslon.

Više detalja

Budući da zaslon koristi 4-žilni SPI protokol za komunikaciju i ima vlastiti međuspremnik okvira koji se može adresirati pikselima, može se koristiti s bilo kojom vrstom mikrokontrolera. Zaslon od 1,8 inča ima 128x160 piksela u boji. Tu je i utor za kartice microSD memorija, stoga možete jednostavno preuzeti punu boju rasterske slike iz FAT16/FAT32 sustav datoteka microSD kartice.

Karakteristike:

  • Dijagonala zaslona - 1,8 inča, rezolucija 128x160 piksela, 18-bitna boja (262 144 boje)
  • Kontroler s ugrađenim adresiranjem piksela međuspremnika video memorije
  • Ugrađeni microSD utor - koristi više od 2 digitalne linije
  • Kompatibilan s 3,3 i 5V
  • Dimenzije: 34 mm x 56 mm x 6,5 m


Programiranje Arduino kontrolera

Nakon što smo se odlučili za komponente za meteorološku stanicu, krećemo s programiranjem kontrolera. Okruženje koje se koristi za Arduino firmware Arduino razvoj IDE. Također se koriste biblioteke iz Adafruita.

Prije nego prijeđemo na skicu, pogledajmo funkcionalnost:

  • Očitavanja se uzimaju sa senzora svakih 10 sekundi, a na ekranu se ažuriraju samo oni pokazatelji koji su se promijenili u odnosu na prethodno mjerenje
  • Implementiran prijenos podataka preko COM porta

Skica

#uključi // biblioteka za komunikaciju s I2C uređajima #include // Osnovna biblioteka za sve senzore #include // biblioteka za BMP180 #include // Osnovna grafička biblioteka #include // Biblioteka specifična za hardver #include // biblioteka za komunikaciju sa SPI uređajima #include "dht.h" // biblioteka za DHT #define DHT22_PIN 2 // spojite podatkovni pin DHT22 na 2 digitalni pin #define TFT_CS 10 // spojite CS pin TFT-a na 10 digitalni pin #define TFT_RST 9 // spojite RST pin TFT-a na 9 digitalni pin // ovo također možete spojiti na Arduino reset // u kojem slučaju postavite ovaj #define pin na 0! #define TFT_DC 8 // spojite DC pin TFT-a na 8 digitalni pin Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST); //inicijalizirati TFT #define TFT_SCLK 13 // spojiti SCLK pin TFT-a na 13 digitalni pin #define TFT_MOSI 11 // spojiti MOSI pin TFT-a na 11 digitalni pin dht DHT; Adafruit_BMP085_Unified bmp = Adafruit_BMP085_Unified(10085); //inicijaliziraj BMP180 int bmpFlag = 0; struct ( uint32_t total; uint32_t ok; uint32_t crc_error; uint32_t time_out; uint32_t povezivanje; uint32_t ack_l; uint32_t ack_h; uint32_t unknown; ) stat = ( 0,0,0,0,0,0,0,0); // struktura za dht status void setup(void) ( Serial.begin(9600); Serial.println("Meteo Test"); Serial.println(""); if(!bmp.begin()) // provjeri vezu za BMP180 ( Serial.print("Ooops, nije otkriven BMP180 ... Provjerite svoje ožičenje ili I2C ADDR!"); bmpFlag = 1; ) tft.initR(INITR_BLACKTAB); // Inicijalizirajte TFT i ispunite crnom bojom tft.fillScreen (ST7735_BLACK); tft.setRotation(tft.getRotation() + 1); tft.setTextSize(1.5); delay(500); // odgoda kako bi se osiguralo da je TFT inicijaliziran ) // zadnji izmjereni podaci float oldTemperature = 0 , stara nadmorska visina = 0, stari pritisak = 0, staraDHTHvlažnost = 0, staraDHTTtemperatura; bool wasUpdate = false; void loop(void) ( if(Serial.available() > 0) // imamo podatak serijski port ( Serial.read(); // čitanje bajta sa serijskog porta i slanje zadnjih izmjerenih podataka printValue("Pressure", oldPressure , " hPa", false); printValue("Temperatura", oldTemperature, " C", false); printValue("Nadmorska visina", oldAltitude, " m", false); printValue("Vlažnost", oldDHTHvlažnost, "%", false); printValue("DHT_temperature", oldDHTTemperature, " C", false); Serial.println("END_TRANSMISSION"); ) sensors_event_t događaj; temperatura plovka, nadmorska visina; if(bmpFlag == 0)( bmp.getEvent(&event) ; // dobivanje podataka iz BMP180 if (event.pressure) ( bmp.getTemperature(&temperature); float seaLevelPressure = SENSORS_PRESSURE_SEALEVELHPA; altitude = bmp.pressureToAltitude(seaLevelPressure, event.pressure, temperature); ) else ( Serial.println("Senzor) greška"); ) ) uint32_t start = micros(); int chk = DHT.read22(DHT22_PIN); // dobivanje podataka iz DHT22 uint32_t stop = micros(); stat.total++; switch (chk) // provjera statusa DHT22 ( slučaj DHTLIB_OK: stat.ok++; pauza; case DHTLIB_ERROR_CHECKSUM: stat.crc_error++; Serial.print("Pogreška kontrolnog zbroja,\t"); pauza; case DHTLIB_ERROR_TIMEOUT: stat.time_out++; Serial.print("Greška isteka vremena,\t"); pauza; case DHTLIB_ERROR_CONNECT: stat.connect++; Serial.print("Pogreška povezivanja,\t"); pauza; case DHTLIB_ERROR_ACK_L: stat.ack_l++; Serial.print("Ack Low error,\t"); pauza; case DHTLIB_ERROR_ACK_H: stat.ack_h++; Serial.print("Ack High error,\t"); pauza; zadano: stat.unknown++; Serial.print("Nepoznata pogreška,\t"); pauza; ) if(bmpFlag ! = 0 || !event.pressure) // ažuriranje podataka ( tft.fillRect(0, 30, 160, 6, ST7735_BLACK); tft.setCursor(0, 30); tft.setTextColor(ST7735_RED); printValue("GREŠKA BMP INICIJALIZACIJE", 0 , "", istina); ) else ( if(event.pressure != oldPressure) ( tft.fillRect(0, 30, 160, 7, ST7735_BLACK); tft.setCursor(0, 30); tft.setTextColor(ST7735_RED) ; printValue("Tlak", event.pressure, " hPa", true); oldPressure = event.pressure; wasUpdate = true; ) if(temperature != oldTemperature) ( tft.fillRect(0, 38, 160, 7, ST7735_BLACK) ); tft.setCursor(0, 38); tft.setTextColor(ST7735_WHITE); printValue("Temperatura", temperatura, " C", true); oldTemperature = temperatura; wasUpdate = true; ) if(visina != oldAltitude) ( tft.fillRect(0, 46, 160, 7, ST7735_BLACK); tft.setCursor(0, 46); tft.setTextColor(ST7735_BLUE); printValue("Visina", visina, " m", istina); oldAltitude = visina; wasUpdate = true; ) ) if(DHT.humidity != oldDHTHhumidity) ( tft.fillRect(0, 54, 160, 7, ST7735_BLACK); tft.setCursor(0, 54); tft.setTextColor(ST7735_GREEN); printValue("Vlažnost", DHT.vlažnost, "%", istina); oldDHTHvlažnost = DHT.vlažnost; wasUpdate = istina; ) if(DHT.temperature != oldDHTTemperature) ( tft.fillRect(0, 80, 160, 7, ST7735_BLACK); tft.setCursor(0, 80); tft.setTextColor(ST7735_YELLOW); printValue("DHT_temperature", DHT. temperatura, " C", istina); oldDHTTempature = DHT.temperatura; wasUpdate = true; ) if(wasUpdate) ( Serial.println("END_TRANSMISSION"); ) wasUpdate = false; kašnjenje (10000); ) void printValue(char* naslov, dvostruka vrijednost, char* mjera, bool tftPrint) ( if(tftPrint) // ispis podataka na TFT ( tft.print(title); tft.print(": "); tft.print( vrijednost); tft.println(mjera); ) Serial.print(naslov); // slanje podataka na serijski port Serial.print(": "); Serial.print(vrijednost); Serial.println(mjera); )

Vrijeme je za sastavljanje tijela

Glavni uvjet tečaja bio je radni prototip u prezentiranom obliku. Stoga sam morao kupiti kućište i, naoružan turpijom, na bilo koji način umetnuti meteorološku stanicu u kućište.

Kućište je kupljeno u lokalnoj trgovini radioelektronike.

Okvir

(kutija na fotografiji je malo drugačija. ja imam proziran poklopac)



Zatim su pomoću turpije napravljene rupe za izlaz senzora i napajanje. Odlučio sam pomaknuti senzore van jer sam tijekom testiranja sustava bez kućišta primijetio da se stražnja strana ekrana jako zagrijala, što bi utjecalo na temperaturu unutar kućišta.

Kućište s otvorima za senzore i napajanje



Budući da sam morao zalemiti noge na 2 senzora i spalio sam stazu na jednom od njih, odlučio sam ne iskušavati sudbinu i ne lemiti žice na senzore (vježbat ću na nečemu drugom), ali kako bi spoj da budem koliko-toliko pouzdan, odlučio sam premotati električnu traku.

Sustav prije "trpanja" u kućište



Kako je kućište puno veće od Arduina (manjeg nije bilo), morao sam smisliti nosač da se ploča ne bi pomicala unutar kućišta. Također, od pjene je izrezana figura u kojoj se nalazio pravokutnik za ekran kako bi se sakrila unutrašnjost kućišta. Nisam imao pri ruci superljepilo, pa sam morao upotrijebiti dvostranu traku.

Čudo-juda riba-kit



Zavrnite poklopac, spojite napajanje i pričekajte.

Dovršena meteorološka stanica u zgradi



Nakon prikaza rezultata na ekranu, identificiramo neugodnu pogrešku u mjerenju vlažnosti: DHT22 marljivo proizvodi brojku od 99,90% (1,00% je izuzetno rijetko). Počnimo otkrivati ​​u čemu je problem. Prvo što radimo je da pogledamo izlaz vrijednosti na COM port. Dobar osjećaj. Nakon nekoliko punjenja, rastavljanja i ponovnog sastavljanja kućišta, dolazi mi na pamet ideja da odgovor potražimo na Googleu. Očekivano, ruski Google nije rekao ništa korisno. U REDU. Krenemo tražiti na engleskom i na jednom od foruma naiđemo na dečke sa sličnim problemom. Prve četiri stranice rasprave ne daju ništa korisno, ali na petoj stranici nalazimo odgovor na naše pitanje:
Na senzore vlage lako mogu utjecati pogrešni plinovi ili vrlo dugo izlaganje visokoj vlažnosti IIRC. U podatkovnoj tablici postoji postupak kako "resetirati" senzor, možete pokušati.

Ostalo je samo pitanje kada i kako sam uspio oštetiti DHT22. Ali približavalo se vrijeme za polaganje kolegija i stoga sam rješenje ovog problema ostavio za kasnije.

Pogovor

Nastava je položena. Meteorološka stanica je odgođena na neodređeno vrijeme dok se sva jalovišta na sveučilištu ne zatvore. Međutim, morali smo se vratiti na meteorološku stanicu ranije nego što sam mislio. Dogodilo se da sam sredinom studenog promijenio radno mjesto iu novom timu upoznao ljude koje zanima Arduino platforma i slično. Stoga je moj interes za ovu platformu, a da nisam imao vremena da se ohladim, ponovno planuo. Izvadio sam svoju meteorološku stanicu, spojio je na računalo i sjetio se da sam implementirao prijenos podataka s Arduina preko COM porta. I onda mi je sinula ideja da napišem program koji prima podatke preko COM porta od Arduina i šalje te podatke javnom nadzoru
  • Arduino
  • Dodaj oznake

    Nastavljamo razvijati našu meteorološku stanicu.

    Prije nego što prijeđemo na ažuriranje, želim malo pojasniti.

    Jedan naš kolega mi je pisao zašto je uveden watchdog timer?

    Watchdog timer je postavljen u slučaju nužde. Kao što praksa pokazuje, ENC28J60 ne traje duže (ako memorija ne zakaže) 4 simultane veze. Uzimajući u obzir koliko se uslužnih veza stalno događa da bi se održao rad same mreže i samo lijevog prometa koji stvaraju sve vrste kućanskih igračaka (npr. moderni televizori, skenirajte dostupne hostove na mreži i njihove otvorene portove) dizajn jednostavno pada u stupor. ENC28J60 ne može samostalno raditi s mrežni protokoli a sve se provodi u knjižnicama. Možda su to samo oni.
    Provjerio sve dostupne knjižnice i različite module(iznenada brak), ali postići stabilan rad Dugo nisam mogao. Maksimalni rok bilo je oko 3-4 tjedna.
    Zato se “pas” tu vrti i, ako se nešto dogodi, povlači regulator. Nakon ovoga problem je nestao.
    Također ne poričem da možda postoje određene nijanse ili problemi u mojoj kućnoj mreži. Ali budući da sam ja imao problem, možda ga ima i druga osoba. Do sada sam našao samo ovo rješenje.
    Koliko ja znam, čipovi iz Wizneta (W5100 i noviji) to nemaju ili jednostavno nisu izgledali dovoljno dobro.

    Prijeđimo na ažuriranje

    Što je najvažnije, udaljavamo se od čipa ENC28J60 i idi na W5100. Pokušao sam implementirati sve na starom čipu, ali nema dovoljno memorije mikrokontrolera zbog vrlo velikih biblioteka za ENC28J60. Kada koristite novi čip, standard knjižnicama od programera i svih unesenih promjena, ostaje još više 20% slobodna memorija mikrokontroler ATMega328. A ovo su nove kiflice!

    U ovoj verziji (nazovimo je drugom) mogućnost prijenosa očitanja sa senzora putem bežična komunikacija pomoću frekvencije 433 MHz. Same module sam uzeo od Kineza, oznake XY-MK-5V. Želio bih napomenuti da je kvaliteta prijenosa daleko od savršene. Mogući gubitak signala, šum, nemogućnost simultanog prijenosa itd., itd. Ali njihova cijena (manje od 1 USD po kompletu) nadoknađuje ove nedostatke. Reći ću vam tajnu da se ovi (najjeftiniji) moduli nalaze u mnogim markiranim meteorološkim stanicama kućnu upotrebu. Vau, neočekivano?

    Počnimo s baznom stanicom

    Selimo se u Arduino UNO I Ethernet štit(prva verzija) na temelju čipa W5100. Ovo je sendvič i nema smisla opisivati ​​ga. Opisat ću samo dodatno uključene kontakte za module XY-MK-5V.

    Modul odašiljača koristi struju 5V, GND(gdje bismo bez majke) i D2 pin na kontroleru. Uredi kontakt D2 (PODACI) možete koristiti funkciju vw_set_tx_pin iz vw knjižnice.

    Za razliku od prethodnog skeča, ovaj uključuje dvoje dodatne knjižnice:

    #uključi #uključi

    Sama skica

    Skriveni tekst

    #uključi #uključi #uključi #uključi #uključi #uključi #uključi #uključi #define DHTTYPE DHT22 #define DHTPIN 5 DHT dht(DHTPIN, DHTTYPE); bajt mac = (0x54, 0x34, 0x31, 0x31, 0x31, 0x31); char server = "narodmon.ru"; int port = 8283; IP adresa ip(192,168,0,201); EthernetClient klijent; BMP085 dps = BMP085(); dugo Temperatura = 0, Tlak = 0; plovak H, dP, dPt; bool interval = istina; EasyTransferVirtualWire ET; struct SEND_DATA_STRUCTURE( byte ID; // ID uređaja int Temperatura; // Temperatura float Pressure; // Pressure float Vlažnost; // Vlažnost float dewPoint; // Točka rose/smrzavanja); SEND_DATA_STRUCTURE emitiranje; void setup() ( // Inicijaliziraj Watchdog timer wdt_disable(); delay(8000); wdt_enable(WDTO_8S); // Inicijaliziraj konzolu Serial.begin(9600); // Inicijaliziraj DHT senzor dht.begin(); / / Inicijalizacija 433 MHz modula ET.begin(details(broadcast)); vw_set_ptt_inverted(true); vw_set_tx_pin(2); vw_setup(2000); // Pokretanje mreže, ako nismo čekali podatke s DHCP poslužitelja, zatim // sami sebi dodijelimo adresu if (Ethernet.begin(mac) == 0) Ethernet.begin(mac, ip); // Inicijalizacija 1-Wire Wire.begin(); delay(200); // Inicijalizacija BMP180 s podešavanjem visine // dps.init (MODE_STANDARD, 3200, true); // Inicijaliziraj BMP180 dps.init(); Serial.println(Ethernet.localIP()); // Pošalji prve podatke odmah nakon uključivanja uređaja send_info (istina); ) // funkcija dewPoint NOAA / / referenca (1) : http://wahiduddin.net/calc/density_algorithms.htm // referenca (2) : http://www.colorado.edu/geography/weather_station /Geog_site/about.htm dvostruka točka rosišta (dvostruki celzijus, dvostruka vlažnost) ( // (1) Tlak zasićene pare = ESGG(T) dvostruki OMJER = 373,15 / (273,15 + celzijus); dvostruki RHS = -7,90298 * (OMJER - 1); RHS += 5,02808 * log10 (OMJER); RHS += -1,3816e-7 * (pow(10, (11,344 * (1 - 1/OMJER))) - 1) ; RHS += 8,1328e-3 * (pow(10, (-3,49149 * (OMJER - 1))) - 1) ; RHS += log10(1013,246); // faktor -3 služi za podešavanje jedinica - Tlak pare SVP * vlažnost dvostruko VP = pow(10, RHS - 3) * vlažnost; // (2) ROSIŠTE = F(tlak pare) dvostruko T = log(VP/0,61078); // temp var return (241,88 * T) / (17,558 - T); ) void send_info(bool eth) ( bool fail = true; while(fail) ( // Pokušavamo očitati podatke s DHT senzora vlage dok // ne dobijemo rezultat. U 90% slučajeva sve radi dobro, ali trebamo 100 % if((H = dht.readHumidity()) >= 0) ( // Dobivanje vlažnosti i temperature od BMP180 senzora dps.getPressure(&Pressure); dps.getTemperature(&Temperature); // Izračunajte točku rosišta ako vanjska temperatura je iznad 0 stupnjeva Celzijevih // i očekujte rezultat iznad 0, inače ispišite 0. Ovo je neophodno // kako ne bi doveli u zabludu tijekom zimske sezone. // dP = Temperatura>0?((dPt=rosište(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); }

    Samim modulima mora se dodati antena. Za 433 MHz Dovoljna je obična duga bakrena žica 17 cm. Bez antene možete zaboraviti na normalan rad.

    Prijeđimo na najvažniji dio ovog ažuriranja – lokalnu bežičnu stanicu

    Za njegovu provedbu (na koljenu) koristio sam analogni Arduino NANO(na bazi ATMega328) I TFT prikaz na čipu ST7735S s dopuštenjem 128 x 160

    Skriveni tekst



    Pinout zaslon -> kontroler

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

    Modul prijemnika je povezan na isti način kao i odašiljač, samo PODACI zakačiti D7.

    Par slika kako to izgleda:

    Skriveni tekst

    Skica prijemnika

    Skriveni tekst

    #uključi #uključi #uključi #uključi int x, y; int w = 128, h = 160; int veličina; // 433 EasyTransferVirtualWire ET; struct SEND_DATA_STRUCTURE( byte ID; // ID uređaja int Temperatura; // Temperatura float Pressure; // Pressure float Vlažnost; // Vlažnost float dewPoint; // Točka rose/smrzavanja); SEND_DATA_STRUCTURE emitiranje; int Log_Temperatura = -1; float Log_Pressure = -1; float Log_Vlažnost = -1; float Log_dewPoint = -1; // TFT #define cs 10 #define dc 9 #define rst 8 char Temperatura, tlak, vlažnost, rosište; Informacije o nizu; TFT TFT zaslon = TFT (cs, dc, prvi); void setup())( Serial.begin(9600); // Inicijalizacija 433 MHz modula ET.begin(details(broadcast)); vw_set_ptt_inverted(true); vw_set_rx_pin(7); vw_setup(2000); vw_rx_start(); // Inicijalizacija i početno podešavanje prikaza TFTscreen.begin(); TFTscreen.setRotation(2); TFTscreen.background(0, 0, 0); // Crtanje statičnih elemenata // 1. Posjetite nas TFTscreen.stroke(255, 255) , 255); TFTscreen.setTextSize(1); TFTscreen.text(" ", 10, 10); // 2. Opis očitanja sa senzora TFTscreen.text("mmHg", w/2+5, 80); TFTscreen .text ("%", w/2+5, 100); TFTscreen.text("C", w/2+5, 120); emitiranje.Temperatura = 0; emitiranje.Tlak = 0; emitiranje.Vlažnost = 0 ; emitiranje .dewPoint = 0; TFTPrint(); ) void loop())( if(ET.receiveData())( if(broadcast.ID == 1) TFTPrint(); /* Serial.println(broadcast.Temperature) ; Serial. println(broadcast.Pressure); Serial.println(broadcast.Humidity); Serial.println(broadcast.dewPoint); Serial.println(); */ ) ) void promjene(int veličina, int x, int y, bool up, bool clear = false) ( if(clear) TFTscreen.stroke(0, 0, 0); else ( promjene (veličina, x, y, !gore, istina); TFTscreen.stroke((gore)?0:255, 0, (gore)?255:0); ) if((veličina%2) == 0 ) veličina++; dok(veličina > 0) ( TFTscreen.line(x, y, x+(veličina--), y); ++x, (gore)?--y:++y, --veličina; ) /* dok( veličina > 0) ( TFTscreen.line(x, y, (gore)?x+veličina-1:x, (gore)?y:y+veličina-1); ++x, ++y, --veličina; ) */ ) int x_centar(int w, int duljina, int veličina) ( return floor((w-duljina*(veličina*5)+veličina*2)/2); ) int x_alignment_right(int w, int duljina, int size) ( return ceil(w-length*(size*5)+size*2); ) void TFTPrint() ( size = 3; // ================== ==================================================== === =============== // Prikaz očitanja temperature // ============== ============ =========================================== ==== if(emitiranje. Temperatura != Log_Temperature) ( TFTscreen.setTextSize(size); // Prebriši zastarjele podatke 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, veličina), 35); / / Prikaži informacije o novim očitanjima = String(broadcast. Temperatura); info.concat("C"); if(broadcast.Temperature > 0) info = "+"+info; info.toCharArray(Temperatura, info.length()+1); // Promjena boje vrijednosti temperature ovisno o samoj temperaturi int r, g = 0, b; if(broadcast.Temperature > 0) ( r = map(broadcast.Temperature, 0, 40, 255, 150); // Crveno b = map(broadcast.Temperature, 0, 40, 30, 0); // Promijenite nijansa za vizualniji prijelaz kroz nulu ) else ( r = map(broadcast.Temperature, -40, 0, 0, 30); // Promijenite nijansu za vizualniji prijelaz kroz nulu b = map(broadcast.Temperature, - 40, 0, 150, 255); // Plavi ) TFTscreen.stroke(b, g, r); // PAŽNJA: položaji boja u knjižnici su pomiješani, RGB mjesto koristi BGR! TFTscreen.text(Temperatura, x_centar(w, info.length()+1, size), 35); ) veličina = 1; // ================================================== ==== ==================================== // Očitanja izlaznog tlaka // === ====== ============================================== ========= ======================= if(broadcast.Pressure != Log_Pressure) ( TFTscreen.setTextSize(size); / / Prebriši zastarjele podatke info = String(Log_Pressure); info.toCharArray(Pressure, info.length()); TFTscreen.stroke(0, 0, 0); TFTscreen.text(Pressure, x_alignment_right(w/2-5, info) .length(), size), 80); // Izlaz novih očitanja info = String(broadcast.Pressure); info.toCharArray(Pressure, info.length()); TFTscreen.stroke(255, 255, 255); TFTscreen .text(Pressure, x_alignment_right(w/ 2-5, info.length(), size), 80); changes(10, 106, 85, (broadcast.Pressure > Log_Pressure)?true:false); ) else ( changes (10, 106, 85, istina, istina); promjene (10, 106, 85, laž, istina); ) // ======================= ======== ============================================ =========== = // Očitanja izlazne vlažnosti // ================================ =========================== ======================== ================== if(broadcast.Humidity != Log_Humidity) ( TFTscreen.setTextSize(size); // Prepiši zastarjele informacije o podacima = String(Log_Humidity); info.toCharArray(Vlažnost, info.length()); TFTscreen.stroke(0, 0, 0); TFTscreen.text(Vlažnost, x_alignment_right(w/2-5, info.length(), veličina), 100); // Prikaz novih očitanja info = String(broadcast.Humidity); info.toCharArray(Vlažnost, info.length()); TFTscreen.stroke(255, 255, 255); TFTscreen.text(Vlažnost, x_alignment_right(w/2-5, info.length(), veličina), 100); promjene(10, 106, 105, (broadcast.Humidity > Log_Humidity)?true:false); ) else ( promjene(10, 106, 105, istina, istina); promjene(10, 106, 105, laž, istina); ) // ================== ==================================================== === ============== // Izlaz očitanja točke rosišta/točke smrzavanja // ============ ========== ============================================= ====== if(broadcast.dewPoint ! = Log_dewPoint) ( TFTscreen.setTextSize(size); // Prebriši zastarjele podatke 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); // Izlaz novih očitanja info = String(broadcast.dewPoint); info.toCharArray(dewPoint, info.length()); TFTscreen.stroke(255, 255, 255); TFTscreen.text(dewPoint, x_alignment_right(w/2-5, info.length(), size), 120); changes(10, 106, 125, (broadcast.dewPoint > Log_dewPoint)?true:false); ) else ( changes(10, 106, 125, true, true); changes(10, 106, 125, false, true); ) // Ažuriraj vrijednosti u zapisnicima za sljedeće usporedba očitanja Log_Temperature = emitiranje.Temperatura; Log_Pressure = emitiranje.Pressure; Log_Humidity = emitiranje.Vlažnost; Log_dewPoint = emitiranje.dewPoint; )

    Očitanja su prikazana prilično kompaktno, ali kao što praksa pokazuje (i savjet mojih drugova) - "okus i boja, čak ni žena nije prijatelj." Slušao sam puno savjeta i sugestija, ali oni su proturječni. Stoga, učinite to po svom ukusu.

    Činilo mi se da je dizajn dio projekta koji oduzima najviše vremena!

    Skriveni tekst

    Neki su podaci izmišljeni kako bi odražavali neke elemente dizajna.

    Artefakti na displeju su prašina i druga prljavština koja se nakupila tijekom dugog vremena u kojem je displej bio... tamo negdje,... pa, tamo, ne sjećam se odakle mi to! Pusti me na miru!

    Skica ima funkcije pozicioniranja. Oni su prilično primitivni, ali vam omogućuju postizanje određenih učinaka.

    1. x_centar
    2. x_poravnanje_desno

    Prvi centrira tekst, a drugi ga poravnava na desnu stranu navedene zone. Svi izračuni se rade u odnosu na dimenzije dati tekst, na temelju izraza 1 veličina = 1PX x 1PX segment fonta.

    Zaslon također prikazuje elemente koji odgovaraju povećanju ili smanjenju određene očitane vrijednosti. Prikazuju se u obliku trokuta. Ali u kodu funkcije promjene Postoji alternativni zaslon u obliku trokuta zakrenutih za 45 stupnjeva. Ako se očitanja povećaju, element je crven, u protivnom plavi.

    Usput, boja i sjena glavne temperature mijenjaju se ovisno o samoj temperaturi. Prilično kontroverzna odluka, ali po mom mišljenju, vizualno ugodna. Mučio sam se s tim neko vrijeme i shvatio da su vrijednosti u funkciji moždani udar, prigovarati TFT zaslon, navedeni su pogrešnim redoslijedom. BGR mjesto RGB. Ovo je pogreška programera ili ja nešto ne razumijem.

    P.S: Sve je dosta zanimljivo, ali po mom mišljenju zaslužuje daljnji razvoj. To je ono što ćemo učiniti nakon nekog vremena.

    Jednog dana, dok sam šetao gradom, vidio sam novu trgovinu radio elektronike koja se otvorila. Kad sam ušao u njega, našao sam veliki brojŠtitovi za Arduino jer Kod kuće sam imao Arduino Uno i Arduino Nano i odmah je došla ideja da se igram s odašiljačima signala na daljinu. Odlučio sam kupiti najjeftiniji odašiljač i prijemnik na 433 MHz:

    Odašiljač signala.


    Prijemnik signala.

    Snimivši jednostavnu skicu prijenosa podataka (primjer preuzet odavde), pokazalo se da uređaji za prijenos mogu biti sasvim prikladni za prijenos jednostavnih podataka, kao što su temperatura, vlaga.

    Odašiljač ima sljedeće karakteristike:
    1. Model: MX-FS - 03V
    2. Domet (ovisno o prisutnosti blokirajućih objekata): 20-200 metara
    3. Radni napon: 3,5 -12V
    4. Dimenzije modula: 19 * 19 mm
    5. Modulacija signala: AM
    6. Snaga odašiljača: 10mW
    7. Frekvencija: 433MHz
    8. Potrebna duljina vanjske antene: 25cm
    9. Jednostavno spajanje (samo tri žice): DATA ; VCC ; Zemlja.

    Karakteristike prijemnog modula:
    1. Radni napon: DC 5V
    2. Struja: 4mA
    3. Radna frekvencija: 433,92 MHz
    4. Osjetljivost: - 105dB
    5. Dimenzije modula: 30 * 14 * 7 mm
    6. Neophodno vanjska antena: 32 cm.

    Internet kaže da domet prijenosa informacija pri 2Kb/sec može doseći i do 150m. Nisam to osobno provjerio, ali u dvosobnom stanu je posvuda prihvaćen.

    Hardver kućne meteorološke stanice

    Nakon nekoliko eksperimenata, odlučio sam spojiti senzor temperature, vlažnosti i transmiter na Arduino Nano.


    Senzor temperature DS18D20 povezan je s Arduinom na sljedeći način:

    1) GND na minus mikrokontrolera.
    2) DQ kroz pull-up otpornik na masu i na pin D2 Arduina
    3) Vdd do +5V.

    MX-FS - 03V odašiljački modul napaja se s 5 volti, izlaz podataka (ADATA) spojen je na pin D13.

    Povezan na Arduino Uno LCD zaslon i barometar BMP085.


    Dijagram povezivanja na Arduino Uno

    Prijemnik signala spojen je na pin D10.

    Modul BMP085 - digitalni senzor atmosferski pritisak. Senzor omogućuje mjerenje temperature, tlaka i nadmorske visine. Sučelje za povezivanje: I2C. Napon napajanja senzora 1,8-3,6 V

    Modul je povezan s Arduinom na isti način kao i drugi I2C uređaji:

    • VCC - VCC (3,3 V);
    • GND - GND;
    • SCL - na analogni pin 5;
    • SDA - na analogni pin 4.
    • Vrlo niska cijena
    • Napajanje i I/O 3-5 V
    • Određivanje vlažnosti 20-80% s 5% točnosti
    • Detekcija temperature 0-50 stupnjeva. s 2% točnosti
    • Frekvencija prozivanja ne veća od 1 Hz (ne više od jednom svake 1 sekunde)
    • Dimenzije 15,5 mm x 12 mm x 5,5 mm
    • 4 igle s razmakom od 0,1 inča

    DHT ima 4 pina:

    1. Vcc (3-5V napajanje)
    2. Data out - Izlaz podataka
    3. Nije korišten
    4. Općenito

    Spaja se na D8 Arduina.

    Softverski dio kućne meteorološke stanice

    Odašiljački modul mjeri i prenosi temperaturu svakih 10 minuta.

    U nastavku je program:

    /* Sketch verzija 1.0 Šalji temperaturu svakih 10 minuta. */ #include #include #include #define ONE_WIRE_BUS 2 //Pin za spajanje Dallas OneWire senzora oneWire(ONE_WIRE_BUS); Senzori temperature u Dallasu (&oneWire); DeviceAddress insideTermometar; void setup(void) ( //Serial.begin(9600); vw_set_ptt_inverted(true); // Neophodno za DR3100 vw_setup(2000); // Postavite brzinu prijenosa (bit/s) sensors.begin(); if (! senzori .getAddress(insideThermometer, 0)); printAddress(insideThermometer); sensors.setResolution(insideThermometer, 9); ) void printTemperature(DeviceAddress deviceAddress) ( float tempC = sensors.getTempC(deviceAddress); //Serial.print("Temp C : "); //Serial.println(tempC); //Formiranje podataka za slanje int number = tempC; char symbol = "c"; //Servisni simbol za utvrđivanje da se radi o senzoru String strMsg = "z" ; strMsg += simbol; strMsg += " "; strMsg += broj; strMsg += " "; char msg; strMsg.toCharArray(msg, 255); vw_send((uint8_t *)msg, strlen(msg)); vw_wait_tx (); / / Pričekajte da se prijenos završi delay(200); ) void loop(void) ( for (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); } }

    Prijemni uređaj prima podatke, mjeri tlak i temperaturu u prostoriji i prenosi ih na zaslon.

    #include #include LiquidCrystal lcd(12, 10, 5, 4, 3, 2); #uključi dht11 senzor; #define DHT11PIN 8 #include #include BMP085 dps = BMP085(); dugo Temperatura = 0, Tlak = 0, Nadmorska visina = 0; void setup() ( Serial.begin(9600); vw_set_ptt_inverted(true); // Potrebno za DR3100 vw_setup(2000); // Postavljanje brzine prijema vw_rx_start(); // Pokretanje praćenja emitiranja lcd.begin(16, 2) ; Wire.begin(); delay(1000); dps.init(); //lcd.setCursor(14,0); //lcd.write(byte(0)); //lcd.home(); ) void loop() ( uint8_t buf; // Međuspremnik za poruku uint8_t buflen = VW_MAX_MESSAGE_LEN; // Dužina međuspremnika if (vw_get_message(buf, &buflen)) // Ako je poruka primljena ( // Počnite analizirati int i; // Ako poruka nije upućena nama, izađite ako (buf != "z") ( return; ) char naredba = buf; // Naredba je na indeksu 2 // Numerički parametar počinje na indeksu 4 i = 4; int broj = 0; // Budući da je prijenos znak po znak, tada trebate pretvoriti skup znakova u broj dok (buf[i] != " ") ( broj *= 10; broj += buf[i] - "0"; i++; ) dps.getPressure(&Tlak); dps.getAltitude (&Visina); dps.getTemperature(&Temperatura); //Serial.print(naredba); Serial.print(" "); Serial.println( broj); lcd.print("T="); lcd.setCursor(2,0); lcd.ispis(broj); lcd.setCursor(5,0); lcd.print("P="); lcd.print (pritisak/133,3); lcd.print("mmH"); lcd.setCursor(0,1); lcd.print("T="); lcd.print(Temperatura*0,1); lcd.print("H="); lcd.ispis(senzor.vlažnosti); lcd.home(); //kašnjenje(2000); int chk = sensor.read(DHT11PIN); prekidač (chk) ( case DHTLIB_OK: //Serial.println("OK"); break; case DHTLIB_ERROR_CHECKSUM: //Serial.println("Checksum error"); break; case DHTLIB_ERROR_TIMEOUT: //Serial.println("Time out" pogreška"); prekid; zadano: //Serial.println("Nepoznata pogreška"); prekid; ) ) )

    p.s. U budućnosti planiram dodati sljedeće:
    - senzor vlažnosti na odašiljač, preraditi algoritam prijenosa podataka
    - senzor za mjerenje brzine i smjera vjetra.
    - dodajte još jedan zaslon prijemnom uređaju.
    - prijenos prijemnika i odašiljača na zaseban mikrokontroler.

    Ispod je fotografija onoga što se dogodilo:

    Popis radioelemenata

    Oznaka Tip Vjeroispovijest Količina BilješkaDućanMoja bilježnica
    Prijenosni dio.
    Arduino ploča

    Arduino Nano 3.0

    1 U bilježnicu
    senzor temperature

    DS18B20

    1 U bilježnicu
    Otpornik

    220 Ohma

    1 U bilježnicu
    Modul odašiljačaMX-FS-03V (433 MHz)1 U bilježnicu
    Radio prijemni dio.
    Arduino ploča

    Arduino Uno

    1 U bilježnicu
    Trimer otpornik 1 U bilježnicu
    Otpornik

    Kao osnova uzet je projekt meteorološke stanice iz knjige V. Petina "Projekti koji koriste Arduino kontroler", 2. izdanje (projekt 5, dodatak 2). Koristio Arduino IDE 1.8.5 na Windows 10.
    Došlo je do pogreške prilikom pokretanja skice

    Na internetu možete preuzeti biblioteke za Arduino koje imaju iste nazive, ali različitog sadržaja. Skica možda neće raditi ako koristite pogrešnu biblioteku. Očito sam naišao na krive knjižnice. U projekt sam dodao senzor BMP180 za mjerenje atmosferskog tlaka i preradio skicu.

    Dijagram povezivanja

    Skeniranje adresa

    Prvo spojite BMP180 senzor i LCD1602 indikator na Arduino. Sastavite skicu I2C skenera i pokrenite je da odredite adrese uređaja na I2C sabirnici.

    Svakih 5 sekundi program skenira uređaje i izdaje adrese na COM portu. Našao sam dva uređaja s adresama 0x3F i 0x77. BMP180 standardno ima adresu 0x77, što znači da LCD indikator ima adresu 0x3F.
    U nekim sklopovima knjige, mjesta gdje su SDA i SCL signali spojeni na Arduino ploču su pomiješana. Trebalo bi biti: SDA - na A4, SCL - na A5. Ako BMP180 modul ima pet pinova, tada se na VIN pin dovodi +5 volti.

    Dijagram ožičenja

    Sada sastavite krug u potpunosti. Koristio sam običnu katodu RGB LED postavljenu na ploču zajedno s otpornicima od 150 ohma. Zajednička katoda spojena je na GND pin, ostali pinovi su spojeni prema dijagramu. Nema potrebe mijenjati skicu, jer se svjetlina LED dioda mijenja prema cikličkom zakonu.
    Na dijagramu je prikazan spoj RGB LED-a sa zajedničkom anodom, kao u knjizi.
    Ako se na LCD1602 zaslonu ne vide znakovi, okrenite kontrolu svjetline. Pozadinsko osvjetljenje indikatora troši dosta struje, stoga koristite napajanje sa strujom od najmanje 2 A. Koristio sam USB hub s vanjskim napajanjem od 2 A.
    Krug je koristio ZP-22 piezo zvono. Otpornik spojen na zvono je 100 ohma. Frekvencija zvuka se može promijeniti u programu. Odabrao sam frekvenciju od 1000 Hz. Ako naiđete na zujalicu s fiksnom frekvencijom zvuka, možete je uključiti i isključiti jednostavnim primjenom i uklanjanjem napona, poput obične LED diode. Kada skica započne, čuje se kratki zvučni signal. Možete omogućiti periodično signaliziranje dok program radi uklanjanjem komentara iz reda //bzz(100); u skici.
    U projektu sam koristio senzor DHT11 u obliku modula s već montiranim otpornikom od 4,7 kOhm. Otpor može biti od 4,7 do 10 kOhm.
    Spojite Vcc pin modula sata DS1302 na sabirnicu +5 V. Na ovaj način ćete smanjiti potrošnju baterije, u biti će raditi samo kada je Arduino isključen.

    Program (skica)

    Knjižnica bmp085 koristi se za servisiranje BMP180. Vrijednost tlaka ovisi o nadmorskoj visini područja. Za točnu vrijednost atmosferskog tlaka potrebno je odabrati nadmorsku visinu. Da biste to učinili, uredite redak dps.init(MODE_STANDARD, 10000, true); Moja visina je 100 m (10000 cm). Fragment izračuna tlaka preuzet je iz primjera BMP085_test2.ino biblioteke bmp085.

    Skica meteo_P

    #uključi
    #uključi
    #uključi
    #uključi "DHT.h"
    #uključi
    BMP085 dps = BMP085();
    dugi tlak = 0, nadmorska visina = 0;
    nepredpisano dugo vrijeme1 = 0;

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

    int kCePin = 4; // RST DS1302
    int kIoPin = 3; // Podaci 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); // unesite svoju adresu 0x20...0xff adresu
    unsigned long memTime;
    int bzzPin = 8;

    void HumTempRead() (
    float hum = dht.readHumidity();
    float temp = dht.readTemperature();
    if (isnan(hum) || isnan(temp)) (
    Serial.println("Nije uspjelo čitanje s DHT senzora!");
    lcd.setCursor(0, 1);
    lcd.print("H=--% T=---");
    lcd.setCursor(11, 1);
    lcd.print((char)223);
    lcd.setCursor(12, 1);
    lcd.print("C ");
    ) inače (
    lcd.setCursor(0, 1);
    lcd.print("H=");
    lcd.setCursor(2, 1);
    lcd.ispis (pjevušenje);
    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, IZLAZ);
    }

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

    void setup() (
    Serial.begin(9600);
    Wire.begin();
    kašnjenje (1000);

    dps.init(MODE_STANDARD, 10000, istina); // 100 metara (nadmorska visina u cm)

    dht.početak();
    postavljanje_bzz();
    bzz(100);

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

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

    //rtc.setDOW(PETAK); // Postavite dan u tjednu na PETAK postavite dan u tjednu
    //rtc.setTime(4, 58, 0); // Postavite vrijeme na 12:00:00 (24-satni format)
    //rtc.setDate(6, 8, 2010); // Postavite datum na 6. kolovoza 2010. postavite datum (dan, mjesec, godina)
    }

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

    if ((milis() - memTime > 2000) ili (millis()< memTime)) { // DHT11/22 1 time each 2 seconds
    HumTempRead();
    memTime = millis();
    }
    kašnjenje (100);

    if (((milis() - vrijeme1) / 1000,0) >= 1,0) (
    dps.calcTrueTemperature();
    vrijeme1 = millis();
    }
    dps.getPressure(&Pritisak);
    Serial.print(" Tlak (Pa):");
    Serial.println(pritisak);

    dugi p2;
    int pi;
    p2 = (pritisak / 133,3224); // Pa u mmHg.
    pi = trunc(p2); // odbacivanje razlomljenog dijela broja

    lcd.setCursor(0, 0);
    lcd.print("P=");
    lcd.setCursor(2, 0);
    lcd.ispis(pi); // izlaz atm. pritisak na LCD-u
    lcd.setCursor(5, 0);
    lcd.print("mm");
    // kašnjenje(3000);
    //bzz(100); // odkomentirajte ako želite slušati signale
    {
    za (int vrijednost = 0; vrijednost<= 255; value += 1) {
    analogWrite(REDpin, vrijednost);
    analogWrite(GREENpin, 255 - vrijednost);
    analogWrite(BLUEpin, 255);
    kašnjenje(5);
    }

    za (int vrijednost = 0; vrijednost<= 255; value += 1) {
    analogWrite(REDpin, 255);
    analogWrite(GREENpin, vrijednost);
    analogWrite(BLUEpin, 255 - vrijednost);
    kašnjenje(5);
    }

    za (int vrijednost = 0; vrijednost<= 255; value += 1) {
    analogWrite(REDpin, 255 - vrijednost);
    analogWrite(GREENpin, 255);
    analogWrite(BLUEpin, vrijednost);
    kašnjenje(5);
    }
    }
    }

    U katalogu datoteka možete preuzeti skicu i biblioteke koje su korištene u projektu.

    Uvezite biblioteke LiquidCrystal_I2C.zip, bmp085.zip, DS1302.zip i DHT.zip iz preuzete arhive u Arduino IDE. Idite na izbornik Skica Povežite knjižnicu Dodaj .ZIP biblioteku... au prozoru odaberite zip arhivu knjižnice.
    Učitaj meteo_P skicu. Zamijenite adresu LCD1602 na skici s vrijednošću dobivenom skeniranjem I2C sabirnice. Kompajlirajte i pokrenite skicu.
    Ako skica radi, otvorite monitor priključka i pogledajte prikazane poruke. Podesite visinu u izjavi dps.init(MODE_STANDARD, 10000, true); da biste dobili stvarne vrijednosti tlaka.
    Namjestite svoj sat. Odkomentirajte liniju //rtc.setTime(4, 58, 0); a u zagradama navedite trenutno vrijeme (sat, minute i sekunde odvojene zarezima) i ponovno učitajte skicu u kontroler. Nakon što je vrijeme postavljeno, ponovno komentirajte ovaj redak i ponovo pokrenite skicu.
    Ako vas živcira noćno osvjetljenje, možete ga prilagoditi promjenom duljine odgode u for petljama na kraju skice. S odgodom(2); ciklus traje 2-3 sekunde, s odgodom(5); — od 4 do 5 sekundi, s odgodom (30); - do 15-16 sekundi. Podaci o indikatoru ažurirat će se u istom intervalu.
    Kada se meteorološka stanica koristi autonomno, tj. bez spajanja na USB priključak računala, komentirajte retke na skici riječima Serial ... da biste onemogućili izlaz informacija na monitor COM priključka.

    P.S. Na skici knjige i u primjerima za DHT biblioteku naznačena je linija definicije #definiraj DHTTYPE DHT 11. Skica se pokreće, ali se ruši nakon nekoliko sati. Sat se zaustavlja, zaslon se ne mijenja. Na monitoru priključaka pojavljuje se nejasna poruka koja sadrži vezu na dht.
    U ovom redu sam uklonio slova DHT, tj. učinio #define DHTTYPE 11. Nakon toga, skica je počela raditi stabilno.

    Članak ažuriran 25. lipnja 2018

    Korišteni resursi
    1. Petin V.A. Projekti koji koriste Arduino kontroler (elektronika) 2. izdanje, St. Petersburg. BHV-Petersburg, 2015. 464 str.
    2. Petin V. A., Binyakovsky A. A. Praktična enciklopedija Arduina. - M., DMK Press, 2017. - 152 str.
    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. primjer BMP085_test2.ino iz biblioteke 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/

    Uradi sam meteorološka stanica.

    Bila je večer, nije se imalo što raditi poslije Nove godine. Kao i obično, tijekom zimskih novogodišnjih praznika želim zaokupiti glavu i ruke nečim korisnim i kreativnim. Tijekom ovih novogodišnjih praznika odlučio sam napraviti meteorološku stanicu vlastitim rukama. Počeo sam se pripremati unaprijed, nabavio i montirao sve komponente prije Nove godine, a glavno programiranje odradio tijekom praznika.

    (ima puno fotografija ispod rezanja!)

    Prvo ću proći kroz komponente, neću davati poveznice, jer su proizvodi na eBayu (na mom osobnom računu) arhivirani. Ležerno sam kupovao mnoge komponente na eBayu. Prvi sam put pokušao s aukcijom; prije sam uvijek kupovao "kupi odmah". Što reći, ako ne žurite u kupnju, neke komponente možete kupiti jeftinije (razlika je ponekad dvostruko veća).

    Senzor pritiska VMR085
    Ovo je glavni senzor. Kad sam to vidio na eBayu, znao sam da želim napraviti kućnu meteorološku stanicu.
    Senzor je stigao u običnoj kuverti, iznutra obloženom folijom s mjehurićima.

    Unutar kuverte nalazila se prodavačeva posjetnica i senzor, upakirani u antistatičku vrećicu i umotani u drugi sloj folije s mjehurićima.

    Antistatička vrećica bila je zatvorena tako da vlaga tijekom leta nije prijetila senzoru

    Izvadimo senzor. S jedne strane nalazi se zalemljena linija kontakata, koji su umetnuti u pjenu kako bi se spriječilo njihovo savijanje. S druge strane nalazi se sam senzor i kontaktne oznake.




    Sve bi bilo u redu, ali kontaktne oznake se primjenjuju u zrcalnoj slici.
    Senzor je povezan preko I2C sabirnice i napaja se s 3,3 V. To jest, za normalan rad trebate 4 žice (+, -, SDA, SCL)
    Senzor možete ispitati na 2 načina: ili kroz biblioteku ili koristeći funkcije izravno u skici.
    Primjer programa:

    #uključi

    #define BMP085_ADDRESS 0x77 // I2C adresa BMP085

    Const unsigned char OSS = 0; // Postavka preduzorkovanja

    // Kalibracijske vrijednosti
    int ac1;
    int ac2;
    int ac3;
    unsigned int ac4;
    unsigned int ac5;
    unsigned int ac6;
    int b1;
    int b2;
    int mb;
    int mc;
    int md;

    Kratka temperatura;
    dugi pritisak;

    Postavljanje praznine()
    {
    Serial.begin(9600);
    Wire.begin();
    bmp085Kalibracija();
    }

    void petlja()
    {
    temperatura = bmp085GetTemperature(bmp085ReadUT());
    tlak = bmp085GetPressure(bmp085ReadUP());
    Serial.print("Temperatura: „);
    Serial.print(temperature/10.0, DEC);
    Serial.println("C");
    Serial.print("Tlak: „);
    Serial.print(pressure/133.322, Dec);
    Serial.println("mm Hg");
    Serial.println();
    kašnjenje (1000);
    }

    Void bmp085Calibration()
    {
    ac1 = bmp085ReadInt(0xAA);
    ac2 = bmp085ReadInt(0xAC);
    ac3 = bmp085ReadInt(0xAE);
    ac4 = bmp085ReadInt(0xB0);
    ac5 = bmp085ReadInt(0xB2);
    ac6 = bmp085ReadInt(0xB4);
    b1 = bmp085ReadInt(0xB6);
    b2 = bmp085ReadInt(0xB8);
    mb = bmp085ReadInt(0xBA);
    mc = bmp085ReadInt(0xBC);
    md = bmp085ReadInt(0xBE);
    }

    Kratki bmp085GetTemperature(unsigned int ut)
    {
    dugo x1, x2;
    x1 = (((dugi)ut - (dugi)ac6)*(dugi)ac5) >> 15;
    x2 = ((dugi)mc<< 11)/(x1 + md);
    b5 = x1 + x2;

    Povratak ((b5 + 8)>>4);
    }

    Dugo bmp085GetPressure(nepodpisano dugo gore)
    {
    dugi x1, x2, x3, b3, b6, p;
    nepredznačeni dugi b4, b7;
    b6 = b5 - 4000;
    // Izračunaj B3
    x1 = (b2 * (b6 * b6)>>12)>>11;
    x2 = (ac2 * b6)>>11;
    x3 = x1 + x2;
    b3 = (((((dugi)ac1)*4 + x3)<>2;
    // Izračunaj B4
    x1 = (ac3 * b6)>>13;
    x2 = (b1 * ((b6 * b6)>>12))>>16;
    x3 = ((x1 + x2) + 2)>>2;
    b4 = (ac4 * (dugi bez predznaka)(x3 + 32768))>>15;
    b7 = ((nepredpisani dugi)(gore - b3) * (50000>>OSS));
    ako (b7< 0x80000000)
    p = (b7<<1)/b4;
    drugo
    p = (b7/b4)<<1;
    x1 = (p>>8) * (p>>8);
    x1 = (x1 * 3038)>>16;
    x2 = (-7357 * p)>>16;
    p += (x1 + x2 + 3791)>>4;
    povratak p;
    }

    // Čitanje 1 bajta iz BMP085 na "adresi"
    char bmp085Read(nepotpisana char adresa)
    {
    podaci bez potpisa;

    Wire.write(adresa);
    Wire.endTransmission();
    Wire.requestFrom(BMP085_ADDRESS, 1);
    dok(!Žica.dostupno())
    ;
    return Wire.read();
    }

    Int bmp085ReadInt(adresa bez potpisa)
    {
    nepredpisani znakovi msb, lsb;
    Wire.beginTransmission(BMP085_ADDRESS);
    Wire.write(adresa);
    Wire.endTransmission();
    Wire.requestFrom(BMP085_ADDRESS, 2);
    dok (Wire.available()<2)
    ;
    msb = Wire.read();
    lsb = Wire.read();
    povratak (int) msb<<8 | lsb;
    }

    // Očitajte vrijednost nekompenzirane temperature
    unsigned int bmp085ReadUT()
    {
    unsigned int ut;
    // Zapišite 0x2E u registar 0xF4
    // Ovo zahtijeva očitavanje temperature
    Wire.beginTransmission(BMP085_ADDRESS);
    Wire.write(0xF4);
    Wire.write(0x2E);
    Wire.endTransmission();
    // Pričekajte najmanje 4,5 ms
    kašnjenje(5);
    // Čitanje dva bajta iz registara 0xF6 i 0xF7
    ut = bmp085ReadInt(0xF6);
    vratiti ut;
    }

    // Očitajte nekompenziranu vrijednost tlaka
    unsigned long bmp085ReadUP()
    {
    nepredpisani znakovi msb, lsb, xlsb;
    unsigned long up = 0;
    // Napišite 0x34+(OSS<<6) into register 0xF4
    // Zatražite očitanje tlaka s postavkom prekomjernog uzorkovanja
    Wire.beginTransmission(BMP085_ADDRESS);
    Wire.write(0xF4);
    Wire.write(0x34 + (OSS<<6));
    Wire.endTransmission();
    // Pričekajte konverziju, vrijeme odgode ovisi o OSS-u
    kašnjenje(2 + (3<// Čitanje registara 0xF6 (MSB), 0xF7 (LSB) i 0xF8 (XLSB)
    Wire.beginTransmission(BMP085_ADDRESS);
    Wire.write(0xF6);
    Wire.endTransmission();
    Wire.requestFrom(BMP085_ADDRESS, 3);
    // Pričekajte da podaci postanu dostupni
    dok (Wire.available()< 3)
    ;
    msb = Wire.read();
    lsb = Wire.read();
    xlsb = Wire.read();
    gore = (((nepotpisani dugi) msb<< 16) | ((unsigned long) lsb << 8) | (unsigned long) xlsb) >> (8-OSS);
    vratiti se gore;
    }


    Osim toga, senzor ima svoj toplinski senzor za kompenzaciju tlaka i visinomjer

    Arduino Nano v3.0
    Ovo je srce cijele meteorološke stanice. Jednostavno rečeno, kontroler je minijaturne veličine.
    kupio sam
    Neću govoriti detaljno o kontroleru, jer je to već učinjeno prije mene:


    Lightake paket je bio montažni, kontroler je došao u paketu koji sadrži USB kabel i Arduino u zatvorenoj antistatičkoj vrećici.

    Kako bih procijenio veličinu, stavio sam kovanicu od 1 rublje pored Arduina.

    Upravljačka ploča izbliza



    USB kabel je dobar, s feritnim prstenom. Arduino se napaja putem USB kabela. Razvojno okruženje se može preuzeti (stranica za preuzimanje). Jezik je nalik C-u, nije bilo problema sa svladavanjem jer na poslu dosta programiram na njemu.

    LCD ekran
    Na poslu sam pronašao kompatibilni LCD 1602 ekran u smeću. Morao sam petljati s vezom jer nisam mogao pronaći podatkovnu tablicu za to. Kao rezultat toga, LCD je počeo raditi.

    Ali nakon kraćeg razdoblja korištenja primijetio sam da mi ovaj zaslon nije dovoljan i da više podataka nije moguće prikazati jer ima samo 2 retka po 16 znakova. Na prvu se čini da su ti parametri dovoljni, ali kada počnete programirati, shvatite da je maksimalno 3-4 parametra što možete ugurati. A ako napravite izbornik (razmišljao sam o tome da napravim izbornik na ovom ekranu), onda ostaje samo 1-2 parametra slobodnog prostora.
    Kao rezultat toga, počeo sam tražiti drugi zaslon. Isprva sam pomno promatrao grafički zaslon iz Nokie 3310 i čak sudjelovao na aukciji na eBayu da ga kupim, ali nije išlo (zbog čega sam jako sretan), pa sam morao odustati od ovog zaslona. Sada razumijem da bi to bilo premalo za moje potrebe, jer postoji nešto za usporedbu.
    Dok sam nasumično gledao kroz štitove na Arduinu, naišao sam na grafički ekran od 12864 na ST7920 kontroleru. Ovaj zaslon ima pravu veličinu i dobru rezoluciju za moje potrebe (128x64). To jest, možete lako postaviti 6-7 redaka od 20 znakova u normalno čitljiv font. Budući da je zaslon grafički, osim teksta, grafika se može postaviti u različitim fontovima. Ukratko, to je upravo ono što mi je trebalo, sve je bilo prisutno na ovom ekranu, pa nisam mogao odoljeti i naručio sam ga.
    Paket je stigao brzo i standardno zapakiran: omotnica s mjehurićima, unutra još jedan sloj s mjehurićima i ekran u antistatičkoj vrećici:






    Kako bih procijenio veličinu, stavio sam kovanicu od 1 rublje pored LCD-a.




    Kako bih brzo spojio zaslon na Arduino, zalemio sam niz kontakata na LCD igle. LCD se može spojiti preko serijske sabirnice ili paralelne sabirnice. Odabrao sam prvu opciju, jer već ima malo slobodnih Arduino kontakata.
    Veza (preuzeto s weba):

    - Pin 1 (GND) spojen je na zajedničku sabirnicu
    - Pin 2 (VCC) je spojen na sabirnicu napajanja +5V, a potrošnja struje je relativno mala i displej se može napajati iz ugrađenog Arduino stabilizatora.
    - Pinovi 4, 5 i 6 spajaju se na Arduino digitalne izlaze, tvoreći SPI serijsko sučelje:
    pin 4 – (RS) – odgovara CS liniji (na primjer 7)
    pin 5 – (RW) – odgovara MOSI liniji (na primjer 8)
    pin 6 – (E) – odgovara liniji SCK (na primjer 3)
    Arduino kontakt brojevi mogu biti bilo što, glavna stvar je ne zaboraviti ih ispravno naznačiti u tekstu programa prilikom inicijalizacije zaslona.
    - Pin 15 (PSB) spojen je na zajedničku sabirnicu.
    - Kontakti 19 (A) i 20 (K) su napajanje pozadinskog osvjetljenja (+5V odnosno GND). Za podešavanje svjetline pozadinskog osvjetljenja, možete koristiti promjenjivi otpornik od 10 kOhm spojen između sabirnice napajanja i GND-a. Napon iz njegovog motora dovodi se do kontakta 19 zaslona.
    Prema ovim uputama spojio sam sve osim pozadinskog osvjetljenja. Koristio sam Arduino PWM za napajanje pozadinskog osvjetljenja.
    Za programsko povezivanje LCD-a s Arduinom koristi se biblioteka u8glib. Možete ga preuzeti. Ako bude problema s preuzimanjem, mogu učitati biblioteku na narod.ru.
    Sama biblioteka nije komplicirana i omogućuje vam prikaz teksta u različitim fontovima, crtanje linija, crtanje jednostavnih geometrijskih oblika (pravokutnik, krug), te prikaz vlastitih slika pripremljenih na poseban način. U principu, ovaj alat je dovoljan za većinu zadataka.
    Ovo je rezultat jednostavnog programa:

    Sam program:

    #include "U8glib.h"

    U8GLIB_ST7920_128X64 u8g(3, 9, 8, U8G_PIN_NIJEDAN); // SPI E = 3, RW = 9, RS = 8

    // Potprogram za određivanje slobodne memorije
    int freeRam() (
    extern int __heap_start, *__brkval;
    int v;
    return (int) &v - (__brkval == 0? (int) &__heap_start: (int) __brkval);
    }

    Postavljanje praznine(void) (
    u8g.setFont(u8g_font_6x10); // font
    u8g.setRot180(); //Okreni zaslon
    analogWrite(6, 115); // Postavite svjetlinu zaslona (anoda pozadinskog osvjetljenja na 6 pinova)
    }

    Void petlja(void) (
    u8g.prvaStranica();
    čini (

    u8g.setPrintPos(1, 12); // položaj
    u8g.print("Pozdrav!!!"); // izlazni tekst
    u8g.drawBox(0,22,128,9); // Obojite pravokutnik u bijelo
    u8g.setColorIndex(0); // bijela tinta, crna pozadina
    u8g.setPrintPos(1, 30); // položaj
    u8g.print("Riječ..."); // izlazni tekst

    U8g.setColorIndex(1); // bijela tinta, crna pozadina
    u8g.setPrintPos(1, 50); // položaj
    u8g.print("Nakon pokretanja ="); // izlazni tekst
    u8g.setPrintPos(85, 50); // položaj
    u8g.print(milis() / 1000); // ispis broja sekundi nakon početka
    u8g.setPrintPos(1, 64); // položaj
    u8g.print(freeRam()); // izlaz koliko je memorije zauzeto
    ) dok(u8g.nextPage());

    Odgoda (200);
    }

    Sat realnog vremena DS1307
    Još jedna komponenta za moju meteorološku stanicu. Ovaj štit implementira sat stvarnog vremena. Naručila sam ih na eBayu. Prodavač je šal sa satom poslao u nerealno velikoj kutiji


    U kutiji su bila dva lista reklame formata A4 i rupčić za sat umotan u celofan


    Želio bih napomenuti da naknada ne prelazi 2 rublja. novčića, a kutijica dimenzija 13x15x5 cm.
    Ploča je bila zapakirana u antistatičku vrećicu

    Šal izbliza



    Morao sam petljati s ovim modulom. Prvo, bilo je poteškoća s vezom. I drugo, na ovoj ploči nema kvarca. Da sam znao da ću potrošiti toliko vremena na modul, najvjerojatnije bih ga sam sastavio, jer je internet pun dijagrama. Najjednostavniji sklop sadrži 4-5 komponenti.
    Što se tiče veze. Pronašao sam biblioteku koja kaže da se I2C sučelje može spojiti ne na uobičajene Arduino analogne ulaze (A4 i A5), već na bilo koje diskretne. Učinio sam kako je napisano. Isprva ništa nije išlo, ali nakon dugog plesa uz tamburicu sat se pokrenuo. Pa, pomislio sam, to je to, problemi su gotovi, ali nakon što sam pokušao spojiti isti modul na drugi Arduino, ples uz tamburicu se nastavio. Proveo sam dosta vremena tražeći rješenje za ovaj problem i gotovo posvuda je naznačeno ili neispravna veza ili odsutnost pull-up otpornika na SCL i SDA kontaktima. Već sam htio ući u ploču s lemilicom, ali sam na jednom forumu slučajno naišao na kod u kojem je rečeno da treba spojiti SCL i SDA na standardne I2C portove na Arduinu. Nakon standardnog spajanja, sve je odmah radilo.
    Sada o kvarcu. Ne znam kakav su kvarc Kinezi tamo stavili, ali satovi s takvim kvarcom bježali su 10-11 sekundi dnevno. Ova greška iznosi 5 minuta mjesečno i 1 sat godišnje. Nema potrebe za ovakvim satom. Morao sam ponovo otići na internet i tražiti kako popraviti ovu grešku. Prvo rješenje koje se pojavi kaže da morate uzemljiti kvarc. Uspio sam - rezultat je bio nula. Također sam negdje našao da trebam pronaći staru matičnu ploču i ukloniti kvarcni sat odatle. Uspio sam - ima rezultata. Sada sat ne bježi za 10-11 sekundi, već za 1,5 sekundi dnevno. Recimo samo da je postalo bolje, ali daleko je od idealnog. Kako mi se više ne da petljati po lemilu, odlučeno je programski namjestiti sat, odnosno sat namjestiti na željenu vrijednost jednom dnevno. Nakon 10 dana sat se pomaknuo ne više od sekunde. Metoda je dobra, ali samo kada je Arduino uređaj za sinkronizaciju spojen na napajanje, inače sat radi na bateriju i dalje bježi.
    Mali program za testiranje:

    #include "Wire.h"
    #define DS1307_I2C_ADDRESS 0x68 // SDA A4, SCL A5

    Bajt decToBcd(bajt val)
    {
    povratak ((val/10*16) + (val%10));
    }

    Bajt bcdToDec(bajt val)
    {
    povratak ((val/16*10) + (val%16));
    }

    Void setDateDs1307(bajt sekunda, // 0-59
    bajt minuta, // 0-59
    bajt sat) // 0-99
    {

    Wire.write(0);
    Wire.write(decToBcd(drugi));
    Wire.write(decToBcd(minute));
    Wire.write(decToBcd(sat));
    Wire.endTransmission();
    }

    Void getDateDs1307(bajt *drugi,
    bajt *minuta,
    bajt *sat)
    {

    Wire.beginTransmission(DS1307_I2C_ADDRESS);
    Wire.write(0);
    Wire.endTransmission();

    Wire.requestFrom(DS1307_I2C_ADDRESS, 3);

    *drugi = bcdToDec(Wire.read());
    *minuta = bcdToDec(Wire.read());
    *sat = bcdToDec(Wire.read());
    }

    Postavljanje praznine()
    {
    bajt sekunda, minuta, sat;
    Wire.begin();
    Serial.begin(9600);

    Drugi = 45;
    minuta = 5;
    sat = 16;

    SetDateDs1307(sekunda, minuta, sat);
    }

    void petlja()
    {
    bajt sekunda, minuta, sat;

    GetDateDs1307(&sekunda, &minuta, &sat);
    Serial.print(sat, DEC);
    Serial.print(":");
    Serial.print(minute, DEC);
    Serial.print(":");
    Serial.println(drugi, DEC);

    Kašnjenje (1000);
    }


    Knjižnica se ovdje ne koristi, a funkcije za vrijeme čitanja i pisanja su skraćene.

    Senzor temperature i vlažnosti DHT11
    Nema se što reći o ovom senzoru. Ne bih ga ni koristila da vlaga nije potrebna. Nažalost nisam ga slikao kad sam ga dobio pa neće biti ni fotki. Fotografije senzora možete vidjeti ispod, gdje sam ga spojio na Arduino. Spajanje senzora je jednostavno (+, digitalni izlaz, -). Tipično se senzori izrađuju s četiri pina. S ovim faktorom oblika, treći pin nije povezan ni s čim.
    Možete koristiti biblioteku za povezivanje s Arduinom. Možete ga preuzeti.
    Mali testni program s izlazom informacija na LCD zaslonu 1602:

    // uključiti kod knjižnice:
    #uključi
    #uključi

    // Deklarirajte objekte
    dht11 DHT11;
    LiquidCrystal lcd (12, 11, 6, 5, 4, 3);

    #definiraj DHT11PIN 7
    int i;

    Postavljanje praznine()
    {
    lcd.begin(16, 2);
    lcd.print("Status: „);
    i=0;
    }

    void petlja()
    {
    int chk = DHT11.read(DHT11PIN);
    lcd.setCursor(8, 0);
    prekidač (chk)
    {
    slučaj 0: lcd.print(“U redu“); prekid;// lcd.setCursor(11, 0); lcd.print(milis()/2000); pauza;
    case -1: lcd.print(“Greška kontrolne sume”); mErr(); pauza;
    case -2: lcd.print("Greška isteka vremena"); mErr(); pauza;
    zadano: lcd.print("Nepoznata pogreška"); mErr(); pauza;
    }
    kašnjenje (500);
    lcd.setCursor(15, 0);
    prekidač(i)
    {
    slučaj 0: lcd.print("^"); lcd.setCursor(15, 1); lcd.print(" ");prekid;
    slučaj 1: lcd.print("v"); lcd.setCursor(15, 1); lcd.print(" ");prekid;
    zadano: lcd.setCursor(15, 1); lcd.print("E"); pauza;
    }
    i=i+1;
    ako je (i>1) i=0;
    lcd.setCursor(0, 1);
    lcd.print("H=");
    lcd.setCursor(2, 1);
    lcd.print((float)DHT11.humidity, 0);
    lcd.setCursor(4, 1);
    lcd.print("%");
    lcd.setCursor(8, 1);
    lcd.print("T=");
    lcd.setCursor(10, 1);
    lcd.print((float)DHT11.temperature, 0);
    lcd.setCursor(12, 1);
    lcd.print("C");

    Poništi mErr()
    {
    lcd.setCursor(2, 1);
    lcd.print("**");
    lcd.setCursor(10, 1);
    lcd.print("**");
    i=5;
    }


    Senzor ima neke nedostatke - podaci sa senzora su samo u cijelim brojevima, a domet je slab.

    Čini se da sam pisao o svim komponentama. Ostaje samo sakupiti sve u jednu cjelinu.
    Ups, skoro sam zaboravio! Za sastavljanje uređaja potrebna vam je kutija. Kutiju sam također naručila na Ebayu. Ispostavilo se da je prodavač iz Engleske. Pošiljka je stigla brzo, ali je nisam slikala. Sve fotografije slučaja nalaze se u nastavku.

    Prvo sam sve sastavio na stolu pomoću posebnih žica. Napisao sam testni program i učitao ga na kontroler.



    Zapravo, plava boja pozadinskog osvjetljenja je mnogo svjetlija. Čak i pri minimalnoj svjetlini (Bright=5), okvir je osvijetljen.

    Kako bi se sve sklopilo bežično, odlučeno je napraviti mini matičnu ploču, a na konektore su stavljene Arduino ploče i shieldovi. Ako se nešto dogodi, mogu se brzo i jednostavno ukloniti. Također sam odlučio pričvrstiti LCD zaslon i upravljačke tipke na konektore, samo da zalemim senzor temperature na žice.
    Ovako je ispao šal



    Na zadnjoj fotografiji nisam u potpunosti isprao flux. Zalijepio sam poroznu gumu ispod štitnika pored konektora tako da postoji barem neka podrška. Iako se zapravo štitnici u konektorima na kontaktima sasvim dobro drže.

    Matična ploča s instaliranim shieldom i Arduino pločom.

    Ovako izgleda kompletan spoj na matičnu ploču


    Umjesto gumba, koristio sam kućni štit zalemljen na matičnu ploču. Kao gumbe koristio sam gumbe od starih miševa.
    Kao što vidite, broj žica se smanjio.

    Glavni problem postavljanja u kućište je izrezivanje glatkog utora za LCD zaslon. Koliko god sam se trudila, još uvijek nije savršeno uspjelo. Razmaci su na nekim mjestima bili nešto veći od 1 mm. Kako bi sve izgledalo uredno, uzeo sam crno brtvilo za akvarij i ispunio sve pukotine, istovremeno sam pričvrstio ekran na ovo brtvilo. Nakon što se brtvilo osušilo, odrezao sam višak s vanjske strane. Pri jakom svjetlu, brtvilo je vidljivo, ali pri normalnom svjetlu sve se stapa s tijelom.
    Ovako kućište izgleda iznutra s instaliranim LCD ekranom i matičnom pločom.

    Ovako izgleda izvana na jakom svjetlu (ispričavam se za otiske prstiju, vidio sam ih kad sam sređivao fotografije).

    Dugo sam razmišljao kako uklopiti gumbe u kućište i, što je najvažnije, koje gumbe koristiti...
    U radio-elektroničkim trgovinama svidio im se gumb s dugom iglom i vrhovima koji pristaju na ovu iglu. Ovi gumbi služe za lemljenje na ploču. Sve bi bilo u redu, ali imaju jedan minus - hod pritiska je vrlo mali i glasan.
    Morali smo postaviti gumbe u dvije faze: prva je bila postaviti tipke na ploču, a druga je bila montirati ovu ploču na drugu ploču. I onda sve to stavite u tijelo na vodilice.

    Ovako izgleda šal s gumbima:



    Ovako izgleda ploča držača:


    Ovdje možete vidjeti vodilice u koje se umeće ploča s gumbima. Neki elementi su zalemljeni kako bi se ploči dala krutost.

    Sada sve stavljamo u tijelo
    Bez tipki za povezivanje:


    Sa spojem na gumb:

    Zatvorite kućište i uključite ga. Sve radi super, tipke rade kako treba.

    Na kraju objavljujem kratki video rada uređaja u različitim načinima rada:
    http://www.youtube.com/watch?v=KsiVaUWkXNA&feature=youtu.be
    Za one koji ne vide video ovdje, evo poveznice na

    Vrijeme je da završimo recenziju.
    Napisat ću malo o programu, a zatim nekoliko kratkih zaključaka. Kada sam pisao program, nisam mislio da ću vrlo brzo dosegnuti ograničenje od 30.720 bajtova.


    Morao sam optimizirati kod. Premjestio sam mnogo dijelova koda u potprograme. Nikada ne bih pomislio da naredba switch...case u kompiliranom obliku zauzima više prostora od nekoliko naredbi if...else. Ispravna deklaracija varijabli također štedi prostor. Ako deklarirate dugi niz, iako je sasvim moguće dobiti po bajtu, tada prekoračenje memorije doseže 500 bajtova, ovisno o veličini niza. Kada napišete program, ne razmišljate o njemu, a tek kasnije, kada analizirate program, shvatite da ste neke stvari krivo napravili i počnete optimizirati kod. Nakon što su problemi s veličinom programa riješeni, naišao sam na ograničenje RAM-a. To je izraženo u činjenici da se program počeo zamrzavati nakon učitavanja. Morao sam uvesti potprogram za izračunavanje slobodnog RAM-a. Kao rezultat toga, bio sam prisiljen napustiti jedan algoritam za prognozu vremena, jer mora prikazati ikone na ekranu. Sam algoritam radi, ali je izlaz ikona morao biti snimljen. Još uvijek imam ideje o tome kako optimizirati kod, ali u bliskoj budućnosti ostavit ću uređaj da radi kako bi procijenio njegovu izvedbu i identificirao sve greške.

    Sada neki zaključci
    minusi
    1) Cijena. Opravdanje za ovaj nedostatak je da hobi nikad nije jeftin.

    profesionalci
    1) Velika funkcionalnost uređaja
    2) Povećanje funkcija ograničeno je samo regulatorom koji se koristi i vašom vlastitom željom
    3) Estetski užitak od kontemplacije i moralno zadovoljstvo od činjenice da sam konačno sastavio i dovršio ovaj uređaj

    Planiram kupiti +85 Dodaj u favorite Svidjela mi se recenzija +137 +304

    Najbolji članci na temu