Hemma väderstation på Arduino och skickar data till "People's Monitoring". Väderstation på NodeMcu. Offentlig övervakning Ta emot data som skickas från "Port Monitor" till Arduino

Detta är ett gemensamt projekt. Länkar till kanaler, hemsida och författararkiv finns i slutet av beskrivningen. Ett blockstyrsystem för vind- och solkraftverket skapas. Vi har två sommarstugor med alternativ energiförsörjning. I ett område finns extern el, i det andra är det fullständig frånvaro av det. Webbplatserna är belägna i olika regioner i Ryssland. På den första platsen finns en hemmagjord vindgenerator med en effekt på 1 kW, 6 stationära solpaneler, 100 W vardera, seriekopplade, två delar på 24 V, och 6 hemmagjorda paneler, även anslutna till 24 volt, installerade på en solar tracker. På den andra platsen finns 4 permanent installerade paneler på 100 W vardera och 2 hemmagjorda paneler på 60 W vardera, även de anslutna till ett 24 voltssystem. Projektet kommer att möjliggöra anslutning av både 12 volt och 24 volt system utan mekaniska förändringar. Systemet består av fem oberoende block. Kommunikation mellan enheterna sker via radiokanal genom NRF24L01-moduler (med extern antenn).

  1. Modul "Kontrollenhet" baserad på ARDUINO MEGA2560— samlar in all information och visar den på LCD-skärmen IIC/I2C 2004 4Х20, styra block, enheter och ange olika inställningar med hjälp av 4X4 matris tangentbord. Temperatur, luftfuktighet, tryck (trycksensor bmp180), datum, tid (timmar DS3231). All inställningsinformation matas in via menyn och sparas i EEPROM. Efter att ha ställt in alla nödvändiga korrigeringsfaktorer i felsökningsläge skickas denna data via radiokanal till dess block, vilket gör att du kan finjustera all data. (Blocket fortsätter att utvecklas).
  2. Modul "Wattmeter block" baserad på ARDUINO NANO tillsammans med kraftenheten - mäter och beräknar inkommande och utgående strömmar och spänningar med hjälp av en mätstav med strömsensorer installerade på den ACS712 30A och ACS754SCU 100A, ADS1015 12-bitars ADC, resistiva spänningsdelare. Dessutom reglerar den spänningen som genereras av vindgeneratorn i parametrarna med hjälp av en ballastlast, värmer vatten med kokskydd baserat på en förseglad sensor DS18B20. Stänger av växelriktaren när batterierna är urladdade under den procent som anges i parametrarna. Inkluderar ett kylsystem för en trefas diodbrygga. (Sensor DS18B20).
  3. Modul "Vindgeneratorblock" baserad på ARDUINO NANO— Består av två block:
  • Direkt mäter och sänder "Wind Generator Unit": generatorhastighet (Hallsensor), temperatur på generatorlindningarna, temperatur och fuktighet i generatorutrymmet ( DS18B20 och DHT22), bestämning av dag och natt ( fotoresistorer). Vindturbinens bakläge. Och även, av säkerhetsskäl, en trestrålad LED-fyr (vindgeneratormast 17 m hög).
  • "Anemometerblock" - vindhastighetsmätning (Hall-sensor), vindriktningsindikator (Hall-sensorer, digital portexpander IIC I2C MCP23017).

4. "WEB-server"-modul baserad på ARDUINO MEGA 2560 och internetsköld W5100 Ethernet— visar all information om kraftverket på webbplatsen för möjligheten att övervaka avläsningar på distans.

5. "Solar Tracker"-modul - styrning av solpanelernas position i solen och i tid om det inte finns några, styrning med en IR-fjärrkontroll, automatisk återgång av trackern till positionen österut efter mörkrets inbrott. Ställ in trackern i "vindskyddsläge" om vindhastigheten överstiger den inställda. Tracker körkontroll. Enheten har faktiskt fungerat i ett år nu. Inte i arkivet än, eftersom... Det implementeras i det allmänna blockschemat.

Projektet började använda NEXTION-monitorn (en underbar sak, vi kommer definitivt att använda den någonstans), men sedan övergav vi den på grund av stora förseningar på grund av mängden överförd information och beslutet att göra systemet modulärt.

Alla ARDUINO NANO blinkar också via WiFi med ESP8266-01. Detta för att uppdatera den fasta programvaran, i händelse av skisskorrigering, utan att ta bort blocken från deras installationsplatser. Det finns fortfarande ett problem med MEGA2560, vi vet orsaken, men vi kan inte lösa det ännu. Men det är en annan historia.

Skisser i FLProg-format, tryckta kretskort i Sprint-Layout-format som uppdateras regelbundet

Vi fortsätter att utveckla vår väderstation.

Innan vi går vidare till uppdateringen vill jag förtydliga lite.

En av våra kollegor skrev till mig och frågade varför vakthundstimern infördes?

Watchdog-timern är på plats i händelse av en nödsituation. Som praxis visar, hanterar ENC28J60 inte mer än (om inte minnet misslyckas) 4 samtidiga anslutningar. Med tanke på hur många tjänsteanslutningar som ständigt uppstår för att upprätthålla driften av själva nätverket och bara lämnat trafik skapad av alla möjliga hushållsleksaker (till exempel, moderna tv-apparater, skanna tillgängliga värdar på nätverket och deras öppna portar) går designen helt enkelt i dvala. ENC28J60 kan inte arbeta självständigt med nätverksprotokoll och allt är implementerat i biblioteken. Kanske är det bara de.
Jag kontrollerade alla tillgängliga bibliotek och olika moduler (plötsligt defekta), men jag kunde inte uppnå stabil drift under lång tid. Den maximala perioden var ca 3-4 veckor.
Det är därför "hunden" snurrar dit och, om något händer, drar i kontrollern. Efter detta försvann problemet.
Jag förnekar inte heller att det är möjligt i min hemnätverk det finns vissa nyanser eller problem. Men eftersom jag hade ett problem kan en annan person också ha det. Hittills har jag bara hittat denna lösning.
Så vitt jag vet har inte chips från Wiznet (W5100 och högre) detta, eller så såg de bara inte tillräckligt bra ut.

Låt oss gå vidare till uppdateringen

Det viktigaste är att vi går bort från chippet ENC28J60 och gå till W5100. Jag försökte implementera allt på det gamla chippet, men det finns inte tillräckligt med mikrokontrollerminne på grund av mycket stora bibliotek för ENC28J60. Vid användning av ett nytt chip, standard bibliotek från utvecklaren och alla ändringar som gjorts, det återstår ännu mer 20% gratis minne för mikrokontroller ATMega328. Och det här är nya bullar!

I denna version (låt oss kalla det den andra) möjligheten att överföra avläsningar från sensorer via trådlös kommunikation använder frekvens 433 MHz. Jag tog själva modulerna från kineserna, markeringar XY-MK-5V. Jag skulle vilja notera att kvaliteten på överföringen är långt ifrån perfekt. Eventuell signalförlust, brus, oförmåga att sända samtidigt, etc., etc. Men deras pris (mindre än $1 per set) kompenserar för dessa brister. Jag ska berätta en hemlighet att dessa (de billigaste) modulerna finns i många märkesvarorstationer för hemmabruk. Wow, oväntat?

Låt oss börja med basstationen

Vi flyttar till Arduino UNO Och Ethernet Shield(första versionen) baserat på chip W5100. Det här är en smörgås och det är ingen idé att beskriva den. Jag kommer endast att beskriva de ytterligare involverade kontakterna för modulerna XY-MK-5V.

Sändarmodulen använder ström 5V, GND(var skulle vi vara utan mamma) och D2 stift på kontrollen. Redigera kontakt D2 (DATA) du kan använda funktionen vw_set_tx_pin från vw-biblioteket.

Till skillnad från den föregående skissen använder den här två ytterligare bibliotek:

#omfatta #omfatta

Själva skissen

Dold text

#omfatta #omfatta #omfatta #omfatta #omfatta #omfatta #omfatta #omfatta #define DHTTYPE DHT22 #define DHTPIN 5 DHT dht(DHTPIN, DHTTYPE); byte mac = (0x54, 0x34, 0x31, 0x31, 0x31, 0x31); char server = "narodmon.ru"; int port = 8283; IP-adress ip(192,168,0,201); EthernetClient-klient; BMP085 dps = BMP085(); lång Temperatur = 0, Tryck = 0; flottör H, dP, dPt; bool intervall = sant; EasyTransferVirtualWire ET; struct SEND_DATA_STRUCTURE( byte ID; // Device ID int Temperature; // Temperaturfloat Pressure; // Pressure flottör Fuktighet; // Fuktighet flytande daggpunkt; // Dagg/frostpunkt ); SEND_DATA_STRUCTURE sändning; void setup() ( // Initiera Watchdog-timern wdt_disable(); delay(8000); wdt_enable(WDTO_8S); // Initiera konsolen Serial.begin(9600); // Initiera DHT-sensorn dht.begin(); / / Initialisering av 433 MHz-modulen ET.begin(detaljer(broadcast)); vw_set_ptt_inverted(true); vw_set_tx_pin(2); vw_setup(2000); // Starta nätverket, om vi inte har väntat på data från DHCP-servern, sedan // tilldela oss själva en adress if (Ethernet.begin(mac) == 0) Ethernet.begin(mac, ip); // Initializing 1-Wire Wire.begin(); delay(200); // Initializing BMP180 med höjdjustering // dps.init (MODE_STANDARD, 3200, true); // Initiera BMP180 dps.init(); Serial.println(Ethernet.localIP()); // Skicka den första datan direkt efter att du har slagit på enheten send_info (true); ) // dewPoint-funktion NOAA // referens (1) : http://wahiduddin.net/calc/density_algorithms.htm // referens (2) : http://www.colorado.edu/geography/weather_station /Geog_site/about.htm dubbel daggpunkt(dubbel celsius, dubbel luftfuktighet) ( // (1) Mättnadsångtryck = ESGG(T) dubbelförhållande = 373,15 / (273,15 + celsius); dubbel RHS = -7,90298 * (FÖRHÅLLANDEN - 1); RHS += 5,02808 * log10 (FÖRHÅLLANDEN); RHS += -1,3816e-7 * (pow(10, (11,344 * (1 - 1/FÖRHÅLLAND))) - 1); RHS += 8,1328e-3 * (pow(10, (-3,49149 * (FÖRHÅLLANDE - 1))) - 1); RHS += log10(1013,246); // faktor -3 är att justera enheter - Vapor Pressure SVP * fuktighet dubbel VP = pow(10, RHS - 3) * fuktighet; // (2) DEWPOINT = F(ångtryck) dubbel T = log(VP/0,61078); // temp var retur (241.88 * T) / (17.558 - T); ) void send_info(bool eth) ( bool fail = true; while(fail) ( // Vi försöker läsa data från DHT fuktsensorn tills vi får // ett resultat. I 90 % av fallen fungerar allt bra, men vi behöver 100 % if((H = dht.readHumidity()) >= 0) ( // Får luftfuktighet och temperatur från BMP180-sensorn dps.getPressure(&Pressure); dps.getTemperature(&Temperature); // Beräkna daggpunkten om temperaturen är utanför över 0 grader Celsius // och förvänta dig ett resultat över 0, annars utmatning 0. Detta är nödvändigt // för att inte vara vilseledande under vintersäsongen. // dP = Temperatur>0?((dPt=daggpunkt(Temperature*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); }

En antenn måste läggas till själva modulerna. För 433 MHz Det räcker med en vanlig lång koppartråd 17 cm. Utan antenn kan du glömma normal drift.

Låt oss gå vidare till den viktigaste delen av denna uppdatering - den lokala trådlösa stationen

För att implementera det (på knäet) använde jag en analog Arduino NANO(på basen ATMega328) Och TFT visas på ett chip ST7735S med tillåtelse 128 x 160

Dold text



Pinout display -> kontroller

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

Mottagarmodulen ansluts endast på samma sätt som en sändare DATA att nåla D7.

Ett par bilder på hur det ser ut:

Dold text

Mottagare skiss

Dold text

#omfatta #omfatta #omfatta #omfatta int x, y; int w = 128, h = 160; int storlek; // 433 EasyTransferVirtualWire ET; struct SEND_DATA_STRUCTURE( byte ID; // Device ID int Temperature; // Temperaturfloat Pressure; // Pressure flottör Fuktighet; // Fuktighet flytande daggpunkt; // Dagg/frostpunkt ); SEND_DATA_STRUCTURE sändning; int Log_Temperature = -1; float Log_Pressure = -1; float Log_Humidity = -1; float Log_dewPoint = -1; // TFT #define cs 10 #define dc 9 #define rst 8 char Temperatur, Pressure, Fuktighet, DewPoint; Stränginformation; TFT TFTskärm = TFT(cs, dc, först); void setup())( Serial.begin(9600); // Initiering av 433 MHz-modulen ET.begin(detaljer(broadcast)); vw_set_ptt_inverted(true); vw_set_rx_pin(7); vw_setup(2000); vw_rx_start(); // Initialisering och initial visningsinställningar TFTscreen.begin(); TFTscreen.setRotation(2); TFTscreen.background(0, 0, 0); // Rita statiska element // 1. Kom och besök oss TFTscreen.stroke(255, 255) , 255); TFTscreen.setTextSize(1); TFTscreen.text(" ", 10, 10); // 2. Beskrivning av avläsningar från sensorer TFTscreen.text("mmHg", w/2+5, 80); TFTscreen .text ("%", w/2+5, 100); TFTscreen.text("C", w/2+5, 120); broadcast.Temperature = 0; broadcast.Pressure = 0; broadcast.fuktighet = 0 ; broadcast .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(); */ ) ) ogiltiga ändringar (int size, int x, int y, bool up, bool clear = false) ( if(clear) TFTscreen.stroke(0, 0, 0); else (ändringar(storlek, x, y, !upp, sant); TFTscreen.stroke((upp)?0:255, 0, (upp)?255:0); ) if((storlek%2) == 0 ) storlek++; while(storlek > 0) ( TFTscreen.line(x, y, x+(storlek--), y); ++x, (upp)?--y:++y, --size; ) /* while( storlek > 0) ( TFTscreen.line(x, y, (upp)?x+storlek-1:x, (upp)?y:y+storlek-1); ++x, ++y, --storlek; ) */ ) int x_center(int w, int length, int size) ( return floor((w-length*(size*5)+size*2)/2); ) int x_alignment_right(int w, int length, int storlek) ( return ceil(w-length*(size*5)+size*2); ) void TFTPrint() ( storlek = 3; // ================= ================================================== === ================ // Visa temperaturavläsningar // =========================== ================================================= if(sändning. Temperatur != Log_Temperature) ( TFTscreen.setTextSize(size); // Skriv över föråldrad data String info = String(Log_Temperature); info.concat(" C"); if(Log_Temperature > 0) info = "+"+info; info .toCharArray(Temperature, info.length()+1); TFTscreen.stroke(0, 0, 0); TFTscreen.text(Temperature, x_center(w, info.length()+1 , storlek), 35); / / Visa information om nya avläsningar = String(broadcast. Temperatur); info.concat("C"); if(broadcast.Temperature > 0) info = "+"+info; info.toCharArray(Temperature, info.length()+1); // Ändra färgen på temperaturvärdet beroende på själva temperaturen int r, g = 0, b; if(broadcast.Temperature > 0) ( r = map(broadcast.Temperature, 0, 40, 255, 150); // Red b = map(broadcast.Temperature, 0, 40, 30, 0); // Ändra nyans för en mer visuell övergång till noll ) else ( r = map(broadcast.Temperature, -40, 0, 0, 30); // Ändra nyansen för en mer visuell övergång genom noll b = map(broadcast.Temperature, - 40, 0, 150, 255); // Blå ) TFTscreen.stroke(b, g, r); // OBSERVERA: färgpositionerna i biblioteket är blandade, RGB-platsen används av BGR! TFTscreen.text(Temperature, x_center(w, info.length()+1, storlek), 35); ) storlek = 1; // ================================================ ==== ===================================== // Utgående tryckavläsningar // === ====== ============================================ ========= ======================== if(broadcast.Pressure != Log_Pressure) ( TFTscreen.setTextSize(size); / / Skriv över föråldrad data 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(), storlek), 80 ); // Mata ut nya avläsningar 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 ( ändringar (10, 106, 85, sant, sant); ändringar(10, 106, 85, falskt, sant); ) // ===================== ======== ========================================== =========== = // Utgående luftfuktighetsavläsningar // ================================ =================================================== ================== if(broadcast.Humidity != Log_Humidity) ( TFTscreen.setTextSize(size); // Skriv över föråldrad data info = String(Log_Humidity); info.toCharArray(Humidity, info.length()); TFTscreen.stroke(0, 0, 0); TFTscreen.text(Humidity, x_alignment_right(w/2-5, info.length(), storlek), 100); // Visa nya avläsningar info = String(broadcast.Humidity); info.toCharArray(Humidity, info.length()); TFTscreen.stroke(255, 255, 255); TFTscreen.text(Humidity, x_alignment_right(w/2-5, info.length(), storlek), 100); ändringar(10, 106, 105, (broadcast.Humidity > Log_Humidity)?true:false); ) else ( ändringar(10, 106, 105, sant, sant); ändringar (10, 106, 105, falskt, sant); ) // ================== ================================================== === =============== // Utdata för daggpunkt/frostpunktsavläsningar // ====================== ==================================================== if(broadcast.dewPoint! = Log_dewPoint) ( TFTscreen.setTextSize(size); // Skriv över föråldrad data 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(), storlek), 120); // Mata ut nya avläsningar 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(), storlek), 120); changes(10, 106, 125, (broadcast.dewPoint > Log_dewPoint)?true:false); ) else (changes(10, 106, 125, true, true); changes(10, 106, 125, false, true); ) // Uppdatera värdena i loggarna för efterföljande jämförelse av avläsningar Log_Temperature = broadcast.Temperature; Log_Pressure = broadcast.Pressure; Log_Humidity = broadcast.Humidity; Log_dewPoint = broadcast.dewPoint; )

Avläsningarna visas ganska kompakt, men som praktiken visar (och råden från mina kamrater) - "smak och färg, inte ens frun är en vän." Jag lyssnade på många råd och förslag, men de motsäger varandra. Gör det därför efter din smak.

Det verkade för mig som att design är den del av projektet som tar det mesta av tiden!

Dold text

En del av data är tillverkade för att återspegla vissa designelement.

Artefakter på displayen är damm och annan smuts som har samlats under den långa tiden som displayen var i... någonstans där... ja, där minns jag inte var jag fick det ifrån! Lämna mig ifred!

Skissen har positioneringsfunktioner. De är ganska primitiva, men de låter dig uppnå vissa effekter.

  1. x_center
  2. x_alignment_right

Den första centrerar texten och den andra justerar den till höger om den angivna zonen. Alla beräkningar görs i förhållande till dimensioner given text, baserat på uttrycket 1 storlek = 1PX x 1PX teckensnittssegment.

Displayen visar också element som motsvarar en ökning eller minskning av ett visst avläsningsvärde. De visas i form av trianglar. Men i funktionskoden ändringar Det finns en alternativ display i form av trianglar roterade 45 grader. Om avläsningarna ökar är elementet rött, annars blått.

Förresten ändras färgen och nyansen på huvudtemperaturen beroende på själva temperaturen. Ett ganska kontroversiellt beslut, men enligt mig, visuellt bekvämt. Jag kämpade med det ett tag och insåg att värdena i funktionen stroke, TFT-visningsobjekt listas i fel ordning. BGR plats RGB. Detta är ett utvecklarfel, eller så förstår jag inte något.

PS: Allt är ganska intressant, men enligt mig förtjänar det vidareutveckling. Det är vad vi kommer att göra efter ett tag.

God dag, läsare och de som precis kommit hit. Jag är prenumerant på YouTube-kanalen AlexGyver och se en video om "PC Hardware Monitoring",

Jag bestämde mig för att upprepa denna hemgjorda produkt, eftersom... Jag tyckte att det var ganska intressant, och jag har alltid velat visa systemstatus på ett hårdvarusätt, på en extra skärm och inte på en datorskärm. Gör från en dator julgran Jag ville inte, så jag bestämde mig för att inte installera RGB-bakgrundsbelysning och bestämde mig också för att vägra hemgjord reobass, därför att min Gigabyte-mamma vet perfekt hur man styr fläkthastigheterna utan några mellanhänder med hjälp av BOIS.

Jag valde och beställde de billigaste komponenterna som erbjöds av författaren:

  1. ATmega 328 https://goo.gl/DkWhmU
  2. Anslutning av kablar https://goo.gl/NHmQqs
  3. Skärm för 4 rader 20 tecken https://goo.gl/4MAowg

Jag beställde allt detta från en säljare så att det skulle komma tillsammans, i ett paket. Och ett litet liv hack: om du lägger allt i varukorgen från en säljare som har en fraktavgift, och sedan betalar en gång, så kommer fraktavgiften att debiteras en gång. (Och inte för var och en av de 3 produkterna).

4. Jag beställde ingen mini USB-kabel utan lödde fast den direkt till Arduino och kopplade den med sladdar (från punkt 2) till den interna USB-kontakten. Men du behöver inte oroa dig och beställ https://goo.gl/LA7sb3 det är enklare

Och han började vänta. Allt kom ganska snabbt, på 15 dagar. Det finns också en knapp i kretsen, som när den är stängd växlar skärmar med information om systemets tillstånd. Först tog jag den här:

men idén visade sig inte vara särskilt bra, för... det fanns inget som kunde fästa den på datorns frontpanel. Därför valdes i en lokal radioelektronikbutik en icke-låsande knapp, med en bekväm fäste till fodralet, såväl som en växelströmbrytare för att stänga av detta "mirakel" på natten. Därför att allt som är anslutet till USB-porten på min dator är ständigt strömförsörjd och tenderar att lysa och blinka, och stängs endast av genom att koppla ur datorn från uttaget.

I allmänhet tillbringade jag flera timmar med att montera detta mirakel tekniska framsteg, skära ut en plats för skärmen i frontluckan på datorn och borra hål för knappen och vippströmbrytaren. Nästa, för fullvärdigt arbete, allt detta måste lödas enligt kretsen och ett inbyggt program måste startas för att övervaka datorns resurser. Här är vad som hände:

Nåväl, det blev ganska bra, nästan som jag ville. Det återstår att eliminera små problem i programvaran som överför temperaturer. Av någon anledning överförs de till maximalt: sensormatta. CPU, GPU, moderkortskort, som hindrar dig från att övervaka din dator i ett tyst tillstånd, när vilotemperaturerna inte är höga.

Om någon inte kan ladda ner källkoden från AlexGyvers hemsida, här är en återuppladdning till min hemsida: .

Efter att ha rotat igenom programmet hittade jag mycket som inte passade mig och i stort sett inte fungerade korrekt. Efter att ha tillbringat ett par kvällar, med hjälp av vänner, kom jag på lite både koden för skissen på Arduino och OpenHardwareMonitor-koden, som faktiskt överför utdataparametrarna till skärmen. Och han gjorde förändringar som tillfredsställde mig.

Ändringar i OpenHardwareMonitor-programmet:

  • hur CPU-temperaturen nu överförs inte temperaturen för den hetaste kärnan, utan temperaturen på CPU-sensorn från modern;
  • hur GPU-temperaturen nu överförs inte den maximala temperaturen mellan moderkort och GPU, utan GPU-temperaturen från grafikkortssensorn;
  • Hur moderkortets temperatur nu överförs är inte den maximala temperaturen mellan: moderkort, GPU och CPU temperatursensor från mamman, och moderkortstemperatur från sensorn;
  • Dessutom, i värdena 12 och 13 från OpenHardwareMonitor, överförs nu fläkthastigheten för CPU:n och moderkortet istället för manuella kontrollflaggor för fläktar respektive bakgrundsbelysning.

Ändringar i sketchen för Arduino:

  • Borttagen spårning av att trycka på den andra knappen som bytte skärm i omvänd ordning;
  • På den andra skärmen har informationsutgången ersatts; nu, istället för temperaturen på 2 externa temperatursensorer (TMP1, TMP2), visar jag rotationshastigheten för CPU-fläkten (FanC) och MotherBoard (FanM).
  • Spårning för manuell styrning av fläktar och belysning har tagits bort.

Arkivet med alla ändringar och källor kan laddas ner här (Som vi fick reda på empiriskt fungerar ändringarna i OpenHardwareMonitor bra på Gigabyte-moderkort, som mitt, och med största sannolikhet kommer det att finnas fel på moderkort från andra tillverkare).

Vinter och katter till alla!

Lycka till med att experimentera!

Vår organisation har distribuerat en Zabbix-server för att övervaka prestanda för servrar och arbetsstationer. På grund av den tekniska processens egenheter är utrustningen "utspridd" över flera rum och distribuerad över hela företaget. Naturligtvis, tillsammans med de grundläggande parametrarna för datorer (fungerar/fungerar inte), vill jag också kontrollera mikroklimatet i serverrummen. Samtidigt, som vanligt, är möjligheterna mycket begränsade, och att "hitta" betydande medel för komplexa temperaturövervakningssystem (jag inkluderar styrkort med termiska sensorer för APC-rack-UPS) är ett separat uppdrag.

I huvudserverrummet är allt enkelt - ett sådant kort är installerat (köpt för länge sedan av föregångaren tillsammans med huvudutrustningen), en APC termisk sensor är inkopplad, en agent skapas i Zabbix, allt fungerar via SNMP . Tråkigt :) Det finns ingen utrustning för att övervaka fjärrstyrd hårdvara, inte heller pengar - se ovan. Därför bestämde man sig för att vara smart, spara budget och samtidigt utveckla en ny kompetens genom att konstruera en enkel och billig ”knock-on”-lösning som ändå passar in i den befintliga Zabbix övervakningsinfrastrukturen.

Nödvändiga komponenter:

  • Grunden i systemet är Arduino Nano V3
  • Lokal nätverksmodul (ethernet-sköld)
  • Och faktiskt en digital temperatursensor baserad på DS18B20
Den totala kostnaden för komponenterna är $10 inklusive leverans.

Att montera enheten är inte svårt. Nätverksmodulen placeras på huvudkortet som en "smörgås", den termiska sensorn är fastlödd till sina stift. Givaranslutning: röd +5 V, svart - jord, gul - data; Mellan +5V och Data löder vi ett 4,7 kOhm pull-up motstånd.

Datastiftet väljs baserat på vilka stift som används nätverksmodul(D10 – SS; D11 – MOSI; D12 – MISO; D13 – SCK; D2 – IRQ).

Rake: i prototypen av enheten stötte jag på en konflikt - temperaturdata utfärdades slumpmässigt, "varannan till var tredje." Anledningen visade sig vara att jag anslutit en temperatursensor till stift 2, som, som jag senare hittade på Internet, används av nätverksmodulen för att generera ett avbrott när ett paket kommer. Jag flyttade den till 4:an - den fungerade som en klocka.

Efter att ha monterat hårdvaran går vi vidare till mjukvaran.

Enheten kommer att fungera på nätverket och låtsas vara en Zabbix-agent, för detta behöver den en MAC och IP-adress. Vi bestämmer vad som är bekvämare - koppla in det under programmering, generera en MAC från adressen till temperatursensorn och få en IP via DHCP, etc. Jag tog den enklaste vägen och hårdkodade båda parametrarna.

Utbytesprotokollet med Zabbix-servern beskrivs i dokumentationen. Vår enhet kommer att svara på två kommandon - agent.ping Och env.temp(det finns utrymme för ytterligare kreativitet här; du kan ansluta vilken som helst av expansionsmodulerna som finns tillgängliga för Arduino - till och med en fuktsensor, till och med en ljussensor - vad du än vill). Den kommer att svara på alla andra kommandon med ett standardsvar som är förståeligt för Zabbix-servern.

För de som börjar om från början (som jag) görs Arduino-programmering med Arduino IDE, vars installation och konfiguration är enkel. För att komponenterna ska fungera krävs biblioteken UIPEthernet och OneWire, som är installerade och anslutna till projektet via Sketch-menyn - Anslut bibliotek - Hantera bibliotek...
Om du har andra komponenter (till exempel en nätverksmodul inte på enc28j60, utan på ett annat chip), behöver du andra bibliotek!

Koden för att arbeta med nätverksmodulen och temperatursensorn är typisk, från Internet, med vissa antaganden och förenklingar.

Efter att ha laddat upp koden till styrenheten och anslutit Ethernet-kabeln kontrollerar vi från konsolen:

$ zabbix_get -s 192.168.4.5 -k agent.ping 1 $ zabbix_get -s 192.168.4.5 -k env.temp 23.12 $ zabbix_get -s 192.168.4.5 -k bla-blah ZBX_NOTSUPED
Rake: den kompilerade versionen av zabbix_get för Windows som publicerats på zabbix.com är föråldrad och använder ett annat protokoll (med ZBXD\x01-huvudet i serverförfrågan). Linuxversionen är uppdaterad och protokollet motsvarar den givna koden.

Allt fungerar som det är tänkt. I Zabbix adminpanel skapar vi en ny värd med vald IP, den innehåller två nycklar, Numeric (osignerad) agent.ping och Numeric (float) env.temp, och njut av arbetet. Diagram, triggers - allt är som vanligt.

Enheten drivs via inbyggd USB. Fodral - valfritt: lämplig plastlåda, värmekrymp, blå eltejp.

Sensorns upplösning är ungefär 0,06 (närmare bestämt 1/16) °C, noggrannheten - när den var nedsänkt i smältande snö visade den 0,19 °C (kanske skulle den ha sjunkit lägre, men det var lite snö och det hela smälte snabbt). Jag tror att det är mer än tillräckligt för en enhet som kostar $10 och de syften som beskrivs.

Skiss

#omfatta #omfatta byte mac = ( 0xDE, 0x05, 0xB6, 0x27, 0x39, 0x19 ); // slumpmässig MAC-byte ip = (192, 168, 4, 5); // IP-adress i det lokala nätverket String readString = String(20); byte adr; OneWire ds(4); // DS18B20 på pin 4 EthernetServer-server(10050); // Zabbix port void setup() ( Ethernet.begin(mac, ip); server.begin(); ds.search(addr); ) void loop() ( byte data; float celsius; readString = ""; if ( EthernetClient client = server.available()) ( while (client.connected()) ( if (client.available()) ( char c = client.read(); if (c == "\n") // end av fråga från zabbix server ( client.print("ZBXD\x01"); // svarshuvud if (readString == "agent.ping") ( byte responseBytes = (0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 , 0x00, "1"); client.write(responseBytes, 9); ) else if (readString == "env.temp") ( ds.reset(); ds.select(addr); ds.write(0x44) ; // starta konvertering med vanlig (icke-parasit!) effektfördröjning(1000); ds.reset(); ds.select(addr); ds.write(0xBE); // läs Scratchpad-data = ds.read() ; data = ds.read(); int16_t raw = (data<< 8) | data; celsius = (float)raw / 16.0; byte responseBytes = {(byte) String(celsius).length(), 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; client.write(responseBytes, 8); client.print(celsius); } else { byte responseBytes = {0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; client.write(responseBytes, 8); client.print("ZBX_NOTSUPPORTED"); } break; } else if (readString.length() < 20) { readString = readString + c; } } } delay(10); client.stop(); } }