Waking from sleep.

Hello,

I have some code that will put my system to sleep, but I am not sure how take it out of sleep.

Do I need to attached an interrupt?

Ideally I would like it to wake up when it receives an analog signal in. This is why I am using the Idle mode. I believe that in idle, it can still receive analog signals. However, that may be incorrect.

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

int count = 0;
int analogPin = 0;

void setup()
{
  Serial.begin(9600);
  pinMode(analogPin, INPUT);
}

void sleepNow()
{
  set_sleep_mode(SLEEP_MODE_IDLE);
  
  sleep_enable();    //enables the sleep mode bits in the register
  
  power_spi_disable();
  power_timer0_disable();
  power_timer1_disable();
  power_timer2_disable();
  power_twi_disable();
  
  sleep_mode();
  
  sleep_disable();
  
  power_all_enable();
}

void loop()
{
  count++;
  delay(1000);
  
  if(analogRead(analogPin) < 10 && count == 10)
    {
      Serial.print("Sleeping");
      delay(100);  //Delay needed to avoid error
      //count = 0;
      sleepNow();
    }
    if(analogRead(analogPin) > 11)
    {
      Serial.println("Hello again");
      delay(100);
      count = 0;
  }
}

One of the Jeelabs libraries has this functionality nicely packaged, try googling 'Sleepy::loseSomeTime()' and have a look at the source code.

Depending on the level of the analog signal, you might also be able to use the analog comparator in the chip. See section 22 in the atmega328p datasheet.

If your intent is to conserve power, you should also get rid of all delay() calls, as they, if I'm not mistaken, are implemented as delay loops and therefore keep the processor running full speed consuming power.

If you want to wake-up only on a certain analog input level, dc42's suggestion is good and you should use the analog comparator. Otherwise you'll conserve more power by just polling the ADC input a few times a second, but removing all delay() calls. Any interrupt will make you awake from the simple sleep mode.

Take a look at the MsTimer2 lib, it uses an interrupt; if you install a timer handler which only increments a global variable you'll have a periodic interrupt; your loop can then be just a sleep() at the top and then your ADC reading. The sleep() will exit every time an interrupt is triggered.

dc42:
Depending on the level of the analog signal, you might also be able to use the analog comparator in the chip. See section 22 in the atmega328p datasheet.

Thanks for the reply ....yea, I am trying to figure out the analog comparator ...I put up a post about it for a littel help ...so, I will be giving that a good too.

Thanks for all the replies.

Seán