Si të konfiguroni telefonat inteligjentë dhe PC. Portali informativ
  • në shtëpi
  • Në kontakt me
  • Projektet e stacionit të motit Arduino pro mini. BMP085 Moduli i sensorit barometrik të presionit për arduino (ose si të bëni një stacion moti me duart tuaja)

Projektet e stacionit të motit Arduino pro mini. BMP085 Moduli i sensorit barometrik të presionit për arduino (ose si të bëni një stacion moti me duart tuaja)

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 me sensorët (do të praktikoj diçka tjetër), dhe në mënyrë që të lidhem 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.

Mrekullia-juda 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
  • Arduino
  • Shto etiketa

    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 trajton më shumë se (përveç nëse memoria dështon) 4 lidhje të njëkohshme. Duke marrë parasysh se sa lidhje shërbimi ndodhin vazhdimisht për të ruajtur funksionimin e vetë rrjetit, dhe sa trafiku i lënë thjesht i krijuar nga të gjitha llojet e lodrave shtëpiake (për shembull, televizorët modernë skanojnë hostet e disponueshëm në rrjet dhe portat e tyre të hapura), dizajni thjesht hyn në një hutim. ENC28J60 nuk mund të funksionojë në mënyrë të pavarur me protokollet e rrjetit dhe gjithçka zbatohet në biblioteka. Ndoshta janë vetëm ata.
    Kontrollova të gjitha bibliotekat e disponueshme dhe modulet e ndryshme (papritmas me defekt), por nuk arrita të arrij një funksionim të qëndrueshëm për një kohë të gjatë. Periudha maksimale 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ë mund të ketë disa nuanca ose probleme në rrjetin tim të shtëpisë. 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 pa 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 me valë 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 them një sekret që këto module (më të lira) gjenden në shumë stacione të motit të markës për përdorim në shtëpi. 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ërdor 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 madhësinë e tekstit të 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, objektet e ekranit 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 meriton zhvillim të mëtejshëm. Kjo është ajo që ne do të bëjmë pas një kohe.

    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
    Rezistenca e prerësit 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/

    Stacioni i motit DIY.

    Ishte mbrëmje, nuk kishte asgjë për të bërë pas Vitit të Ri. Si zakonisht, gjatë festave dimërore të Vitit të Ri dua të pushtoj kokën dhe duart e mia me diçka të dobishme dhe krijuese. Gjatë këtyre festave të Vitit të Ri vendosa të bëj një stacion meteorologjik me duart e mia. Fillova të përgatitem paraprakisht, bleva dhe montova të gjithë komponentët para Vitit të Ri dhe programimin kryesor e bëra gjatë festave.

    (ka shumë foto nën prerje!)

    Së pari, do të kaloj mbi komponentët; nuk do të jap lidhje, pasi produktet në eBay (në llogarinë time personale) janë arkivuar. Bleva shumë komponentë me kohë në eBay. Provova një ankand për herë të parë; më parë blija gjithmonë "blej tani". Çfarë mund të them, nëse nuk nxitoni për të blerë, mund t'i blini disa komponentë më lirë (ndryshimi ndonjëherë është dyfishi).

    Sensori i presionit VMR085
    Ky është sensori kryesor. Kur e pashë në eBay, e dija se doja të ndërtoja një stacion moti në shtëpi.
    Sensori mbërriti në një zarf të zakonshëm, të mbuluar me mbështjellës flluskë brenda.

    Brenda zarfit ishte kartëvizita e shitësit dhe një sensor, të paketuar në një qese antistatike dhe të mbështjellë me një shtresë tjetër mbështjellëse me flluska.

    Qesja antistatike ishte e mbyllur në mënyrë që lagështia gjatë fluturimit të mos kërcënonte sensorin

    Ne nxjerrim sensorin. Në njërën anë ka një linjë kontaktesh të ngjitura, të cilat u futën në shkumë për të parandaluar përkuljen e tyre. Në anën tjetër ka vetë sensorin dhe shenjat e kontaktit.




    Gjithçka do të ishte mirë, por shenjat e kontaktit aplikohen në një imazh pasqyre.
    Sensori është i lidhur nëpërmjet autobusit I2C dhe mundësohet nga 3.3 V. Kjo do të thotë, për funksionimin normal ju nevojiten 4 tela (+, -, SDA, SCL)
    Mund ta merrni në pyetje sensorin në 2 mënyra: ose përmes bibliotekës, ose duke përdorur funksionet drejtpërdrejt në skicë.
    Shembull i programit:

    #përfshi

    #define BMP085_ADDRESS 0x77 // Adresa I2C e BMP085

    char pa nënshkruar OSS = 0; // Cilësimi i mbikampionimit

    // Vlerat e kalibrimit
    int ac1;
    int ac2;
    int ac3;
    i panënshkruar int ac4;
    i panënshkruar int ac5;
    i panënshkruar int ac6;
    int b1;
    int b2;
    int mb;
    int mc;
    int md;

    Temperatura e shkurtër;
    presion i gjatë;

    Konfigurimi i zbrazët ()
    {
    Seriali.fillim(9600);
    Wire.begin();
    bmp085Kalibrimi();
    }

    void loop ()
    {
    temperatura = bmp085GetTemperature(bmp085ReadUT());
    presioni = bmp085GetPressure(bmp085ReadUP());
    Serial.print("Temperatura: ");
    Serial.print (temperatura/10.0, DEC);
    Serial.println("C");
    Serial.print("Presioni: ");
    Serial.print(presioni/133.322, DEC);
    Serial.println(“mm Hg”);
    Seriali.println();
    vonesë (1000);
    }

    Kalibrimi i pavlefshëm bmp085()
    {
    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);
    }

    Shkurtër bmp085GetTemperature (i panënshkruar int ut)
    {
    e gjatë x1, x2;
    x1 = (((e gjate)ut - (e gjate)ac6)*(e gjate)ac5) >> 15;
    x2 = ((i gjatë) mc<< 11)/(x1 + md);
    b5 = x1 + x2;

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

    I gjatë bmp085GetPressure (i panënshkruar gjatë)
    {
    e gjatë x1, x2, x3, b3, b6, p;
    e gjatë e panënshkruar b4, b7;
    b6 = b5 - 4000;
    // Llogarit B3
    x1 = (b2 * (b6 * b6)>> 12)>> 11;
    x2 = (ac2 * b6)>> 11;
    x3 = x1 + x2;
    b3 = ((((((i gjatë)ac1)*4 + x3)<>2;
    // Llogarit B4
    x1 = (ac3 * b6)>> 13;
    x2 = (b1 * ((b6 * b6)>> 12))>> 16;
    x3 = ((x1 + x2) + 2)>>2;
    b4 = (ac4 * (i gjatë i panënshkruar)(x3 + 32768))>>15;
    b7 = ((i gjatë i panënshkruar) (lart - b3) * (50000>>OSS));
    nëse (b7< 0x80000000)
    p = (b7<<1)/b4;
    tjetër
    p = (b7/b4)<<1;
    x1 = (p>>8) * (p>>8);
    x1 = (x1 * 3038)>> 16;
    x2 = (-7357 * p)>> 16;
    p += (x1 + x2 + 3791)>>4;
    kthimi p;
    }

    // Lexoni 1 bajt nga BMP085 në "adresa"
    char bmp085Lexo (adresa e panënshkruar char)
    {
    të dhëna karakteresh të panënshkruara;

    Wire.write(adresa);
    Wire.endTransmission();
    Wire.requestFrom(BMP085_ADDRESS, 1);
    while(!Wire.available())
    ;
    ktheje Wire.read();
    }

    Int bmp085ReadInt (adresa char e panënshkruar)
    {
    char i panënshkruar msb, lsb;
    Wire.beginTransmission (BMP085_ADDRESS);
    Wire.write(adresa);
    Wire.endTransmission();
    Wire.requestFrom(BMP085_ADDRESS, 2);
    while(Wire.available()<2)
    ;
    msb = Wire.read();
    lsb = Wire.read();
    kthej (int) msb<<8 | lsb;
    }

    // Lexoni vlerën e temperaturës së pakompensuar
    i panënshkruar int bmp085ReadUT()
    {
    i panënshkruar int ut;
    // Shkruani 0x2E në Regjistrin 0xF4
    // Kjo kërkon një lexim të temperaturës
    Wire.beginTransmission (BMP085_ADDRESS);
    Wire.write(0xF4);
    Wire.write(0x2E);
    Wire.endTransmission();
    // Prisni të paktën 4,5 ms
    vonesë (5);
    // Lexoni dy bajt nga regjistrat 0xF6 dhe 0xF7
    ut = bmp085ReadInt(0xF6);
    kthej ut;
    }

    // Lexoni vlerën e presionit të pakompensuar
    i panënshkruar i gjatë bmp085ReadUP()
    {
    char i panënshkruar msb, lsb, xlsb;
    i panënshkruar gjatë lart = 0;
    // Shkruani 0x34+(OSS<<6) into register 0xF4
    // Kërkoni një lexim të presionit me vendosjen e mbikampionimit
    Wire.beginTransmission (BMP085_ADDRESS);
    Wire.write(0xF4);
    Wire.write(0x34 + (OSS<<6));
    Wire.endTransmission();
    // Prisni për konvertim, koha e vonesës varet nga OSS
    vonesë (2 + (3<// Lexoni regjistrin 0xF6 (MSB), 0xF7 (LSB) dhe 0xF8 (XLSB)
    Wire.beginTransmission (BMP085_ADDRESS);
    Wire.write(0xF6);
    Wire.endTransmission();
    Wire.requestFrom(BMP085_ADDRESS, 3);
    // Prisni që të dhënat të bëhen të disponueshme
    while(Wire.available()< 3)
    ;
    msb = Wire.read();
    lsb = Wire.read();
    xlsb = Wire.read();
    lart = (((i gjatë i panënshkruar) msb<< 16) | ((unsigned long) lsb << 8) | (unsigned long) xlsb) >> (8-OSS);
    kthehu lart;
    }


    Përveç kësaj, sensori ka sensorin e tij termik për kompensimin e presionit dhe një lartësimatës

    Arduino Nano v3.0
    Kjo është zemra e të gjithë stacionit të motit. E thënë thjesht, kontrolluesi është në madhësi miniaturë.
    une bleva
    Unë nuk do të flas në detaje për kontrolluesin, pasi kjo është bërë tashmë para meje:


    Paketa Lightake ishte e parafabrikuar, kontrollori erdhi në një paketë që përmbante një kabllo USB dhe një Arduino në një qese antistatike të mbyllur.

    Për të vlerësuar madhësinë, vendosa një monedhë 1 rubla pranë Arduino.

    Bordi i kontrolluesit nga afër



    Kablloja USB është e mirë, me një unazë ferriti. Arduino mundësohet përmes një kablloje USB. Mjedisi i zhvillimit mund të shkarkohet (faqja e shkarkimit). Gjuha është e ngjashme me "C", nuk ka pasur probleme me zotërimin e saj, pasi unë bëj shumë programim në të në punë.

    Ekran LCD
    Në punë gjeta një ekran të përputhshëm LCD 1602 në kosha. Më duhej të ndërhyja me lidhjen, pasi nuk mund të gjeja një fletë të dhënash për të. Si rezultat, LCD filloi të funksionojë.

    Por pas një periudhe të shkurtër përdorimi, vura re se ky ekran nuk më mjaftonte dhe nuk do të mund të shfaqja më shumë të dhëna, pasi ka vetëm 2 rreshta me 16 karaktere secila. Në fillim duket se mjaftojnë këto parametra, por kur filloni të programoni, kupton se maksimumi që mund të shtrydhni është 3-4 parametra. Dhe nëse krijoni një menu (po mendoja të bëja një menu në këtë ekran), atëherë ka vetëm 1-2 parametra hapësirë ​​​​të lirë.
    Si rezultat, fillova të kërkoja një ekran tjetër. Në fillim pashë nga afër ekranin grafik të Nokia 3310 dhe madje mora pjesë në ankandin e eBay për ta blerë, por nuk funksionoi (për të cilën jam shumë i lumtur), kështu që më duhej të hiqja dorë nga ky ekran. Tani e kuptoj që do të ishte shumë e vogël për qëllimet e mia, pasi ka diçka për të krahasuar.
    Ndërsa shikoja rastësisht nëpër mburojat në Arduino, hasa në një ekran grafik 12864 në një kontrollues ST7920. Ky ekran ka madhësinë e duhur dhe rezolucion të mirë për nevojat e mia (128x64). Kjo do të thotë, mund të vendosni lehtësisht 6-7 rreshta me 20 karaktere në një font normalisht të lexueshëm. Meqenëse ekrani është grafik, përveç tekstit, grafika mund të vendoset edhe në fonte të ndryshme. Me pak fjalë, kjo është pikërisht ajo që më duhej, gjithçka ishte e pranishme në këtë ekran, ndaj nuk munda të rezistoja dhe e porosita.
    Parcela mbërriti shpejt dhe u paketua si standard: një zarf mbështjellës me flluskë, brenda kishte një shtresë tjetër mbështjellës flluskë dhe një ekran në një qese antistatike:






    Për të vlerësuar madhësinë, vendosa një monedhë 1 rubla pranë LCD.




    Për të lidhur shpejt ekranin me Arduino, bashkova një linjë kontaktesh në kunjat LCD. LCD mund të lidhet nëpërmjet një autobusi serik ose paralel. Zgjodha opsionin e parë, pasi tashmë ka pak kontakte falas Arduino.
    Lidhja (marrë nga uebi):

    - Pini 1 (GND) është i lidhur me autobusin e përbashkët
    - Pini 2 (VCC) është i lidhur me autobusin e energjisë +5V dhe konsumi aktual është relativisht i vogël dhe ekrani mund të mundësohet nga stabilizuesi i integruar Arduino.
    - Kunjat 4, 5 dhe 6 lidhen me daljet dixhitale Arduino, duke formuar ndërfaqen serike SPI:
    pin 4 - (RS) - korrespondon me linjën CS (për shembull 7)
    pin 5 - (RW) - korrespondon me linjën MOSI (për shembull 8)
    pin 6 - (E) - korrespondon me linjën SCK (për shembull 3)
    Numrat e kontaktit të Arduino mund të jenë çdo gjë, gjëja kryesore është të mos harroni t'i tregoni saktë në tekstin e programit kur inicializoni ekranin.
    - Pin 15 (PSB) është i lidhur me autobusin e përbashkët.
    - Kontaktet 19 (A) dhe 20 (K) janë furnizimi me energji të dritës së prapme (përkatësisht +5V dhe GND). Për të rregulluar ndriçimin e dritës së prapme, mund të përdorni një rezistencë të ndryshueshme 10 kOhm të lidhur midis autobusit të energjisë dhe GND. Tensioni nga motori i tij furnizohet në pinin 19 të ekranit.
    Sipas këtyre udhëzimeve, unë lidha gjithçka përveç dritës së prapme. Kam përdorur Arduino PWM për të fuqizuar dritën e pasme.
    Për të lidhur në mënyrë programore LCD-në me Arduino, përdoret biblioteka u8glib. Mund ta shkarkoni. Nëse ka probleme me shkarkimin, mund ta ngarkoj bibliotekën në narod.ru.
    Vetë biblioteka nuk është e komplikuar dhe ju lejon të shfaqni tekstin me shkronja të ndryshme, të vizatoni një vijë, të vizatoni forma të thjeshta gjeometrike (drejtkëndësh, rreth) dhe të shfaqni imazhet tuaja të përgatitura në një mënyrë të veçantë. Në parim, ky mjet është i mjaftueshëm për shumicën e detyrave.
    Këtu është rezultati i një programi të thjeshtë:

    Vetë programi:

    #include "U8glib.h"

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

    // Nënprogrami për përcaktimin e memories së lirë
    int freeRam() (
    extern int __heap_start, *__brkval;
    int v;
    kthimi (int) &v - (__brkval == 0? (int) &__heap_start: (int) __brkval);
    }

    Konfigurimi i zbrazët (i pavlefshëm) (
    u8g.setFont(u8g_font_6x10); // font
    u8g.setRot180(); //Kthejeni ekranin
    analogWrite(6, 115); // Cakto ndriçimin e ekranit (anoda e dritës së prapme në 6 pin)
    }

    Cikli i zbrazët (i pavlefshëm) (
    u8g.firstPage();
    bej(

    u8g.setPrintPos(1, 12); // pozicion
    u8g.print("Përshëndetje!!!"); // nxjerr tekstin
    u8g.drawBox(0,22,128,9); // Ngjyrosni drejtkëndëshin të bardhë
    u8g.setColorIndex(0); // bojë e bardhë, sfond i zi
    u8g.setPrintPos(1, 30); // pozicion
    u8g.print("Fjala..."); // nxjerr tekstin

    U8g.setColorIndex(1); // bojë e bardhë, sfond i zi
    u8g.setPrintPos(1, 50); // pozicion
    u8g.print ("Pas fillimit ="); // nxjerr tekstin
    u8g.setPrintPos(85, 50); // pozicion
    u8g.print(millis() / 1000); // nxjerr numrin e sekondave pas fillimit
    u8g.setPrintPos(1, 64); // pozicion
    u8g.print(freeRam()); // nxjerr sa memorie është e zënë
    ) while(u8g.nextPage());

    Vonesa (200);
    }

    Ora në kohë reale DS1307
    Një tjetër komponent për stacionin tim të motit. Kjo mburojë zbaton një orë në kohë reale. I porosita në eBay. Shitësi e dërgoi shallin e orës në një kuti jorealiste të madhe


    Brenda kutisë kishte dy fletë reklamash A4 dhe një shami ore të mbështjellë me celofan


    Dua të vërej se tarifa nuk kalon 2 rubla. monedhë, dhe kutia me përmasa 13x15x5 cm.
    Tabela ishte e paketuar në një qese antistatike

    Shall nga afër



    Më duhej të ndërhyja me këtë modul. Së pari, kishte vështirësi në lidhje. Dhe së dyti, nuk ka kuarc në këtë tabelë. Nëse do ta dija që do të shpenzoja kaq shumë kohë në modul, me shumë mundësi do ta kisha mbledhur vetë, pasi interneti është plot me diagrame. Qarku më i thjeshtë përmban 4-5 komponentë.
    Në lidhje me lidhjen. Gjeta një bibliotekë që thoshte se ndërfaqja I2C mund të lidhet jo me hyrjet e zakonshme analoge të Arduino (A4 dhe A5), por me ndonjë diskrete. E bëra ashtu siç ishte shkruar. Në fillim asgjë nuk funksionoi, por pas një kërcimi të gjatë me dajre, ora filloi. Epo, mendova, kaq, problemet mbaruan, por pasi u përpoqa të lidhja të njëjtin modul me një Arduino tjetër, vallëzimi me dajre vazhdoi. Kalova shumë kohë duke kërkuar një zgjidhje për këtë problem dhe pothuajse kudo u tregua ose një lidhje e gabuar ose mungesa e rezistorëve tërheqës në kontaktet SCL dhe SDA. Unë tashmë doja të futesha në tabelë me një hekur saldimi, por në një forum rastësisht hasa në një kod ku thuhej se lidhte SCL dhe SDA me portat standarde I2C në Arduino. Pas një lidhjeje standarde, gjithçka funksionoi menjëherë.
    Tani në lidhje me kuarcin. Nuk e di se çfarë lloj kuarci vendosën kinezët atje, por orët me kuarc të tillë ikën me 10-11 sekonda në ditë. Ky gabim është 5 minuta në muaj dhe 1 orë në vit. Nuk ka nevojë për një orë si kjo. Më duhej të shkoja përsëri në internet dhe të kërkoja se si ta rregulloja këtë gabim. Zgjidhja e parë që del thotë se ju duhet të tokëzoni kuarcin. E bëra - rezultati ishte zero. Gjithashtu gjeta diku që më duhet të gjej një motherboard të vjetër dhe të heq kuarcin e orës prej andej. E bëra - ka një rezultat. Tani ora ikën jo me 10-11 sekonda, por me 1.5 sekonda në ditë. Le të themi se është bërë më mirë, por është larg idealit. Meqenëse nuk më pëlqen më të merrem me saldator, u vendos që të rregulloj orën në mënyrë programore, domethënë të rregulloj orën në vlerën e kërkuar një herë në ditë. Pas 10 ditësh, ora u fik jo më shumë se një sekondë. Metoda është e mirë, por vetëm kur pajisja e sinkronizimit Arduino është e lidhur me energjinë, përndryshe ora funksionon me fuqinë e baterisë dhe ende ikën.
    Një program i vogël testimi:

    #përfshi "Wire.h"
    #define DS1307_I2C_ADDRESS 0x68 // SDA A4, SCL A5

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

    Byte bcdToDec (bajt val)
    {
    kthimi ((val/16*10) + (val%16));
    }

    Set DateDs1307 i pavlefshëm (byte sekondë, // 0-59
    byte minutë, // 0-59
    byte orë) // 0-99
    {

    Wire.shkruaj(0);
    Wire.write(decToBcd(sekond));
    Wire.write(decToBcd(minutë));
    Wire.write(decToBcd(orë));
    Wire.endTransmission();
    }

    E pavlefshme getDateDs1307(byte *sekondë,
    byte *minutë,
    byte *orë)
    {

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

    Wire.requestFrom(DS1307_I2C_ADDRESS, 3);

    *second = bcdToDec(Wire.read());
    *minuta = bcdToDec(Wire.read());
    *orë = bcdToDec(Wire.read());
    }

    Konfigurimi i zbrazët ()
    {
    byte sekondë, minutë, orë;
    Wire.begin();
    Seriali.fillim(9600);

    E dyta = 45;
    minutë = 5;
    orë = 16;

    SetDateDs1307 (sekondë, minutë, orë);
    }

    void loop ()
    {
    byte sekondë, minutë, orë;

    GetDateDs1307 (&sekond, &minuta, &orë);
    Serial.print(orë, Dhjetor);
    Serial.print(":");
    Serial.print (minuta, DEC);
    Serial.print(":");
    Serial.println (e dyta, DEC);

    Vonesa (1000);
    }


    Biblioteka nuk përdoret këtu dhe funksionet për kohën e leximit dhe shkrimit janë të shkurtuara.

    Sensori i temperaturës dhe lagështisë DHT11
    Nuk ka asgjë për të thënë për këtë sensor. Unë as nuk do ta përdorja nëse nuk do të ishte e nevojshme lagështia. Fatkeqësisht, nuk e bëra një foto kur e mora, kështu që nuk do të ketë asnjë foto. Fotot e sensorit mund të shihen më poshtë, ku e lidha atë me Arduino. Lidhja e sensorit është e thjeshtë (+, dalje dixhitale, -). Zakonisht sensorët bëhen me katër kunja. Me këtë faktor forme, kunja e tretë nuk është e lidhur me asgjë.
    Ju mund të përdorni bibliotekën për t'u lidhur me Arduino. Mund ta shkarkoni.
    Një program i vogël testimi me dalje informacioni në ekranin LCD 1602:

    // përfshin kodin e bibliotekës:
    #përfshi
    #përfshi

    // Deklaroni objekte
    dht11 DHT11;
    LCD Crystal Liquid(12, 11, 6, 5, 4, 3);

    #define DHT11PIN 7
    int i;

    Konfigurimi i zbrazët ()
    {
    lcd.begin(16, 2);
    lcd.print("Statusi: ");
    i=0;
    }

    void loop ()
    {
    int chk = DHT11.read(DHT11PIN);
    lcd.setCursor(8, 0);
    kaloni (chk)
    {
    case 0: lcd.print(“OK“); break;// lcd.setCursor(11, 0); lcd.print(millis()/2000); pushim;
    case -1: lcd.print(“Gabim i shumës së kontrollit”); mErr(); pushim;
    case -2: lcd.print("Time out error"); mErr(); pushim;
    default: lcd.print ("Gabim i panjohur"); mErr(); pushim;
    }
    vonesë (500);
    lcd.setCursor(15, 0);
    ndërprerësi (i)
    {
    case 0: lcd.print("^"); lcd.setCursor(15, 1); lcd.print(" ");break;
    rasti 1: lcd.print("v"); lcd.setCursor(15, 1); lcd.print(" ");break;
    default: lcd.setCursor(15, 1); lcd.print("E"); pushim;
    }
    i=i+1;
    nëse (i>1) i=0;
    lcd.setCursor(0, 1);
    lcd.print("H=");
    lcd.setCursor(2, 1);
    lcd.print((float)DHT11.lagështia, 0);
    lcd.setCursor(4, 1);
    lcd.print("%");
    lcd.setCursor(8, 1);
    lcd.print("T=");
    lcd.setCursor(10, 1);
    lcd.print((float)DHT11.temperaturë, 0);
    lcd.setCursor(12, 1);
    lcd.print("C");

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


    Sensori ka disa disavantazhe - të dhënat nga sensori janë vetëm në numra të plotë, dhe diapazoni është i dobët.

    Duket sikur kam shkruar për të gjithë komponentët. Gjithçka që mbetet është të mbledhim gjithçka në një tërësi të vetme.
    Oops, pothuajse harrova! Për të montuar pajisjen, ju nevojitet një kuti. E porosita edhe rastin në Ebay. Shitësi doli të ishte nga Anglia. Pakoja mbërriti shpejt, por nuk e fotografova. Të gjitha fotot e rastit janë më poshtë.

    Së pari, mblodha gjithçka në tryezë duke përdorur instalime elektrike speciale. Shkrova një program testimi dhe e ngarkova në kontrollues.



    Në fakt, ngjyra blu e dritës së prapme është shumë më e ndritshme. Edhe me ndriçimin minimal (Bright=5), korniza ndriçohet.

    Për të mbledhur gjithçka me valë, u vendos të bëhej një mini motherboard, dhe bordet dhe mburojat Arduino u vendosën në lidhës. Nëse ndodh diçka, ato mund të hiqen shpejt dhe lehtë. Vendosa gjithashtu të bashkoj ekranin LCD dhe butonat e kontrollit te lidhësit, vetëm për të bashkuar sensorin e temperaturës në tela.
    Kështu doli shalli



    Në foton e fundit nuk e kam larë plotësisht fluksin. Ngjita gome poroze nën mburojat pranë lidhësve, në mënyrë që të kishte të paktën një mbështetje. Edhe pse në fakt mburojat në lidhësit në kontakte po qëndrojnë mirë.

    Motherboard me mburoja të instaluara dhe pllakë Arduino.

    Kështu duket një lidhje e plotë me motherboard


    Në vend të butonave, përdora një mburojë të bërë vetë të ngjitur në një dërrasë buke. Kam përdorur butona nga minjtë e vjetër si butona.
    Siç mund ta shihni, numri i telave është zvogëluar.

    Problemi kryesor i vendosjes në kuti është prerja e një brazdë të lëmuar për ekranin LCD. Sado që u përpoqa, përsëri nuk funksionoi në mënyrë perfekte. Boshllëqet në disa vende ishin pak më shumë se 1 mm. Për ta bërë gjithçka të duket e rregullt, mora ngjitësin e zi të akuariumit dhe mbusha të gjitha të çarat, në të njëjtën kohë i ngjita ekranin këtij ngjitësi. Pasi të ishte tharë ngjitësi, e preva tepricën nga jashtë. Në dritë të ndritshme, ngjitësi është i dukshëm, por në dritën normale, gjithçka bashkohet me trupin.
    Kështu duket kasa nga brenda me një ekran LCD dhe motherboard të instaluar.

    Kështu duket nga jashtë në dritë të fortë (më falni për gjurmët e gishtërinjve, i pashë kur po zgjidhja fotot).

    Kam menduar për një kohë të gjatë se si t'i vendos butonat në kasë dhe, më e rëndësishmja, çfarë butona të përdor...
    Në dyqanet radio-elektronike, u pëlqente butoni me një gjilpërë të gjatë dhe majat që përshtateshin në këtë kunj. Këta butona përdoren për bashkim në tabelë. Gjithçka do të ishte mirë, por ata kanë një minus - goditja e ngutshme është shumë e vogël dhe e zhurmshme.
    Ne duhej t'i vendosnim butonat në dy faza: e para ishte vendosja e butonave në tabelë, e dyta ishte montimi i kësaj dërrase në një tabelë tjetër. Dhe pastaj vendoseni të gjithë këtë në trup në udhëzues.

    Ja si duket një shall me kopsa:



    Kështu duket tabela mbajtëse:


    Këtu mund të shihni udhëzuesit në të cilët është futur bordi me butona. Disa elementë u bashkuan për t'i dhënë ngurtësi tabelës.

    Tani vendosim gjithçka në trup
    Pa butona lidhës:


    Me lidhjen e butonave:

    Mbyllni kasën dhe ndizni. Gjithçka funksionon shkëlqyeshëm, butonat funksionojnë ashtu siç duhet.

    Në fund postoj një video të shkurtër të pajisjes duke punuar në mënyra të ndryshme:
    http://www.youtube.com/watch?v=KsiVaUWkXNA&feature=youtu.be
    Për ata që nuk e shohin videon këtu, këtu është lidhja për të

    Është koha për të përfunduar rishikimin.
    Do të shkruaj pak për programin dhe më pas disa përfundime të shkurtra. Kur shkrova programin, nuk mendova se do të arrija shumë shpejt kufirin e 30,720 bajt.


    Më duhej të optimizoja kodin. Kam zhvendosur shumë pjesë kodi në nënprograme. Nuk do ta kisha menduar kurrë se një deklaratë switch...case në formë të përpiluar zë më shumë hapësirë ​​se disa deklarata if...else. Deklarimi i saktë i variablave gjithashtu kursen hapësirë. Nëse deklaroni një grup të gjatë, megjithëse është mjaft e mundur të merret me byte, atëherë tejkalimi i memories arrin 500 bajt, në varësi të madhësisë së grupit. Kur shkruani një program, nuk mendoni për të dhe vetëm më vonë, kur analizoni programin, kuptoni se i keni bërë disa gjëra gabim dhe filloni të optimizoni kodin. Pasi u zgjidhën problemet me madhësinë e programit, hasa në një kufizim RAM. Kjo u shpreh në faktin se programi filloi të ngrijë pas ngarkimit. Më duhej të prezantoja një nënprogram për llogaritjen e RAM-it të lirë. Si rezultat, u detyrova të braktisja një algoritëm të parashikimit të motit, pasi ai duhet të shfaqë ikona në ekran. Vetë algoritmi funksionon, por dalja e ikonave duhej të regjistrohej. Unë kam ende ide se si të optimizoj kodin, por në të ardhmen e afërt do ta lë pajisjen të funksionojë siç është për të vlerësuar performancën e saj dhe për të identifikuar të gjitha gabimet.

    Tani disa përfundime
    Minuset
    1) Çmimi. Arsyetimi për këtë disavantazh është se një hobi nuk është kurrë i lirë.

    pro
    1) Funksionalitet i madh i pajisjes
    2) Rritja e funksioneve kufizohet vetëm nga kontrolluesi i përdorur dhe dëshira juaj
    3) Kënaqësi estetike nga soditja dhe kënaqësi morale nga fakti që më në fund montova dhe përfundova këtë pajisje

    Kam në plan të blej +85 Shto te të preferuarat Më pëlqeu rishikimi +137 +304

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