ESP8266-01 a měření teploty

9.11.2015

 
Nedávno jsem narazil v konferenci na Facebooku na zajímavý problém.
Jak měřit teplotu a odesílat ji na server pro zobrazení grafu vývoje teploty.
Autor dotazu měl tyto požadavky:
1. Bateriové napájení - v místě měření není dostupný přívod elektrické energie.
2. V místě měření je teplota jako venku. Tzn. -20 až +40°C
3. Co nejdelší doba mezi výměnou baterií
4. Co nejmenší rozměry
5. Graf přístupný odkudkoliv z internetu

Rozhodl jsem se, že se pokusím takové zařízení sestavit.
1. Napájení:
Vzhledem k tomu, že zařízení bude vystaveno teplotám pod bodem mrazu, není možné použít k napájení LiIon članek. Těm moc teploty nižší než 5°C nesvědčí. Olověné akumulátory nevyhovují požadavku na malé rozměry. Proto jsem se rozhodl zařízení napájet NiMh, nebo klasickými alkalickými články.
2 Rozměry:
Jako první se nabízelo použití malého Arduina MINI, nebo MIKRO, jako čidlo teploty použít DS18B20 a data odesílat přes WiFi pomocí modulu ESP8266-01 na AccesPoint, který je v dosahu. Toto řešení by bylo asi funkční, ale potom mne napadlo, že Arduino je vlastně v tomto případě zbytečné. DS18B20 je možné připojit přímo k ESP8266, a jeho procesor využít k načítání teplot, a zároveň k odesílání dat na server. Zmenšily by se rozměry celého zařízení, a klesl by i odběr proudu z baterií.

Zapojení:

schema

Vzhledem k bodu 
3. Nejnižší odběr zařízení
jsem vynechal veškerou další elektroniku, která by mohla zbytečně zvyšovat odběr proudu z baterií. Zapojení jsem proti zadání ještě malinko vylepšil. Místo teploměru DS18B20 jsem použil čidlo DHT22, které kromě teploty měří i vlhkost vzduchu.

Zapojení je klasické: Napájení, GND a datový pin z DHT22 připojený na GPIO2. Napájení složené ze tří kusů tužkových (AA) článků. Buď nabíjecích NiMh, nebo klasických alkalických.

Teď si asi říkate, jestli jsem se nezbláznil. Vždyť všude na internetu červeně píšou, že "ESP8266 are not 5V tolerant". Asi bych tomu věřil, ale nedávno jsem v jednom mém zařízení s Arduinem zjistil, že jsem ESP8266 omylem připojil na 5V, místo na 3.3V, a že to zařízení takhle jelo 7 měsíců naprosto bez problému. Data odesílalo na server v intervalu 5 minut. Je možné, že kdyby vysílalo data kontinuálně, tak by mohlo dojít k přehřátí procesoru a k jeho poškození, ale v tomto případě, kdy cca 2s vysílá, a potom nic nedělá k ničemu takovému nedošlo.

Dalším krokem ke snížení spotřeby je uspávání procesoru do DeepSleep módu. Procesor ESP8266 načte údaje z čidla, a odešle je na server. Potom dalších 5 minut nebude nic dělat, takže je zbytečné, aby těch 5 minut běžel, a zbytečně odebíral energii z baterií. Proto ho po načtení hodnot z čidla, a jejich odeslání uspím do DeepSleep módu. Bohužel, k probuzení modulu z DeepSleep je třeba propojit výstup GPIO16 s RST signálem. ESP8266-01 ale nemá signál GPIO16 vyvedený na žádný pin. Proto si musíme trochu pomoci. Je nutno připájet tenký drát na pin RST, a druhý konec přímo na nožičku procesoru. Sice se to zdá jako složitá operace, ale není to tak těžké. Pin GPIO16 je na okraji integrovaného obvodu, takže není problém tenkým hrotem mikropájky připájet drát přímo na tento pin: 

propojka GPIO16 a RST

Pokud budete chtít použít ESP8266-12 (označované jako NodeMCU V3), musíte ze stejného důvodu propojit pin označený D0 a RST. Vzhledem k tomu, že ESP8266-12 je o trochu větší, je i propojení těchto pinů jednodušší. Můžete použít buď klasické propojení drátem s piny, nebo naletovat propojku tak, jek je to na dalším obrázku:

NodeMCU

(Drát jsem tam naletoval jenom na ukázku. Samozřejmě bych ho tam takto blbě nenechal.)

 


Dalším krokem bude zapojit zařízení podle schématu. Já nejsem velkým zastáncem nepájivého kontaktního pole, tak jsem použil kousek univerzálního plošného spoje. Do něho jsem zaletoval 3 konektory, a propojil je kouskem drátu. Ještě jsem přidal jumper jako vypínač :-)
zapojeni1

A poskládané dohromady:
poskladane

Včetně baterií:
s bateriema

Baterie jsem použil mé oblíbené alkalické články z IKEA. Mají rozumný poměr cena/kapacita - Viz mé Testy kapacity baterií
Software:

Jak to bude celé fungovat?
1. ESP8266 se připojí k WiFi AP
2. Načte teplotu a vlhkost z čidla DHT22
3. Odešle načtená data na server Thingspeak, kde se z něho vytvoří grafy
4. ESP8266 usne (DeepSleep) na dobu 300 sekund.
5. Po probuzení znovu na bod 1.

Nejprve nahrajeme do ESP8266 firmware NodeMCU.
Jak nahrát firmware do ESP8266 najdete na předchozí stránce
Použijte verzi
nodemcu_float_0.9.6-dev_20150704.bin  která umí výpočty s desetinnou čárkou.

Jako první potřebujete knihovnu pro čidlo DHT22. Tu si stáhnete zde dht22.lua. Knihovna je standardní, není třeba v ní nic měnit.

Dále potřebujete startovací script, soubor init.lua.
V tomto souboru si nastavíte jméno a heslo svého AP, kam se bude ESP8266 připojovat:

----------
print(wifi.sta.getip())
wifi.setmode(wifi.STATION)
wifi.sta.config("SSID","PASSWORD")
print(wifi.sta.getip())
dofile("realinit.lua")
----------

Další soubor, který potřebujete je realinit.lua.
V tomto souboru si změníte WRITE_APIKEY na svoje, které vám bude vygenerováno serverem Thingspeak.
Na konci programu najdete toto:
node.dsleep(300000000, 0)
hodnota  
300000000 je právě zmíněnných 300s (5minut), po které bude ESP8266 v Dsleep módu.

V případě, že nebudete zapojovat propojku z GPIO16 na RST nahraďte tento řádek příkazem:
tmr.alarm(0, 300000, 1, function() sendData() end )
Tento příkaz má stejnou funkci jako delay(300000);
Potom ale napájecí baterie samozřejmě nevydrží tak dlouho, protože procesor stále poběží.

----------
PIN = 4 --  data pin, GPIO2
APIKEY="WRITE_APIKEY"

tmr.alarm(0,100, 1, function()
    if wifi.sta.status() == 5 then
        print(wifi.sta.getip())
        tmr.stop(0)
        dht22 = require("dht22")
        dht22.read(PIN)
        t = dht22.getTemperature()
        h = dht22.getHumidity()
        sendline=""
        if h == nil then
            sendline="GET /update?key="..APIKEY.."&field3=1 HTTP/1.1\r\n"
            print("DHT Error")
        else
            t = t / 10
            h = h / 10
            sendline="GET /update?key="..APIKEY.."&field1="..t.."&field2="..h.." HTTP/1.1\r\n"
            print("DHT OK "..t.." "..h)
        end
        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(sendline)
        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)
            -- release module
            dht22 = nil
            package.loaded["dht22"]=nil
            --sleep for 5 mins
            print("Go to sleep")
            node.dsleep(300000000, 0)
        end)
    end
end)
----------

Po zapojení na napájení by se měl ESP8266 připojit k WiFi, a začít odesílat data na server Thingspeak.


Doplněno 12.ledna 2017:
Psala mi spousta lidí, že se jim program často "kouše".
Ano, občas se kousne. Program byl napsán zjednodušeně, pouze pro tento projekt. Tedy pouze pro otestování, jak dlouho zařízení vydrží běžet na baterie. V programu se nikde netestuje, jestli opravdu došlo k připojení k Acces Pointu. Takže v případě, že se ESP8266 nepřipojí napoprvé k AP z důvodu např. zarušeného signálu, nebo AP je v tu chvíli z nějakého důvodu nedostupny, dojde k tomuto problému.
Ve smyčce:
tmr.alarm(0,100, 1, function()
    if wifi.sta.status() == 5 then
        print(wifi.sta.getip())
        tmr.stop(0)
se čeká na odpověď, že je ESP připojený k AP. Čeká se na jinou odpověď než 'nil'. V připadě, že nedošlo na začátku programu init.lua k připojení, tak se čeká stále dokola, a čeká, a čeká...
Proto jsem program upravil, aby k této situaci nedocházelo. Nechtělo se mi upravovat realinit.lua, protože bych ho musel celý přepsat. Proto jsem doplnil do init.lua smyčku, ve které se max. 10x za sebou zkontroluje, jestli je ESP připojen k AP. Pokud ne, program se restartuje, pokusí se připojit znovu, a znovu 10x kontroluje stav připojení. Podle mých testů proběhne smyčka maximálně 3x, a program pokračuje dál.

Upravená verze je zde:
----------
wifi.setmode(wifi.STATION)
wifi.sta.config("SSID","PASSWORD")

print( 'Connecting WiFi...' )

retries = 0
tmr.alarm( 1, 3000, 1, function()
  ip = wifi.sta.getip()
  if ip == nil then
    print( "Retry #"..retries)
    if retries >= 10 then
      print( 'WiFi connection failed!' )
      tmr.stop(1) -- stop timer 1
       node.dsleep(5000, 0)
    else
      retries = retries + 1
    end
  else
    tmr.stop(1) -- stop timer 1
    print( 'IP: ' .. ip )
    print( 'MAC: ' .. wifi.sta.getmac() )
    status = wifi.sta.status() -- status=5 'STATION GOT IP'
    dofile("realinit.lua")
  end
end)
----------
V případě, že nebudete zapojovat propojku z GPIO16 na RST nahraďte
node.dsleep(5000, 0)

příkazem:
ESP.reset()
Tento příkaz by měl udělat softwarový reset, ale nezkoušel jsem to.

 

Doplněno 23. března 2017:

Vzhledem k tomu, že někteří lidé nechtějí používat LUA scripty, napsal jsem program i pro Arduino IDE.

Programy jsou ke stažení zde:

esp8266_1_dht22_dsleep.ino
- verze s DSLEEP -nutno propojit GPIO16 na RST, data odesílána na server Thingspeak

esp8266_1_dht22.ino
- verze BEZ DSLEEP

Pro správný běh programu je NUTNÉ použít tuto knihovnu DHT-sensor-library S jinou, kterou jsem dříve používal pro Arduino UNO program nefungoval!
Program do ESP8266-01 nebo ESP-12 nahrajete programem Arduino IDE (zkoušeno s verzí 1.8.1), kterou používáte normálně pro programování Arduina.
V případě, že budete program nahrávat do ESP-12, změňte
#define DHTPIN 2

na
#define DHTPIN D2

Pro nahrání programu do ESP použijte toto (defaultní) nastavení:

V programu jsou vloženy výpisy na sériový port, na kterých se dá v případě problému poznat, kde program nepracuje správně (připojeník AP, přidělená IP adresa, síla signálu, načtení hodnot z čidla, připojení a odeslání dat na server Thingspeak). tyto výpisy je samozřejmě možné z programu odstranit.

 


Při načítání hodnot z čidla, a odesílání dat na server odebírá ESP8266 z baterií cca 80mA:

cuurent1

Tento stav trvá cca 2 sekundy.
Poté se ESP8266 uvede do DeepSleep módu, a spotřeba celého zařízení klesne na cca 1,4mA. Je to celkem vysoký odběr, ale je způsoben tím, že jsem použil čidlo DHT22, které samo o sobě obsahuje procesor STM8S103F3P6
, který se neuspává, a má stále nějakou spotřebu (na rozkuchané čidlo DHT22 se můžete podívat v předchozím článku na konci). Pokud vám bude stačit jenom teplota, a použijete čidlo teploty DS18B20, tak se určitě dostanete na mnohem nižší odběr v dsleep módu.

current2

(Hodnoty ampérmetru je nutno brát s rezervou, přesnější měřák jsem bohužel zapoměl doma)


Jak dlouho to může na tři AA články běžet?

Zařízení jsem vyrobil a zapnul 9. listopadu 2016.
 

Sice jsou tam občas výpadky, ale ty jsou způsobeny velkou vzdáleností od AP, a rušením signálu, ke kterému bohužel u nás v paneláku dochází. Každý druhý byt má vlastní AP, výkon vyhulený naplno, a kanálů na 2,4GHz je jenom pár.

Zařízení se přestalo připojovat k AP 3.ledna 2017, tzn. po 55ti dnech ! Což si myslím, že je docela úspěch. Zařízení přestalo načítat hodnoty a připojovat se, když napětí na bateriích kleslo na 3.282V

 

Zde vidíte konec grafu od 9. prosince 2016 do 3. ledna 2017, kdy došlo k výpadku:






 


Pokud budete chtít s něčím poradit, napište mi na email dole.





Na hlavní stránku