——- sprostowanie———–
Hej,
Od czasu publikacji tego kursu minęło trochę czasu. Projekt cały czas się rozwija i to co zostało opisane w tym kursie jest już nieaktualne
teraz historyczne dane najlepiej zapisywać w zmiennych, dzięki temu widzimy i aktualną temperaturę, wilgotność ciśnienie i mamy równocześnie podgląd historii.
Przygotowałem szybkie wideo jak to zrobić, wybaczcie że nie napisałem pełnego kursu – zrobię to jak wszystkie inne rzeczy będą gotowe, obecnie pracuję nad nową stroną internetową.
Połączenia opisane w kursie poniżej zostają takie same do zmiany jest kod i strona internetowa. Teraz jest dużo prościej :)
dzięki i powodzenia :)
—– koniec sprostowania —–
Cześć,
Ostatnio na Majsterkowo pojawił się projekt dotyczący stacji pogodowej z wykorzystaniem Wemos’u i RaspberryPi jako serwera.
Ja chciałbym Wam przedstawić inną wersję tego projektu tzn serwer zamiast na Waszym RaspberryPi będzie się znajdował “w chmurze” dla Was oznacza to, że nie potrzebujecie już RaspberryPi. Myśle ze mój projekt spodoba się osobom co RaspberryPi nie mają albo nie mają ochoty/umiejętności/ czasu konfigurować taki serwer na RaspberryPi
Oczywiście decydując się na proponowane przeze mnie rozwiązanie nie macie takiej swobody jak w projekcie wspomnianym wyżej , jednak założenie systemu RemoteMe jest takie żeby jednak dać Wam maksymalną swobodę w programowaniu – Wasze strony html mogą być w pełni przez Was modyfikowane, dostęp do nich macie tylko Wy i osoby którym taki dostęp dacie.
Projekt ten jest podzielony na dwa osobne scenariusze w pierwszym Wasze ESP ( będę w artykule używał również nazwy arduino a oznaczać będzie to po prostu płytkę deweloperską z ESP na pokładzie programowalną przez Arduino IDE ) będzie cały czas uruchomione, a na stronie będziecie mogli odczytać w każdym momencie aktualną temperaturę ciśnienie i wilgotność.
Drugi projekt to ESP co jakiś czas wysyła dane (temperatura wilgotność, ciśnienie ) na serwer do bazy danych, a dane na stronie pojawiają się jako wykres. Po wysłaniu ESP będzie usypiane aż do czasu następnego odczytu. Jednak całość nie nadaje się do zasilania bateryjnego ze względu że takie płytki deweloperskie jednak trochę prądu w stanie deep sleep pobierają (zasilanie modułu serial<-> USB, nie bardzo energoszczedne LDO. Pewnie przygotuje za czas jakiś artykuł jak zrealizować taki projekt do zasilania z baterii)
Dla tych co nie widzieli moich wcześniejszych projektów to słowem wstępu chce zaznaczyć, że od jakiegoś czasu tworzę system ( jedna osoba po godzinach pracy ) remoteme.org jest on przeznaczony dla osób które lubią zabawę z elektroniką, RaspberryPi, arduino i chcą skomunikować swoje urządzenia przez internet. RemoteMe posiada biblioteki które taką komunikację w łatwy sposób realizują, a sam system RemoteMe daje możliwość hostowania Waszych stron w chmurze jak również możliwość zapisu danych do baz danych. Cały system remoteMe.org jest cały czas w wersji beta, więc wskazówki, sugestie itd są jak najbardziej mile widziane, a nawet pożądane :) . A jeżeli ktoś chciałby ten projekt ze mną rozwijać to zapraszam.
Pisząc artykuły na majsterkowo wychodzę z założenia, że osoba chcąca zrobić projekt chce jak najszybciej otrzymać coś działającego, aby się za wcześnie nie zniechęcić. A jak już ma działający projekt to z nim eksperymentować. dlatego nie skupiam się tutaj na opisywaniu jak wszystko działa “pod maską” – zresztą takie było założenie RemoteMe, w artykule znajdziecie opis ciekawszych fragmentów kodu które otwierają drogę do własnych prób . Gdy macie takie pytania chętnie odpowiem w komentarzach.
Zachęcam też do zadawania pytań jak coś jest niejasne :)
Cały kurs znajduję się jako film:
Na filmie pokazuję jedynie kroki jakie należy wykonać żeby otrzymać działające projekty, nie zagłębiam się w to jak to działa (opis fragmentów kodu w tym artykule). zachęcam do odwiedzenia strony https://remoteme.org i zapoznanie się z innymi projektami i dokumentacją systemu
Temperatura ciśnienie i wilgotność na żądanie
Założenia
Dostęp do całego mechanizmu będzie spoza sieci lokalnej, czyli nie będzie problemu odczytać temperaturę z komórki w autobusie.
Żeby odczytać temperaturę stworzymy synchroniczną komunikacje, po wysłaniu wiadomości do naszego ESP w odpowiedzi dostaniemy temperaturę, wilgotność i ciśnienie.
Ogólnie żeby stworzyć tego typu scenariusz musimy mieć dostęp do naszego arduino spoza sieci lokalnej – rozwiązań jest kilka ja pokaże jak to zrobić za pomocą remoteme.org
Jaki efekt chcemy uzyskać
Stronę internetową o takim wyglądzie:
Po załadowaniu strony odczytujemy dane, i podobnie dane są odświeżane po kliknięciu przycisku Refresh.
Elementy
Połączenia
Konfiguracja app.remoteme.org
Konfigurowanie systemu remoteme:
Zanim wrócimy do naszego arduino zarejestrujmy się w systemie i utwórzmy token – którego zadania opisałem wyżej.
Rejestracja
- przejdźmy pod adres klik tutaj
- zakładka Sign Up
- nie podajecie swojego maila więc nie ma możliwości odzyskania hasła – musicie je zapamiętać
- klik SignUp system od razu nas zaloguje
Tworzenie tokenu
Za pomocą tokenu dodanego do programu na arduino, arduino będzie się łączyło do naszego konta.
- Przechodzimy po lewej stronie do zakładki Tokens
- Klikamy New Token, uzupełniamy nazwę (obojętne co wpiszemy ) i klikamy OK
- [3] jest to jedyne pole jakie wypełniacie – nazwy tokenu jest tylko dla nas, nie jest wykorzystywana nigdzie indziej poza wyświetleniem tokenu na liście tokenów.
- Token zostanie utworzony:
- Jak tokenu nie widać odświeżamy stronę.
- w moim przypadku token to “~267_ZxoWtJ)0ph&2c” można go skopiować klikając w niebieską ikonkę
Program na arduino
potrzebne biblioteki:
- WebSockets by Markus Sattler
- ArduinoHttpClient by Arduino
- ESP8266WiFi by Iven Grokhotkov
- SparkFun BME280 by SparkFun Electronics
- RemoteMe libraries by Remoteme.org
- Jak pisze ten kurs biblioteki nie są jeszcze dostępne w repozytorium i należy zainstalować je ręcznie
- ściągnijmy paczkę zip najnowszych bibliotek stąd
- a następnie dodajemy bibliotekę jako zipa:
- i sprawdźmy czy wysztko jest OK:
Właściwy program na arduino tutaj
Myśle że sam program jest dość czytelny, a najważniejszą funkcję onUserSyncMessage opisałem powyżej. Oczywiście musimy uzupełnić nasze stałe:
1 2 3 4 5 |
#define WIFI_NAME "" #define WIFI_PASSWORD "" #define DEVICE_ID 204 #define DEVICE_NAME "temperatureOnRequest" #define TOKEN "" |
Dodatkowo opis działania na dole artykułu
Wgrywamy program na arduino. Po uruchomieniu w zakładce Devices pojawi się nasz ESP:
Strona internetowa
Teraz pora na utworzenie strony internetowej która będzie się łączyła do naszego ESP i pokazywała odczyt.
W zakładce Devcies Wybieramy przycisk New, a następnie “New WebPage”
- Uzupełniamy jak na screenie. Informacja co oznaczają poszczególne pola tutaj.
- Teraz wgrajmy trzy pliki do naszej strony internetowej.
- Pliki do wgrania index.html, script.js and styles.css znajdują się tutaj
- Najprościej jest poprostu przeciągnąć pliki z githuba do naszej strony internetowej, pokazane na filmiku
- Otwarcie strony internetowej: klikamy na plik index.html i wybieramy opcje Open in New Tab. Na nowej zakładce pojawi się nasza strona internetowa gdzie po kliknięciu Refresh temperatura, ciśnienie i wilgotność będzie się nam zmieniała na aktualna
Jak To wszystko działa.
Cała logika znajduję się w plikach script.js i w programie na arduino. Omówmy więc fragmenty:
script.js
1 2 3 4 5 6 7 8 9 10 |
function setup(){ remoteme = new RemoteMe({ automaticlyConnectWS: true, automaticlyConnectWebRTC:false, webSocketConnectionChange: webSocketConnectionChange, webRTCConnectionChange: undefined, mediaConstraints: {'mandatory': {'OfferToReceiveAudio': false, 'OfferToReceiveVideo': false}} }); } |
standardowe ustawienia. Program odrazu się łączy i rejestruje do aplikacji remoteme.org. I ciekawe odwołanie do funkcji
1 |
webSocketConnectionChange: webSocketConnectionChange, |
sama funkcja wygląda tak:
1 2 3 4 5 6 |
function webSocketConnectionChange(state){ if (state==WebsocketConnectingStatusEnum.CONNECTED){ readDataNow(); } } |
czyli po poprawnym połączeniu z remoteme.org program zczytuje dane. Ta sama funkcja readDataNow() jest wywoływana po kliknięciu w przycisk “Refresh”.
Zobaczmy zatem co robi funkcja readDataNow():
1 2 3 |
function readDataNow(){ remoteme.sendUserSyncMessageWebSocket(temperatureArduinoDeviceId,[],onResponse); } |
wysyła ona dane do naszego ESP(dlatego potrzebne jest temperatureArduinoDeviceId które wskaże ID czyli adres naszego ESP u nas jet to 204) jako dane wysyłamy pustą tablice : [], a po przyjściu odpowiedzi ma się wywołać funkcja onResponse.
Przejdźmy zatem do programy na ESP i zobaczmy jak obsługujemy przychodzące synchronicze wiadomości
arduino.ino:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
void onUserSyncMessage(uint16_t senderDeviceId, uint16_t dataSize, uint8_t* data, uint16_t &returnDataSize, uint8_t *&returnData) { uint16_t pos = 0; returnDataSize = sizeOf(float32)*3; returnData = (uint8_t*)malloc(returnDataSize); RemoteMeMessagesUtils::putFloat(returnData,pos, (mySensor.readTempC())); RemoteMeMessagesUtils::putFloat(returnData, pos, (mySensor.readFloatPressure() )); RemoteMeMessagesUtils::putFloat(returnData, pos, (mySensor.readFloatHumidity() )); } |
ta funkcja zostanie wywołana gdy nadejdzie wiadomość z script.js parametry:
- senderDeviceId – id naszej storny internetowej
- dataSize – jak duzo danych wysyłą nasz script.js ponieważ wysłałiśmy pusta tablice będzie tutaj 0
- data – dane jakie wysł script.js u nas nic tu nie będzie
- returnDataSize – tutaj wpiszemy ile bajtów wyślemy jako odpowiedź – my wysyłamy 12 bo mamy trzy odczyty, a każdy zapisujemy we floatcie który ma 4 bajty
- returnData – tutaj zapiszemy zwrócone liczby
-
123456returnData = (uint8_t*)malloc(returnDataSize);RemoteMeMessagesUtils::putFloat(returnData,pos, (mySensor.readTempC()));RemoteMeMessagesUtils::putFloat(returnData, pos, (mySensor.readFloatPressure() ));RemoteMeMessagesUtils::putFloat(returnData, pos, (mySensor.readFloatHumidity() ));
korzystając z funkcji putFloat wpisujemy do wyjściowej tablicy po kolei trzy odczyty (pos jest za każdym razem powieszany o liczbę bajtów wpisanych do tablicy). Więc po wyjściu z funkcji mamy zapisaną tablice bajtów gdzie po kolei zapisane są liczby : temperatura, ciśnienie i wilgotność. Jak widzicie nie korzystamy nigdzie z danych które wysłał nam script.js dlatego wysyłamy pustą tablice
Wróćmy do pliku script.js i do odczytu tych wartośći:
script.js
1 2 3 4 5 6 7 8 9 10 11 12 |
function onResponse(output){ var data = new RemoteMeData(output); var temp = data.popFloat32(); var pressure = data.popFloat32(); var humm = data.popFloat32(); $("#tempOut").html(temp.toFixed(2)+" C"); $("#pressOut").html((pressure/100).toFixed(2)+" hPa"); $("#hummOut").html(humm.toFixed(2)+" %"); } |
funkcją popFloat32 pobieramy po koleij trzy pwisane liczby i po odpowiednim sformatowaniu wyświetlamy przy pomocy jquery w odpowiednie elementy.
Temperatura ciśnienie i wilgotność zapisywane na serwer i wyświetlane na wykresie
Tym razem niechcemy odczytywać temperatury na życzenie ale zapisywać odczyty co jakiś czas (w przykładzie 5minut) zapisać na serwer i mieć do nich dostęp w formie wykresu.
Zasada działania
ESP co jakiś czas wybudza się z trybu deepSleep odczytuje dane z GY-BME280 i zapisuje je na serwer,żeby potem znowu usnąć i wybudzić sie za czas jakiś, i tak w kółko.
Oczywiście nie potrzebujecie własnej bazy danych – remoteme.org udostępnia funkcje do zapisu danych do chmury -a za pomocą dostarczonego API odczyt ich
Wykres jaki uzyskamy:
Połączenia
Prawie identyczne jak w projekcie do odczytu na żądanie, róznica to zielony przewód – pozwala on na samowybudzanie się układu – zainteresowanych zachęcam do zapoznania się z trybem deepSleep
Kod źródłowy
Po prostu wgrajmy do remoteme.org i na nasze arduino pamiętając o wprowadzeniu danych do łączenia się z siecią wifi i tokenu. Wszystko analogicznie jak w poprzednim przykładzie.
Opis ciekawszych framgnetów kodu
arduino:
odczyt temperatury:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
double temp[10]; double pressure[10]; double humm[10]; for(int i=0;i<9;i++){ temp[i]= mySensor.readTempC(); pressure[i]= mySensor.readFloatPressure(); humm[i]= mySensor.readFloatHumidity(); delay(100); } sort(temp,10); sort(humm,10); sort(pressure,10); |
Wykonujemy 9 pomiarów w odstępnie 100ms, a nastęnie sortujemy, żęby na serwer wysłać mediane – pozwoli to na pozbycie się błędnych danych – czasem nasz czujnik zwraca dziwne wartości
1 2 3 |
remoteMe.sendAddDataMessage(1, RemotemeStructures::_5M, 0, temp[5]); remoteMe.sendAddDataMessage(2, RemotemeStructures::_5M, 0, pressure[5]); remoteMe.sendAddDataMessage(3, RemotemeStructures::_5M, 0,humm[5]) |
funkcje po kolei zapisuja na serwer dane pod numerami 1,2,3 (pierwszy parametr). Obrazowo dane będa zapisywane do różnych tabel do tabeli pierwszej trafi temperatura itd.
Drugi parametr wkazuje zaokraglenie czasu ustawione jest na 5minut, oznacza to ze jezeli wyślemy dane 03.06.2018 18:41:23 po stronie serwera zostanie to zapisane z czasem 03.06.2018 18:40:00. Dzięki temu zaokrągleniu po stronie serwera dane będą się lepiej układać na wykresie ( dostępne są inne zaokraglenia lub możemy wogole nie zaokrąglać (szczegóły w dokumentacji))
ostani parametr – np temp[5] to mediana odczytanych temperatur.
po dokonaniu pomiarów ESP usypia się na 4minuty
1 |
ESP.deepSleep(1e6*60*4);//4min |
jeżeli było by to dokładnie 5minut to ponieważ obudzenie się ESP i wysłanie czasu na serwer trochę trwa ( ja założyłem że nie więcej niż 1minute) mielibyśmy po jakimś czasie braki na naszym wykresie
script.js
Najciekawszym momentem to odebranie danych i wyświetleniem ich na wykresie.
1 2 3 4 5 6 7 8 9 |
function createChart(){ var yestarday=moment().subtract(1, 'days').format("DD.MM.YYYY HH:mm"); var now=moment().format("DD.MM.YYYY HH:mm"); var url =`/api/rest/v1/data/get/dd.MM.yyyy HH:mm/${yestarday}/${now}/1,2,3/`; $.get(url, function(data, status){ |
aplikacje udostępnia nasze dane pod linkiem
( dokumentacja całego REST Api aplikacji remoteme w tym linku )
1 |
/api/rest/v1/data/get/{FORMAT}/{FROM}/{TO}/{SERIES ids}/ |
link zwroci nam dane dla series podanych w parametrze {SERIES ids} używając formatu czasu podanym w {FORMAT} z przedziału [ {FROM} – {TO} [ i zwróci dane w psotaci jsona
w naszym przykładzie javascript wygeneruje linka:
1 |
http://app.remoteme.org/api/rest/v1/data/get/dd.MM.yyyy HH:mm/02.06.2018 18:53/03.06.2018 18:53/1,2,3/ |
dane pobieramy – na jeden dzień do tyłu – zachęcam do rozbudowania ;)
Sprawdźmy co znajduję się pod wskazanym linkiem ( ograniczyłem w danych czas do 20minut)
“dataSeriesId” to id naszych danych czyli w 1 będzie temperatura ponieważ w arduino jest:
1 |
remoteMe.sendAddDataMessage(1, RemotemeStructures::_5M, 0, temp[5]); |
a pierwszy parametr czyli 1 oznacza “zapisz moje dane do dataseriesID =1 “
ponieważ w linku ostanim paramtrem jest 1,2,3 pobieramy za jednym zamchem temperature, ciśnienie i wilgotność.
Tak pobranego jsona plotly wyświetla w postaci wykresu . Żeby zobaczyć jak wykres jest konfigurowany zachęcam do sprawdzenia funkcji createChart i sprawdzeniu dokumentacji plotly.
Żeby zobaczyć wykre należy otworzyć plik index.html identycznie jak w przykładzie poprzednim.
Podgląd naszych danych
w zakładce Series możemy zobaczyć jakie dane mamy zapisane w systemie.
Zachęcam do zapoznania się z dokumentacją , gdzie szczegółowo opisane są funkcje z których korzystaliśmy.
Pozdrawiam,
Maciek
Dziękuję. Bardzo fajny artykuł. Przyda się do ewentualnych modernizacji czy też rozbudowy własnej stacji.
Dziekuję, gdyby były jakieś problemy sluze pomocą, jakby czegos brakowalo to tez moge dorobic :)
Ja omijam wszystkich takich dostawców. Dziś serwis jest, a jutro się zwija. Już wolę te odczyty zapisywać na malinie, albo w jakimś hostingu.
Trochę racji w tym co piszesz jest. Przykładem są choćby najwięksi – Thingspeak.com był kiedyś darmowy, a aktualnie darmowe konta są delikatnie mówiąc trochę upośledzone.
Ale dobrze, że Maciej_85 opublikował taki projekt – czytelnicy mają wybór, a przy okazji więcej przykładów do nauki (z czego ja sam korzystam).
Jasne rozumiem, ważna jest społeczność zbudowana wokół danego projektu. Dlatego też pisze artykuły i zachęcam Was do korzystania
Dzięki. Wszystko super opisane. Szukałem czegoś takiego do budowy własnej stacji.
Hej, zmieniłem parę rzeczy w systemie (a w sumie to dość sporo ;) ), teraz jest prościej, zamieściłem na górze artykułu sprostowanie
Witam. Zrobiłem kilka dni temu testową stronę w oparciu o ten poradnik. Na razie tylko zapisują dane o jednej temperaturze. Działa poprawnie zgodnie z moimi oczekiwaniami. Czy jest możliwość dodania do takiej bazy starszych danych ? Mam kilkumiesięczne dane z 5 czujników zapisane w bazie SQL. Chciałem cały projekt przenieść na tę stroną wraz z importem wszystkich danych.
hmm ciekawy pomysł :) > Planuje odswiezenie artykułu o nowe funkcję bo system się trochę rozwinął i dodam opcje importu. Dzięki
Pingback: Pomiar temperatury, ciśnienia i wilgotności z BME280 do aplikacji na smartphonie » Arduino, Elektronika, ESP8266 » poradnik zrób to sam na Majsterkowo.pl
Witam, super projekt.
Jestem zielony w temacie ale ten art. wiele mi wyjaśnił.
Mam pytanie czy można by dopisać funkcję alarmu po przekroczeniu ( w dół lub górę) temperatury?
Pozdrawiam
czesc, fajny projekt, nie robilem wczesniej nic na arduino, i tutaj moje pytania.
dodam ,ze chce pomiar cieczy zrobić wiec sondy jakies musze zrobic
pozdrawiam