Mikrokontrolery

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

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…

Wojtek

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?

    • 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

Ostatnie posty

Tani moduł IoT z kamerką ESP32 CAM – pierwsze uruchomienie

Mega tanie, bezprzewodowe moduły Internet of Things na dobre zadomowiły się w naszych sieciach. Od…

2 dni temu

Aktualizacja oprogramowania w stacji lutowniczej AiXun T3A

Pewnie nie każdy posiadacz tytułowej stacji lutowniczej wie, że posiada ona możliwość aktualizacji firmware'u. Producent…

2 tygodnie temu

Programator USB AVR ISP z Arduino Nano

Jakiś czas temu, przeglądając Aliexpress natknąłem się na ciekawy shield do Arduino Nano. Według opisu…

4 tygodnie temu

Tester elementów elektronicznych na atmega – aktualizacja firmware’u

W mailach i komentarzach kilka razy przewijała się prośba o ten wpis. Chodzi o aktualizację…

2 miesiące temu

Wzmacniacz słuchawkowy Lovely Cube – popularny klon Lehmanna

Dziś tematyka audio, a nawet audiofilska. Uznany wzmacniacz słuchawkowy Lehmann Black Cube Linear o dość…

2 miesiące temu

Podsumowanie 2023 roku

Tradycyjnie w styczniu, publikuję podsumowanie minionego roku na stronie grylewicz.pl. Poniżej trochę liczb, lista najpopularniejszych…

3 miesiące temu