Let your Arduino get enough sleep

The sensor I am building is based on an Arduino Pro Mini (Atmega328p) with ESP8266 wifi module and a sensor. It will run on batteries with a sample rate of 1 sample per hour. With such low sampling rate it is very obvious that I need to make my microcontroller and the wifi module sleep to reduce power consumption. To wake up the Atmega328p MCU from power down sleep I have to use either the Watchdog Timer (WDT) or an external interrupt. The problem with the WDT on that MCU is that the maximum sleep time it supports is 8 seconds. And to make it sleep longer you need to put the sleep statement in a loop that puts it back into sleep until it reaches a certain count value then resume working.

This is an example of such solution:

for (int i = 1; i <= count ; i++) {
    sleep_cpu ();

However, in 1 hour of needed sleep the MCU will wake up 450 times!

The solution!, in my case I was able to solve this problem with the help of the wifi module which I am using. The ESP8266 has its own deep sleep mode timer that can keep the module asleep for hours or maybe days (I am not sure what is the maximum value that it supports). The deep sleep is triggered with the AT command AT+GSLP and similat to the Arduino the values that it uses is in milliseconds, so “AT+GSLP=60000” will make it sleep for one minute. The ESP8266 has a dedicated pin (XPD_DCDC or GPIO16) that is used to wake up the module by wiring it directly to the reset pin of the module. So when the sleep time is over that pin will pull the reset pin low causing the module to wake-up and restart. I thought about using that pin (XPD_DCDC) to act as an external interrupt (INT0 / Pin2) to wake up the arduino so I tried it and it works. And in order to wake up the wifi module itself which is still asleep I simply connected one of the arduino pins to its reset pin and a quick High-Low-High was enough to get it up and running again.

Here is a fritzing diagram of the connections:

Arduin & ESP8266 Deep Sleep(Note, the ESP8266 ESP-01 has no exposed connection for the wake-up pin XPD_DCDC, put I soldered a wire directly to that pin on the chip which I learned from this Blog while on other variants of the ESP8266 wifi module like ESP-07 and ESP-12 that pin would be the GPIO16)

 ESP8266 wake-up pinHere is a code to show how it is done:

void sleepnow() {
  // Sent sleep command for 1 hour
  set_sleep_mode (SLEEP_MODE_PWR_DOWN);

  // Set INT0 to trigger on Low Level (default)
  EICRA &= ~(_BV(ISC01) | _BV(ISC00));
  // Enable INT0 (Pin 2 on Arduino)
  EIMSK |= _BV(INT0);


  sleep_cpu ();

  // After wakeing up disable sleep then
  // reset ESP8266.

  pinMode(ESP8266_Reset_pin, OUTPUT);
  digitalWrite(ESP8266_Reset_pin, LOW);
  digitalWrite(ESP8266_Reset_pin, HIGH);
  // Stop setting it high to save power since
  // the wifi chip has its own pull-up.
  pinMode(ESP8266_Reset_pin, INPUT);

6 thoughts on “Let your Arduino get enough sleep”

  1. I have tried to use this technique with an ESP-07 and Arduino Pro Mini. It works well with short sleep times but I can’t get it to work with longer times. I am trying to sleep for 15 minutes(AT+GSLP=900000) but the Arduino gets an interrupt from the ESP-07 after approximately six and a half minutes so I cannot sleep for longer than that. If I use the ESP-07 on it’s own and send the sleep command from a terminal it will wake up after about 14 minutes which although not accurate is a lot better than 6 and a half minutes. Have you seen anything like this?

    1. Not really, but are you sure that interrupt the Arduino gets is from the ESP8266?

      In my case while debugging with serial connected to the computer if I press a key on the keyboard that will cause it to wake up, since it also uses interrupts. Otherwise, it will sleep for exactly the time I set it too, I had it running for ~ 2weeks with 30min sleep time and I was plotting the result, there will be few minutes difference between every sleep cycle due to the other tasks that the Arduino does (like waiting for wifi to connect and sensors data…etc)

      1. Thanks for the reply and for publishing this information on your blog.
        I think I have found the problem. My project is currently on a breadboard and I found a poor connection with the pull down resistor on GPIO15. I have made it more secure and checked all other connections and the sleep and wake up is now working correctly. Not sure why this gave me the symptom I was seeing but maybe a stray pulse due to a poor connection somewhere.

  2. How in the world were you able to solder that little pin? I’ve tried several times and can’t get it to stay or i end up burning the chip.

    1. You need a magnifying lens, a small tip for the solder iron and a lot of trial and error.
      Using a magnifying lens or a soldering microscope is great but you need to get used to them since you lose perspective at first.

Comments are closed.