ESP-07 deep sleep depending on state of input or other way?

Are there any examples around on how to make an ESP-07 based design run in deep sleep mode when on batteries (when deployed) but possible to get running continuously depending on the state of an input pin or some other means?

I have a project that runs well on a power supply but it will not last long if powered from batteries. I need the board to be running for a while when I am reconfiguring it via WiFi but when it is in monitoring use it should wake up regularly, take a temp/humid reading and go back to deep sleep. How can this be accomplished via an input pin or some other better way?

The sketch must be modified in the setup() section of course and I also need to modify the circuit if the pin state is to be used. Maybe a pin check inside setup() that will make the readings and then send it to deep sleep or else go to the loop() if the pin check fails? A pin check would make it a bit clumsy to work with, so if there are some other way I would be grateful for a hint. Best would be a way over WiFi to make this happen....

Maby this will help: https://www.losant.com/blog/making-the-esp8266-low-powered-with-deep-sleep

OK, there is one (at least) thing I am wondering about in this context: - I am going for deep sleep. - Apparently this mode will cause a reset to happen a defined time into the future. - When this happens the sketch starts from the beginning and the action should happen in setup()

What I am wondering about this is if the internal clock starts over such that if the first thing done in setup() is to read millis() and this will always return the same value. Or is there a background process that runs all the time and causes millis to increment while the deep sleep is on-going?

I need to use some time reference so that my reads will happen at the same time each hour. But I guess some testing will reveal if there is a time shift or not...

The other issue I have is that my firmware includes two tcp socket channels for configuration (one is a straight socket server and the other is a web server showing a config screen to the user). I would like to somehow keep these accessible but I can't figure out how. Except of course by using a jumper on a pin that is read in setup() and can switch off the deep sleep function. This works only if there is physical access to the device, which is not always the case.

Finally I also have a firmware update server in my sketch. It uses the ESP8266HTTPUpdateServer library and is the way I use to change the firmware of these devices over the network. In some howto pages I have found it is stated that if I use the deep sleep function by connecting GPOI0 to RST I cannot update the firmware... Is this really true about updating via the web updater too?

Checked the millis() read and it returns the same value if starting by power-on or after a software induced deep-sleep restart. So in effect one can rely on the ESP starting from scratch every time.

Oh boy, seems like I am getting deepsleep current consumed in other places than expected...

1) I have a little switched regulator module producing the 3.3V and it draws 0.6 mA when just connected on the input side. Maybe I should replace this with a linear 3.3V regulator, but which type can I use? All IC:s I have found yesterday by googling seem to use up a lot of idle current even though there is no load... I found a number of really small surface mount devices, which really do not seem to be able to take much power dissipation at all. When the system is operational it pulls a lot of current for the WiFi to operate so the regulator should be able to handle that power...

2) I added a command to set the ESP-07 into deep sleep for 10 seconds so I could measure current. Turns out that when it is running my board pulls 41.6 mA from the power supply. But in deep sleep it still pulls 1.9 mA, i.e. it pulls 1.3 mA on top of the idling current of the 3.3V regulator module! One thing I observed is that there is an LED on the ESP-07 module that is [u]still lighted[/u] while the ESP is set to [u]deep sleep[/u]!

Is there some command I can send to the ESP-07 to switch off this LED? Or do I need to peel off the LED from the ESP-07 module?

BosseB: that when it is running my board pulls 41.6 mA from the power supply. But in deep sleep it still pulls 1.9 mA, i.e. it pulls 1.3 mA on top of the idling current of the 3.3V regulator module!

so you'd be getting 3.2ma in deep-sleep that is less than 10 % what did you expect ?

BosseB: Checked the millis() read and it returns the same value if starting by power-on or after a software induced deep-sleep restart. So in effect one can rely on the ESP starting from scratch every time.

Pretty much if you want a constant time within your sketch you could either fetch it from a NTP- server or add a real-time clock.

The other issue I have is that my firmware includes two tcp socket channels for configuration (one is a straight socket server and the other is a web server showing a config screen to the user). I would like to somehow keep these accessible but I can't figure out how.

Because when something is asleep either the alarm-clock or a touch can wake it up, nothing else. This issue shows up on the forum more often, what can be done is letting the ESP wake-up at regular intervals and post data onto a different server, which can be accessed all the time, configuration data could also be submitted there and communicated to the ESP the next time it wakes up and makes contact.

Deva_Rishi: so you'd be getting 3.2ma in deep-sleep that is less than 10 % what did you expect ?

I expected less than 50 uA so a battery could last a year or so with the device operating for 10 s every hour when it takes readings and posts the results to the webserver script. I have seen other how-tos where they seem to get a year out of 3 AA batteries...

Well as you know it will need to reconnect every time it wakes up, so i somehow doubt that to be completely accurate. But check the datasheet for it's power-consumption during deep-sleep, also you will probably get better efficiency from a buck-converter than from a regulator. (definitely for peak power)

Deva_Rishi: Well as you know it will need to reconnect every time it wakes up, so i somehow doubt that to be completely accurate. But check the datasheet for it's power-consumption during deep-sleep, also you will probably get better efficiency from a buck-converter than from a regulator. (definitely for peak power)

Yes, I intend it to wake up every hour so the sleep time will be calculated based on the millis() reading at the start of setup() and another just before the deepsleep command. The connection to WiFi seems to be very quick normally so this is not an issue, however the dead time from start from sleep until setup() starts is what I need to get a handle on. Probably needs some long-time test to adjust that. Regarding power I have tried to figure out how long a 2000 mAh battery supply will last by using the base drain 50uA plus the extra drain of 100 mA for 10s every hour. Seems to last about 240 days. But it depends heavily on the actual drain during operation with WiFi running. My prototype uses a 3.3V switching regulator block with a 7805 pinout and this is what draws 1.3 mA with nothing connected. Clearly if I use that the battery will go flat much faster, so I need a low-current linear regulator to get idle current down to 10 uA or so... And I have to peel off the ESP-07 power LED. Maybe it is not possible to reach a year but I really want it to work for 6 months over winter.

BosseB:
Is there some command I can send to the ESP-07 to switch off this LED? Or do I need to peel off the LED from the ESP-07 module?

No, but using two soldering irons you can remove the LED.

I read that it is actually easy just with a knife to peel it off, no need to solder apparently.

Now I have checked how the deepsleep works by testing with different values of a command parameters giving me whole minute sleep times and timing it with a stopwatch. This is what I got:

Request  Actual  Diff (all seconds)
-----------------------------------
 60        56     -4
120       111     -9
180       164    -16
240       219    -21
300       271    -28

The code I used to command the deepsleep:

case '5':   //Initiate a deep-sleep cycle of 10 s or by parameter
    uint64_t sleeptime;
    sleeptime = 1e7;  //Default 10s
    if ((cmd[1]) > 0) //Second char holds number of minutes to sleep
    {
        sleeptime = (uint64_t)(cmd[1] - '0') * 6e7; //Calculate microseconds
        if (sleeptime == 0) sleeptime = 1e7; //Special case where 0 is given, do 10s
        SerialDebug.print("Starting deepsleep() with T=");
        SerialDebug.println((unsigned long int)sleeptime);
    }
    ESP.deepSleep(sleeptime);
    break;

So it seems like the clock for the deepsleep function is not really accurate (off by 5-10%)! What is the oscillator type for the deepsleep clock? How accurate is it?

How can I make this accurate to a second in an hour?

I did some research on the inaccuracy of the deepsleep timeout and it looks like it is really bad. The discussions I have found reference a 3% or more inaccuracy of the sleep time. And even though the time is a 64 bit value in microseconds it seems like the maximum sleep time is about 3 hours! Not even a full 24 hour daily interval is possible. My own tests show that the inaccuracy is closer to 10%....

So there seems to be no way using what is available in the ESP-07 to have any accuracy in the deepsleep. Suggestions are to use an external RTC and hook the alarm output to the reset pin of the ESP. That would mean a more complex design of the board and makes it difficult to make a neat prototype.

BTW: Peeling off the on-board power LED from the ESP-07 module (using a screwdriver) reduced the deepsleep current drain by approximately 0.8 mA.

[u]UPDATE:[/u] As described in my other thread (Suggestion for an external interrupt timer generator?) about possible ways to accurately time the start after deep sleep I have now checked that my ESP-07 board in deep-sleep pulls just 19 uA! So it will be OK for long time deployment on 3 AA batteries! It should also be possible to design a self-calibrating algorithm for adjusting the deep-sleep argument for timing accuracy.

UPDATE2:
I have now built a proof-of-concept prototype that is cased in a plastic box with a battery pack and possibility to connect up to 4 DHT sensors.
I added a jumper to the design which is read on startup and determines if the unit shall measure and then go to deep sleep or stay running so it can be accessed for configuration via the network.
Using this prototype and the breadboard version I have found that I could add a calibration value to the config such that I can calibrate the timing while in deep sleep.
On the two different units I have had to use a factor of 1.0391 and 1.0389 respectively to get to a situation where the sleep can be controlled. Seems like these two ESP-07 units are having a similar deviation from the sleep timing stated in the manual. I have yet to find out if this is temperature dependent though. They are as yet in my indoors study.
But I am right now measuring every 10 minutes and in the code I calculate the time to the next start as:
Tds=((preset interval, say 10 min) - (the millis() value immediately before deep sleep)) * (calibration factor)
With the calibration as shown above the time of measurement increments precisely at 600 seconds on both units for at least an hour or more.

Making this an automatic feature (calculating the calibration value) requires me to get accurate time from outside via the Internet since there is no way to remember any values across deepsleep restarts, they are just like any other reset and erase the data.
So I think I will have to skip this.
There m

BosseB: since there is no way to remember any values across deepsleep restarts, they are just like any other reset and erase the data.

What about the EEPROM ? you measure time offset store, measure time offset again, compare, calculate and store correction value, and read from then onwards and at times check if the correction value is still OK. Not many writes to the flash..

My problem is what to write into EEPROM and how to verify it back... Maybe a calibration cycle similar to this: 1) Write current time into EEPROM, then immediately deep sleep for an hour or so with nominal time argument 2) On wakeup get current time and millis() so that the time at [u]start from sleep[/u] can be calculated (subtract millis) 3) Now compare the elapsed time from deep sleep start to end with what was commanded 4) Calculate a correction factor to be used from now on.

This depends on the possibility to read an [u]accurate current time value[/u] both in the cycle that begins the deep sleep and the following cycle. I think that we will get at least a 1 sec uncertainty since by what I have seen the time server sets time to the second only... Any suggestion for some compact code I can use in order to get the ESP to provide a current time with at least 1 s accuracy to be used for the calibration above?

But another issue I have seen is that if you start a deep sleep cycle from a regularly started execution cycle or from a cycle that woke up from deep sleep then the timing of the next deep sleep cycle seems to differ. In my tests the first sleep cycle after power-on is always a little shorter than the following cycles even though the exact same code is executed... Seems strange, but that is what I have seen.

And something else I can test in the coming days: Is the deep sleep timing [u]temperature dependent[/u]? I will create some environmental protection for my DHT sensor so I then can put the battery operated unit outside in minus degree weather. If it deviates from the programmed cycle then it looks like I need a calibration cycle now and then (once per day?)

This depends on the possibility to read an accurate current time value both in the cycle that begins the deep sleep and the following cycle. I think that we will get at least a 1 sec uncertainty since by what I have seen the time server sets time to the second only...

you could do more reads per second for a second to get as close to the second changeover as possible.

In my tests the first sleep cycle after power-on is always a little shorter than the following cycles even though the exact same code is executed...

so discard the first cycle for calibration data (or keep it but calibrate the first cycle separately, but now we are doing some more EEPROM writes, though to determine if it is actuall the first cycle after power-on should not be hard to do.) and accept that deepsleep on the first cycle is just a tad off.

1) Write current time into EEPROM, then immediately deep sleep for an hour or so with nominal time argument 2) On wakeup get current time and millis() so that the time at start from sleep can be calculated (subtract millis) 3) Now compare the elapsed time from deep sleep start to end with what was commanded 4) Calculate a correction factor to be used from now on.

that looks right yeah.. btw that first cycle not being accurate compared to the others makes me think that the deepsleep timer is somehow a hwTimer with capacitor discharging and the millis() get set after wake-up to a predefined value.

Now looking at NTP time and I am a bit confused as to the time_t type... Is this a value that is an integer that states the number of seconds since a starting date? If so: 1) When is this starting date? 2) What is the maximum time time_t holds? 3) Is it basically an unsigned integer or is it signed?

I want to store the current time into EEPROM at the moments of: - Starting the DHT measurement cycle - Going to deep sleep I also will store a millis() value so I can check if there are different times to get to the measurements depending for instance on network speed and accessibility.

Then I need to calculate time differences, which would be simple if the time_t variables contain integer seconds, because I can just subtract one from the other and get the difference in seconds.

But the first hit when I Googled it says that there is no standard definition of either the size of the time_t type or its base... How can this be so? And what does the Arduino compiler use?

Is this a value that is an integer that states the number of seconds since a starting date? If so: 1) When is this starting date? 2) What is the maximum time time_t holds? 3) Is it basically an unsigned integer or is it signed?

as far as i know (it came up a few months ago in a thread and i am quoting from memory) it is an unsigned long which is the number of seconds since January 1st 1970. just in case check this and this timelib takes care of a lot of stuff