Tworzenie stacji pogodowej na arduino z lokalnym serwerem. Bezprzewodowa stacja pogodowa

Stacja pogodowa zrób to sam.

Było wieczorem, po nowym roku nie było nic do roboty. Jak zwykle w zimowe święta Nowego Roku chcę zająć głowę i ręce czymś pożytecznym i kreatywnym. Podczas tych świąt noworocznych postanowiłem zrobić stację pogodową własnymi rękami. Zacząłem przygotowywać się z wyprzedzeniem, kupiłem i zmontowałem wszystkie komponenty przed nowym rokiem, a główne programowałem podczas wakacji.

(Dużo zdjęć pod cięciem!)

Najpierw omówię komponenty, nie podam linków, ponieważ towary na eBayu (na moim koncie) trafiły do ​​archiwum. Kupiłem wiele części bez pośpiechu w serwisie eBay. Wypróbowałem aukcję po raz pierwszy, zawsze kupowałem „kup teraz”. Cóż mogę powiedzieć, jeśli nie spieszysz się z zakupami, to niektóre elementy można kupić taniej (czasami różnica jest dwa razy).

Czujnik ciśnienia BMP085
To jest główny czujnik. Kiedy zobaczyłem go na eBayu, zdałem sobie sprawę, że chcę zbudować domową stację pogodową.
Czujnik dotarł w zwykłej kopercie, oklejonej małą folią bąbelkową w środku.

Wewnątrz koperty znajdowała się wizytówka sprzedawcy i czujnik, zapakowane w antystatyczną torbę i owinięte kolejną warstwą folii bąbelkowej

Torba antystatyczna została uszczelniona, aby wilgoć podczas lotu nie zagrażała czujnikowi

Dostajemy czujnik. Z jednej strony przylutowano linię styków, które włożono w piankę, aby się nie wyginały. Po drugiej stronie znajduje się sam czujnik i oznaczenie styków.




Wszystko byłoby w porządku, ale oznaczenie styków jest naniesione w lustrzanym odbiciu.
Czujnik jest podłączony poprzez magistralę I2C i zasilany jest napięciem 3,3 V. Oznacza to, że do normalnej pracy potrzebne są 4 przewody (+, -, SDA, SCL)
Możesz odpytywać czujnik na 2 sposoby: albo przez bibliotekę, albo używając funkcji bezpośrednio w szkicu.
Przykład programu:

#włączać

#define BMP085_ADDRESS 0x77 // adres I2C BMP085

Const unsigned char OSS = 0; // Ustawienie oversamplingu

// Wartości kalibracyjne
int ac1;
intac2;
intac3;
unsigned int ac4;
niepodpisany int ac5;
unsigned int ac6;
int b1;
intb2;
intmb;
wew mc;
intmd;

krótka temperatura;
długi nacisk;

Unieważnij konfigurację()
{
Serial.początek(9600);
Wire.początek();
bmp085Kalibracja();
}

Pusta pętla()
{
temperatura = bmp085GetTemperature(bmp085ReadUT());
ciśnienie = bmp085GetPressure(bmp085ReadUP());
Serial.print("Temperatura: ");
Serial.print(temperatura/10.0, DEC);
Serial.println("C");
Serial.print("Ciśnienie: ");
Serial.print (ciśnienie/133.322, DEC);
Serial.println("mm Hg");
Serial.println();
opóźnienie (1000);
}

Brak kalibracji 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);
}

Krótki bmp085GetTemperature (unsigned int ut)
{
długi x1, x2;
x1 = (((long)ut - (long)ac6)*(long)ac5) >> 15;
x2 = ((długi)mc<< 11)/(x1 + md);
b5 = x1 + x2;

Powrót ((b5 + 8)>>4);
}

Długi bmp085GetPressure (długi bez podpisu)
{
długie x1, x2, x3, b3, b6, p;
bez znaku długie b4, b7;
b6 = b5 - 4000;
// Oblicz B3
x1 = (b2 * (b6 * b6)>>12)>>11;
x2 = (ac2 * b6)>>11;
x3 = x1 + x2;
b3 = (((((długi)ac1)*4 + x3)<>2;
// Oblicz B4
x1 = (ac3 * b6)>>13;
x2 = (b1 * ((b6 * b6)>>12))>>16;
x3 = ((x1 + x2) + 2)>>2;
b4 = (ac4 * (długi bez znaku)(x3 + 32768))>>15;
b7 = ((unsigned long)(up - b3) * (50000>>OSS));
jeśli (b7< 0x80000000)
p = (b7<<1)/b4;
w przeciwnym razie
p = (b7/b4)<<1;
x1 = (p>>8) * (p>>8);
x1 = (x1 * 3038)>>16;
x2 = (-7357 * p)>>16;
p += (x1 + x2 + 3791)>>4;
powrót p;
}

// Odczytaj 1 bajt z BMP085 pod adresem "adres"
char bmp085Read (adres znaku bez znaku)
{
niepodpisane dane znaków;

wire.write(adres);
Wire.endTransmission();
Wire.requestFrom(BMP085_ADDRESS, 1);
while(!Wire.available())
;
return Wire.read();
}

Int bmp085ReadInt (adres znaków bez znaku)
{
niepodpisany znak msb, lsb;
Wire.beginTransmission(BMP085_ADDRESS);
wire.write(adres);
Wire.endTransmission();
Wire.requestFrom(BMP085_ADDRESS, 2);
while(Przewód.dostępny()<2)
;
msb = Drut.odczyt();
lsb = Drut.odczyt();
return (int) msb<<8 | lsb;
}

// Odczytaj nieskompensowaną wartość temperatury
unsigned int bmp085ReadUT()
{
niepodpisany int ut;
// Zapisz 0x2E do rejestru 0xF4
// To żąda odczytu temperatury
Wire.beginTransmission(BMP085_ADDRESS);
Wire.write(0xF4);
Wire.write(0x2E);
Wire.endTransmission();
// Odczekaj co najmniej 4,5 ms
opóźnienie(5);
// Odczytaj dwa bajty z rejestrów 0xF6 i 0xF7
ut = bmp085ReadInt(0xF6);
wróć;
}

// Odczytaj nieskompensowaną wartość ciśnienia
unsigned long bmp085ReadUP()
{
niepodpisany znak msb, lsb, xlsb;
unsigned long up = 0;
// Napisz 0x34+(OSS<<6) into register 0xF4
// Poproś o odczyt ciśnienia z ustawieniem nadpróbkowania
Wire.beginTransmission(BMP085_ADDRESS);
Wire.write(0xF4);
Wire.write(0x34 + (OSS<<6));
Wire.endTransmission();
// Czekaj na konwersję, czas opóźnienia zależny od OSS
opóźnienie(2 + (3 .)<// Odczytaj rejestr 0xF6 (MSB), 0xF7 (LSB) i 0xF8 (XLSB)
Wire.beginTransmission(BMP085_ADDRESS);
Wire.write(0xF6);
Wire.endTransmission();
Wire.requestFrom(BMP085_ADDRESS, 3);
// Poczekaj, aż dane staną się dostępne
while(Przewód.dostępny()< 3)
;
msb = Drut.odczyt();
lsb = Drut.odczyt();
xlsb = Drut.odczyt();
w górę = (((długi bez znaku) msb<< 16) | ((unsigned long) lsb << 8) | (unsigned long) xlsb) >> (8-OSS);
wrócić do góry;
}


Dodatkowo czujnik posiada własny czujnik termiczny do kompensacji ciśnienia oraz wysokościomierz.

Arduino Nano v3.0
To serce całej stacji pogodowej. Mówiąc prościej, kontroler ma miniaturowy rozmiar.
Kupił
Nie będę mówił szczegółowo o kontrolerze, ponieważ zostało to już zrobione przede mną:


Opakowanie z lightake było prefabrykowane, kontroler był w paczce z kablem USB i Arduino w szczelnej torbie antystatycznej.

Aby oszacować rozmiar, obok Arduino połóż monetę o nominale 1 rubla.

Płytka kontrolera z bliska



Kabel USB jest dobry, z pierścieniem ferrytowym. Zasilany przez Arduino przez kabel USB. Środowisko programistyczne można pobrać (strona pobierania). Język jest podobny do „C”, nie było problemów z opanowaniem, ponieważ dużo na nim programuję w pracy.

wyświetlacz LCD
W pracy w śmietnikach znalazłem kompatybilny ekran LCD 1602. Musiałem majstrować przy połączeniu, ponieważ nie znalazłem dla niego arkusza danych. W rezultacie LCD zarobił.

Ale po krótkiej operacji zauważyłem, że ten ekran mi nie wystarcza i nie będę mógł wyświetlić więcej danych, ponieważ ma tylko 2 linie po 16 znaków każda. Na początku wydaje się, że te parametry są wystarczające, ale kiedy zaczynasz programować, rozumiesz, że możesz wcisnąć maksymalnie 3-4 parametry. A jeśli zrobisz menu (myślałem o zrobieniu menu na tym ekranie), to pozostaje 1-2 wolne miejsce na parametry.
W rezultacie zacząłem szukać innego ekranu. Najpierw spojrzałem na ekran graficzny z Nokii 3310 i nawet wziąłem udział w aukcji eBay, żeby go kupić, ale nie wyszło (z czego bardzo się cieszę), więc musiałem zrezygnować z tego ekranu. Teraz rozumiem, że byłoby to za małe dla moich celów, bo jest z czym porównać.
Przeglądając tarcze na Arduino przypadkiem natknąłem się na ekran graficzny 12864 na kontrolerze ST7920. Ten ekran ma odpowiedni rozmiar i dobrą rozdzielczość dla moich potrzeb (128x64). Oznacza to, że możesz bezpiecznie umieścić 6-7 wierszy po 20 znaków w normalnie czytelnej czcionce. Ponieważ ekran jest graficzny, oprócz tekstu w różnych czcionkach można również umieścić grafikę. Krótko mówiąc, dokładnie tego potrzebowałem, wszystko było obecne w tym ekranie, więc nie mogłem tego znieść i zamówić.
Przesyłka dotarła szybko i została zapakowana w standardowy sposób: folia bąbelkowa, w środku kolejna warstwa folii bąbelkowej i ekran w woreczku antystatycznym:






Aby oszacować rozmiar, obok LCD połóż monetę o nominale 1 rubla.




Aby szybko podłączyć ekran do Arduino, przylutowałem linię styków do pinów LCD. Wyświetlacz LCD można podłączyć za pomocą magistrali szeregowej i równoległej. Wybrałem pierwszą opcję, ponieważ wolnych kontaktów Arduino jest tak mało.
Połączenie (pobrane z sieci):

-Pin 1 (GND) łączy się ze wspólną magistralą
- Pin 2 (VCC) jest podłączony do szyny zasilającej +5V, a pobór prądu jest stosunkowo niewielki, a wyświetlacz może być zasilany z wbudowanego regulatora Arduino.
- Piny 4, 5 i 6 są podłączone do wyjść cyfrowych Arduino, tworząc interfejs szeregowy SPI:
pin 4 - (RS) - odpowiada linii CS (np. 7)
pin 5 - (RW) - odpowiada linii MOSI (np. 8)
pin 6 - (E) - odpowiada linii SCK (np. 3)
Numery pinów Arduino mogą być dowolne, najważniejsze jest, aby nie zapomnieć o ich prawidłowym wskazaniu później w tekście programu podczas inicjalizacji wyświetlacza.
- Pin 15 (PSB) jest podłączony do wspólnej magistrali.
- Piny 19 (A) i 20 (K) to zasilanie podświetlenia (odpowiednio +5V i GND). Do regulacji jasności podświetlenia można użyć rezystora zmiennego 10kΩ podłączonego między szynami zasilającymi a GND. Napięcie z jego silnika jest podawane na pin 19 wyświetlacza.
Zgodnie z tą instrukcją podłączyłem wszystko oprócz podświetlenia. Do zasilania podświetlenia użyłem Arduino PWM.
W celu programowego połączenia wyświetlacza LCD z Arduino wykorzystywana jest biblioteka u8glib. Możesz pobrać. Jeśli są problemy z pobieraniem, mogę wgrać bibliotekę na narod.ru.
Sama biblioteka nie jest skomplikowana i pozwala na wyświetlanie tekstu różnymi czcionkami, rysowanie linii, rysowanie najprostszych kształtów geometrycznych (prostokąt, koło), wyświetlanie przygotowanych w specjalny sposób obrazów. W zasadzie to narzędzie jest wystarczające do większości zadań.
Oto wynik prostego programu:

Sam program:

#include "U8glib.h"

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

// Podprogram do określania wolnej pamięci
int freeRam()(
extern int __heap_start, *__brkval;
w telewizji;
return (int) &v - (__brkval == 0? (int) &__heap_start: (int) __brkval);
}

Unieważnij konfigurację (unieważnij) (
u8g.setFont(u8g_font_6x10); // czcionka
u8g.setRot180(); // Odwróć ekran
analogZapis(6, 115); // Ustaw jasność ekranu (anoda podświetlenia na 6 pinów)
}

Pętla pustki (pustka) (
u8g.pierwszaStrona();
robić(

u8g.setPrintPos(1, 12); // pozycja
u8g.print("Cześć!!!"); // wyjście tekstowe
u8g.drawBox (0,22,128,9); // Wypełnij prostokąt kolorem białym
u8g.setColorIndex(0); // biały atrament, czarne tło
u8g.setPrintPos(1, 30); // pozycja
u8g.print("Słowo..."); // wyjście tekstowe

U8g.setColorIndex(1); // biały atrament, czarne tło
u8g.setPrintPos(1, 50); // pozycja
u8g.print("Po uruchomieniu ="); // wyjście tekstowe
u8g.setPrintPos(85, 50); // pozycja
u8g.print(millis() / 1000); // wypisuje liczbę sekund po starcie
u8g.setPrintPos(1, 64); // pozycja
u8g.print(freeRam()); // wyświetla ilość używanej pamięci
) while(u8g.nextPage());

opóźnienie(200);
}

Zegar czasu rzeczywistego DS1307
Kolejny element mojej stacji pogodowej. Ta tarcza ma zegar czasu rzeczywistego. Zamówiłem je na eBayu. Sprzedawca wysłał chusteczkę do zegarka w nierealistycznie dużym pudełku


Wewnątrz pudełka znajdowały się dwa arkusze A4 z reklamami i chusteczka do zegarka zawinięta w celofan


Pragnę zauważyć, że opłata nie przekracza kwoty 2 rubli. moneta, a pudełko miało wymiary 13x15x5 cm.
Deska została zapakowana w woreczek antystatyczny

Szal z bliska



Musiałem majstrować przy tym module. Po pierwsze, pojawiły się problemy z połączeniem. A po drugie, na tej płycie nie ma kwarcu. Gdybym wiedział, że tyle czasu spędzę nad modułem, to najprawdopodobniej sam bym go zmontował, bo sieć jest pełna schematów. Najprostszy obwód zawiera 4-5 elementów.
Odnośnie połączenia. Znalazłem bibliotekę, która mówi, że interfejs I2C można podłączyć nie do zwykłych wejść analogowych Arduino (A4 i A5), ale do dowolnych dyskretnych. Zrobiłem, jak napisano. Na początku nic nie działało, po długim tańcu z tamburynem zegar nakręcił się. Cóż, myślałem, że to koniec problemów, ale po tym, jak spróbowałem podłączyć ten sam moduł do innego Arduino, taniec z tamburynem trwał dalej. Spędziłem dużo czasu na szukaniu rozwiązania tego problemu i prawie wszędzie wskazywano albo nieprawidłowe połączenie, albo brak rezystorów podciągających na pinach SCL i SDA. Chciałem już wejść na płytkę lutownicą, ale na jednym forum przypadkowo natknąłem się na kod, w którym było powiedziane, że SCL i SDA należy podłączyć do standardowych portów I2C w Arduino. Po standardowym połączeniu wszystko od razu działało.
Teraz o kwarcu. Nie wiem, jaki kwarc umieścili tam Chińczycy, ale zegarki z takim kwarcem biegały 10-11 sekund na dobę. Ten błąd wynosi 5 minut miesięcznie i 1 godzinę rocznie. Nie potrzebujesz takiego zegara. Musiałem ponownie przejść do trybu online i poszukać sposobu naprawienia tego błędu. Pierwsze rozwiązanie, które pojawiło się, mówi, że musisz uziemić kwarc. Zrobiłem to - wynik zero. Znalazłem gdzieś indziej, gdzie musiałem znaleźć starą płytę główną i niesprzedany zegarek kwarcowy. Zrobione - wynik jest. Teraz zegar ucieka nie o 10-11 sekund, ale o 1,5 sekundy dziennie. Powiedzmy, że polepszyło się, ale dalekie od ideału. Ponieważ bardziej niechętnie bawi się lutownicą, postanowiono ustawić zegar programowo, czyli raz dziennie ustawić zegar na żądaną wartość. Po 10 dniach zegar minął nie więcej niż sekundę. Metoda jest dobra, ale tylko wtedy, gdy urządzenie do pomiaru czasu Arduino jest podłączone do zasilania, w przeciwnym razie zegar działa na baterii i nadal ucieka.
Mały program testowy:

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

Bajt decToBcd (wartość bajtu)
{
zwrot ((wartość/10*16) + (wartość%10));
}

Bajt bcdToDec (wartość w bajtach)
{
zwrot ((wartość/16*10) + (wartość%16));
}

Unieważnij setDateDs1307 (bajt sekund, // 0-59
bajt minut, // 0-59
bajt godzin) // 0-99
{

Wire.write(0);
Wire.write(decToBcd(drugi));
Wire.write(decToBcd(minuta));
Wire.write(decToBcd(godzina));
Wire.endTransmission();
}

Unieważnij getDateDs1307(bajt *sekunda,
bajt*minuta,
bajt*godzina)
{

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

Wire.requestFrom(DS1307_I2C_ADDRESS, 3);

*druga = bcdToDec(Przewód.odczyt());
*minuta = bcdDoDec(Przewód.odczyt());
*godzina = bcdDoDec(Przewód.odczyt());
}

Unieważnij konfigurację()
{
bajt sekunda, minuta, godzina;
Wire.początek();
Serial.początek(9600);

Drugi = 45;
minuty = 5;
godziny = 16;

SetDateDs1307(sekunda, minuta, godzina);
}

Pusta pętla()
{
bajt sekunda, minuta, godzina;

GetDateDs1307(&sekunda, &minuta, &godzina);
Serial.print(godzina, DEC);
druk seryjny(":");
Serial.print(minuta, DEC);
druk seryjny(":");
Serial.println(drugi, DEC);

opóźnienie (1000);
}


Biblioteka nie jest tutaj używana, a funkcje są obcinane na czas czytania i pisania.

Czujnik temperatury i wilgotności DHT11
O tym czujniku nie ma wiele do powiedzenia. Nawet bym go nie używał, gdybym nie potrzebował wilgoci. Niestety nie zrobiłem mu zdjęcia, kiedy go otrzymałem, więc nie będzie żadnych zdjęć. Zdjęcia czujnika można zobaczyć poniżej, gdzie podłączyłem go do Arduino. Podłączenie czujnika jest proste (+, wyjście cyfrowe, -). Zazwyczaj czujniki są wykonane z czterech pinów. Przy takim współczynniku kształtu trzeci kontakt nie jest z niczym połączony.
Aby połączyć się z Arduino, możesz skorzystać z biblioteki. Możesz pobrać.
Mały program testowy z wyjściem informacji na wyświetlacz LCD 1602:

// dołącz kod biblioteki:
#włączać
#włączać

// Zadeklaruj obiekty
dht11 dht11;
LCD LiquidCrystal (12, 11, 6, 5, 4, 3);

#zdefiniuj DHT11PIN 7
wew;

Unieważnij konfigurację()
{
lcd.początek(16, 2);
lcd.print("Stan: ");
i=0;
}

Pusta pętla()
{
int chk = DHT11.read(DHT11PIN);
lcd.setCursor(8, 0);
przełącznik (chk)
{
przypadek 0: lcd.print("OK"); przerwa;// lcd.setCursor(11, 0); lcd.print(millis()/2000); przerwanie;
case -1: lcd.print("Błąd sumy kontrolnej"); merr(); przerwanie;
case -2: lcd.print("Błąd przekroczenia limitu czasu"); merr(); przerwanie;
domyślnie: lcd.print("Nieznany błąd"); merr(); przerwanie;
}
opóźnienie (500);
lcd.setCursor(15, 0);
przełącznik(i)
{
przypadek 0: lcd.print("^"); lcd.setCursor(15, 1); lcd.print(" ");przerwa;
przypadek 1: lcd.print("v"); lcd.setCursor(15, 1); lcd.print(" ");przerwa;
domyślnie: lcd.setCursor(15, 1); lcd.print("E"); przerwanie;
}
i=i+1;
jeśli (i>1) i=0;
lcd.setCursor(0, 1);
lcd.print("H=");
lcd.setCursor(2, 1);
lcd.print((float)DHT11.wilgotność, 0);
lcd.setCursor(4, 1);
lcd print("%");
lcd.setCursor(8, 1);
lcd.print("T=");
lcd.setCursor(10, 1);
lcd.print((float)DHT11.temperatura, 0);
lcd.setCursor(12, 1);
lcd.print("C");

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


Czujnik ma wady - dane z czujnika przychodzą tylko w liczbach całkowitych, a zasięg jest słaby.

Wydaje się, że pisał o wszystkich podzespołach. Pozostaje zebrać wszystko w jedną całość.
Ups, prawie zapomniałem! Aby złożyć urządzenie, potrzebujesz etui. Sprawa zamówiona również w serwisie eBay. Sprzedawca pochodził z Anglii. Przesyłka przyszła szybko, ale nie zrobiłem jej zdjęcia. Wszystkie zdjęcia ciała znajdują się poniżej.

Najpierw wszystko zmontowałem na stole za pomocą specjalnego okablowania. Napisałem program testowy i wgrałem go do sterownika.



W rzeczywistości niebieski kolor podświetlenia jest znacznie jaśniejszy. Nawet przy minimalnej jasności (Bright=5) kadr jest naświetlony.

Aby zmontować wszystko bez przewodów, postanowiono zrobić mini płytę główną, a na złączach nałożono płytkę Arduino i nakładki. W takim przypadku można je łatwo i szybko usunąć. Postanowiłem też podpiąć ekran LCD i przyciski sterujące na złączach, tylko czujnik temperatury przylutować na przewodach.
Tak wyszedł szalik



Na ostatnim zdjęciu jeszcze nie zmyłem topnika. Pod osłonami przy złączach przykleiłem porowatą gumę tak, aby była przynajmniej jakaś podpora. Chociaż w rzeczywistości ekrany w złączach na stykach są już doskonale trzymane.

Zainstalowana płyta główna z osłonami i płytą Arduino.

Tak wygląda pełne połączenie z płytą główną


Zamiast przycisków użyłem domowej roboty tarczy lutowanej na płytce stykowej. Jako przyciski użyłem przycisków ze starych myszy.
Jak widać, zmniejszyła się liczba przewodów.

Głównym problemem z umieszczeniem w etui jest równomierne wycięcie rowka na ekran LCD. Bez względu na to, jak bardzo się starałem, to i tak nie wyszło idealnie. Szczeliny w niektórych miejscach miały nieco ponad 1 mm. Aby wszystko wyglądało schludnie wziąłem czarny uszczelniacz do akwarium i wypełniłem wszystkie pęknięcia, jednocześnie przymocowałem sitko do tego konkretnego uszczelniacza. Po wyschnięciu szczeliwa odciąłem nadmiar z zewnątrz. W jasnym świetle szczeliwo jest widoczne, aw normalnym świetle wszystko łączy się z obudową.
Tak wygląda obudowa od środka z zamontowanym ekranem LCD i płytą główną.

Tak to wygląda z zewnątrz w jasnym świetle (przepraszam za odciski palców, widziałem je przy sortowaniu zdjęć).

Długo myślałem, jak wpiąć guziki do etui i co najważniejsze, jakich użyć…
W sklepach elektronicznych podobał mi się przycisk z długą szpilką i końcówkami, które na tę szpilkę nakłada się. Przyciski te służą do lutowania do płytki. Wszystko byłoby w porządku, ale mają minus - skok docisku jest bardzo mały i głośny.
Musiałem rozmieścić przyciski w dwóch etapach: pierwszym było umieszczenie przycisków na planszy, drugim było zamontowanie tej planszy na innej planszy. A potem włóż to wszystko do ciała na prowadnicach.

Tak wygląda szalik z guzikami:



Tak wygląda tablica:


Tutaj możesz zobaczyć prowadnice, do których wkładana jest tablica z przyciskami. Wlutowałem kilka elementów w celu usztywnienia płytki.

Teraz wszystko wkładamy do ciała
Bez przycisków łączących:


Z podłączeniem przycisku:

Zamknij pudełko i włącz je. Wszystko działa dobrze, przyciski działają tak, jak powinny.

Na koniec zamieszczam krótki filmik z urządzenia w różnych trybach:
http://www.youtube.com/watch?v=KsiVaUWkXNA&feature=youtu.be
Dla tych, którzy nie widzą filmu tutaj, oto link do

Czas zakończyć recenzję.
Napiszę trochę o programie, a potem krótkie wnioski. Kiedy pisałem program, nie sądziłem, że bardzo szybko natknę się na limit 30720 bajtów.


Musiałem zoptymalizować kod. Przeniesiono wiele fragmentów kodu do podprogramów. Nigdy bym nie pomyślał, że instrukcja switch ... case w skompilowanej formie zajmuje więcej miejsca niż kilka if ... else. Prawidłowa deklaracja zmiennych również oszczędza miejsce. Jeśli zadeklarujesz tablicę long, chociaż całkiem możliwe jest obejście się za pomocą byte, to przepełnienie pamięci sięga 500 bajtów, w zależności od rozmiaru tablicy. Kiedy piszesz program, nie myślisz o tym, a dopiero później, kiedy analizujesz program, uświadamiasz sobie, że zrobiłeś coś źle i zaczynasz optymalizować kod. Po rozwiązaniu problemów z rozmiarem programu natknąłem się na ograniczenie pamięci RAM. Wyrażało się to tym, że program zaczął się zawieszać po załadowaniu. Musiałem wprowadzić podprogram do obliczania wolnej pamięci RAM. W rezultacie zmuszony byłem zrezygnować z jednego algorytmu prognozowania pogody, ponieważ musi on wyświetlać ikony na ekranie. Sam algorytm działa, ale wyjście ikon musiało być zarezerwowane. Wciąż mam pomysły na optymalizację kodu, ale w niedalekiej przyszłości pozostawię urządzenie działające bez zmian, aby ocenić wydajność i zidentyfikować wszystkie błędy.

Teraz kilka wniosków
Minusy
1) Cena. Usprawiedliwieniem tego minusa jest to, że hobby nigdy nie jest tanie.

plusy
1) Świetna funkcjonalność urządzenia
2) Rozszerzenie funkcji jest ograniczone tylko używanym kontrolerem i własnym pragnieniem;
3) Estetyczna przyjemność z kontemplacji i moralna przyjemność z faktu, że mimo wszystko zmontowałem i skompletowałem to urządzenie

Planuję kupić +86 Dodaj do ulubionych Podobała mi się recenzja +137 +304

W jakiś sposób, spacerując po mieście, zobaczyłem nowy sklep z elektroniką radiową, który został otwarty. Wchodząc w to znalazłem dużą ilość nakładek dla Arduino. Miałem w domu Arduino Uno i Arduino Nano i od razu wpadłem na pomysł, aby bawić się nadajnikami sygnału na odległość. Postanowiłem kupić najtańszy nadajnik i odbiornik na 433 MHz:

Nadajnik sygnału.


odbiornik sygnału.

Po nagraniu najprostszego szkicu transmisji danych (przykład zaczerpnięto stąd) okazało się, że urządzenia nadawcze mogą być całkiem odpowiednie do przesyłania prostych danych, takich jak temperatura, wilgotność.

Nadajnik posiada następujące cechy:
1. Model: MX-FS-03V
2. Promień działania (zależy od obecności obiektów blokujących): 20-200 metrów
3. Napięcie robocze: 3,5-12 V
4. Wymiary modułu: 19*19mm
5. Modulacja sygnału: AM
6. Moc nadajnika: 10mW
7. Częstotliwość: 433 MHz
8. Wymagana długość anteny zewnętrznej: 25 cm
9. Łatwe podłączenie (tylko trzy przewody): DATA ; VCC ; Ziemia.

Charakterystyka modułu odbiorczego:
1. Napięcie robocze: DC 5 V
2. Prąd: 4mA
3. Częstotliwość robocza: 433,92 MHz;
4. Czułość:-105dB
5. Wymiary modułu: 30*14*7mm
6. Wymagana antena zewnętrzna: 32 cm.

W ogromie internetu mówi się, że zasięg transmisji informacji przy 2Kb/s może sięgać nawet 150m. Sam tego nie sprawdzałem, ale w dwupokojowym mieszkaniu akceptuje wszędzie.

Sprzęt do domowej stacji pogodowej

Po kilku eksperymentach zdecydowałem się podłączyć do Arduino Nano czujnik temperatury, wilgotności i nadajnik.


Czujnik temperatury DS18D20 podłącza się do arduino w następujący sposób:

1) GND do minusa mikrokontrolera.
2) DQ przez rezystor podciągający do masy i do pinu D2 Arduino
3) Vdd do +5V.

Moduł nadajnika MX -FS - 03V zasilany jest napięciem 5 V, wyjście danych (ADATA) jest podłączone do pinu D13.

Do Arduino Uno podłączyłem wyświetlacz LCD i barometr BMP085.


schemat połączeń dla arduino uno

Odbiornik sygnału jest podłączony do pinu D10.

Moduł BMP085 to cyfrowy czujnik ciśnienia atmosferycznego. Czujnik umożliwia pomiar temperatury, ciśnienia i wysokości. Interfejs połączenia: I2C. Napięcie zasilania czujnika 1,8-3,6 V

Moduł łączy się z Arduino w taki sam sposób jak inne urządzenia I2C:

  • VCC - VCC (3,3 V);
  • GND-GND;
  • SCL - do pinu analogowego 5;
  • SDA - do pinu analogowego 4.
  • Bardzo niski koszt
  • Zasilanie i I/O 3-5V
  • Oznaczanie wilgotności 20-80% z dokładnością 5%
  • Oznaczanie temperatury 0-50 stopni. z dokładnością 2%
  • Częstotliwość odpytywania nie większa niż 1 Hz (nie częściej niż raz na 1 sek.)
  • Wymiary 15,5 mm x 12 mm x 5,5 mm
  • 4 piny z rozstawem nóg 0,1"

DHT ma 4 piny:

  1. Vcc (zasilanie 3-5 V)
  2. Wyjście danych - Wyjście danych
  3. Nieużywany
  4. Ogólny

Łączy się z D8 Arduino.

Oprogramowanie domowej stacji pogodowej

Moduł nadajnika mierzy i przesyła temperaturę co 10 minut.

Poniżej program:

/* Szkic w wersji 1.0 Wysyłaj temperaturę co 10 min. */ #include #include #include #define ONE_WIRE_BUS 2 //Pin do podłączenia czujnika Dallas OneWire oneWire(ONE_WIRE_BUS); DallasCzujniki temperatury(&oneWire); Adres urządzenia wewnątrzTermometr; void setup(void) ( //Serial.begin(9600); vw_set_ptt_inverted(true); // Wymagane dla DR3100 vw_setup(2000); // Ustaw szybkość transmisji (bps) sensor.begin(); if (!sensors .getAddress (insideThermometer, 0)); printAddress(insideThermometer); sensors.setResolution(insideThermometer, 9); ) void printTemperature(DeviceAddress deviceAddress) ( float tempC = sensors.getTempC(deviceAddress); //Serial.print("Temp C : " //Serial.println(tempC); //Formacja danych do wysłania int number = tempC; char symbol = "c"; //Symbol usługi określający, że jest to czujnik String strMsg = "z "; strMsg + = symbol; strMsg += " "; strMsg += liczba; strMsg += " "; char msg; strMsg.toCharArray(msg, 255); vw_send((uint8_t *)msg, strlen(msg)); vw_wait_tx(); / / Poczekaj na zakończenie transferu delay(200); ) void loop(void) ( for (int j=0; j<= 6; j++) { sensors.requestTemperatures(); printTemperature(insideThermometer); delay(600000); } } //Определение адреса void printAddress(DeviceAddress deviceAddress) { for (uint8_t i = 0; i < 8; i++) { if (deviceAddress[i] < 16); //Serial.print("0"); //Serial.print(deviceAddress[i], HEX); } }

Urządzenie odbiorcze odbiera dane, mierzy ciśnienie i temperaturę w pomieszczeniu i przekazuje je na wyświetlacz.

#include #include LiquidCrystal lcd(12, 10, 5, 4, 3, 2); #dołącz czujnik dht11; #define DHT11PIN 8 #include #include BMP085 dps = BMP085(); długa Temperatura = 0, Ciśnienie = 0, Wysokość = 0; void setup() ( Serial.begin(9600); vw_set_ptt_inverted(true); // Wymagane dla DR3100 vw_setup(2000); // Ustaw szybkość odbioru vw_rx_start(); // Uruchom monitorowanie powietrza lcd.begin(16, 2); Wire.begin(); delay(1000); dps.init(); //lcd.setCursor(14,0); //lcd.write(byte(0)); //lcd.home(); ) void loop() ( uint8_t buf; // Bufor komunikatów uint8_t buflen = VW_MAX_MESSAGE_LEN; // Długość bufora if (vw_get_message(buf, &buflen)) // Jeśli wiadomość została odebrana ( // Rozpocznij analizowanie int i; // Jeśli wiadomość jest nie zaadresowane do nas , exit if (buf != "z") ( return; ) char polecenie = buf; // Polecenie jest pod indeksem 2 // Parametr numeryczny zaczyna się od indeksu 4 i = 4; int liczba = 0; // Ponieważ transfer odbywa się znak po znaku , należy przekonwertować zestaw znaków na liczbę while (buf[i] != " ") ( liczba *= 10; liczba += buf[i] - "0"; i++; ) dps.getPressure(&ciśnienie); dps.getAltitude (&wysokość); dps.getTemperature(&temperatura); //Serial.print(polecenie); Serial.print(" "); Druk seryjnyln(liczba); lcd.print("T="); lcd.setCursor(2,0); druk lcd (liczba); lcd.setCursor(5,0); lcd.print("P="); lcd.print (ciśnienie/133.3); lcd.print("mmH"); lcd.setCursor(0,1); lcd.print("T="); lcd.print (temperatura*0.1); lcd.print("H="); lcd.print(czujnik.wilgotności); lcd.home(); //opóźnienie(2000); int chk = sensor.read(DHT11PIN); switch (chk) ( case DHTLIB_OK: //Serial.println("OK"); break; case DHTLIB_ERROR_CHECKSUM: //Serial.println("Błąd sumy kontrolnej"); break; case DHTLIB_ERROR_TIMEOUT: //Serial.println("Time out błąd"); przerwa; domyślnie: //Serial.println("Nieznany błąd"); przerwa; ) ) )

PS W przyszłości planuję dodać następujące:
- czujnik wilgotności do nadajnika, przerobienie algorytmu transmisji danych
- czujnik do pomiaru prędkości i kierunku wiatru.
- dodaj kolejny wyświetlacz do odbiornika.
- przenieść odbiornik i nadajnik do osobnego mikrokontrolera.

Poniżej znajduje się zdjęcie tego, co się stało:

Lista elementów radiowych

Przeznaczenie Typ Określenie Ilość NotatkaWynikMój notatnik
część nadawcza.
Płytka Arduino

Arduino Nano 3.0

1 Do notatnika
czujnik temperatury

DS18B20

1 Do notatnika
Rezystor

220 omów

1 Do notatnika
moduł nadajnikaMX-FS-03V (433 MHz)1 Do notatnika
część odbiorcza radio.
Płytka Arduino

Arduino Uno

1 Do notatnika
Rezystor przycinania 1 Do notatnika
Rezystor

Zaleca się pobranie oprogramowania przed podłączeniem komponentów, aby upewnić się, że płyta działa. Po montażu można ponownie błysnąć, tablica powinna spokojnie błysnąć. W projektach z odbiornikami dużej mocy w obwodzie zasilania płytki 5V (adresowalna taśma LED, serwa, silniki itp.) konieczne jest doprowadzenie zewnętrznego zasilania 5V do obwodu przed podłączeniem Arduino do komputera, ponieważ USB nie zapewni niezbędny prąd, jeśli na przykład pasek tego wymaga. Może to przepalić diodę zabezpieczającą na płytce Arduino. Instrukcja pobierania i wgrywania oprogramowania znajduje się pod spojlerem w następnym wierszu.

Zawartość folderów w archiwum

  • biblioteki– biblioteki projektów. Zastąp istniejące wersje
  • oprogramowanie układowe- Firmware dla Arduino
  • schematy– schematy połączeń komponentów

do tego

  • Jak pokazał eksperyment, na zewnątrz obudowy czujnik temperatury pokazuje o 0,5 stopnia mniej niż w środku! Konieczne jest skuteczniejsze rozmieszczenie elektroniki, usuwanie i osłanianie ciepła z elementów grzejnych ...

  • Jeśli wyświetlacz jest zbyt ciemny/biały
    Na płytce sterownika wyświetlacza (do której podłączone są przewody) znajduje się pokrętło kontrastu, za jego pomocą można dostosować kontrast do pożądanego. Również kontrast zależy od kąta widzenia wyświetlacza (jest to LCD) i można ustawić wyświetlacz tak, aby był czytelny nawet pod kątem „wyświetlacz jest na poziomie pępka, patrzymy z góry”. A kontrast mocno zależy od zasilania: od 5V wyświetlacz pokazuje tak wyraźnie i jasno, jak to możliwe, natomiast przy zasilaniu z USB przez Arduino napięcie wyniesie około 4,5V (z tego część pada na diodę ochronną wzdłuż USB linia), a wyświetlacz nie jest tak jasny. Reguluj moc pokrętłem z zewnętrznym zasilaniem od 5V!

  • Jeśli czujnik CO2 nie działa poprawnie (infa od Jewgienija Iwanowa)
    Cóż, w przykładach są szkice do kalibracji w folderze biblioteki czujników. można go również uruchomić bezmyślnie, zwierając złącze „HD” do masy na ponad 7 sekund.
    Oczywiście na ulicy na mrozie nie trzeba tego robić ... możesz po prostu napełnić butelkę świeżym powietrzem z czujnikiem w środku i zamknąć ją. kalibracja trwa co najmniej 20 minut.
    Domyślnie czujnik dostarczany jest z włączoną autokalibracją, która odbywa się codziennie, a jeśli czujnik jest używany w niewentylowanym pomieszczeniu, to ta kalibracja szybko pobiera wartości z normy poza horyzont, więc musi być wyłączona .
    Dokumentacja.

  • Autokalibracja czujnika CO2 jest wyłączone na szkicu!

  • Jeśli masz Czujnik BME280 nie działa, najprawdopodobniej ma inny adres. Projekt wykorzystuje bibliotekę Adafruit_BME280, która nie posiada osobnej funkcji zmiany adresu, dlatego adres ustawiany jest ręcznie w pliku biblioteki Adafruit_BME280.h niemal na samym początku pliku ( znajduje się w folderze Adafruit_BME280 w folderze bibliotek, powinieneś go tam zainstalować), mój moduł miał adres 0x76. Jak mogę znaleźć adres mojego modułu BME280? Istnieje specjalny szkic zwany skanerem i2c. Możesz to wygooglować, możesz. Flash ten szkic, otwórz port i uzyskaj listę adresów urządzeń podłączonych do magistrali i2c. Aby inne moduły Ci nie przeszkadzały, możesz je wyłączyć i zostawić tylko BME280. Otrzymany adres podajemy w bibliotece, zapisujemy plik i wczytujemy firmware zegara pogodowego. Wszystko!

  • Jeśli zegar się spóźnia, problem najprawdopodobniej dotyczy obwodu zasilania. Jeśli problem nie ustąpi przy zmianie zasilacza na lepszy, powiesić kondensator do zasilania modułu RTC (przylutować bezpośrednio na płytce do VCC i GND): koniecznie ceramiczny, 0,1-1 uF (oznaczenie 103 lub 104, patrz tabela oznaczeń ). Możesz również umieścić elektrolit (6,3 V, 47-100 uF)

Ustawienia oprogramowania układowego

#define RESET_CLOCK 0 // zresetuj zegar podczas ładowania oprogramowania (dla modułu z niewymienną baterią). Nie zapomnij wpisać 0 i ponownie flashować! #define SENS_TIME 30000 // czas odświeżania odczytów czujnika na ekranie, milisekundy #define LED_MODE 0 // Typ LED RGB: 0 - katoda główna, 1 - anoda główna #define LED_BRIGHT 255 // Jasność diody CO2 (0 - 255) # define BLUE_YELLOW 1 // kolor żółty zamiast niebieskiego (1 tak, 0 nie), ale ze względu na cechy połączenia żółty nie jest tak jasny #define DISP_MODE 1 // wyświetlanie w prawym górnym rogu: 0 - rok, 1 - dzień tygodnia , 2 - sekundy #define WEEK_LANG 1 // język dnia tygodnia: 0 - angielski, 1 - rosyjski (transliterowany) #define DEBUG 0 // wyświetl dziennik inicjalizacji czujnika przy starcie #define PRESSURE 1 // 0 - ciśnienie wykres, 1 - wykres prognozy deszczu (zamiast ciśnienia). Nie zapomnij naprawić limitów wykresów // limitów wyświetlania dla wykresów #define TEMP_MIN 15 #define TEMP_MAX 35 #define HUM_MIN 0 #define HUM_MAX 100 #define PRESS_MIN -100 #define PRESS_MAX 100 #define CO2_MIN 300 #define CO2_MAX 2000

Mój kolega niedawno był gospodarzem małego targu naukowego.
Mój nauczyciel poprosił mnie o przedstawienie studentom projektu elektroniki. Miałem dwa dni na wymyślenie czegoś dość ciekawego i prostego.



Ponieważ warunki pogodowe są tu dość zmienne, a temperatura oscyluje w granicach 30-40 °C, postanowiłem zrobić domową stację pogodową.

Jakie są funkcje domowej stacji pogodowej?
Stacja pogodowa Arduino z wyświetlaczem to urządzenie zbierające dane o pogodzie i warunkach środowiskowych za pomocą różnych czujników.

Zwykle są to następujące czujniki:

  • wiatr
  • wilgotność
  • deszcz
  • temperatura
  • nacisk
  • wysokości

Moim celem jest wykonanie przenośnej stacjonarnej stacji pogodowej własnymi rękami.

Powinien być w stanie zdefiniować następujące parametry:

  • temperatura
  • wilgotność
  • nacisk
  • wzrost

Krok 1: Kup odpowiednie komponenty







  • DHT22, czujnik temperatury i wilgotności.
  • BMP180, czujnik ciśnienia.
  • Lutować
  • Złącze jednorzędowe 40 wyjść

Ze sprzętu będziesz potrzebować:

  • lutownica
  • szczypce do nosa
  • przewody

Krok 2: czujnik temperatury i wilgotności DHT22







Do pomiaru temperatury wykorzystywane są różne czujniki. Popularne są DHT22, DHT11, SHT1x

Wyjaśnię czym się od siebie różnią i dlaczego użyłem DHT22.

Czujnik AM2302 wykorzystuje sygnał cyfrowy. Ten czujnik działa w oparciu o unikalny system kodowania i technologię czujników, dzięki czemu jego dane są wiarygodne. Jego element czujnikowy jest podłączony do 8-bitowego komputera jednoukładowego.

Każdy czujnik tego modelu jest skompensowany termicznie i dokładnie skalibrowany, współczynnik kalibracji przechowywany jest w jednorazowo programowalnej pamięci (pamięć OTP). Podczas odczytu odczytu czujnik przywoła współczynnik z pamięci.

Małe rozmiary, niskie zużycie energii, duża odległość transmisji (100m) sprawiają, że AM2302 nadaje się do prawie wszystkich zastosowań, a 4 wyjścia w rzędzie sprawiają, że instalacja jest bardzo łatwa.

Przyjrzyjmy się zaletom i wadom trzech modeli czujników.

DHT11

Plusy: nie wymaga lutowania, najtańszy z trzech modeli, szybki stabilny sygnał, zasięg powyżej 20 m, silne zakłócenia.
Minusy: Biblioteka! Brak opcji rozdzielczości, błąd pomiaru temperatury +/- 2°С, błąd pomiaru poziomu wilgotności względnej +/- 5%, nieodpowiedni zakres mierzonych temperatur (0-50°С).
Zastosowania: ogrodnictwo, rolnictwo.

DHT22

Plusy: nie wymaga lutowania, niski koszt, gładkie krzywe, małe błędy pomiarowe, duży zakres pomiarowy, zasięg powyżej 20 m, silne zakłócenia.
Wady: czułość może być wyższa, powolne śledzenie zmian temperatury, potrzebna biblioteka.
Zastosowania: badania środowiskowe.

SHT1x

Zalety: nie wymaga lutowania, gładkie krzywe, małe błędy pomiarowe, szybka reakcja, niskie zużycie energii, automatyczny tryb uśpienia, wysoka stabilność i spójność danych.
Minusy: dwa interfejsy cyfrowe, błąd pomiaru poziomu wilgotności, zakres mierzonych temperatur 0-50°C, potrzebna biblioteka.
Zastosowania: praca w trudnych warunkach oraz w długotrwałych instalacjach. Wszystkie trzy czujniki są stosunkowo niedrogie.

Mieszanina

  • Vcc - 5 V lub 3,3 V
  • Gnd - z Gnd
  • Dane - do drugiego pinu Arduino

Krok 3: Czujnik ciśnienia BMP180



BMP180 to barometryczny czujnik ciśnienia atmosferycznego z interfejsem I2C.
Czujniki ciśnienia barometrycznego mierzą bezwzględną wartość otaczającego powietrza. Wskaźnik ten zależy od konkretnych warunków pogodowych i wysokości nad poziomem morza.

Moduł BMP180 miał regulator 3,3V 662k ohm, który przez własną głupotę przypadkowo wysadziłem. Musiałem wykonać uderzenie bezpośrednio w chip.

Ze względu na brak stabilizatora jestem ograniczony w doborze źródła zasilania - napięcia powyżej 3,3V zniszczą czujnik.
Inne modele mogą nie mieć stabilizatora, sprawdź go.

Schemat podłączenia czujnika i magistrali I2C z Arduino (nano lub uno)

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

Porozmawiajmy trochę o ciśnieniu i jego związku z temperaturą i wysokością.

Ciśnienie atmosferyczne w żadnym punkcie nie jest stałe. Złożona współzależność między obrotem Ziemi a nachyleniem osi Ziemi powoduje wiele obszarów wysokiego i niskiego ciśnienia, co z kolei skutkuje codziennymi wzorcami pogodowymi. Obserwując zmianę ciśnienia, możesz sporządzić krótkoterminową prognozę pogody.

Na przykład spadek ciśnienia zwykle oznacza deszczową pogodę lub zbliżanie się burzy (zbliżanie się do obszaru niskiego ciśnienia, cyklonu). Rosnące ciśnienie zwykle oznacza suchą, bezchmurną pogodę (przepływa nad tobą obszar wysokiego ciśnienia, antycyklon).

Ciśnienie atmosferyczne zmienia się również wraz z wysokością. Ciśnienie bezwzględne w bazie pod Everestem (5400 m n.p.m.) jest niższe niż ciśnienie absolutne w Delhi (216 m n.p.m.).

Ponieważ odczyty ciśnienia bezwzględnego różnią się w każdym miejscu, będziemy odnosić się do ciśnienia względnego lub ciśnienia na poziomie morza.

Pomiar wysokości

Średnie ciśnienie na poziomie morza wynosi 1013,25 GPa (lub milibary). Jeśli wzniesiesz się ponad atmosferę, ta wartość spadnie do zera. Krzywa tego spadku jest całkiem zrozumiała, więc wysokość można obliczyć samemu za pomocą następującego równania: alti=44330*

Jeśli przyjmiesz ciśnienie na poziomie morza 1013,25 GPa jako p0, rozwiązaniem równania jest Twoja aktualna wysokość.

Środki ostrożności

Należy pamiętać, że BMP180 potrzebuje dostępu do atmosfery, aby móc odczytać ciśnienie powietrza, nie należy umieszczać czujnika w zamkniętej obudowie. Wystarczy mały otwór wentylacyjny. Ale nie zostawiaj go zbyt otwartego - wiatr obniży odczyty ciśnienia i wysokości. Rozważ ochronę przed wiatrem.

Chronić przed ciepłem. Do pomiaru ciśnienia wymagane są dokładne odczyty temperatury. Staraj się chronić czujnik przed wahaniami temperatury i nie zostawiaj go w pobliżu źródeł wysokich temperatur.

Chronić przed wilgocią. Czujnik BMP180 jest wrażliwy na poziom wilgoci, spróbuj zapobiec ewentualnemu przedostaniu się wody do czujnika.

Nie oślepiaj czujnika. Niespodzianką była wrażliwość silikonu w czujniku na światło, które może na niego padać przez otwór w osłonie chipa. Aby uzyskać jak najdokładniejsze pomiary, staraj się chronić czujnik przed światłem otoczenia.

Krok 4: Montaż urządzenia







Instalacja złącz jednorzędowych dla Arduino Nano. Zasadniczo przycięliśmy je na wymiar i trochę przeszlifowaliśmy, aby wyglądały tak, jak były. Następnie je lutujemy. Następnie instalujemy złącza jednorzędowe dla czujnika DHT22.

Zainstalować rezystor 10kΩ od wyjścia danych do uziemienia (Gnd). Lutujemy wszystko.
Następnie w ten sam sposób montujemy jednorzędowe złącze do czujnika BMP180, wykonujemy zasilanie 3,3V. Wszystko łączymy magistralą I2C.

Na koniec podłączamy wyświetlacz LCD do tej samej magistrali I2C, co czujnik BMP180.
(Planuję później podłączyć moduł RTC (zegar czasu rzeczywistego) do czwartego złącza, aby urządzenie wyświetlało również czas).

Krok 5: Kodowanie




Pobierz biblioteki

Aby zainstalować biblioteki na Arduino, kliknij link

#włączać
#include #include #include "DHT.h" #include

ciśnienie SFE_BMP180;

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

#define DHTPIN 2 // do jakiego pinu cyfrowego jesteśmy podłączeni

// Usuń komentarz z dowolnego używanego typu! //#define DHTTYPE DHT11 // DHT 11 #define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321 DHT dht(DHTPIN, DHTTYPE); LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin, Kołek Rs, Kołek D4, Kołek D5, Kołek D6, Kołek D7); pływak 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 = ciśnienie.pobierzTemperatura(T); if (status != 0) ( Serial.print("1"); lcd.clear(); lcd.setCursor(0,0); lcd.print("Temperatura Baro: "); lcd.setCursor(0,1 lcd.print(T,2);lcd.print("stopień C");t1=T;opóźnienie(3000);

status = ciśnienie.startCiśnienie(3); if (status != 0) ( // Poczekaj na zakończenie pomiaru: delay(status);

status = ciśnienie.getPressure(P,T); if (status != 0) (lcd.clear(); lcd.setCursor(0,0); lcd.print("ciśnienie abslt: "); lcd.setCursor(0,1); lcd.print(P,2 lcd.print("mb");opóźnienie(3000);

p0 = ciśnienie.poziom morza(P,WYSOKOŚĆ); // jesteśmy na wysokości 1655 metrów (Boulder, CO)

a = ciśnienie.wysokość(P,p0); lcd.clear(); lcd.setCursor(0,0); lcd.print("Wysokość: "); lcd.setCursor(0,1); lcd.print(a,0); lcd.print("metry"); opóźnienie(3000); ) ) ) ) float h = dht.odczytWilgotność(); // Odczytaj temperaturę w stopniach Celsjusza (domyślnie) float t = dht.readTemperature(); t2=t; lcd.clear(); lcd.setCursor(0,0); // przejdź na początek drugiej linii lcd.print("Wilgotność: "); lcd.setCursor(0,1);lcd.print(h); lcd.print("%"); opóźnienie(3000); lcd.clear(); lcd.setCursor(0,0); // przejdź na początek drugiej linii lcd print("Tempuratura DHT: "); lcd.setCursor(0,1); druk lcd(t); lcd.print("degC"); opóźnienie(3000); lcd.clear(); lcd.setCursor(0,0); // przejdź do początku drugiej linii lcd.print("Średnia temperatura: "); lcd.setCursor(0,1); lcd.print((t1+t2)/2); lcd.print("degC"); opóźnienie(3000); )

Użyłem Arduino w wersji 1.6.5, kod pasuje dokładnie, później też mogą działać. Jeśli kod nie pasuje z jakiegoś powodu, użyj wersji 1.6.5 jako podstawowej.

Oglądanie pogody to bardzo ekscytujące zajęcie. Postanowiłem zbudować swoją stację pogodową w oparciu o popularne .

Prototyp stacji pogodowej wygląda tak:

Funkcje mojej stacji pogodowej:

  • pomiar i wyświetlanie temperatury pokojowej i zewnętrznej;
  • wyświetlanie aktualnego czasu (godziny i minuty);
  • wyświetlanie aktualnych faz księżyca i dnia księżycowego;
  • przesyłanie wyników pomiarów do komputera przez łącze szeregowe;
  • transmisja wyników pomiarów protokołem MQTT za pomocą aplikacji na komputerze.


klątwa
-plik
oprogramowanie układowe dla (wersja z dnia 9 maja 2018 r.) - .
Jak migać klątwa-plik na tablicę Arduino Opisałem.

Mikrokontroler Arduino Nano 3.0

„Sercem” mojej stacji pogodowej jest mikrokontroler eBay):

Do kontroli wskazań i odpytywania czujników używam timera 1 Arduino, powodując przerwania z częstotliwością 200 Hz (okres - 5 ms).

Wskaźnik

Aby wyświetlić zmierzone odczyty czujników i aktualny czas, połączyłem się z Arduino czterocyfrowy wskaźnik LED Foryard FYQ-5643BH ze wspólnymi anodami (anody identycznych segmentów wszystkich wyładowań są połączone).
Wskaźnik zawiera cztery siedmiosegmentowe cyfry i dwie oddzielające (godzinne) kropki:

Anody wskaźnika są połączone za pomocą rezystorów ograniczających prąd do zacisków Arduino:

wypisać 1 2 3 4
wniosek A3 A2 D3 D9

Katody segmentowe połączone z pinami Arduino:

człon a b c d mi f g p
wniosek D7 D12 D4 D5 D6 D11 D8 D13

Segment wskaźnika zapala się, jeśli anoda odpowiedniego wyładowania ma wysoki potencjał (1) i niski potencjał (0) na katodzie.

Używam dynamicznej indykacji do wyświetlania informacji o indykatorze - w danym momencie tylko jedna cyfra jest aktywna. Aktywne wyładowania występują naprzemiennie z częstotliwością 200 Hz (okres wyświetlania 5 ms). Jednocześnie migotanie segmentów jest niezauważalne dla oczu.

Czujnik temperatury DS18x20

Dla możliwości zdalnego pomiaru temperatury podłączyłem czujnik , który zapewnia szeroki zakres pomiarów temperatury zewnętrznej. Czujnik jest podłączony do magistrali 1 przewód i ma trzy wyjścia - moc ( VCC), dane ( DAT), Ziemia ( GND):

wyjście czujnika VCC DAT GND
wniosek Arduino 5V A1 GND

Między szpilkami VCC oraz DAT Dołączyłem rezystor podciągający 4,7 kΩ.

Aby dokonać konwersji między stopniami Celsjusza i Fahrenheita, możesz użyć następującej tabliczki:

Czujnik umieściłem za oknem domu w plastikowym etui z długopisu:

\

Profesjonalne stacje pogodowe wykorzystują ekran Stevensona do ochrony termometru przed bezpośrednim działaniem promieni słonecznych i umożliwienia cyrkulacji powietrza. ekran Stevensona):

Czujnik ciśnienia i temperatury BMP280

Barometry rtęciowe i aneroidowe są tradycyjnie używane do pomiaru ciśnienia atmosferycznego.

W barometr rtęci ciśnienie atmosferyczne jest równoważone ciężarem słupa rtęci, którego wysokość służy do pomiaru ciśnienia:

W barometr aneroidowy stosuje się ściskanie i rozciąganie pudła pod ciśnieniem atmosferycznym:

Do pomiaru ciśnienia atmosferycznego i temperatury pokojowej w domowej stacji pogodowej używam czujnika - mały smd- Czujnik 2 x 2,5 mm oparty na technologii piezorezystywnej:

Chusteczka z czujnikiem została zakupiona na targowisku eBay:

Czujnik jest podłączony do magistrali I2C(dane kontaktowe - SDA/SDI, pin synchronizacji - SCL/SCK):

wyjście czujnika VCC GND SDI SCK
wniosek Arduino 3V3 GND A4 A5

adafruit- akta Adafruit_Sensor.h, Adafruit_BMP280.h, Adafruit_BMP280.cpp.

Jednostki ciśnienia atmosferycznego

Czujnik przez funkcję przeczytajCiśnienie podaje wartość ciśnienia atmosferycznego w paskalach. Podstawową jednostką pomiaru ciśnienia atmosferycznego jest hektopaskal(hPa) (1 hPa = 100 Pa), którego analogiem jest jednostka poza systemem " milibar" (mbar) (1 mbar = 100Pa = 1hPa). Aby przeliczyć między powszechnie stosowaną niesystemową jednostką ciśnienia " milimetr słupa rtęci" (mm Hg) i hektopaskalach, stosuje się następujące stosunki:
1 hPa = 0,75006 mmHg Sztuka. ≈ 3/4 mm Hg; 1 mmHg =1,3332 hPa 4/3 hPa.

Zależność ciśnienia atmosferycznego od wysokości nad poziomem morza

Ciśnienie atmosferyczne można przedstawić zarówno w formie bezwzględnej, jak i względnej.
Ciśnienie bezwzględne QFE(Język angielski) ciśnienie bezwzględne) to rzeczywiste ciśnienie atmosferyczne, bez uwzględnienia korekty nad poziomem morza.
Ciśnienie atmosferyczne spada o około 1 hPa wraz ze wzrostem wysokości 1 m:

Formuła barometryczna pozwala określić korektę odczytów barometru w celu uzyskania ciśnienia względnego (w mmHg):
$\Delta P = 760 \cdot (1 - (1 \over (10^ ( (0.0081350 \cdot H) \over (T + 0.00178308 \cdot H) ))))$ ,
gdzie $T$ to średnia temperatura powietrza w skali Rankina, ° Ra, $H$ - wysokość nad poziomem morza, stopy.
Zamiana stopni Celsjusza na stopnie Rankine'a:
$^(\circ)Ra = (^(\circ)C \cdot 1.8) + 491,67$
Formuła barometryczna służy do niwelacji barometrycznej - wyznaczania wysokości (z błędem 0,1 - 0,5%). Formuła nie uwzględnia wilgotności powietrza i zmiany przyspieszenia swobodnego spadania wraz z wysokością. W przypadku małych różnic wysokości tę zależność wykładniczą można aproksymować z wystarczającą dokładnością za pomocą zależności liniowej.
Ciśnienie względne QNH(Język angielski) ciśnienie względne, Kod Q Nautical Wysokość) to ciśnienie atmosferyczne dostosowane do średniego poziomu morza. średni poziom morza, MSL) (dla JEST i temperatura 15 stopni Celsjusza) i jest wstępnie ustawiana z uwzględnieniem wysokości, na której znajduje się stacja pogodowa. Można go znaleźć w danych służb meteorologicznych, odczytach kalibrowanych przyrządów w miejscach publicznych, lotnisku (z raportów METAR), z Internetu.
Na przykład dla pobliskiego lotniska Homel ( UMGG) Widzę aktualną prognozę pogody METAR na ru.allmetsat.com/metar-taf/russia.php?icao=UMGG :
UMGG 191800Z 16003MPS CAVOK M06/M15 Q1014 R28/CLRD//NOSIG ,
gdzie Q1014- nacisk QNH na lotnisku wynosi 1014 hPa.
Historia biuletynów METAR dostępne na stronie aviationwxchartsarchive.com/product/metar.
Dla normalnego względnego ciśnienia powietrza QNH dopuszczalne ciśnienie 760 mm Hg. Sztuka. lub 1013,25 hPa (w temperaturze 0ºС, pod szerokością geograficzną 45º półkuli północnej lub południowej).
Ustawiłem ciśnienie dla barometru aneroidowego QNH za pomocą śruby regulacji czułości:

Prognoza pogody

Analiza zmian ciśnienia pozwala zbudować prognozę pogody, a jej dokładność jest tym większa, im gwałtowniej zmienia się ciśnienie. Na przykład, stara praktyczna zasada nawigatora mówi, że spadek ciśnienia o 10 hPa (7,5 mmHg) w ciągu 8 godzin oznacza, że ​​zbliżają się silne wiatry.

Skąd wieje wiatr? Powietrze przepływa do środka strefy niskiego ciśnienia, wiatr- poziomy ruch powietrza z obszarów o wysokim ciśnieniu do obszarów o niskim ciśnieniu (wysokie ciśnienie atmosferyczne ściska masy powietrza w obszary o niskim ciśnieniu atmosferycznym). Jeśli ciśnienie jest bardzo niskie, wiatr może dosięgnąć burza. W tym samym czasie w okolicy zredukowany ciśnienie (depresja baryczna lub cyklon), ciepłe powietrze unosi się i tworzy chmury, które często przynoszą deszcz lub śnieg.

Kierunek wiatru w meteorologii to kierunek, z którego wieje wiatr:

Ten kierunek jest zredukowany do ośmiu punktów.

Algorytm jest często używany do przewidywania pogody na podstawie ciśnienia atmosferycznego i kierunku wiatru. Zambretti.

Czujnik wilgotności

Do określenia wilgotności względnej powietrza używam modułu DHT11(zakupiony z marketplace) eBay):

Czujnik wilgotności DHT11 posiada trzy wyjścia - moc ( + ), dane ( na zewnątrz), Ziemia ( - ):

wyjście czujnika + na zewnątrz -
wniosek Arduino 5V D10 GND

Do pracy z czujnikiem korzystam z biblioteki z adafruit- akta DHT.h, DHT.cpp.

Wilgotność charakteryzuje ilość pary wodnej zawartej w powietrzu. Wilgotność względna pokazuje proporcję wilgoci w powietrzu (w procentach) w stosunku do maksymalnej możliwej ilości w aktualnej temperaturze. Służy do pomiaru wilgotności względnej :

Dla osoby optymalny zakres wilgotności powietrza wynosi 40 ... 60%.

Zegar czasu rzeczywistego

Jako zegar czasu rzeczywistego zastosowałem moduł RTC DS1302(chusteczka z zegarkiem została zakupiona na targowisku) eBay):

Moduł DS1302 podłączony do autobusu 3 przewody. Aby korzystać z tego modułu z Arduino biblioteka opracowana arduino_RTC( z iarduino.ru).

Płytka z modułem DS1302 ma pięć pinów, które podłączyłem do pinów płytki Arduino Nano:

wniosek RTC VCC GND RST CLK DAT
wniosek Arduino 5V GND D2 D1 D0

Aby zachować prawidłowe wskazania zegara przy wyłączonym zasilaniu włożyłem baterię do gniazda na płytce. CR2032.

Dokładność mojego modułu zegara nie była zbyt wysoka - zegar jest szybszy o około minutę w ciągu czterech dni. Dlatego resetuję minuty do „zera” i godzinę do najbliższej przytrzymując przycisk podłączony do pinu A0 Arduino po włączeniu zasilania stacji pogodowej. Po inicjalizacji pin A0 służy do przesyłania danych przez łącze szeregowe.

Przesyłanie danych do komputera i praca przez protokół MQTT

Aby przesłać dane przez połączenie szeregowe do Arduinołączy USB-UART przetwornik:

Wniosek Arduino służy do przesyłania danych w formacie 8N1(8 bitów danych, bez parzystości, 1 bit stopu) przy 9600 bps. Dane przesyłane są w pakietach, a długość pakietu to 4 znaki. Transfer danych odbywa się w „ trochę huku Tryb ", bez korzystania ze sprzętowego portu szeregowego Arduino.

Format przesyłanych danych:

Parametr 1-szy bajt 2-gi bajt 3 bajt 4-ty bajt
temperatura zewnętrzna o spacja lub minus dziesiątki stopni lub przestrzeni jednostki stopni
temperatura pokojowa i spacja lub minus dziesiątki stopni lub przestrzeni jednostki stopni
Ciśnienie atmosferyczne p setki mm Sztuka. dziesiątki mm Hg jednostki mmHg Z.
wilgotność względna h przestrzeń dziesiątki procent lub spacja jednostki procentowe
Obecny czas dziesiątki godzin jednostki godzin dziesiątki minut jednostki minut

MQTT

golang aplikacja - klient protokołu MQTT, który przesyła informacje otrzymane ze stacji pogodowej na serwer ( MQTT-pośrednik) :

Usługa umożliwia założenie konta z darmowym planem” " (limity: 10 połączeń, 10 Kb/s):

Aby monitorować odczyty stacji pogodowej, możesz użyć Android-Załącznik :

Żywność

Do zasilania stacji pogodowej używam ładowarki ze starego telefonu komórkowego. Motorola, wyprowadzające napięcie 5 V o prądzie do 0,55 A i podłączone do styków 5V(+) i GND (-):

Do zasilania można również użyć baterii 9 V, podłączonej do styków VIN(+) i GND (-).

Obsługa stacji pogodowej

Podczas uruchamiania czujniki są inicjowane i sprawdzane.

W przypadku braku czujnika DS18x20 pojawia się błąd "E1", jeśli nie ma czujnika - błąd "E3".

Następnie rozpoczyna się cykl pracy stacji pogodowej:

  • pomiar i wyświetlanie temperatury zewnętrznej;
  • pomiar i wyświetlanie temperatury pokojowej;
  • pomiar i wyświetlanie ciśnienia atmosferycznego oraz trendu jego zmiany;
  • pomiar i wyświetlanie względnej wilgotności powietrza;
  • wyświetlanie aktualnego czasu;
  • wyświetlanie fazy księżyca i dnia księżycowego.


Film z mojej stacji pogodowej jest dostępny na my -kanał: https://youtu.be/vVLbirO-FVU

Wyświetlacz temperatury

Podczas pomiaru temperatury wyświetlane są dwie cyfry temperatury, a dla temperatury ujemnej znak minus (z symbolem stopni na skrajnej prawej cyfrze);
dla temperatury zewnętrznej znak stopni jest wyświetlany na górze:


dla temperatury pokojowej - poniżej:

Wyświetlacz ciśnienia

Podczas pomiaru ciśnienia wyświetlane są trzy cyfry ciśnienia w mmHg (z symbolem „ P” w skrajnej prawej cyfrze):

Jeśli ciśnienie gwałtownie spadło, zamiast symbolu „ P„znak” jest wyświetlany w skrajnej prawej cyfrze L"jeśli gwałtownie urosło - to" H". Kryterium ostrości zmiany wynosi 8 mm Hg w ciągu 8 godzin:

Ponieważ moja stacja pogodowa wyświetla ciśnienie bezwzględne ( QFE), to odczyty okazują się nieco zaniżone w porównaniu z informacjami zawartymi w podsumowaniu METAR(co zapewnia QNH) (14 UTC 28 marca 2018 r.):

Stosunek ciśnień (zgodnie z ATIS) wyniosło $(1015 \ponad 998) = 1,017 $. Elewacja lotniska Homel (kod ICAO UMGG) nad poziomem morza 143,6 m. Temperatura wg ATIS wynosiła 1° C.

Odczyty mojej stacji pogodowej prawie pokrywały się z ciśnieniem absolutnym QFE według ATIS!

Maks./min. ciśnienie ( QFE) zarejestrowane przez moją stację meteorologiczną z całego okresu obserwacji:

Wskaźnik wilgotności względnej

Wilgotność względna powietrza jest wyświetlana w procentach (symbol procentu jest wyświetlany w dwóch cyfrach po prawej stronie):

Wyświetlanie aktualnego czasu

Aktualny czas jest wyświetlany na wskaźniku w formacie „GG:MM”, ​​z dwukropkiem oddzielającym migającym raz na sekundę:

Wyświetlanie faz księżyca i dnia księżycowego

Pierwsze dwie cyfry wskaźnika wyświetlają aktualną fazę księżyca, a kolejne dwie - aktualny dzień księżycowy:

Księżyc ma osiem faz (podano angielskie i rosyjskie (niebieskie - niedokładne) nazwy):

Na wskaźniku fazy wyświetlane są piktogramy:

faza piktogram
rosnący sierp (półksiężyc)
zanikający półksiężyc (półksiężyc)

Przesyłanie danych do komputera

Jeśli połączysz stację pogodową z USB-UART konwerter (na przykład oparty na mikroukładzie CP2102) połączony z USB-port komputera, wtedy można za pomocą programu terminalowego obserwować dane transmitowane przez stację pogodową:

Opracowałem w języku programowania golang program, który prowadzi dziennik obserwacji meteorologicznych i przesyła dane do serwisu i można go oglądać na Android-smartfon za pomocą aplikacji :

Zgodnie z dziennikiem obserwacji meteorologicznych można np. zbudować wykres zmian ciśnienia atmosferycznego:
przykład wykresu z zauważalnym minimum ciśnienia


przykład wykresu z niewielkim wzrostem ciśnienia

Planowane ulepszenia:

  • dodanie czujników kierunku i prędkości wiatru,

W stacjach pogodowych do pomiaru prędkości wiatru stosuje się anemometr z trzema filiżankami (1), a wiatrowskaz (2) służy do określania kierunku wiatru:

Służy również do pomiaru prędkości wiatru. anemometry z gorącym drutem żarowym(Język angielski) anemometr z gorącym drutem). Jako podgrzewany drut możesz użyć żarnika wolframowego z żarówki z potłuczonym szkłem. W przemysłowych anemometrach z gorącym drutem czujnik jest zwykle umieszczony na rurze teleskopowej:

Zasada działania tego urządzenia polega na tym, że ciepło jest usuwane z elementu grzejnego w wyniku konwekcji przez strumień powietrza - wiatr. W takim przypadku opór żarnika zależy od temperatury żarnika. Prawo zmiany rezystancji żarnika $R_T$ od temperatury $T$ ma postać:
$R_T = R_0 \cdot (1 + (\alpha \cdot (T - T_0)))$ ,
gdzie $R_0$ to opór żarnika w temperaturze $T_0$, $\alpha$ to temperaturowy współczynnik oporu (dla wolframu $\alpha = 4.5\cdot(10^(-3) (^(\circ)(C^ (-1))))$).

Wraz ze zmianą prędkości przepływu powietrza temperatura zmienia się przy stałym prądzie żarzenia (anemometr z prądem stałym, inż. CCA). Jeśli temperatura elementu grzejnego jest utrzymywana na stałym poziomie, prąd przepływający przez element będzie proporcjonalny do prędkości przepływu powietrza (anemometr stałotemperaturowy, inż. CTA).

Ciąg dalszy nastąpi

KATEGORIE

POPULARNE ARTYKUŁY

2022 „kingad.ru” - badanie ultrasonograficzne narządów ludzkich