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ć.
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.
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 <vowstar@nodemcu.com>
-- 2015/02/14 sza2 <sza2trash@gmail.com> 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.
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…
Po co alternatywny firmware do programatora usbasp? Otóż posiada on jedną, użyteczną przewagę nad oryginalnym…
Dziś lekki, wakacyjny wpis. Od dawna, na używanych przeze mnie routerach, instalowałem linuksa. Było o…
Radio nieodłącznie kojarzy się z nieśmiertelnym FM lub transmisją intermetową. Standard DAB+ wydaje się być…
Poniżej opiszę odpowiednik drogiej (w stosunku do pojemności) baterii 9V o oznaczeniu 6F22. Ze względu…
Widząc migającą na pomarańczowo lampę ostrzegawczą, zastanawiałem się (ciekawe czy tylko ja) jak jest zbudowana,…
W tym wpisie przedstawię bardzo ciekawe narzędzie na RaspberryPi, przydatne każdemu administratorowi urządzeń sieciowych. W…
Zobacz komentarze
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?