Napisano dnia 25.01.2019 r. o godzinie 20:52
Autor: Piotr Sperka
W ostatnim czasie, a dokładnie niedługo przed końcem 2018 roku, zainteresowałem się dostępnymi tanimi sensorami pozwalającymi na pomiar zapylenia powietrza. W niedługim czasie z tego zainteresowania wyniknął układ, pozwalający mierzyć zapylenie powietrza, a także temperaturę, wilgotność oraz ciśnienie atmosferyczne. Jako, że nie dysponuję dużą ilością wolnego czasu, postanowiłem urządzenie zrealizować w formie projektu na jeden, góra dwa weekendy, składającego się w dużej mierze z gotowych modułów. Dzięki temu taki układ może zbudować niemal każdy, kto dysponuje podstawowymi narzędziami i nawet niewielkimi umiejętnościami z zakresu elektroniki. Zapraszam do lektury tego krótkiego opisu, w którym postaram się przybliżyć Wam działanie urządzenia.
Po szybkim przejrzeniu dostępnych w handlu modułów, swoje urządzenie postanowiłem oprzeć o znany mi moduł ESP8266 (ESP-12), a także czujniki:
Czujnik zapylenia komunikuje się w oparciu o UART, BMP280 wykorzystuje I²C, natomiast DTH22 działa z wykorzystaniem protokołu nieco podobnego do 1-Wire. Ponieważ układ ESP8266 wykorzystuje swój sprzętowy UART do programowania, do sterowania sensorem PMS5003 postanowiłem wykorzystać programowy UART. Po krótkiej analizie dostępnych wyjść oraz wejść w ESP, doszedłem do następującego schematu połączeń:
Do zasilania układu postanowiłem wykorzystać zasilacz wtyczkowy 12V oraz moduł przetwornicy opartej o klon LM2596, która wytwarza 5V potrzebne do zasilania PMS5003. Do zasilenia pozostałych elementów wykorzystałem napięcie 3,3V, które zapewnia stabilizator LD1117 zamontowany na płytce pod ESP-12. Tutaj uwaga dla wszystkich, którzy chcieliby powielić ten układ – należy dokładnie zweryfikować połączenia na płytce, gdyż moja była przystosowana do innego (rzadziej spotykanego) stabilizatora, o inaczej rozlokowanych wyprowadzeniach. Ale nie było to nic, czego nie można było poprawić nożykiem i drutem.
Ponieważ urządzenie to nie miało być komercyjnym rozwiązaniem, a jedynie weekendowym projektem, postanowiłem znacząco ułatwić sobie pracę i wykorzystać… Arduino dla ESP8266. Prawdę mówiąc, byłem mocno zdziwiony, że takie coś istnieje. Arduino zawsze kojarzyło mi się nieodłącznie z płytkami z mikrokontrolerami AVR. Jednak takie rozwiązanie nie tylko istnieje, ale jak się okazało działa całkiem sprawnie i skutecznie. Jego dodatkową wielką zaletą są również dostępne biblioteki, które w zasadzie zwalniają z konieczności pisania programu do obsługi zewnętrznych czujników.
Obsługa czujników, choć jest w pewnym sensie najważniejszą częścią tego projektu, była najprostsza do zrealizowania. Wystarczyło bowiem wykorzystać kilka gotowych bibliotek dostępnych dla Arduino:
Wymyśliłem sobie, że dobrze by było zapisywać czas, kiedy zostały zaktualizowane dane z konkretnego czujnika. Jest to tym bardziej istotne, że dane z czujnika zapylenia pobierane są rzadziej niż z pozostałych. Pojawił się wtedy problem: skąd brać aktualny czas? Ponieważ ESP8266 nie posiada zegara z podtrzymaniem (ani w ogóle żadnego dedykowanego zegara RTC), postanowiłem wykorzystać do tego milisekundowy timer dostępny w Arduino (funkcja millis()), synchronizowany co godzinę do serwera czasu NTP. Po krótkich poszukiwaniach okazało się, że NTP działa w oparciu o protokół UDP, i tak naprawdę jest całkiem prosty w obsłudze. Dla zainteresowanych – obsługa czasu jest zrealizowana w funkcji getTimeFromNtp().
Postanowiłem, że dane z czujników będą zapisywane w bazie danych. Jest to wygodne z kilku powodów, chociażby dlatego, że będę posiadał historię danych z dłuższego czasu, a także będę miał możliwość prezentacji danych na żywo w internecie. Bazę danych (MySQL) postanowiłem umieścić na zewnętrznym serwerze, tak, by była dostępna z internetu. Aby uprościć sobie zadanie wysyłania danych z ESP do serwera, na serwerze stworzyłem skrypt w PHP. Skrypt ten dokonuje autoryzacji zapytania poprzez ustawione hasło i przyjmuje dane do zapisania w bazie w formacie JSON. Wychodzi więc na to, że po stronie ESP jest jedynie zebranie danych do JSONa i wysłanie ich wraz z hasłem do ustawionego adresu poprzez POST. Resztą, czyli parsowaniem danych i umieszczeniem ich w bazie zajmuje się skrypt.
Dane mogą być zaprezentowane użytkownikowi na dwa sposoby. Pierwszy z nich polega na podłączeniu się poprzez przeglądarkę internetową na adres naszego urządzenia. Ma on jednak wady – prezentowane są dane jedynie z ostatniego odczytu, oraz w większości przypadków z urządzeniem możemy połączyć się tylko z naszej sieci lokalnej. Dlatego umożliwiłem również podgląd danych poprzez prostą stronę internetową. W tym celu pobierane są dane z bazy danych, odpowiednio obrabiane i prezentowane w formie wykresów użytkownikowi.
Pierwszym problemem, na jaki możemy się natknąć po uruchomieniu urządzenia, jest wprowadzenie danych do połączenia WiFi. Żeby uniknąć zapisywania danych w kodzie, konieczności łączenia się przez UART, albo innych nieeleganckich metod, wykorzystałem bibliotekę WifiManager. Biblioteka ta próbuje połączyć się z ostatnio zapisaną siecią. Jeżeli takiej nie ma, albo łączenie się nie powiodło, urządzenie przełącza się w tryb WiFi AP. Wtedy wystarczy podłączyć się do niego na przykład smartfonem i wprowadzić dane do połączenia. Urządzenie zresetuje się i połączy z naszą siecią. Aby ułatwić sobie aktualizację oprogramowania w urządzeniu bez jego rozkręcania, wykorzystałem moduł ESP8266HTTPUpdateServer umożliwiający aktualizację OTA, czyli przez WiFi. Dodatkowo na urządzeniu działa również serwer mDNS, dzięki któremu nie musimy znać IP urządzenia. Na kompatybilnym urządzeniu (na Windowsie trzeba doinstalować Bonjour) wystarczy wejść na adres powietrze.local i ukaże nam się strona urządzenia.
Ogółem, poza wspomnianymi wcześniej, wykorzystałem jeszcze biblioteki:
Urządzenie postanowiłem umieścić w wodoszczelnej obudowie Z54JS. Do odbudowy wymodelowałem i wydrukowałem w 3D dodatkowe elementy: osłonę dla czujnika zapylenia, „komin” na pozostałe czujniki, a także różnorakie elementy montażowe.
Projekt udało mi się ukończyć prawie zgodnie z założeniami, w niewiele ponad dwa weekendy, oczywiście nie pracując non-stop. Urządzenie działa już od ponad miesiąca i nie sprawia żadnych problemów. Jedyne wątpliwości jakie mam to dokładność odczytów temperatury. Mam wrażenie, że są one nieco zawyżone (a dokładniej o około 3ºC). Możliwe, że powoduje to umiejscowienie czujnika relatywnie blisko reszty układu (który się przecież nagrzewa). Muszę zweryfikować to, gdy będę miał trochę wolnego czasu. Jeżeli ktokolwiek jest tym zainteresowany, można podejrzeć odczyty pod adresem http://powietrze.piotrsperka.info.
Kody źródłowe wraz z projektem (Visual Studio Code z PlatformIO), a także schemat i modele STL można znaleźć na moim GitHubie – dokładnie TUTAJ.