Väderstation på arduino med ett tryckgrafexempel. Trådlös väderstation



"Så, låt oss komma överens omedelbart: du kommer inte att göra en film för Hollywood. Inte ens i Underlandet godkänns inte mer än fem procent av alla manus, och bara en procent går sedan i produktion ... Så istället för allt detta kommer du att skapa ditt eget Hollywood. ”
Ed Gaskel "Shooter digital cinema, or Hollywood at home"

Förord

Vadå, ännu en Arduino väderstation?! Ja, en till och, något säger mig, inte den sista på Internet of things.


Precis som varje programmerare måste skriva ett "Hello World!"-program, så måste varje arduinian ha erfarenhet av att bygga en enkel eller inte särskilt väderstation.
Ett stort antal redan skapade projekt av väderstationer på Internet beskrivs, läsaren kan välja vilken som helst av dem för implementering. Ärligt talat studerade jag noggrant ett dussin liknande projekt och ett gäng relaterade. Därför kan det inte sägas att jag skapade allt från grunden, självklart "stod jag på jättarnas axlar."


Jag måste genast säga att mina planer inte inkluderade användningen av tredjepartstjänster för att lagra och visa data. Jag ville personligen känna och förstå hur det hela fungerar från insidan från början till slut, från A till Ö.


Så för den som snabbt vill nita något ur ingenting är den här artikelserien med största sannolikhet inte lämplig. Det är lättare att gå och köpa ett färdigt kit med monteringsanvisningar. Proffs inom mikroelektronik har absolut ingenting att göra här, kanske gnägga och komma ihåg sig själva i början av resan.
Men för de som verkligen vill förstå tror jag att de kommer att gilla det. Kanske kan materialet vara användbart som läromedel.



Detta projekt genomfördes redan 2016, men jag hoppas att det fortfarande är relevant.

Teknik set

Vi kommer att studera och arbeta med enkla och komplexa saker:

  • temperatur- och fuktgivare typ DHT22, DHT11
  • barometertryckgivare typ BMP180
  • WiFi-modul ESP8266
  • radiomodul typ nRF24 2,4 GHz
  • familjen Arduino Pro Mini, Arduino Mega
  • solpaneler och batterier
  • programmeringsspråket C/C++
  • PHP programmeringsspråk
  • MySQL-databashanteringssystem
  • programmeringsspråket Java och Android-ramverket (skapa en applikation för Adnroid för att visa väderdata på en smartphone).

Vissa av de ämnen som anges är inte värda ett dugg, och vissa kan studeras i flera år. Därför kommer vi att beröra komplexa saker endast i den del som är direkt relaterad till detta projekt, så att du förstår hur det hela fungerar.


Men vi börjar från början höger. Nämligen från beskrivningen och designen av den framtida enheten "på pappret" så att varje tegelsten till slut låg på sin plats.

prototypframställning

Som Wikipedia korrekt säger oss, prototypframställningär ett snabbt utkast till implementering av ett fungerande system. Vilket, ja, inte kommer att fungera helt ineffektivt och med vissa fel, men kommer att ge en uppfattning om hantverket bör utvecklas till en industriell design. Processen att skapa en prototyp bör inte vara lång. Prototypstadiet följs av analys av systemet och dess förfining.


Men det här är i en bransch där arbetare är heltidsanställda.


Alla som nitar sitt husdjursprojekt till "sakernas internet" på kvällarna bör vara medvetna om att de skapar en prototyp, en halvfabrikat. Det är mycket långt ifrån nivån på en normal industriprodukt. Det är därför du bör inte anförtro våra amatörhantverk några kritiska livsuppehållande områden och hoppas att de inte sviker oss.


En industriprodukt är byggd på en industriell elementbas och går sedan igenom många fler stadier, inklusive felsökning, testning och underhåll, innan den blir en storsäljare.


Så istället för allt detta tråkiga kommer vi att skapa vår egen leksak, men inte en enkel sådan. Med inslag av teknisk kreativitet, början av programmering och kunskap (under skapandet) av många andra relaterade saker.


Naturligtvis kommer elektronikingenjörer att ha det svårt i programmeringsstadiet, och programmerare kommer att behöva svettas över kretsar, men författaren kommer att försöka ange allt så tillgängligt som möjligt och tydligt beskriva varför vissa lösningar användes.

Krav

Vanligtvis hoppas man över detta steg. Bestämmer mig för att göra något sånt här just nu, och så visar det sig små detaljer som sätter hela projektet i en återvändsgränd eller till och med gör det outhärdligt. All vår önskelista behöver spelas in, jag använder Google Drive för detta, den är tillgänglig från en PC och från en mobil enhet.


Så vår väderstation bör:

  • mäta temperatur och luftfuktighet ute
  • mäta temperaturen och luftfuktigheten i huset
  • mäta atmosfärstryck
  • visa de angivna värdena på displayen
  • överföra data till en server på Internet, där data kommer att lagras i en databas och visas på en webbsida, eller användas i en mobilapplikation.

Sensorer används enklast och billigast. Till exempel, när jag ser framåt, kommer jag att säga att DHT22 mäter temperaturen ganska exakt, men det är lite felaktigt med luftfuktighet. Men, återigen, jag upprepar, det spelar ingen roll, eftersom vi har en prototyp framför oss, och en spridning av 5% luftfuktighet kommer inte att påverka något viktigt i vårt liv.


Systemarkitektur, hårdvara och programvara bör möjliggöra ytterligare systemutbyggbarhet för att lägga till nya sensorer och nya funktioner.

Järn. Komponentval

Detta är den viktigaste delen, och inte lödning eller programmering alls. Efter att ha definierat kraven för systemet är det nödvändigt att bestämma med hjälp av exakt vad de ska implementeras.


Här finns en nyans. För att välja komponenter måste du känna till deras kapacitet väl, du måste känna till själva teknologierna. Det vill säga, här behöver du med andra ord vara långt ifrån en nybörjare elektronikingenjör och programmerare. Så vad ska man nu ägna ett par år åt att studera hela utbudet av möjliga enheter?


Ond cirkel? Men onda cirklar finns för att bryta dem.


Det finns en utgång. Du kan bara ta och upprepa någons projekt. Jag studerade de redan existerande projekten av väderstationer och jag hoppas att jag tog ett steg framåt.


Så. Väderstationens arkitektur är baserad på Arduino. Eftersom Arduino har en liten tröskel för inträde och jag har redan tagit itu med detta. Då är det lättare att välja.


Det blev omedelbart klart att väderstationen skulle inkludera en fjärrkontroll utanför fönstret och en central modul.


Den centrala huvudenheten kommer att placeras inomhus. Det är viktigt att fastställa inledande skede, från denna "dans" så viktiga egenskaper som temperaturregimen för drift och kraft.


Fjärrsensorn (eller sensorerna) kommer att vara utan "hjärnor", dess uppgift är att regelbundet ta mätningar och överföra data till den centrala hemenheten. Centralenheten tar emot data från alla sensorer, visar dem på skärmen och skickar dem till Internet till databasen. Tja, det är redan mycket lättare där, så fort data finns i databasen kan du göra vad du vill med den, till och med rita grafer.


För kommunikation med omvärlden valdes Internet otvetydigt av ESP8266 WiFi-modulen med nästan inget alternativ (observera, kanske nu har sådana alternativ dykt upp). Ethernet-expansionskort är tillgängliga för Arduino, men jag ville inte vara bunden till en kabel alls.



En intressant fråga var hur man kan tillhandahålla kommunikation mellan den yttre sensorn (eller sensorerna, kom ihåg kravet på systemexpansionsmöjlighet?) och centrum. 433 MHz radiofyrar är definitivt inte lämpliga (de är inte lämpliga för någonting alls).


Använd ESP8266 igen?


Nackdelar med denna lösning:

    Kräver stabil WiFi utanför hemmet

    kommunikationsräckvidden kommer inte att vara stor

    tillförlitligheten kommer att bli lidande, om Internet misslyckas kommer vi inte att se våra fjärrsensorer

    mer strömförbrukning.

    Strömförbrukning ESP8266:

    vid sändning av 120-170 mA

    vid mottagning av 50-56 mA

    i djupt viloläge 10 µA (µA)

    av tillstånd 5 µA (µA).

Till slut, för att ansluta fjärrsensorer till huvudhemenheten, valdes nRF24L01 +-chippet med en 2,4 GHz-sändare och mottagare i en flaska, med en extra extern antenn, för att säkert "bryta igenom" väggarna.



Strömförbrukning nRF24L01+ 2,4 GHz:

  • vid mottagning av 11 mA
  • vid sändning med en hastighet av 2Mbps - 13 mA
  • i standby-I-läge - 26 μA (μA)
  • från-tillstånd 900 nA (nA).

Både ESP8266 och nRF24L01+ har ett lämpligt driftstemperaturområde: från -40℃ till +80℃.


Du kan köpa nRF24L01+ för cirka $1, eller med en extern antenn för $3. Du kan köpa ESP8266-01 för cirka $4. Läs produktbeskrivningen noggrant! Annars köp en antenn.


Kärnan i systemet växte fram. Låt oss gå vidare till själva sensorerna.


På gatan, som du vet, kan temperaturen nå negativa värden, så DHT11-sensorn är inte lämplig, men DHT22 är helt rätt.



Specifikationer för DHT22 / AM2302:

  • 3,3V till 5V matning, 5V rekommenderas
  • förbrukning max 2,5mA, vid tidpunkten för mätning och dataöverföring
  • luftfuktighetsmätningsområde 0-100 % med ett fel på 2-5 %
  • temperaturmätningsområde från -40 till +125°C med ett fel på ±0,5°C
  • begäran om mätning inte mer än 0,5 Hz - en gång varannan sekund.

Inne i huset hoppas jag att det inte blir några negativa temperaturer, så du kan använda DHT11, speciellt eftersom jag redan hade det.


Funktioner hos DHT11:

  • 3,3V till 5V matning
  • förbrukning max 2,5 mA, vid tidpunkten för mätning och dataöverföring
  • luftfuktighetsmätningsområde 20-80 % med ett fel på 5 %
  • temperaturmätningsområde från 0 till +50°C med ett fel på ±2°C
  • mätbegäran inte mer än 1 Hz - en gång per sekund.

Du kan köpa DHT22 för cirka $3. DHT11 kostar mindre - $1, men det är också mindre exakt.


Nu tillbaka till Arduino igen. Vilken bräda ska man välja?


Jag testade enskilda delar av systemet på Arduino UNO. De där. Jag kopplade ESP-modulen till uno och studerade den, stängde av den, kopplade sedan in nRF24 osv. För den slutliga implementeringen av fönstersensorn valde jag Arduino Pro Mini som den närmaste miniatyren till Uno.



När det gäller strömförbrukning ser Arduino Pro Mini också bra ut:

  • det finns ingen USB-TTL-omvandlare, som i sig "äter" mycket,
  • Lysdioden är ansluten via ett 10k motstånd.

För avancerad energibesparing planerades:

  • ta bort LED-strömindikatorn på Arduino Pro Mini (jag ångrade att jag inte förstörde brädet)
  • eller använd en "bar" enhet på en Atmel ATmega328 mikroprocessor (använde den inte)
  • använd Low Power Library eller JeeLib .

Från de bibliotek jag valde Low Power Library är det enkelt och innehåller bara det du behöver.


För centralenheten, eftersom det var planerat att ansluta många kringutrustning till den, valdes Arduino Mega-kortet. Dessutom är den fullt kompatibel med UNO och har mer minne. Framöver kommer jag att säga att detta val var fullt berättigat.


Du kan köpa Arduino Mega för cirka $8.

Ström och strömförbrukning

Nu om mat och strömförbrukning.


Det finns två typer av Arduino Pro Mini:

  • för matningsspänning 5V och frekvens 16MHz
  • för en matningsspänning på 3,3V och en frekvens på 8MHz.

Eftersom nRF24L01+ radiomodulen kräver 3,3V för strömförsörjning, och hastigheten inte är viktig här, köp en Arduino Pro Mini på 8MHz och 3,3V.


I det här fallet är matningsspänningsområdet för Arduino Pro Mini:

  • 3,35-12V för 3,3V-modell
  • 5-12V för 5V-modell.

Jag hade redan en 5V Arduino Pro Mini, varför jag använde den. Du kan köpa en Arduino Pro Mini för cirka $4.


Strömförsörjningen till centralenheten kommer att vara från 220 V-nätverket genom en liten strömförsörjningsenhet, vilket ger en uteffekt på 12V, 450mA, 5W. Något sånt här för $5. Det finns även en separat utgång för 5V.



Och om detta inte räcker kan du uttrycka det mer kraftfullt. Det är med andra ord inte så meningsfullt att spara ström för centralenheten. Men för en trådlös fjärrsensor är energibesparing den viktigaste delen. Men jag vill inte heller tappa funktionalitet.


Därför kommer Arduino Pro Mini och radiomodulen nRF24 att drivas av ett paket med 4 Ni-Mh-batterier.


Och kom ihåg maximal kapacitet för ett modernt batteri cirka 2500-2700mAh, allt mer är antingen en marknadsföringsgimmick (Ansmann 2850) eller en bluff (UltraFire 3500).


Jag använder inte Li-Ion-batterier av flera anledningar:

  • Väldigt dyr
  • när omgivningstemperaturen sjunker under 0°C minskar litiumjonbatteriets effekt till 40-50 %
  • de som är billiga är gjorda utan skydd och är osäkra (vid kortslutning eller urladdning kan de explodera och brinna, se en massa filmer på YouTube)
  • ålder även om den inte används (det kan dock sägas om alla kemiska grundämnen), efter 2 år tappar Li-Ion-batteriet cirka 20 % av sin kapacitet.

För en prototyp är det fullt möjligt att klara sig med högkvalitativa Ni-MH AA- eller AAA-batterier. Dessutom behöver vi inte stora strömmar. Den enda nackdelen med Ni-MH-batterier är deras långa laddningstid.

Allmänt schema för väderstationen

Låt oss sammanfatta. Här är ett allmänt diagram över hur det hela fungerar.



Fortsättning följer.

fritid, och skrev den här gången instruktioner för att göra en liten väderstation. Den kommer att fungera som en klocka med datum och visa temperaturerna i och utanför rummet. Vi kommer att använda en Arduino UNO som huvudkontroller, men ett annat kort med en Atmega328p ombord duger. För visning använder vi WG12864B grafisk skärm. Vi kommer även att ansluta två ds18b20 temperaturgivare. Den ena är inomhus, den andra tas utanför. Låt oss börja.

I processen att tillverka hemgjorda produkter behöver vi:

Arduino UNO (eller något annat Arduino-kompatibelt kort)
- WG12864B grafisk skärm
- ds18b20 temperaturgivare, 2 st
- Strömförsörjning 6 - 12 V
- Motstånd 4,7 Kom 0,25 W, 2 st.
- Motstånd 100 ohm 0,25 W
- Batterifack för 4 st AAA "lillfinger"-batterier
- Box från SEGA-konsolkassetten
- Isoleringstejp
- Anslutningsledningar
- Kretskort
- Knappar
- Brevpapperskniv
- lödkolv
- Löd, kolofonium
- Dubbelsidig tejp

Steg 1 Förbered WG12864B3.
De som inte har arbetat med skärmar tidigare kan skrämmas av det stora antalet modifieringar av till synes identiska skärmar. Jag ska förklara lite. De flesta skärmar av denna typ fungerar på ks0107/ks0108 chips. Alla skärmar kan delas in i 4 typer:

Alternativ A: HDM64GS12L-4, Crystalfontz CFAG12864B, Sparkfun LCD-00710CM, NKC Electronics LCD-0022, WinStar WG12864B-TML-T

Option B: HDM64GS12L-5, Lumex LCM-S12864GSF, Futurlec BLUE128X64LCD, AZ Displays AGM1264F, Displaytech 64128A BC, Adafruit GLCD, DataVision DG12864-88, Topway LM12864LDW, Digitron SG12864J4, QY-12864F, TM12864J4, QY-12864F, TM12864F

Alternativ C: Shenzhen Jinghua Displays Co Ltd. JM12864

Alternativ D: Wintek- Cascades WD-G1906G, Wintek - GEN/WD-G1906G/KS0108B, Wintek/WD-G1906G/S6B0108A, TECDIS/Y19061/HD61202, Varitronix/MGLS19264/HD6122

De ser nästan likadana ut. Men anslutningsstiften är olika. Jag valde, och jag rekommenderar till dig, WG12864B3 V2.0, men om skärmen kom i en annan, eller om du bara inte har den till hands, kan du enkelt ta reda på det med hjälp av tabellen:

Korta specifikationer:

Det finns många olika anslutningsscheman på Internet, och allt verkar fungera. Saken är att det inte bara finns olika skärmar, utan också två sätt att ansluta dem: seriell och parallell. När vi använder en seriell portanslutning behöver vi bara 3 mikrokontrollerutgångar. Med ett parallellt minimum på 13. Valet i det här fallet är uppenbart, Arduino har inte många slutsatser i alla fall. För parallellkoppling är anslutningsschemat följande:

För en seriell anslutning, som vi kommer att använda, är schemat som följer:

WG12864B - Arduino UNO 1 (GND) - GND 2 (VCC) - +5V 4 (RS) - 10 5 (R/W) - 11 6 (E) - 13 15 (PSB) - GND 19 (BLA) - via resistor 100 Ohm - +5V 20 (BLK) - GND

För att justera kontrasten måste en potentiometer finnas på skärmen. Det finns skärmar utan det, men det här är nu sällsynt:

Ett 100 ohm motstånd behövs så att en spänning på 5 volt inte av misstag bränner bakgrundsbelysningsdioderna.

Steg 2 Gör fallet.
För väskan, ta lådan från kassetten på Sega set-top box. Om du inte hittar den här lådan till hands kan du använda ett annat fodral. Huvudsaken är att skärmen och Arduino passar i den.

Klipp av den genomskinliga filmen, ovanpå lådan, så att det inte finns några bitar kvar:

Skär sedan ut ett 37x69 fönster för skärmen med hjälp av en kontorskniv.

FRÅN baksidan Limma dubbelhäftande tejp längs kanten på utskärningen, helst svart:

Vi tar bort skyddspapperet från den självhäftande tejpen och limmar vår skärm på den:

Från utsidan ska det se ut så här:

Under skärmen, även på dubbelhäftande tejp, monterar vi Arduino, som tidigare har gjort urtag för USB-porten och strömuttaget:

Utskärningar för Arduino-uttagen måste göras på båda sidor av lådan så att den kan stängas fritt:

Steg 3 Temperatursensorer.
Vi kommer att använda DS18B20 digitala temperatursensorer. Genom att använda dem får vi större mätnoggrannhet, ett fel på högst 0,5 °C, i ett brett temperaturområde på -55 ... + 125 °C. Dessutom är sensorn digital och utför alla beräkningar själv, och Arduino får helt enkelt färdiga avläsningar. När du ansluter denna sensor, glöm inte bort 4,7KΩ pull-up-motståndet mellan DQ- och VDD-stiften. Flera anslutningsalternativ är också möjliga. Med extern kraft, enligt mig det bästa alternativet, och vi kommer att använda det:

Med alla strömförsörjningsalternativ är sensorerna parallellkopplade:

Vi kommer att placera inomhustemperatursensorn på en liten tavla tillsammans med två knappar som vi kommer att använda för att ställa in tid och datum för klockan:

Vi ansluter den gemensamma ledningen från båda knapparna till GND, ansluter ledningen från den första knappen till A0, från den andra till A1.
Vi fixar det på dubbelhäftande tejp bredvid Arduino:

Sensorn, som är tänkt att placeras utanför rummet, är bättre att välja i ett dammsäkert metallhus:

Beräkna tråden med önskad längd så att du kan hänga sensorn utanför fönstret, huvudsaken är att den inte ska vara mer än 5 meter, om du behöver en längre längd måste du minska värdet på drag- upp motstånd.

Vi ansluter ledningen från DQ-databussen för båda sensorerna till stift 5 på Arduino.
Vdd - +5 Arduino.
GND - GND Arduino.

Steg 4 Näring.
För ström kan du använda en strömkälla med en spänning på 6 till 12 volt. I slutet av strömavlastningskabeln, löd en kontakt som passar Arduino-uttaget:

Eller så kan du sätta in ett batterifack för fyra "AAA", "lillfinger"-batterier i fodralet. Och anslut den positiva ledningen från viken till Vin Arduino och den negativa ledningen till GND.

Steg 5 Förbered programmeringsmiljön.
Först måste du ladda ner och installera Arduino IDE från den officiella webbplatsen

Och lägg även till de två bibliotek som behövs för skissen. OneWire - krävs för kommunikation med ds18b20-sensorer:

U8glib - används för att visa information på skärmen:

Laddar ner bibliotek. Sedan packar vi upp arkiven och flyttar innehållet i arkiven till mappen "libraries", som finns i mappen med den installerade Arduino IDE. Du kan också lägga till bibliotek genom Arduino IDE. För att göra detta, utan att packa upp arkiven, kör Arduino IDE, välj Sketch - Connect Library från menyn. Högst upp i rullgardinsmenyn väljer du "Lägg till zip-bibliotek". Ange platsen för de nedladdade arkiven. Efter alla steg måste du starta om Arduino IDE.

Steg 6 Redigera skissen.
Temperatursensorer arbetar med One Wire-protokollet och har en unik adress för varje enhet - en 64-bitars kod. Det är inte tillrådligt att lägga till kommandon för att söka efter sensorer i skissen. Det finns inget behov av att ladda Arduino varje gång för att hicka sensorer. Därför, efter att ha samlat allt tillsammans, fyller vi i Arduino-skissen, som finns i menyn Arkiv - Exempel - Dallas Temperatur - OneWireSearch. Sedan startar vi Tools - Port Monitor. Arduino ska hitta våra sensorer, skriva adresser och temperaturavläsningar. Dessa adresser måste skrivas ner eller helt enkelt kopieras någonstans. Öppna nu Ard_Tic_Tak_WG12864B_2_x_Term_Serial-skissen och leta efter linjerna:

Byte addr1=(0x28, 0xFF, 0x75, 0x4E, 0x87, 0x16, 0x5, 0x63);// adress för intern byte addr2=(0x28, 0xFF, 0xDD, 0x14, 0xB4, 0x76, 0xB4, 0x56, 0x76, 0);

Vi byter ut adresserna på de sensorer som motsvarar platsen med våra adresser.
Vår klocka använder inte RTC-modulen (realtidsklocka), så det är nödvändigt att korrigera klockan. För enkelhetens skull, avkommentera raden (sekunder visas på skärmen):

//u8g.setPrintPos(44, 50); u8g.print(sek); // Mata ut sekunder för att kontrollera om draget är korrekt

Installera rätt tid, via portmonitorn. För att göra detta, öppna portmonitorn, vänta tills de initiala temperaturmätningarna är klara och ange aktuellt datum och tid i formatet "dag, månad, år, timmar, minuter, sekunder". Inga mellanslag, siffror separeras med kommatecken eller punkter.

Om klockan har bråttom, ändra värdet till ett större, jag rekommenderar att experimentera med ett steg på 100 enheter. Om eftersläpning skulle minska värdet på raden:

If (micros() - prevmicros >494000) ( // ändra till något annat för att justera det var 500000

Empiriskt bestämmer vi numret vid vilket klockan går tillräckligt exakt. För att avgöra rörelsens noggrannhet behöver du utdata på sekunder. Efter exakt kalibrering av numret kan sekunder kommenteras ut och därmed tas bort från skärmen.
Laddar upp skissen.

Gör-det-själv väderstation.

Det var på kvällen, det fanns inget att göra efter nyår. Som vanligt, under vinterns nyårshelger, vill jag också sysselsätta mitt huvud och händer med något användbart och kreativt. Under dessa nyårshelger bestämde jag mig för att göra en väderstation med mina egna händer. Jag började förbereda i förväg, köpte och monterade alla komponenter innan det nya året och gjorde huvudprogrammeringen under semestern.

(Många bilder under klippet!)

Först ska jag gå igenom komponenterna, jag kommer inte att ge länkar, eftersom på eBay (i personligt konto) varorna arkiveras. Jag köpte många komponenter i lugn och ro på eBay. Provade auktionen för första gången, brukade alltid köpa "köp nu". Vad kan jag säga, om du inte skyndar dig att köpa, kan vissa komponenter köpas billigare (ibland är skillnaden två gånger).

Tryckgivare BMP085
Detta är huvudsensorn. När jag såg det på eBay insåg jag att jag ville bygga en väderstation för hemmet.
Sensorn kom i ett vanligt kuvert, klistrat över med lite bubbelplast inuti.

Inuti kuvertet låg säljarens visitkort och sensorn, packade i en antistatisk påse och insvept i ytterligare ett lager bubbelplast

Den antistatiska påsen var förseglad så att fukt under flygningen inte hotade sensorn

Vi får sensorn. På ena sidan löddes en linje av kontakter som sattes in i skummet så att de inte skulle böjas. På andra sidan finns själva sensorn och märkningen av kontakterna.




Allt skulle vara bra, men märkningen av kontakterna appliceras i en spegelbild.
Sensorn är ansluten via I2C-bussen och matas med 3,3 V. Det vill säga att 4 ledningar behövs för normal drift (+, -, SDA, SCL)
Du kan förhöra sensorn på två sätt: antingen genom biblioteket eller med hjälp av funktionerna direkt i skissen.
Programexempel:

#omfatta

#define BMP085_ADRESS 0x77 // I2C-adress för BMP085

Const unsigned char OSS = 0; // Inställning för översampling

// Kalibreringsvärden
int ac1;
intac2;
intac3;
osignerad int ac4;
osignerad int ac5;
osignerad int ac6;
int b1;
intb2;
intmb;
int mc;
intmd;

kort temperatur;
långt tryck;

Ogiltig installation()
{
Serial.begin(9600);
Wire.begin();
bmp085Calibration();
}

Void loop()
{
temperatur = bmp085GetTemperature(bmp085ReadUT());
tryck = bmp085GetPressure(bmp085ReadUP());
Serial.print("Temperatur: ");
Serial.print(temperatur/10,0, DEC);
Serial.println("C");
Serial.print("Tryck: ");
Serial.print(tryck/133.322, DEC);
Serial.println("mm Hg");
Serial.println();
fördröjning(1000);
}

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

Short bmp085GetTemperature(osignerad int ut)
{
lång x1, x2;
x1 = (((lång)ut - (lång)ac6)*(lång)ac5) >> 15;
x2 = ((lång)mc<< 11)/(x1 + md);
b5 = xl + x2;

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

Long bmp085GetPressure(osignerad lång upp)
{
lång xl, x2, x3, b3, b6, p;
osignerad lång b4, b7;
b6 = b5 - 4000;
// Beräkna B3
x1 = (b2 * (b6 * b6)>>12)>>11;
x2 = (ac2 * b6)>>11;
x3 = xl + x2;
b3 = ((((((lång)ac1)*4 + x3)<>2;
// Beräkna B4
xl = (ac3 * b6)>>13;
x2 = (b1 * ((b6 * b6)>>12))>>16;
x3 = ((x1 + x2) + 2)>>2;
b4 = (ac4 * (osignerad lång)(x3 + 32768))>>15;
b7 = ((osignerad lång)(upp - b3) * (50000>>OSS));
om (b7< 0x80000000)
p = (b7<<1)/b4;
annan
p = (b7/b4)<<1;
xl = (p>>8) * (p>>8);
xl = (x1 * 3038)>>16;
x2 = (-7357 * p)>>16;
p += (xl + x2 + 3791)>>4;
returnera p;
}

// Läs 1 byte från BMP085 på "adress"
char bmp085Read (osignerad char-adress)
{
osignerad char-data;

wire.write(adress);
Wire.endTransmission();
Wire.requestFrom(BMP085_ADRESS, 1);
while(!Wire.available())
;
returnera Wire.read();
}

Int bmp085ReadInt (osignerad teckenadress)
{
osignerad char msb, lsb;
Wire.beginTransmission(BMP085_ADRESS);
wire.write(adress);
Wire.endTransmission();
Wire.requestFrom(BMP085_ADRESS, 2);
while(Wire.available()<2)
;
msb = Wire.read();
lsb = Wire.read();
returnera (int) msb<<8 | lsb;
}

// Läs av det okompenserade temperaturvärdet
osignerad int bmp085ReadUT()
{
osignerad int ut;
// Skriv 0x2E i register 0xF4
// Detta begär en temperaturavläsning
Wire.beginTransmission(BMP085_ADRESS);
Wire.write(0xF4);
Wire.write(0x2E);
Wire.endTransmission();
// Vänta minst 4,5 ms
fördröjning(5);
// Läs två byte från registren 0xF6 och 0xF7
ut = bmp085ReadInt(0xF6);
returnera ut;
}

// Läs av det okompenserade tryckvärdet
osignerad lång bmp085ReadUP()
{
osignerad char msb, lsb, xlsb;
osignerad lång upp = 0;
// Skriv 0x34+(OSS<<6) into register 0xF4
// Begär en tryckavläsning med inställning för översampling
Wire.beginTransmission(BMP085_ADRESS);
Wire.write(0xF4);
Wire.write(0x34 + (OSS<<6));
Wire.endTransmission();
// Vänta på konvertering, fördröjningstid beroende på OSS
fördröjning(2 + (3<// Läs register 0xF6 (MSB), 0xF7 (LSB) och 0xF8 (XLSB)
Wire.beginTransmission(BMP085_ADRESS);
Wire.write(0xF6);
Wire.endTransmission();
Wire.requestFrom(BMP085_ADRESS, 3);
// Vänta tills data blir tillgänglig
while(Wire.available()< 3)
;
msb = Wire.read();
lsb = Wire.read();
xlsb = Wire.read();
upp = (((osignerad lång) msb<< 16) | ((unsigned long) lsb << 8) | (unsigned long) xlsb) >> (8-OSS);
gå tillbaka upp;
}


Dessutom har sensorn en egen termisk sensor för tryckkompensering och en höjdmätare.

Arduino Nano v3.0
Detta är hjärtat i hela väderstationen. Enkelt uttryckt är regulatorn i miniatyrstorlek.
Köpt
Jag kommer inte att prata i detalj om kontrollern, eftersom detta redan har gjorts före mig:


Paketet med lightake var prefabricerat, kontrollern kom i ett paket med en USB-kabel och en Arduino i en förseglad antistatisk påse.

För att uppskatta storleken, bredvid Arduino, sätt ett mynt med ett nominellt värde på 1 rubel.

Kontrollkort närbild



USB-kabeln är bra, med en ferritring. Drivs av Arduino via USB-kabel. Utvecklingsmiljön kan laddas ner (nedladdningssida). Språket är "C"-likt, det var inga problem att bemästra det, eftersom jag programmerar mycket på det på jobbet.

LCD skärm
På jobbet i papperskorgen hittade jag en kompatibel LCD 1602-skärm. Jag var tvungen att mixtra med anslutningen, eftersom jag inte hittade något datablad för den. Som ett resultat tjänade LCD.

Men efter en kort operation märkte jag att den här skärmen inte räcker för mig och jag kommer inte att kunna visa mer data, eftersom den bara har 2 rader med 16 tecken vardera. Först verkar det som att dessa parametrar räcker, men när du börjar programmera förstår du att du kan proppa max 3-4 parametrar. Och om du gör en meny (jag tänkte göra en meny på den här skärmen), så finns det 1-2 ledigt utrymme kvar för parametrar.
Som ett resultat började jag leta efter en annan skärm. Först tittade jag på den grafiska skärmen från Nokia 3310 och deltog till och med i eBay-auktionen för att köpa den, men det gick inte (vilket jag är väldigt glad över), så jag var tvungen att ge upp den här skärmen. Nu förstår jag att den skulle vara för liten för mina ändamål, då det finns något att jämföra med.
När jag av en slump bläddrade i sköldarna på Arduino kom jag över 12864-grafikskärmen på ST7920-kontrollern. Denna skärm har rätt storlek och bra upplösning för mina behov (128x64). Det vill säga att du säkert kan placera 6-7 rader med 20 tecken i ett normalt läsbart teckensnitt. Eftersom skärmen är grafisk kan förutom text i olika typsnitt även grafik placeras. Kort sagt, detta är precis vad jag behövde, allt fanns i den här skärmen, så jag kunde inte stå ut och beställde.
Paketet kom snabbt och var förpackat på ett vanligt sätt: en bubbelplast, inuti fanns ytterligare ett lager bubbelplast och en skärm i en antistatisk påse:






För att uppskatta storleken, bredvid LCD-skärmen sätt ett mynt med ett nominellt värde på 1 rubel.




För att snabbt ansluta skärmen till Arduino lödde jag en kontaktlinje till LCD-stiften. LCD kan anslutas via seriell buss och parallell. Jag valde det första alternativet, eftersom det finns så få gratis Arduino-kontakter.
Anslutning (hämtad från webben):

- Pin 1 (GND) ansluter till den gemensamma bussen
- Pin 2 (VCC) är ansluten till +5V strömbussen, och strömförbrukningen är relativt liten och displayen kan drivas från den inbyggda Arduino-regulatorn.
- Pins 4, 5 och 6 är anslutna till Arduinos digitala utgångar och bildar det seriella SPI-gränssnittet:
stift 4 - (RS) - motsvarar CS-linjen (till exempel 7)
stift 5 - (RW) - motsvarar MOSI-linjen (till exempel 8)
stift 6 - (E) - motsvarar SCK-linjen (till exempel 3)
Arduino pin-nummer kan vara vad som helst, det viktigaste är att inte glömma att korrekt ange dem senare i programtexten vid initialisering av displayen.
- Pin 15 (PSB) är ansluten till den gemensamma bussen.
- Stift 19 (A) och 20 (K) är strömförsörjning för bakgrundsbelysning (+5V respektive GND). För att justera bakgrundsbelysningens ljusstyrka kan du använda ett 10kΩ variabelt motstånd kopplat mellan strömskenorna och GND. Spänningen från dess motor läggs på stift 19 på displayen.
Enligt denna instruktion kopplade jag allt utom bakgrundsbelysningen. Jag använde Arduino PWM som bakgrundsbelysningskraft.
För att programmatiskt ansluta LCD-skärmen till Arduino, används u8glib-biblioteket. Du kan ladda ner. Om det finns nedladdningsproblem kan jag ladda upp biblioteket till narod.ru.
Biblioteket i sig är inte komplicerat och låter dig visa text i olika typsnitt, rita en linje, rita de enklaste geometriska formerna (rektangel, cirkel), visa dina bilder förberedda på ett speciellt sätt. I princip räcker detta verktyg för de flesta uppgifter.
Här är resultatet av ett enkelt program:

Själva programmet:

#inkludera "U8glib.h"

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

// Subrutin för att fastställa ledigt minne
int freeRam()(
extern int __heap_start, *__brkval;
på tv;
return (int) &v - (__brkval == 0? (int) &__heap_start: (int) __brkval);
}

Void setup(void) (
u8g.setFont(u8g_font_6x10); // teckensnitt
u8g.setRot180(); // Vänd skärmen
analogWrite(6, 115); // Ställ in skärmens ljusstyrka (bakgrundsbelysningsanod till 6 stift)
}

Void loop (void) (
u8g.firstPage();
do(

u8g.setPrintPos(1, 12); // position
u8g.print("Hej!!!"); // textutdata
u8g.drawBox(0,22,128,9); // Fyll rektangeln med vitt
u8g.setColorIndex(0); // vitt bläck, svart bakgrund
u8g.setPrintPos(1, 30); // position
u8g.print("Word..."); // textutdata

U8g.setColorIndex(1); // vitt bläck, svart bakgrund
u8g.setPrintPos(1, 50); // position
u8g.print("Efter start ="); // textutdata
u8g.setPrintPos(85, 50); // position
u8g.print(millis() / 1000); // utgång antal sekunder efter start
u8g.setPrintPos(1, 64); // position
u8g.print(freeRam()); // mata ut hur mycket minne som används
) while(u8g.nextPage());

fördröjning(200);
}

Realtidsklocka DS1307
Ytterligare en komponent till min väderstation. Denna sköld har en realtidsklocka. Jag beställde dem på eBay. Säljaren skickade en klocknäsduk i en orealistiskt stor låda


Inuti lådan fanns två A4-ark med reklam och en klocknäsduk insvept i cellofan


Jag vill notera att avgiften inte överstiger storleken på 2 rubel. mynt, och asken var 13x15x5 cm stor.
Skivan packades i en antistatisk påse

Sjal på nära håll



Jag var tvungen att mixtra med den här modulen. Först fanns det anslutningssvårigheter. Och för det andra, det finns ingen kvarts på denna bräda. Om jag visste att jag skulle spendera så mycket tid på modulen, skulle jag troligen ha monterat den själv, eftersom nätverket är fullt av system. Den enklaste kretsen innehåller 4-5 komponenter.
Angående kopplingen. Jag hittade ett bibliotek som sa att I2C-gränssnittet inte kan anslutas till de vanliga Arduino analoga ingångarna (A4 och A5), utan till vilka som helst diskreta. Gjorde som skrivet. Till en början fungerade ingenting, efter en lång dans med en tamburin gick klockan. Tja, tänkte jag, det är det, problemen är över, men efter att jag försökte koppla samma modul till en annan Arduino fortsatte dansen med tamburinen. Jag tillbringade mycket tid på att leta efter en lösning på detta problem, och nästan överallt indikerades det antingen en felaktig anslutning eller frånvaron av pull-up-motstånd på SCL- och SDA-stiften. Jag ville redan komma in i brädet med en lödkolv, men på ett forum råkade jag råka på en kod där det stod att SCL och SDA skulle kopplas till vanliga I2C-portar på Arduino. Efter standardanslutningen fungerade allt direkt.
Nu om kvarts. Jag vet inte vilken sorts kvarts kineserna satte där, men klockor med sådan kvarts gick 10-11 sekunder om dagen. Detta fel är 5 minuter per månad och 1 timme per år. Du behöver inte en sådan här klocka. Jag var tvungen att gå online igen och leta efter hur jag fixar det här felet. Den första lösningen som kom upp säger att du behöver mala kvartsen. Gjorde det - noll resultat. Jag hittade någon annanstans att jag behövde hitta ett gammalt moderkort och lösa kvarts därifrån. Klart - resultatet är. Nu springer klockan iväg inte med 10-11 sekunder, utan med 1,5 sekunder per dag. Låt oss bara säga att det blev bättre, men långt ifrån idealiskt. Eftersom det är mer ovilligt att pilla med en lödkolv, bestämde man sig för att justera klockan programmatiskt, det vill säga en gång om dagen, justera klockan till önskat värde. Efter 10 dagar var klockan inte borta med mer än en sekund. Metoden är bra, men bara när Arduino tidtagningsenhet är ansluten till ström, annars går klockan på batteri och ändå springer iväg.
Litet testprogram:

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

Byte decToBcd(byte val)
{
return ((val/10*16) + (val%10));
}

Byte bcdToDec(bytevärde)
{
return ((val/16*10) + (val%16));
}

Void setDateDs1307(byte sekund, // 0-59
byte minut, // 0-59
byte hour) // 0-99
{

Wire.write(0);
Wire.write(decToBcd(andra));
Wire.write(decToBcd(minut));
Wire.write(decToBcd(timme));
Wire.endTransmission();
}

Void getDateDs1307(byte *sekund,
byte*minut,
byte*timme)
{

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

Wire.requestFrom(DS1307_I2C_ADDRESS, 3);

*second = bcdToDec(Wire.read());
*minute = bcdToDec(Wire.read());
*timme = bcdToDec(Wire.read());
}

Ogiltig installation()
{
byte sekund, minut, timme;
Wire.begin();
Serial.begin(9600);

Andra = 45;
minuter = 5;
timmar = 16;

SetDateDs1307(sekund, minut, timme);
}

Void loop()
{
byte sekund, minut, timme;

GetDateDs1307(&sekund, &minut, &timme);
Serial.print(timme, DEC);
seriell utskrift(":");
Serial.print(minute, DEC);
seriell utskrift(":");
Serial.println(andra, DEC);

fördröjning(1000);
}


Biblioteket används inte här, och funktionerna är trunkerade för läs- och skrivtid.

Temperatur- och luftfuktighetsgivare DHT11
Det finns inte mycket att säga om denna sensor. Jag skulle inte ens använda den om jag inte behövde fukt. Tyvärr tog jag ingen bild på den när jag fick den, så det blir inga bilder. Bilder på sensorn kan ses nedan, där jag kopplade den till Arduino. Sensoranslutningen är enkel (+, digital utgång, -). Typiskt är sensorer gjorda med fyra stift. Med denna formfaktor är den tredje kontakten inte kopplad till någonting.
För att ansluta till Arduino kan du använda biblioteket. Du kan ladda ner.
Ett litet testprogram med informationsutmatning till LCD-displayen 1602:

// inkludera bibliotekskoden:
#omfatta
#omfatta

// Deklarera objekt
dht11 Dht11;
LiquidCrystal lcd(12, 11, 6, 5, 4, 3);

#define DHT11PIN 7
int i;

Ogiltig installation()
{
lcd.begin(16, 2);
lcd.print("Status: ");
i=0;
}

Void loop()
{
int chk = DHT11.read(DHT11PIN);
lcd.setCursor(8, 0);
switch (chk)
{
fall 0: lcd.print("OK"); break;// lcd.setCursor(11, 0); lcd.print(millis()/2000); ha sönder;
fall -1: lcd.print(“Checksum error”); merr(); ha sönder;
fall -2: lcd.print("Timeout-fel"); merr(); ha sönder;
default: lcd.print("Okänt fel"); merr(); ha sönder;
}
fördröjning(500);
lcd.setCursor(15, 0);
switch(i)
{
fall 0: lcd.print("^"); lcd.setCursor(15, 1); lcd.print(" ");break;
fall 1: lcd.print("v"); lcd.setCursor(15, 1); lcd.print(" ");break;
default: lcd.setCursor(15, 1); lcd.print("E"); ha sönder;
}
i=i+1;
om (i>1) i=0;
lcd.setCursor(0, 1);
lcd.print("H=");
lcd.setCursor(2, 1);
lcd.print((float)DHT11.fuktighet, 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;
}


Sensorn har nackdelar - data från sensorn kommer bara i heltal, och intervallet är svagt.

Det verkar som att han skrev om alla komponenterna. Det återstår att samla allt till en enda helhet.
Oj, glömde nästan! För att montera enheten behöver du ett fodral. Fodralet även beställt på Ebay. Säljaren var från England. Paketet kom snabbt, men jag tog ingen bild på det. Alla bilder på kroppen finns nedan.

Först monterade jag allt på bordet med hjälp av speciella ledningar. Jag skrev ett testprogram och laddade upp det till styrenheten.



Faktum är att den blå färgen på bakgrundsbelysningen är mycket ljusare. Även vid lägsta ljusstyrka (Ljus=5) exponeras ramen.

För att montera allt utan kablar beslutades det att göra ett mini-moderkort, och Arduino-kortet och sköldarna sattes på kontakterna. I så fall kan de enkelt tas bort snabbt. Jag bestämde mig också för att haka fast LCD-skärmen och kontrollknapparna på kontakterna, bara löda temperatursensorn på ledningarna.
Så här kom halsduken ut



På den sista bilden har jag inte tvättat bort flussmedlet än. Jag limmade poröst gummi under sköldarna bredvid kontakterna så att det åtminstone blev någon form av stöd. Även om i själva verket skärmarna i kontakterna på kontakterna redan hålls perfekt.

Moderkort med sköldar och Arduino-kort installerat.

Så här ser en komplett anslutning till moderkortet ut


Istället för knappar använde jag en hemmagjord sköld lödd på en brödbräda. Som knappar använde jag knappar från gamla möss.
Som du kan se har antalet ledningar minskat.

Det största problemet med placeringen i fodralet är att skära ut skåran för LCD-skärmen jämnt. Hur mycket jag än försökte fungerade det fortfarande inte perfekt. Glapparna var på vissa ställen något mer än 1 mm. För att allt ska se snyggt ut tog jag en svart tätningsmedel till akvariet och fyllde i alla sprickor, samtidigt fäste jag skärmen på just denna tätning. Efter att fogmassan hade torkat skar jag bort överskottet från utsidan. I starkt ljus är tätningsmedlet synligt, och i normalt ljus smälter allt samman med höljet.
Så här ser fallet ut från insidan med LCD-skärmen och moderkortet installerat.

Så här ser det ut från utsidan i starkt ljus (jag ber om ursäkt för fingeravtrycken, jag såg dem när jag sorterade ut bilderna).

Jag tänkte länge hur man fäster knapparna på fodralet och, viktigast av allt, vilka knappar man ska använda ...
I elektroniska butiker gillade jag knappen med en lång stift och spetsarna som sätts på denna stift. Dessa knappar används för att löda till kortet. Allt skulle vara bra, men de har ett minus - tryckslaget är väldigt litet och högt.
Jag var tvungen att placera knapparna i två steg: det första var att placera knapparna på brädet, det andra var att montera det här brädan på ett annat bräde. Och lägg sedan in allt detta i kroppen på guiderna.

Så här ser halsduken med knappar ut:



Så här ser tavlan ut:


Här kan du se guiderna i vilka tavlan med knapparna sätts in. Jag lödde fast några element för att styva brädan.

Nu stoppar vi in ​​allt i kroppen
Utan anslutningsknappar:


Med knappanslutning:

Stäng lådan och slå på den. Allt fungerar bra, knapparna fungerar som de ska.

I slutet lägger jag upp en kort video av enheten i olika lägen:
http://www.youtube.com/watch?v=KsiVaUWkXNA&feature=youtu.be
För de som inte ser videon här, här är länken till

Det är dags att avsluta recensionen.
Jag kommer att skriva lite om programmet, och sedan korta slutsatser. När jag skrev programmet trodde jag inte att jag skulle stöta på en gräns på 30720 byte särskilt snabbt.


Jag var tvungen att optimera koden. Flyttade många bitar av kod till subrutiner. Jag skulle aldrig ha trott att en switch ... fallbeskrivning i en sammanställd form tar mer plats än flera om ... annat. Korrekt deklaration av variabler sparar också utrymme. Om du förklarar en array lång, även om det är fullt möjligt att klara sig med byte, så når minnesöverskridandet 500 byte, beroende på arrayens storlek. När du skriver ett program tänker du inte på det, och först senare, när du analyserar programmet, inser du att du gjorde vissa saker fel och du börjar optimera koden. Efter att problemen med storleken på programmet var lösta, stötte jag på en begränsning av RAM. Detta tog sig uttryck i att programmet började hänga efter laddning. Jag var tvungen att ange en subrutin för att beräkna ledigt RAM. Som ett resultat blev jag tvungen att överge en väderprognosalgoritm, eftersom den måste visa ikoner på skärmen. Algoritmen i sig fungerar, men utdata från ikonerna måste reserveras. Jag har fortfarande idéer om hur jag kan optimera koden, men inom en snar framtid kommer jag att låta enheten fungera som den är för att kunna utvärdera prestanda och identifiera alla buggar.

Nu några slutsatser
Minus
1) Pris. Ursäkten för detta minus är att en hobby aldrig är billig.

fördelar
1) Bra funktionalitet hos enheten
2) Funktionsexpansion begränsas endast av den styrenhet som används och din egen önskan
3) Estetisk njutning från kontemplation och moralisk tillfredsställelse från det faktum att jag ändå monterade och färdigställde den här enheten

Jag planerar att köpa +86 Lägg till i favoriter Gillade recensionen +137 +304

I den här artikeln kommer vi att prata om hur man monterar en fullfjädrad väderstation som överför väderdata till den välkända "folkets övervakning" -tjänsten.

Vår väderstation kommer att bestå av två enheter: en kompakt autonom enhet som mäter väderindikatorer, och en repeaterenhet som tar emot dessa indikatorer och skickar dem till "folkets övervakning". Enheterna kommer att kommunicera via en trådlös kommunikationskanal med en frekvens på 433 MHz. Den autonoma delen kommer att drivas av tre AA-batterier och kommer att kunna fungera på en uppsättning batterier i upp till ett år med en sensorpollingperiod på 20 minuter.

Denna design gör att du inte kan borra väggar för att lägga ledningar från gatan, där det är nödvändigt att göra mätningar, till rummet där resultaten av dessa mätningar ska användas.

Vad kräver det?

För att göra en fristående sändare behöver vi:

    x3 AA AA batterihållare

För att göra en repeater behöver vi:

Det är också bekvämt att installera två lysdioder för att indikera processer:

För ljudindikation av batteriurladdningen av den autonoma delen är det bekvämt att använda en piezo-diskant:

Hur sätter man ihop det?

Montering av en fristående del

Repeatermontering

Detta slutför monteringen av den minimalt fungerande repeatern. Om du vill installera LED-indikering och ljudlarm, följ stegen nedan.


Källa

Offline delkod

meteo_sensor.ino #inkludera #omfatta #omfatta #omfatta // Timeout mellan sändningar (högst 65535)#define TIMEOUT 60000 // Antal försök att skicka ett paket#define FÖRSÖK 3 // Sändarens informationsstift#define RF_PIN 5 // Temperatur- och fuktighetssensorstift#define GND1_PIN 10 #define VCC1_PIN 11 #define GND2_PIN 7 #define VCC2_PIN 8 #define DATA_PIN 12 #define CLK_PIN 9 AmperkaLine rf(RF_PIN) ; SHT1x sht1x(CLK_PIN, DATA_PIN) ; void loop(void) ; // Funktion för att få brädan att vila. Varje TIMEOUT sekunder // loop_func kommer att anropas. TEENSY3_LP LP = TEENSY3_LP() ; sleep_block_t* LP_config; void sleep_mode(void) (LP_config = (sleep_block_t*) calloc (1 ,sizeof (sleep_block_t)); // Vi kommer att vakna på en timer LP_config->modules=(LPTMR_WAKE) ; // Ställ in timeout för timern LP_config->lptmr_timeout=TIMEOUT; // Efter timeout kommer loop-funktionen att anropas LP_config->callback=loop; LP.Hibernate(LP_config) ; ) // Perifer aktiveringsfunktion void peripheral_start(void ) ( // Slå på datalinjen pinMode(RF_PIN, OUTPUT) ; // Slå på strömmen och jord för temperatur- och fuktighetssensorerna pinMode(GND1_PIN, OUTPUT) ; pinMode(GND2_PIN, OUTPUT) ; pinMode(VCC1_PIN, OUTPUT) ; pinMode(VCC2_PIN, OUTPUT) ; digitalWrite(GND1_PIN, LOW) ; digitalWrite(GND2_PIN, LOW) ; digitalWrite(VCC1_PIN, HIGH) ; digitalWrite(VCC2_PIN, HIGH) ; // Slå på lysdioden för att indikera överföring pinMode(LED_BUILTIN, OUTPUT) ; digitalWrite(LED_BUILTIN, HIGH) ; // Välj den interna spänningen som referensspänning// source (=1,2V) analogReference(INTERNAL) ; ) // Perifer avstängningsfunktion void peripheral_stop(void ) ( // Stäng av datalinjen pinMode(RF_PIN, INPUT) ; // Stäng av temperatur- och luftfuktighetssensorn pinMode(GND1_PIN, INPUT) ; pinMode(GND2_PIN, INPUT) ; pinMode(VCC1_PIN, INPUT) ; pinMode(VCC2_PIN, INPUT) ; pinMode(18 , INPUT_PULLUP) ; pinMode(19 , INPUT_PULLUP) ; // Stäng av lysdioden digitalWrite(LED_BUILTIN, LOW) ; ) void setup(void ) ( // Vi initialiserar ingenting, vi somnar direkt viloläge() ; ) // Denna funktion exekveras en gång var TIMEOUT sekund void loop(void ) ( osignerad långt meddelande; byte temp, fuktighet, spänning; // Slå på kringutrustning peripheral_start() ; // Vänta tills temperatur- och luftfuktighetssensorn slås på fördröjning(30) ; // Få input från sensorer temp = (byte) (sht1x.readTemperatureC () + 40 .) * 2 ; fuktighet = (byte) sht1x.readHumidity () ; spänning = analogRead(A0) / 4 ; // Komponera ett paket från datan msg = 0 ; msg | = spänning; medd<<= 8 ; msg | = humidity; msg <<= 8 ; msg | = temp; // Skicka ett paket flera gånger för (int i = 0 ; i< ATTEMPTS; i++ ) rf.send (msg) ; // Stäng av kringutrustning peripheral_stop() ; // Efter att ha avslutat funktionen kommer styrelsen att somna igen }

Kod för inomhusbräda

receiver.ino #inkludera #omfatta #omfatta #omfatta byte mac = ( 0x90 , 0xA7 , 0xDA , 0x0F , 0xBC , 0x75 ) ; charserver = "narodmon.com" ; EthernetClient-klient; const int rfpin = 7 ; AperkaLine rf(rfpin) ; void setup(void ) ( pinMode(rfpin, INPUT) ; pinMode(6 , OUTPUT) ; Serial.begin (9600 ); Serial.println ("Startad." ); ) void loop(void ) ( statisk unsigned long pushtimeout = 0 ; statisk flyttemperatur, fuktighet, spänning; osignerat långt meddelande; int res; if ((res = rf.receive (& msg) ) == 0 ) ( temp = ((float ) (msg& 0xFF ) ) / 2 . - 40 .; msg >>= 8 ; fuktighet = (float ) (msg& 0xFF ); msg >>= 8 ; voltage = (float ) (msg& 0xFF ) / 256 . * 1.2 * 10 * 1.1 ; digitalWrite(6 , HIGH); Serial.print ("Temp: " ); Serial.print (temp) ; Serial.print (", fuktighet: " ) ; Serial.print (fuktighet) ; Serial.print (", spänning: " ) ; Serial.println ( voltage); digitalWrite(6 , LOW); ) else Serial.println ("E") ; if (millis() - pushtimeout > 60000 * 5 ) ( pushtimeout = millis() ; Serial.println ("Startar Ethernet... " ); if (Ethernet.begin (mac) == 0 ) ( Serial.println ( "Det gick inte att konfigurera Ethernet med DHCP"); while (1 ) ( ) ) delay(1000 ); Serial.println("ansluter..." ); if (client.connect (server, 8283 ) ) ( Serial.println ("ansluten") ; client.println ( "#90-A7-DA-0F-BC-75#Sensor#55.751775#37.616856#0.0"); client.print("#90A7DA0FBC7501#" ) ; client.print (temp, DEC) ; client.println("#In" ); client.print("#90A7DA0FBC7502#" ) ; client.print(humidity, DEC) ; client.println("#fuktighet"); client.print("#90A7DA0FBC7503#" ); client.print (spänning, DEC) ; client.println("#Voltage"); client.println("##"); ) else Serial.println("anslutningen misslyckades" ); ( unsigned long tm = millis() ; while (millis() - tm< 5000 ) { if (client.available () ) { char c = client.read () ; Serial.print (c) ; } } } client.stop () ; } }

Registrering av en väderstation i "People's Monitoring"

För att data som överförs av vår enhet ska visas korrekt på offentlig övervakning måste du göra följande:


Demonstration av enheten

Vad mer kan göras?

    Teensy har en realtidsklocka (RTC) ombord. För deras prestanda räcker inte bara kvarts. Du kan köpa kvarts vid 32,768 kHz i vilken radioelementbutik som helst och löda den. Då kan du väcka Teensy med ett RTC-larm. Fördelen är att du kan väcka enheten oftare under de timmar då mer exakta avläsningar behövs. Till exempel, under arbetstid, väcka enheten var 5:e minut och resten - var halvtimme.

En kollega till mig var nyligen värd för en liten vetenskapsmässa.
Min lärare bad mig presentera ett elektronikprojekt för studenter. Jag hade två dagar på mig att hitta på något intressant och enkelt nog.



Eftersom väderförhållandena här är ganska föränderliga och temperaturen varierar i intervallet 30-40 ° C, bestämde jag mig för att göra en hemmaväderstation.

Vilka funktioner har en väderstation för hemmabruk?
En Arduino väderstation med en display är en enhet som samlar in data om väder och miljöförhållanden med hjälp av en mängd olika sensorer.

Vanligtvis är dessa sensorer:

  • vind
  • fuktighet
  • regn
  • temperatur
  • tryck
  • höjder

Mitt mål är att göra en bärbar stationär väderstation med mina egna händer.

Den bör kunna definiera följande parametrar:

  • temperatur
  • fuktighet
  • tryck
  • höjd

Steg 1: Köp rätt komponenter







  • DHT22, temperatur- och luftfuktighetssensor.
  • BMP180, tryckgivare.
  • Löda
  • Enkelradskontakt 40 utgångar

Från utrustningen behöver du:

  • lödkolv
  • tång för nosdyna
  • ledningar

Steg 2: DHT22 temperatur- och fuktighetssensor







Olika sensorer används för att mäta temperatur. DHT22, DHT11, SHT1x är populära

Jag kommer att förklara hur de skiljer sig från varandra, och varför jag använde DHT22.

AM2302-sensorn använder en digital signal. Denna sensor fungerar på ett unikt kodsystem och sensorteknologi, så dess data är tillförlitlig. Dess sensorelement är anslutet till en 8-bitars enkelchipsdator.

Varje sensor av denna modell är termiskt kompenserad och exakt kalibrerad, kalibreringskoefficienten lagras i ett engångsprogrammerbart minne (OTP-minne). När du läser en avläsning kommer sensorn att hämta koefficienten från minnet.

Liten storlek, låg strömförbrukning, långt överföringsavstånd (100m) gör AM2302 lämplig för nästan alla applikationer, och 4 utgångar i rad gör installationen mycket enkel.

Låt oss titta på för- och nackdelarna med de tre sensormodellerna.

DHT11

Fördelar: kräver inte lödning, den billigaste av de tre modellerna, snabb stabil signal, räckvidd över 20 m, stark störning.
Nackdelar: Bibliotek! Inga upplösningsalternativ, temperaturmätningsfel +/- 2°С, relativ luftfuktighetsnivåmätfel +/- 5 %, otillräckligt område för uppmätta temperaturer (0-50°С).
Tillämpningar: trädgårdsskötsel, jordbruk.

DHT22

Fördelar: kräver inte lödning, låg kostnad, jämna kurvor, små mätfel, stort mätområde, räckvidd över 20 m, stark interferens.
Nackdelar: känsligheten kan vara högre, långsam spårning av temperaturförändringar, bibliotek behövs.
Ansökningar: miljöstudier.

SHT1x

Fördelar: ingen lödning krävs, jämna kurvor, små mätfel, snabb respons, låg strömförbrukning, automatiskt viloläge, hög stabilitet och datakonsistens.
Nackdelar: två digitala gränssnitt, fel vid mätning av fuktighetsnivån, intervallet för uppmätta temperaturer är 0-50°C, ett bibliotek behövs.
Tillämpningar: drift i tuffa miljöer och i långtidsinstallationer. Alla tre sensorerna är relativt billiga.

Förening

  • Vcc - 5V eller 3,3V
  • Gnd - med Gnd
  • Data - till den andra Arduino-stiften

Steg 3: BMP180 trycksensor



BMP180 är en barometrisk atmosfärstrycksensor med I2C-gränssnitt.
Barometriska trycksensorer mäter det absoluta värdet av den omgivande luften. Denna indikator beror på de specifika väderförhållandena och på höjden över havet.

BMP180-modulen hade en 3,3V 662k ohm regulator, som jag, av min egen dumhet, av misstag sprängde. Jag var tvungen att göra ett kraftslag direkt till chippet.

På grund av bristen på en stabilisator är jag begränsad i att välja strömkälla - spänningar över 3,3V kommer att förstöra sensorn.
Andra modeller kanske inte har en stabilisator, se till att kolla efter det.

Anslutningsschema för sensorn och I2C-bussen med Arduino (nano eller uno)

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

Låt oss prata lite om tryck, och hur det relaterar till temperatur och höjd.

Atmosfärstrycket vid någon punkt är inte konstant. Det komplexa samspelet mellan jordens rotation och lutningen av jordaxeln resulterar i många områden med hög- och lågtryck, vilket i sin tur resulterar i dagliga vädermönster. Genom att observera tryckförändringen kan du göra en kortsiktig väderprognos.

Till exempel betyder ett tryckfall vanligtvis regnigt väder eller närmande av ett åskväder (närmar sig ett lågtrycksområde, en cyklon). Stigande tryck betyder vanligtvis torrt, klart väder (ett område med högt tryck, en anticyklon, passerar över dig).

Atmosfärstrycket förändras också med höjden. Det absoluta trycket vid baslägret vid Everest (5400 m över havet) är lägre än det absoluta trycket i Delhi (216 m över havet).

Eftersom absoluta tryckavläsningar varierar på varje plats kommer vi att hänvisa till det relativa trycket eller havsnivåtrycket.

Höjdmätning

Medeltrycket vid havsnivån är 1013,25 GPa (eller millibar). Om du stiger över atmosfären kommer detta värde att sjunka till noll. Kurvan för denna höst är ganska förståelig, så du kan själv beräkna höjden med följande ekvation: alti=44330*

Om du tar havsnivåtrycket på 1013,25 GPa som p0, är ​​lösningen på ekvationen din nuvarande höjd.

Säkerhetsåtgärder

Tänk på att BMP180-sensorn behöver tillgång till atmosfären för att kunna avläsa lufttrycket, placera inte sensorn i ett stängt hölje. En liten ventil räcker. Men lämna den inte för öppen - vinden kommer att slå ner tryck och höjdavläsningar. Tänk på vindskydd.

Skydda mot värme. Noggranna temperaturavläsningar krävs för att mäta tryck. Försök att skydda sensorn från temperaturfluktuationer och lämna den inte nära källor med höga temperaturer.

Skydda mot fukt. BMP180-sensorn är känslig för fuktnivåer, försök att förhindra eventuellt vatteninträngning på sensorn.

Blind inte sensorn. Överraskningen var känsligheten hos silikonen i sensorn för ljus, som kan falla på den genom ett hål i chipskyddet. För de mest exakta mätningarna, försök att skydda sensorn från omgivande ljus.

Steg 4: Montering av enheten







Installera enradskontakter för Arduino Nano. I princip klippte vi till dem och slipade dem lite så att de ser ut som de var. Sedan löder vi dem. Därefter installerar vi enradiga kontakter för DHT22-sensorn.

Installera ett 10kΩ motstånd från datautgången till jord (Gnd). Vi löder allt.
Sedan installerar vi på samma sätt en enkelradskontakt för BMP180-sensorn, vi gör strömförsörjningen 3,3V. Vi kopplar ihop allt med I2C-bussen.

Slutligen ansluter vi LCD-skärmen till samma I2C-buss som BMP180-sensorn.
(Jag planerar att senare koppla en RTC-modul (realtidsklocka) till den fjärde kontakten så att enheten också visar tiden).

Steg 5: Kodning




Ladda ner bibliotek

För att installera bibliotek på Arduino, följ länken

#omfatta
#inkludera #inkludera #inkludera "DHT.h" #inkludera

SFE_BMP180 tryck;

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

#define DHTPIN 2 // vilket digitalt stift vi är anslutna till

// Avkommentera vilken typ du än använder! //#define DHTTYPE DHT11 // DHT 11 #define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321 DHT dht(DHTPIN, DHTTYPE); LiquidCrystal_I2C lcd(I2C_pin,Rw,Rw Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);float t1,t2;

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

status = tryck.getTemperature(T); if (status != 0) ( Serial.print("1"); lcd.clear(); lcd.setCursor(0,0); lcd.print("Baro Temperature: "); lcd.setCursor(0,1 ); lcd.print(T,2); lcd.print("grad C"); t1=T; delay(3000);

status = tryck.startPressure(3); if (status != 0) ( // Vänta tills mätningen är klar: delay(status);

status = tryck.getPressure(P,T); if (status != 0) (lcd.clear(); lcd.setCursor(0,0); lcd.print("abslt tryck: "); lcd.setCursor(0,1); lcd.print(P,2); ); lcd.print(" mb "); delay(3000);

p0 = tryck.sealevel(P,ALTITUD); // vi är på 1655 meter (Boulder, CO)

a = tryck.höjd(P,p0); lcd.clear(); lcd.setCursor(0,0); lcd.print("Höjd: "); lcd.setCursor(0,1); lcd.print(a,0); lcd.print("meters"); fördröjning(3000); ) ) ) ) float h = dht.readHumidity(); // Läs temperaturen som Celsius (standard) float t = dht.readTemperature(); t2=t; lcd.clear(); lcd.setCursor(0,0); // gå till början av andra raden lcd.print("Fuktighet: "); lcd.setCursor(0,1);lcd.print(h); lcd.print("%"); fördröjning(3000); lcd.clear(); lcd.setCursor(0,0); // gå till början av 2:a raden lcd. print("DHT Tempurature: "); lcd.setCursor(0,1); lcd print(t); lcd.print("degC"); fördröjning(3000); lcd.clear(); lcd.setCursor(0,0); // gå till början av andra raden lcd.print("Mean Tempurature: "); lcd.setCursor(0,1); lcd.print((t1+t2)/2); lcd.print("degC"); fördröjning(3000); )

Jag använde Arduino version 1.6.5, koden passar den exakt, senare kan fungera också. Om koden av någon anledning inte passar, använd version 1.6.5 som bas.

Dela med sig