Does anyone have experience powering down or sleeping & waking a microprocessor-based, battery-operated handheld device?
I am in the final stages of an ESP8285-based handheld device project that is powered by a battery. I want to enter sleep or power down the device after some time of inaction to increase battery life.
After lots of research, I have found that:
Putting the 8285 to sleep for a programmed time can be done in “startup” using ESP.deepSleep() functions. After this time it will wake up [if wired correctly]. It can also be awoken via an I/O pin or interrupt.
This approach has all the code in “startup” and somewhere in that code it tells the processor to sleep for a programmed amount of time after which it awakes and runs “startup”.
In my app I want it to go to sleep after some time of inaction at the devices panel, not on a programmed cycle.
It seems that it is a common need for a device like this to sleep yet I find no examples of how this is done.
The only way I can think to do this is:
Keep track of a timer in the main program (like 10 min).
Reset this timer when a button is pushed.
When no buttons are pushed and the timer expires execute an ESP.deepSleep(0) [0 = infinity]
The user cycles the power switch to reset and therefore wake up the device.
The above seems kludgey to me.
Any other advice and examples are welcome.
I think how you describe it is indeed how it’s done, except for the last thing: any button should be able to wake it up if it’s asleep; shouldn’t have to power reset to wake. What inputs do you have?
When I most recently did this, it was on an ESP32, and it did wake on any button push.
(I’d think that a hardware watchdog-like auto-sleep function would be even more complicated from having to explicitly poke to to make it not to to sleep, or… just hope that they had the particular heuristics you want? Maybe I’m not understanding what you would expect it to work like?)
ex: if I am using D0 as a functional button can I also assign it as a wakeup button. Does the wakeup function stop looking at that button after it wakes?
What does the processor do when the wakeup button is asserted. Is this an interrupt and does it need an ISR? Or does it just do a reset?
I’ve probably run out of helpfulness, because I barely worked with the 16-bit ESPs and mostly have used ESP32 variants, and it’s been too long even there. I don’t know whether I even have the code around for the ESP32 project to check — was a father-son thing and there was a lesson that happened there involving the importance of data backup.
I’d just be surprised if you couldn’t wake up from deep sleep on arbitrary button press because so many gadgets do just that.
I got lost in model numbers. For anyone else who lands here, the ESP8285 is a (single core I think) 32-bit Tensilica like most of the ESP32 family, in a small package with a more limited number of GPIOs.
Espressif consider the Risc-V ESP8684 to be the newer version, which has half the deep-sleep power consumption. The ESP8285 consumes 10 µA in deep sleep, and the ESP8684 consumes 5 µA.
While RTC (Real Time Clock) is the only powered unit during deep sleep, so you would think that you could only wake up based on a timer, it turns out that this RTC unit is also responsible for monitoring external conditions for wakeup. You can configure it to wake up on either high or low condition for the RTC-enabled GPIOs you choose. See the “External Wake up” section in this article:
What I don’t see in the 8285 datasheet is a list of which GPIOs are RTC GPIOs.
In deep sleep the only part of the system running is the RTC; the GPIO system is hard off.
The only way to wake the module is with a soft-reset; this can be generated from the timer on GPIO16 (the RTC timer signal pin) which is linked to RST. You could wake your system by parisiteing that line with the interrupt signal, it’s pull down to reset.
Not tested this mode yet.
Tying GPIO16 to reset causes wakeup (reset) after the programmed time.
I am planning on using the esp_sleep_enable_ ext0_wakeup(), or esp_sleep_enable_ ext0_wakeup() functions which should wakeup from a pin defined in the parameters of those functions. The pin has to be a RTC capable pin.
I was doing some stuff with an ESP32 in a T-Watch and trying to keep the clock/time accurate even through sleep cycles since I didn’t want to use WiFi to keep the clock accurate. It had a builtin RTC after all but what I found was there was no accurate clock signal and if you wanted to come out of deep sleep with an accurate clock you needed the external 32KHz xtal.
Also where I ran into conversations about different sleep modes, lowering clock speeds to CPU and memory to decrease power usage.
So you might find interesting things related to power usage and sleeping in the T-Watch threads.
The T-Watch is a ESP32-S3 device; which has good deep-sleep wake options, from IO pins, uart and it’s internal timers.
The ESP8266 based devices have no deep sleep wake option other than a (soft) reset on the RST pin, so I think Don will end up having to use that. It’s pull-down and easy to have multiple sources of the signal, eg from a seperate RTC and a button.
The T-Watch actually has a a seperate PFC8563 RTC chip onboard with a crystal and backup battery. It has an interrupt pin that goes to a deep-sleep wake capable gpio pin on the ESP32. There is no need to touch the internal RTC of the mcu. The micropython firmware I use gives 2/3 days of on-wrist use by leveraging the RTC, touchscreen and MMU (accelerometer) interrupt features.
That must be some other T-Watch than the 2020 v2 model I have because it has no external RTC, the ESP32 has onboard RTC( and the ESP8285 Don mentioned is more like the ESP32 than the ESP8266 from what I gathered).
There is an onboard RTC and that’s what’s active in deep sleep BUT it’s not very accurate because it likely uses the onboard clock so when you wake up there will be some missing or gained time. ie the time the RTC has is not going to be the same as the outside world. To improve this there are a couple of GPIO pins which can have a more accurate xtal placed across them(32KHz).
There are gobs of forum discussions on this and some tricks which can be played to know the drift and correct for it when a consistent sleep period is used. In Don’s case he wants to wake on an IO so if he cares how accurate the RTC time is, he’ll want to enable/implement the 32KHz xtal support or add an offboard battery backed RTC clock.
example of just one discussion I found: RTC accuracy - ESP32 Forum