Forum: Mikrocontroller und Digitale Elektronik ESP8266 NodeMCU/LUA DeepSleep Wachzeit verkürzen


von Dirk K. (dekoepi)



Lesenswert?

Dazu finde ich wenig hilfreiches im Netz, aber vielleicht hat damit 
schon jemand Erfahrungen gesammelt.

Ich nutze die NodeMCU-Firmware auf einem ESP-12E und habe dadran einen 
Si7021, als mobilen Sensor mit einer LiIon-Zelle. Das Ganze funktioniert 
soweit auch hervorragend, auch schon mit DHT22 - der ist nur zu ungenau 
und hat einen vergleichsweise hohen Ruhestrom.

Softwareseitig habe ich inzwischen alles auf Geschwindigkeit optimiert: 
In LUA Strings zusammenbauen über einen table und table.concat; 
Si7021-Modul compiliert, Hauptprogramm compiliert und als init.lua 
abgespeichert.

Das Programm misst die Zeit vom Start bis zum Datenversand. Beim ersten 
Start kommen da laut Programm 2,4-2,5s zusammen, nach DeepSleep immer 
3,05-3,1s. Das war die erste Merkwürdigkeit, die sich nicht abstellen 
ließ. Auch, wenn ich das Wifi-Setup nur einmal mache und mich auf 
Auto-Reconnect verlasse, bleibt es bei der Geschwindigkeit.

Gucke ich nun mit 1Ohm und Scope drauf, wird das noch merkwürdiger. Der 
ESP ist beim StartUp 9,6s wach, nach DeepSleep nur noch 9,2s. Was aber 
beides deutlich von den vom Programm selbst gemessenen Werten abweicht. 
Kennt ihr Möglichkeiten, die Wachzeit zu drücken? So komme ich auf einen 
Durchschnittsverbrauch von 2,2mA, was mit der LiIon-Zelle theoretisch 
für 17 Tage reicht. Aber das sollte doch besser gehen ...

Proogramm:
1
starttime = tmr.now()
2
-- setup Wifi only once after power cycle
3
local val = rtcmem.read32(0)
4
if val ~= 32767 then
5
  wifi.setmode(wifi.STATION)
6
  wifi.setphymode(wifi.PHYMODE_N)
7
  wifi.sta.config("<SSID>", "<Passwort>")
8
  -- save more power by using static IP instead of DHCP
9
  wifi.sta.setip({ip="<localIP>",netmask="255.255.255.0",gateway="<Gateway IP>"})
10
  wifi.sta.connect()
11
  
12
  rtcmem.write32(0,32767)
13
end
14
15
-- read AM3220 / Si7021 on GPIO2/0 = Pin 4 / 3 - 
16
sda_pin = 4
17
scl_pin = 3
18
si7021 = require("si7021")
19
si7021.init(sda_pin, scl_pin)
20
si7021.read(status)
21
22
wifi.sta.status()
23
--print(wifi.sta.getip())
24
25
26
-- Deep sleep time in ms (300s)
27
deepsleep_time = 300000
28
29
local sensor = "mobile"
30
local host_ip = "<Empfänger-IP>"
31
32
function loop() 
33
  if wifi.sta.status() == 5 then
34
    -- Stop the wifi connection wait-loop
35
    tmr.stop(0)
36
    
37
    conn=net.createConnection(net.TCP, 0) 
38
    conn:on("receive", function(conn, payload)
39
--      print(payload);
40
    end) 
41
    conn:connect(80,host_ip)
42
    conn:on("connection", function(conn, payload)
43
--      print("Connected")
44
      -- read battery voltage
45
      local vbat = 5.555*(adc.read(0)/1024)
46
      local humi = si7021.getHumidity()
47
      local temp = si7021.getTemperature()
48
--        buf = temp.."\n"..humi.."\n"
49
      local my_table = {}
50
      my_table[#my_table + 1]="GET /send.py?sensor="
51
      my_table[#my_table + 1]=sensor
52
      my_table[#my_table + 1]="&temp="
53
      my_table[#my_table + 1]=string.format("%.2f",(temp/100))
54
      my_table[#my_table + 1]="&hum="
55
      my_table[#my_table + 1]=string.format("%.2f",(humi/100))
56
      my_table[#my_table + 1]="&vbat="
57
      my_table[#my_table + 1]=string.format("%.3f",vbat)
58
      my_table[#my_table + 1]="&time="
59
      my_table[#my_table + 1]=string.format("%.3f",((tmr.now() - starttime) / 1000000))
60
      my_table[#my_table + 1]=" HTTP/1.1\r\nHost: "
61
      my_table[#my_table + 1]=host_ip
62
      my_table[#my_table + 1]="\r\nAccept: */*\r\n" 
63
      my_table[#my_table + 1]="User-Agent: Mozilla/4.0 (compatible; esp8266 Lua; Windows NT 5.1)\r\n\r\n"
64
      local my_string=table.concat(my_table)
65
      conn:send(my_string)
66
    end)
67
    conn:on("disconnection", function(conn, payload)
68
--      print('Disconnected') 
69
      conn:close()
70
--      print(buf)
71
--      collectgarbage()
72
--    print("Going to deep sleep for "..(deepsleep_time/1000).." seconds")
73
      node.dsleep(deepsleep_time*1000)
74
--      tmr.delay(1000)
75
    end)
76
  else
77
--    print("Waiting for Wifi ...")
78
  end
79
end
80
81
tmr.alarm(0, 100, 1, function() loop() end)
82
83
-- Watchdog loop, will force deep sleep if the operation somehow takes to long
84
tmr.alarm(1,15000,1,function() node.dsleep(deepsleep_time*1000) end)
85
-- eof

von Dirk K. (dekoepi)



Lesenswert?

Ich antworte mir mal selber, dürfte auch für andere nützlich sein.

Der DeepSleep-Aufruf beim Disconnect ist schuld. In den 
on:Receive-Handler gesetzt, geht der ESP nach 4s schlafen beim StartUp, 
ebenso beim Aufwachen nach DeepSleep.

Ein bisschen optimieren wäre sicher schön, aber so bin ich schon mal 
deutlich zufriedener.

von Michael U. (amiga)


Lesenswert?

Hallo,

meine Erfahrung: der ESP braucht ca. 300-500ms um aufzuwachen, zum AP zu 
connecten, zum MQTT-Broker zu connecten, eine MQTT-Message mit den 
Sensorwerten loszuwerden und wieder schlafen zu gehen.
Bedingung ist dabei auch eine feste IP um die DHCP-Abfrage zu sparen.
Meßzeiten der Sensoren kommen natürlich noch dazu, wenn es Sachen sind, 
die etwas Zeit erfordern (mehrere Messungen für Mittelwert o.ä.) macht 
es Sinn, den ESP aus dem Sleep erst ohne WLAN aufwachen zu lassen, 
ESP.deepSleep(WAIT, RF_DISABLED);.
Das sind dann nur ca. 15mA Stromaufnahme des ESP. Die Messergebnisse im 
EEPORM speichern, Sleep mit 1µs auslösen mit ESP.deepSleep(1, 
RF_CAL);und da dann die Werte senden.

Reduziert je nach Sensoren und Messabstand die durchschnittliche 
Stromaufnahme auf 1/3.

NodeLUA benutze ich allerdings nicht, ist eigene Software. Außer 
Sensorren, ESP8266 und ein MCP1703 als Spannungsregler gibt es da auch 
keine weitere Hardware.

Gruß aus Berlin
Michael

von Dirk K. (dekoepi)



Lesenswert?

Statische IP habe ich ja vermeintlich vergeben. Habe aber durch den 
Hinweis mal mit dem Holzhammer draufgehauen und nach meinem 
"Einmal-Setup" des WLAN die Static IP-Zeile wiederholt. StartUp bleibt 
bei 4s (naja, 3,6s, etwas besser), aber dann beim WakeUp nach DeepSleep 
...

Der ESP selber misst jetzt 300-400ms, bis er vom Start an alle Werte 
ausgelesen und übermittelt hat. Das Scope verrät hier mehr, es sind doch 
1,2s. Kannst du bei dir ja auch mal gegenprüfen, ob die Zeiten bei dir 
ähnlich länger sind in der Realität.

Danke für die Idee! :)

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.