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:

Dodanie kanału w thingspeak

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:

Kanał - ustawienia

Po zapisaniu, mamy nasz pierwszy box, jeszcze bez danych:

Thingspeak pusty wykres

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:

Schemat układy z DS18b20 i esp8266

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:

uklad_z_esp01

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:

Właściwości 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ę:

Kanał z danymi thingspeak.com

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…

Możesz również polubić…

22 komentarze

  1. orideith pisze:

    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

  2. HEX pisze:

    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.

    • Wojtek pisze:

      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.

  3. orideith pisze:

    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

  4. silver111silver111 pisze:

    A czy jest możliwość wykorzystania tego projektu np. z 5szt ds18b20?

  5. silver111silver111 pisze:

    to chyba oczywiste że 5x ds18b20 i jedno esp01 🙂

    • Wojtek pisze:

      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.

  6. oziboy pisze:

    Kolejny ciekawy tutorial. A czy zebrane dane można wyeksportowaź jako txt czy xls do obróbki offline i backupu?

  7. Darek pisze:

    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

    • Wojtek pisze:

      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.

  8. Darek pisze:

    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.

    • Wojtek pisze:

      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.

      • Darek pisze:

        Mam problem z google gauges, pokazuje mi dziwne wartości, zupełnie inne niz powinny być. Moze trzeba cos zmienić w kodzie ?

  9. Adam Pałac pisze:

    Czy z czytających ten wpis robił ktoś odczyt temperatury przy pomocy modułu gsm Air200?

  10. aso pisze:

    Nie powinieneś wpisywać na sztywno adresu Thingspeak, rozwiązywanie DNS na ESP działa bez problemu

  11. Patryk pisze:

    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

  12. Dominik pisze:

    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??

  13. Mariusz Dembowski pisze:

    Witam, jak zbudować analizę jakości powietrza w wysyłaniem danych na stronę www ? [email protected]

Leave a Reply

Witryna wykorzystuje Akismet, aby ograniczyć spam. Dowiedz się więcej jak przetwarzane są dane komentarzy.