Rummys Blog An world of endless Monday

Friday, 30 November, 2018

An IoT Mousetrap Part 3 – wake-stub polling

Filed under: ESP,ESP32 — Andrew.Rowbottom @ 1:00 pm

The current investigation state of my IoT Mousetraps, iteration #3.

Background:

My mousetraps are currently

  • running “directly” off 600mAh batteries
  • using a “replaced” Voltage Regulator that draws ~70µA
  • sensing the status of the actual trap using an input pin in “pull-up” mode (drawing ~70µA)
  • waking fully up at a configurable interval to send quite a lot of status and debug information via espNow to an esp8266 connected to a RaspberryPi and Node-Red
  • fully on for approx 300ms (excluding time-to-wake-up and re-enter deep-sleep)
  • lasting only about 3 months between recharges

Ignoring the 70µA drawn by the Voltage Regulator for the moment, about half of the current drawn during deep-sleep is from using the inbuilt pull-up capabilities of the GPIO used for sensing state.

Now, I could use external pull-up resistors, and that is probably the most sensible approach! But for the hell of it I am investigating “polling”.

Using a WakupStub

There are quite a few things required to use a wakeup stub, for reference see deep-sleep-stub.rst, I’m sure I’ve not covered all of the requirements here, but some of the major points are

  • If you call it void RTC_IRAM_ATTR esp_wake_deep_sleep(void) then you don’t need to explicitly set it as the wakeup stub
  • It needs to be marked as RTC_IRAM_ATTR (or in a specially named source file) so the code is stored in the RTC RAM.
  • The RTC fast (and probably slow) RAM need to be kept enabled when entering deep sleep
    esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_FAST_MEM, ESP_PD_OPTION_ON)
    esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_SLOW_MEM, ESP_PD_OPTION_ON)
  • Everything you want to call needs to be either in ROM, or in RTC_IRAM, and that happens to be a *LOT*, so you’ll have to find the equivalent code and copy it into your project (renamed and marked RTC_IRAM_ATTR)
  • You can re-enter deep sleep, but the calculation is moderately complex, though I have simplified this by computing a “per-second” scale factor in my “setup()” and storing it for easy use in the wakeup stub.
  • If you want to wake up fully you must call esp_default_wake_deep_sleep()
  • If you want to go back into deep sleep you do not need to call esp_default_wake_deep_sleep()

Current Draw and Timings

Playing around with excessive delays in the wake-stub so that I can use a simple multimeter to measure milli-amps gives me a current draw of a little over 12mA (with the built-in LED off).

Comparing that with a constant 70µA means that my polling code can be “awake” in the wakeup stub for approx 0.07/12 of the time .. i.e. 0.5% of the time .. or roughly 5ms every second at a 1 second poll rate, more at a slower poll rate.

Using my oscilloscope initially I had some very disturbing timings, my wake stub was taking 47ms!

The output was:

ets Jun 8 2016 00:22:57

rst:0x5 (DEEPSLEEP_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
set from pre-set=0x70A72
calling my_rtc_sleep_set_wakeup_time with 3053670 + 461426 Wake count 2
with GPIO22 LOW GPIO15 is 0
with GPIO22 HIGH GPIO15 is 1
about to call ledStateIRAM with 1

gpio15 and 22 are connected
about to sleep from wakeup!
sleeping, awake between 3053650 and 3056738 rtc ticks, expected to wake at 3515096
sleeping, awake between 18882309 and 18901404 micros, expected to wake at 21735670

I noticed that it was going back into deep-sleep immediately after the serial output was complete, so I massively reduced the output and had a wake time of about 10ms. Still Too Large!

ets Jun 8 2016 00:22:57

rst:0x5 (DEEPSLEEP_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
Wake count 2

Then I completely removed the code that was flushing the buffer and I now have 0.5ms (Different scale!)

Output:

ets J

This is approx 0.5 ms! Tidily under the 5ms computed budget, and this could be improved dramatically by polling at an even slower rate.

 

For sanity checking rather than just monitoring the serial and state of an output pin I also tagged the current through a 1 Ohm resistor. This gave a 1.5ms “on time” though admittedly a fair bit of that seems to be die down.

I have a very noisy scope, but I think you can see that the current starts to be drawn a reasonable time before the serial output starts.

I’ve measured from the increase to the end of the current draw, you can see the exponential decay on the serial line which would match the deep sleep starting I think.

The Sensible Solution!

Obviously the sensible (easy) solution would be to do a full wake-up every 1 hour, and accept that the trapped mouse isn’t going anywhere. That would have been sensible!

No Comments »

No comments yet.

RSS feed for comments on this post. TrackBack URL

Leave a comment

Powered by WordPress