Page 1 of 34

node.dsleep() reliability - zombie mode

PostPosted: Wed Jan 28, 2015 10:52 am
by GeoNomad
I have been doing some testing using dsleep in anticipation of creating battery operated sensors that can work unattended for long periods.

To that end, I have a modified ESP-01 that "works" for resuming from dsleep.... most of the time.

The original code was a DS18B20 temperature sensor that ran on a tmr.alarm() and posted the temperature to my web site once a minute. It was reliable. For about 40 days, it worked perfectly every time. It just used to much power for battery operation.

So the hardware and the code is in good shape.

Replacing the tmr.alarm with a node.dsleep after the disconnection and with a second "watchdog" alarm that initiates dsleep after 10 seconds in case something goes wrong, everything looked good for over a day. The watchdog tmr.alarm is the first line of the init.lua.

And then, it didn't resume from sleep. Testing for several more days reveals that it can resume properly up to 2,000 times at best and a few hundred at worst. Not resuming seems to be a random thing. Nothing is changed in the hardware or software.

When it doesn't resume, current consumption is on the order of 10 mA. This is an odd number. While sleeping, normal consumption is in the microAmps. While working I see 70-120 mA normally.

So, it appears that the failure to resume (or maybe failure to go to sleep properly) is an inbetween mode.

I don't know if this is Lua code related or an underlying firmware issue (more likely). It might even just be this particular part.

So, I wonder if anyone else has done any long term sleep/resume testing and how reliable it was?

I will probably simplify down to nothing but an alarm and dsleep and do some more testing. I need to know that no matter what, the dsleep will resume the processor. Otherwise, an external clock will be needed.

Re: node.dsleep() reliability - zombie mode

PostPosted: Wed Jan 28, 2015 11:41 am
by GeoNomad
alonewolfx2 has just posted a fork on github

https://github.com/alonewolfx2/nodemcu- ... 03cce2b9ec

new sleep set options added (from 0.9.5 sdk)
-- no wakeup until rst pin to low

-- 4 mean no RF after deepsleep.

It seems that the no RF wakeup draws around 13 mA. Exactly what I was seeing.

It looks like the earlier firmware randomly chose to wake up in noRF mode.

However, in that case it should have gone back to sleep for a minute and woken up properly the next time, unless the mode change remained set.

Interesting. I look forward to hearing insight from alonewolf and others.

Re: node.dsleep() reliability - zombie mode

PostPosted: Wed Jan 28, 2015 1:10 pm
by alonewolfx2
I am using ds18b20 sensor node with this code and hardware setup.2xaa battery, esp-01(ch_pd pin connected vcc with 2.2k resistor)((XPD_DCDC connected to rst pin)(470mf cap connected between gnd and vcc)(ds18b20 connected gpio2 without resistor.)
It's working fine last 8 hours. But code a little buggy. i am using node.dsleep after printing payload(after thingspeak response). 095 sdk's zombi sleep mode problem fixed with new sleep options but my esp not sleep if thingspeak not send any response. propably you can fix this with some extra code lines. for me, its working fine for last 8 hours and i dont have any zombie sleep for now.

Code: Select all
tmr.alarm(0,1000, 1, function()
   if wifi.sta.getip()==nil then
      print("connecting ap")

Code: Select allpin = 4


function bxor(a,b)
   local r = 0
   for i = 0, 31 do
      if ( a % 2 + b % 2 == 1 ) then
         r = r + 2^i
      a = a / 2
      b = b / 2
   return r

function getTemp()

        data = nil
        data = string.char(ow.read(pin))
        data = data .. string.char(ow.read(pin))
        t = (data:byte(1) + data:byte(2) * 256)
         if (t > 32768) then
                    t = (bxor(t, 0xffff)) + 1
                    t = (-1) * t
         t = t * 625
                   lasttemp = t
         --print("Last temp: " .. lasttemp)
    t1 = lasttemp / 10000
    t2 = (lasttemp >= 0 and lasttemp % 10000) or (10000 - lasttemp % 10000)
    tt=t1 .. "." .. string.format("%04d", t2)
conn=net.createConnection(net.TCP, 0)
     conn:on("receive", function(conn, payload) print(payload) node.dsleep(60*1000*1000) end )
     conn:send("GET /update?key=myApiKey".."&field1="..tt.." 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")


Re: node.dsleep() reliability - zombie mode

PostPosted: Wed Jan 28, 2015 1:33 pm
by GeoNomad
alonewolfx2 wrote: but my esp not sleep if thingspeak not send any response. propably you can fix this with some extra code lines.

I would put the node.dsleep in the disconnect message line

Code: Select all   
conn:on("disconnection", function(conn, payload)
       tmr.alarm(1,100,0,function() node.dsleep(60000000-tmr.now()) end)

That way if the connection fails the dsleep will still work.

The other line I have right at the first line of init.lua is

Code: Select alltmr.alarm(1,10000,1,function() node.dsleep(60000000-tmr.now()) end)

which should put it to sleep 10 seconds after it begins, no matter what happens, if it doesn't get to the disconnect first.

Mine runs for as long as 2 days before going into zombie mode. Which I have learned from you is probably the no RF mode.

But it doesn't seem to execute the code or it would go back to sleep in 10 seconds.

I will try the new method and set the mode. Maybe that will calm it down.