Bardzo tani bezprzewodowy pomiar temperatury z odczytem przez www
Ciągły postęp techniczny pozwala nam na automatyzację wielu procesów dnia codziennego. Sterowanie, zbieranie danych, przetwarzanie jest w zasięgu ręki każdego z nas. Elektronika jest już bardzo tania, a oprogramowanie często darmowe. Tylko korzystać. Poniżej opiszę układ za kilkanaście złotych, składający się z bezprzewodowego modułu ESP-01, który mierzy temperaturę za pomocą czujnika DS18B20, a dane wysyła na platformę ThingSpeak.com, gdzie możemy je gromadzić, obrabiać i wyświetlać.
Thingspeak.com
Do zbierania i wyświetlania danych przez www, wykorzystamy stronę thingspeak.com. Na początek – założenie konta, następnie dodanie i konfiguracja kanału – zielony przycisk New Channel:
Teraz ustawienia, nazwa, opis itd. Ważna część, to zaznaczenie ilości pól – ja na jednym kanale będę mierzył jedną wartość – temperaturę, więc ptaszkuję Field 1. Jeśli kanał ma być widoczny dla wszystkich, trzeba zaznaczyć Make Public:
Po zapisaniu, mamy nasz pierwszy box, jeszcze bez danych:
Nadszedł czas na zasilanie naszego kanału danymi.
ESP-01 z obsługą DS18B20 i Thingspeak.com
Hardware wysyłający dane na nasz kanał w serwisie thingspeak.com jest dość prosty. Ja swój układ zbudowałem na płytce stykowej z użyciem modułu ESP-01 z adapterem, płytki zasilającej ustawionej na 3,3V i cyfrowego czujnika temperatury DS18B20. Poglądowo wygląda to tak:
Czyli VCC i CH_PD podłączone pod zasilanie 3,3V, GND do masy, GPIO0 do pinu DQ czujnika DS18B20. Tradycyjnie ten pin został podciągnięty do zasilania rezystorem 3,3kΩ…4,7kΩ. Zdjęcie układu:
Mając sprzęt, można zabrać się za oprogramowanie. Mój soft to tak naprawdę zlepek kodów znalezionych w sieci. Działa co prawda właściwie, ale przydałoby się go bardziej uporządkować. Całość składa się z 3 plików: init.lua, gettemp.lua i ds18b20.lua. Wgrywamy je w odwrotnej kolejności, czyli zaczynając od ds18b20.lua. W ESP-01 miałem wgrane nodemcu_float_0.9.6-dev_20150704.bin. Pod kodami źródłowymi znajdziesz link do pobrania całości.
Kod init.lua:
FileToExecute="gettemp.lua" l = file.list(); for k,v in pairs(l) do if k == FileToExecute then print("*** You've got 3 sec to stop timer 0 ***") tmr.alarm(0, 3000, 0, function() print("Executing ".. FileToExecute) dofile(FileToExecute) end) end end
kod gettemp.lua:
--Connecting to network wifi.setmode(wifi.STATION) wifi.sta.config("nazwa_sieci","haslo_do_sieci") wifi.sta.connect() gpio0 = 3 -- ustawiamy gpio na ktorym mamy ds18b20 na naszej plytce GPIO0 require('ds18b20') ds18b20.setup(gpio0) ds18b20.read() function SendData() t1=ds18b20.read() print("Temp:"..t1.." C\n") --conection to thingspeak.com print("Sending data to thingspeak.com") conn=net.createConnection(net.TCP, 0) conn:on("receive", function(conn, payload) print(payload) end) --api.thingspeak.com 184.106.153.149 conn:connect(80,'184.106.153.149') conn:send("GET /update?key=THINGSPEAK_WRITE_API_KEY&field1="..t1.." HTTP/1.1\r\n") conn:send("Host: api.thingspeak.com\r\n") conn:send("Accept: */*\r\n") conn:send("User-Agent: Mozilla/4.0 (compatible; esp8266 Lua; Windows NT 5.1)\r\n") conn:send("\r\n") conn:on("sent",function(conn) print("Closing connection") conn:close() end) conn:on("disconnection", function(conn) print("Got disconnection...") end) end -------- Main Loop ----- tmr.alarm(0, 600000, 1, function() tmr.alarm(1, 1000, 1, function() if (wifi.sta.getip() == nil) then print("Connecting to Network...") else tmr.stop(1) print("Connected (ip: ".. wifi.sta.getip() ..")") SendData() end end) end)
kod ds18b20.lua:
-------------------------------------------------------------------------------- -- DS18B20 one wire module for NODEMCU -- NODEMCU TEAM -- LICENCE: http://opensource.org/licenses/MIT -- Vowstar <[email protected]> -- 2015/02/14 sza2 <[email protected]> Fix for negative values -------------------------------------------------------------------------------- -- Set module name as parameter of require local modname = ... local M = {} _G[modname] = M -------------------------------------------------------------------------------- -- Local used variables -------------------------------------------------------------------------------- -- DS18B20 dq pin local pin = nil -- DS18B20 default pin local defaultPin = 9 -------------------------------------------------------------------------------- -- Local used modules -------------------------------------------------------------------------------- -- Table module local table = table -- String module local string = string -- One wire module local ow = ow -- Timer module local tmr = tmr -- Limited to local environment setfenv(1,M) -------------------------------------------------------------------------------- -- Implementation -------------------------------------------------------------------------------- C = 0 F = 1 K = 2 function setup(dq) pin = dq if(pin == nil) then pin = defaultPin end ow.setup(pin) end function addrs() setup(pin) tbl = {} ow.reset_search(pin) repeat addr = ow.search(pin) if(addr ~= nil) then table.insert(tbl, addr) end tmr.wdclr() until (addr == nil) ow.reset_search(pin) return tbl end function readNumber(addr, unit) result = nil setup(pin) flag = false if(addr == nil) then ow.reset_search(pin) count = 0 repeat count = count + 1 addr = ow.search(pin) tmr.wdclr() until((addr ~= nil) or (count > 100)) ow.reset_search(pin) end if(addr == nil) then return result end crc = ow.crc8(string.sub(addr,1,7)) if (crc == addr:byte(8)) then if ((addr:byte(1) == 0x10) or (addr:byte(1) == 0x28)) then -- print("Device is a DS18S20 family device.") ow.reset(pin) ow.select(pin, addr) ow.write(pin, 0x44, 1) -- tmr.delay(1000000) present = ow.reset(pin) ow.select(pin, addr) ow.write(pin,0xBE,1) -- print("P="..present) data = nil data = string.char(ow.read(pin)) for i = 1, 8 do data = data .. string.char(ow.read(pin)) end -- print(data:byte(1,9)) crc = ow.crc8(string.sub(data,1,8)) -- print("CRC="..crc) if (crc == data:byte(9)) then t = (data:byte(1) + data:byte(2) * 256) if (t > 32767) then t = t - 65536 end if (addr:byte(1) == 0x28) then t = t * 625 -- DS18B20, 4 fractional bits else t = t * 5000 -- DS18S20, 1 fractional bit end if(unit == nil or unit == 'C') then -- do nothing elseif(unit == 'F') then t = t * 1.8 + 320000 elseif(unit == 'K') then t = t + 2731500 else return nil end t = t / 10000 return t end tmr.wdclr() else -- print("Device family is not recognized.") end else -- print("CRC is not valid!") end return result end function read(addr, unit) t = readNumber(addr, unit) if (t == nil) then return nil else return t end end -- Return module table return M
W pliku gettemp.lua należy wprowadzić swoją nazwę sieci i hasło do niej (3 linijka) oraz Write API Key pobrany z naszego kanału na stronie thingspeak.com z zakładki API Keys (23 linijka). Całość do pobrania:
>> POBIERZ Firmware NodeMcu i kod z obsługą ds18b20 i thingspeak.com
Dokładne opisy co, jak i czym wgrać znajdziesz tutaj: http://grylewicz.pl/tag/esp8266/.
Jak działa program? Tradycyjnie wykonywanie kodu zaczyna się od init.lua, po 3 sekundach zwłoki (przydatne do programowania czy czyszczenia flasha) układ przechodzi do gettemp.lua gdzie w pętli głównej co 10 minut (600000 milisekund) sprawdza czy układ pobrał IP, jeśli tak, to wywołuje funkcję SendData() w której wykonywany jest odczyt temperatury, połączenie z thingspeak.com i wysłanie danych do naszego kanału.
Dane w thingspeak.com
Jeśli wszystko zostało prawidłowo wykonane, co 10 minut na nasz kanał trafia zmierzona temperatura, która tworzy wykres. Sposób wyświetlania, formatowanie, kolory można ustawić, klikając na środkową ikonę pisaka na belce naszego wykresu:
Thingspeak.com posiada możliwości dodawania wtyczek-aplikacji, np. google gauges, mapę z lokalizacją czujnika czy wizualizacje i obróbkę danych stworzonych za pomocą silnika matlaba. Ja na swój kanał wrzuciłem google gauges i mapkę:
Możliwości konfiguracji i obróbki danych są spore. Za sprawą thingspeak.com i malutkiej płytki ESP-01 otrzymaliśmy praktyczny układ za kilkanaście złotych. Jeszcze niedawno urządzenie o zbliżonej funkcjonalności oparłem na terminalu HP T5720, później na BananaPi, teraz wystarczy moduł z ESP8266…
Ja tam arduino polecam, nodemcu mało że dużo miejsca zajmuje to działa niestabilnie mój esp07 bardzo często zwiechy zaliczał a o wgraniu dodatkowych bibliotek można zapomnieć zaraz się miejsce kończy
Po pierwsze to nie ESP 01 jest do takich zadań, a 12 i 13 bo ma ADC, co daje. Po drugie ORIDEITH, sprawdzileś co piszesz? Arduino na dzień dobry zabiera 22kb, LUA jak wyłączysz moduły nie zabiera więcej jak kilka bajtów, zależy to naturalnie od modułów jakie masz aktywne. Jeśli już się upierasz na C to wygodniej i oszczedniej jest w Visual Studio. Najlepszy do tak prostych zadań, nie jest ani LUA, ani C tylko Basic ESP. Dobrej zabawy.
Jeśli nie zasilasz układu z baterii, nie korzystasz z usypiania, to do samego pomiaru temperatury wystarczy ESP-01. Mam w planach budowę podobnego układu do mierzenia temperatury zewnętrznej z ESP-12E + 2 x 18650 + DS18B20 + baterie słoneczne.
Jak wyłączałem moduły to miałem problem z uruchomieniem, fakt może musiałbym posiedzieć na tym. W arduino wysyłanie danych na thing, + prosty serwer lokalnie + DS18B20 + DHT11 zajmuje mi 38kb zostaje mi 42kb wolnego. W node dokładnie ta sama konfiguracja zajęła mi 42kb i miałem 0 wolnej przestrzeni prawie. Poza tym w node miałem przykre przypadki, że jak wywoływałem często serwer tzn co 10-30s to łapał zwiechę. Nie znalazłem w node jakiegoś wathdoga na to
A czy jest możliwość wykorzystania tego projektu np. z 5szt ds18b20?
5x esp8266 z jednym czujnikiem, czy 5x ds18b20 do jednego esp8266?
to chyba oczywiste że 5x ds18b20 i jedno esp01 🙂
Da się podłączyć kilka czujników pod esp-01, ale “co oczywiste”, trzeba będzie nieco zmodyfikować kod i być może zastosować inny plik ds18b20.lua, bo nie wiem, czy ten obsługuje więcej niż jeden czujnik.
Kolejny ciekawy tutorial. A czy zebrane dane można wyeksportowaź jako txt czy xls do obróbki offline i backupu?
Tak, thingspeak umożliwia zarówno import danych do systemu jak i export.
Wszystko fajnie, ale to ma swoje wady:
– układ może pobierać nawet 200mA prądu
– wobec mody żeby wszystko wysyłać na serwery chciałbym poczytać jak zrobić coś takiego w postaci odczytu zdalnego temperatury ale na wyświetlaczu LCD arduino (z pominięciem owych serwerów pośredniczących). Ja wiem że esp zostały stworzone jako EOT ale nikt jakoś nie prezentuje ich zastosowania z pominięciem thinkspeak.com
ESP-12 można usypiać i wtedy dobre ogniwo Li-ion wytrzyma nawet miesiąc. Co do wyświetlania wyniku na LCD ze zdalnych czujników – da się zrobić, na pewno w sieci są opisane sprawdzone rozwiązania.
Wojtek, o usypianiu wiem, ale nie znalazłem żadnej wiadomości ile takie ogniwo na usypianiu będzie działało. Po drugie jeśli dysponujesz jakimiś linkami gdzie są konkretne rozwiązania typu JAK TO ZROBIĆ proszę podaj. Umiem czytac ze zrozumieniem i potrafię przerobić coś pod siebie ale chciałbym bazować na sprawdzonym układzie który jeśli powiele będzie działał na 1000%. W samych tych ESP dopiero raczkuję i stąd to moje asekuranctwo.
Zobacz na nettemp.pl/forum Są tam gotowe opracowania uniwersalnych modułów z esp i różnymi czujnikami. Zamiast arduino całością steruje raspberry, ale masz obsługę LCD itd.
Mam problem z google gauges, pokazuje mi dziwne wartości, zupełnie inne niz powinny być. Moze trzeba cos zmienić w kodzie ?
Google udostępnia obszerną pomoc do gauges. Nie podałeś kodu to ciężko cokolwiek więcej napisać.
Czy z czytających ten wpis robił ktoś odczyt temperatury przy pomocy modułu gsm Air200?
Nie powinieneś wpisywać na sztywno adresu Thingspeak, rozwiązywanie DNS na ESP działa bez problemu
A dlaczego nie powinienem?
Jesteś w stanie stworzyć dla mnie kod oraz układ dla 10 lub 12 czujników ds18b20? Potrzebuję takiego czegoś do Kotła CO na pelet
A czy jest możliwość wykonania kilka kompletów ESP+1szt DS18B20 np 6 kompletów i żeby one wszystkie wysyłały dane do jednego konta na thinkspeak? Chciałbym mierzyć temperaturę w mieszkaniu w 6 – 8 punktach ale niestety musiałbym skorzystać z zasilania bateryjnego w każdym miejscu bo nie chce pruć ścian i prowadzić kabli… Ma ktoś pomyśl jak to zrobić? Albo może np 6 x kpl ESP+D18b20 połączone z jednym Arduino i on wtedy wysyła na serwer??
Witam, jak zbudować analizę jakości powietrza w wysyłaniem danych na stronę www ? [email protected]