Witam wszystkich majsterkowiczów,
dzisiaj chciałbym zaprezentować wam jak zrobić internetową stację meteorologiczną, dzięki której będziemy mogli sprawdzić aktualną temperaturę w naszym domu i za oknem, ciśnienie oraz sumę opadów, z każdego miejsca w którym mamy dostęp do internetu.
Jest to mój pierwszy artykuł na Majsterkowie i pierwszy projekt na Arduino. Jeżeli zauważycie jakiekolwiek błędy piszcie w komentarzach, to poprawię artykuł. ;)
Co nam będzie potrzebne?
• Arduino, w moim przypadku Leonardo
• Moduł sieciowy ENC28J60
• Czujnik temperatury DS18b20, w moim przypadku 2 sztuki
• Czujnik opadów deszczu YL-83
• Publiczne IP
Biblioteki:
• etherShield
• ETHER_28J60
• OneWire
• DS18B20.
• Wire
• DallasTemperature
• BMP180
Od czego zacząć?
Na początku trzeba wszystko podłączyć tak jak na schemacie poniżej.
Następnie wgrywamy kod do naszego Arduino, jeżeli chcemy zmienić IP naszego komunikatora na dostępny w naszej sieci, zmieniamy go w wyznaczonej linijce kodu.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
// By Jakub Dorawa #include "etherShield.h" #include "ETHER_28J60.h" #include <OneWire.h> #include <DS18B20.h> #include <Wire.h> #include <DallasTemperature.h> OneWire linia_danych(9); // pin pod, który podłączyliśmy nasze czujniki temperatury (w moim przypadku pin 9) DallasTemperature czujnik(&linia_danych); #include <BMP180.h> // dodanie bibliotek BMP180 barometer; int indicatorLed = 13; float seaLevelPressure = 99400; // sprawdzamy jakie jest aktualne ciśnienie dla naszej lokalizacji, miasta (w moim przypadku 994 hPa) static uint8_t mac[6] = {0x54, 0x55, 0x58, 0x10, 0x00, 0x24}; // tutaj możemy zmienić adres mac static uint8_t ip[4] = {192, 168, 0, 185}; // tutaj możemy zmienić adres ip naszego komunikatora static uint16_t port = 80; ETHER_28J60 ethernet; void setup() { ethernet.setup(mac, ip, port); Serial.begin(9600); ethernet.print("%"); delay(500); // opoźnienie czujnik.begin(); // uruchamiamy bibliotekę Wire.begin(); pinMode(indicatorLed, OUTPUT); barometer = BMP180(); { barometer.SoftReset(); barometer.Initialize(); } } void loop() { if (ethernet.serviceRequest()) { ethernet.print("<center><H1>Stacja pogodowa</H1></center>"); czujnik.requestTemperatures(); // wysłanie polecenia pobrania temperatury ethernet.print("Temperatura za oknem:"); ethernet.print(czujnik.getTempCByIndex(1)); // wysyłanie temperatury z czujnika nr. 1 (w moim przypadku znajdującym się za oknem) ethernet.print(" 'C"); ethernet.print("\r\n"); ethernet.print("<br />"); // przeniesienie do następnej linii ethernet.print("Temperatura w pokoju:"); ethernet.print(czujnik.getTempCByIndex(0)); // wysyłanie temperatury z czujnika nr. 2 (w moim przypadku znajdującym się w pokoju) ethernet.print(" 'C"); ethernet.print("<br />"); int sensorA = analogRead(A0); int sensorD = digitalRead(12); ethernet.print("Opady:"); int opady =map (sensorA,1023,0,0,100); ethernet.print(opady); ethernet.print(" % "); ethernet.print("<br />"); long currentPressure = barometer.GetPressure(); // Print out the Pressure. ethernet.print("Cisnienie: "); ethernet.print(currentPressure/100); ethernet.print(" hPa"); ethernet.print("<br />"); // Retrive the current altitude (in meters). Current Sea Level Pressure is required for this. float altitude = barometer.GetAltitude(seaLevelPressure); // Retrive the current temperature in degrees celcius. float currentTemperature = barometer.GetTemperature(); ethernet.print("Temperatura: "); // temperatura, z BMP180 ethernet.print(currentTemperature); ethernet.print(" 'C"); ethernet.print("<br />"); ethernet.print("<center><H8>Jakub D.</H8></center>"); ethernet.respond(); } delay(100); //100 } |
Podłączamy teraz nasz moduł sieciowy do sieci. Aby sprawdzić czy wszystko działa lokalnie czyli w naszej sieci, wpisujemy ustawiony adres IP do paska adresu naszej przeglądarki.
Aby można było korzystać z naszej stacji spoza sieci lokalnej, musimy przekierować porty, i skonfigurować router z publicznym IP, czyli DDNS, jeżeli nie wiemy czy mamy publiczne IP wystarczyć wejść w link poniżej.
Jak to zrobić można zobaczyć w internecie, zależy od routera. Jeżeli już przekierujemy port na 80, i będziemy posiadali publiczne IP możemy sprawdzić aktualne dane z naszych czujników spoza sieci lokalnej, po wpisaniu zewnętrznego IP w pasek adresu przeglądarki.
Tutaj możemy sprawdzić nasz publiczny/zewnętrzny adres IP.
Dane z czujników są wyświetlane ” w całościach”, PHP nie wyświetla reszty po przecinku, nie doszedłem do tego jak to zrobić.
Za ewentualne błędy przepraszam, jest to mój pierwszy projekt na Arduino, i artykuł na Majsterkowie.
W razie sugestii i pytań proszę pisać w komentarzach. Dziękuje, Pozdrawiam :)
Bardzo lubię wszystkie projekty związane z Arduino, więc daję 5
Dzięki! :D
Ja też daję 5, bo lubię kiedy ktoś czerwonym przewodem prowadzi VCC, a czarnym GND.
Mam nadzieję, że nabierzesz rozsądku do czasu kiedy otrzymasz prawo do głosowania w tym kraju.
Nadzieja, nadzieja, czyja to matka? Jak to mówią … ona zawsze umiera ostatnia, więc żyj długo inż. Zawodny
PS.
Nie wiem w jakim celu skierowałeś ten komentarz w moją stronę, ale w kaszę nie dam sobie dmuchać.
Na rysunku z Fritzinga jest “kompaktor”. Co to jest?
Taki “konwerter”.
To jest efekt końcowy? Na pająka ? Nie boisz się ze się rozpadnie ? Gdzie jest jakaś obudowa ?
Dla mnie słabiutko. Czekam na kolejna cześć projektu, bo mam nadzieje, że to nie jest koniec.
Nie rozpadnie się, planuję to przenieść na Atmegę i płytkę uniwersalną, w obudowie tego nie umieściłem, bo chcę to rozbudować. ;)
do czego używasz zmiennej altitude ? bo chyba nie jest to potrzebne – czyli poziom ciśnienia seaLevelPressure też nie jest potrzebny… ??
float altitude = barometer.GetAltitude(seaLevelPressure);
Autor oblicza wysokość npm zakładając ciśnienie poziomu morza:
“float seaLevelPressure = 99400;”
Kubaa
Poza tym prognozy pogody nie podają ciśnienia bezwzględnego ale to na poziomie morza
///////////////SealevelPressure
float cisnieniePoziomuMorza = (barometr.readSealevelPressure(260) / 100);
-gdzie 260 to wysokość npm w metrach dla Twojej stacji.
// Print out the Pressure.
ethernet.print(“Cisnienie: “);
ethernet.print(cisnieniePoziomuMorza);
Poza tym, proponuję używać w miarę możliwości czujników AMS3202 (DHT22) ponieważ oprócz temp. bezwzględnej dają także odczyt temp. odczuwalnej (heatIndex).
Możesz zerknąć na mój kod
Dzięki ;)
Aktualnie dane przesyłane są na Thingspeak, tutaj można podejrzeć: https://thingspeak.com/channels/220990
Wysyłam na “hosting”, bo jedna domena na IP już jest, a serwera żeby mieć 2 IP nie mam,.
Myślałem nad wysyłaniem na jakiś zewnętrzny serwer i podłączenie tego pod domenę.
Witaj, podeślesz bibliotekę ETHER_28j60 ? Bo mam problemy z tą która udało mi się znaleźć.
po co termometry, skoro w bmp180 jest termometr?
Dokładność termometru wbudowanego w BMP180 to ok +- 2 C a dokładność DS18B20 to +- 1 C.
Dodatkowo odczyt z DS18B20 tak nie skacze jak z BMP180.
Ta decyzja ma więc jak najbardziej sens.