Cannot put arduino pro mini into sleep

Hello all, I’m new here :slight_smile:

I need to put microcontroller into sleep mode but it doesn’t work as i expected, so probably i didn’t understand something. Example code:

#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/interrupt.h>

void setup() {
  pinMode(13,OUTPUT);
  digitalWrite(13,LOW);
}

void loop() {
  set_sleep_mode(SLEEP_MODE_IDLE);
  sleep_enable();
  sleep_mode();
  /* The program will continue from here. */
  /* First thing to do is disable sleep. */
  sleep_disable(); 
  digitalWrite(13,HIGH);
}

As far as i understand, it should never put high state (turn on led) on 13, because there’s nothing to wake the microcontorller up - it will “freeze” on sleep_mode(); line. But it does, it light the led a moment after turning on and I don’t know why.
Please help :slight_smile:

There are different sleep modes

SLEEP_MODE_IDLE -the least power savings SLEEP_MODE_ADC SLEEP_MODE_PWR_SAVE SLEEP_MODE_STANDBY SLEEP_MODE_PWR_DOWN -the most power savings

Note: In IDLE mode, the clocks are running. This means that (unless you disable it) the normal Timer 0 clock used to count millis() will be running, and thus you will wake up approximately every millisecond. So an Arduino will not realy go to sleep in sleep mode IDLE.

For more information take a look at: http://gammon.com.au/power

Example

//  Arduino Sleep Mode Demo

#include <avr/sleep.h>
int ledPin   = 13;

void setup()
{   pinMode(ledPin, OUTPUT);
}

void loop()
{   for (int i=0; i<3; i++)     // LED will blink 3 times
    {  delay(2000);
       digitalWrite(ledPin, HIGH);
       delay(2000);
       digitalWrite(ledPin, LOW);
    }
    
   /* Now is the time to set the sleep mode. In the Atmega328 datasheet
    * there is a list of sleep modes which explains which clocks and 
    * wake up sources are available in which sleep mode.
    *
    * In the avr/sleep.h file, the call names of these sleep modes are to be found:
    *
    * The 5 different modes are:
    *     SLEEP_MODE_IDLE         -the least power savings 
    *     SLEEP_MODE_ADC
    *     SLEEP_MODE_PWR_SAVE
    *     SLEEP_MODE_STANDBY
    *     SLEEP_MODE_PWR_DOWN     -the most power savings
    *
    * For now, we want as much power savings as possible, so we 
    * choose the according sleep mode: SLEEP_MODE_PWR_DOWN
    */  

    set_sleep_mode(SLEEP_MODE_PWR_DOWN);   // sleep mode is set here

    sleep_enable();    // enables the sleep bit in the mcucr register
        	       // so sleep is possible. just a safety pin 

    sleep_mode();     // here the device is actually put to sleep!	
}

What are you doing to wake up? Such as an interrupt?

Thanks for your answers, with SLEEP_MODE_PWR_DOWN it works as i expected.
What i need is to have my uc sleeping most of the time and being woke up only by two external interrupts, and i have one more question about it. Can do do instructions normally inside interrupt function? It works with blinking led, but causes problems with Serial communication. Example:

#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/interrupt.h>

void setup() {
  attachInterrupt(0, wakiewakie, RISING);
  Serial.begin(9600);
}

void wakiewakie()
{
  sleep_disable(); 
  Serial.println("hello");
}

void loop() {
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  sleep_mode();

  sleep_disable(); 
}

What i get on serial monitor is (after causing some interrupts):

[00][00]•±±˝[01][00]C…´ello[00]C…´ello[00]C…´ello[00]C…´ello[00]C…´ello[00]C…´ello[00]C…´ello[00]C…´ello[00]C…´ello[00]C…´ello[00]C…´ello[00]C…´ello[00]
  1. Interrups should have execution time as short as possible (this is a gernal rule).
  2. You should use only “interrupt proof funcions” - Serial is not (because it uses interrupts itself).

What you normaly do: set a flag in the interrupt routine (change the value of a variable). this variable must be declared volatile. Evaluate the flag (variable) in the loop().

Take a look at an interrupt tutorial like: Gammon Forum : Electronics : Microprocessors : Interrupts

Thank you, I will do it like you advised. I figured that it works good when i do Serial.flush() before putting uc into sleep - I guess i should always do it when i use serial communication and interrupts?

Serial communication is pretty slow - about 1ms for one character at 9600 baud. Within 1ms the microcontroller can do a lot of other things.

Serial.flush() waits for the transmission of outgoing serial data to complete. So if in your program there is serial communication "close" to sending µC to sleep, using Serial.flush() may be a good idea.