I’m experimenting with a 328p in advance of a project where I want the MC to wake up every 24 hours, do something, and go back to sleep to save power. The MC is on a breadboard with a 16Mhz crystal and 22pF caps. The bootloader is just that of the standard Arduino Uno. My experimental code is below based on [Nick Gammon’s power tutorial. It simply turns on an LED for 2 seconds, then sleeps for about 8 seconds using the watchdog timer.
However, each cycle is taking about 11.25 seconds, meaning the sleep cycle is about 9.25 seconds. I’ve tried different sleep modes but it doesn’t seem to make any difference. Is there some way to make the watchdog timer more accurate, or reference the crystal during sleep? Or am I missing something obvious?
void loop(void) {
// Light the LED
pinMode(8, OUTPUT);
digitalWrite(8, HIGH);
delay(2 * 1000);
digitalWrite(8, LOW);
// go to sleep: http://www.gammon.com.au/power
// clear various "reset" flags
MCUSR = 0;
// allow changes, disable reset
WDTCSR = bit (WDCE) | bit (WDE);
// set interrupt mode and an interval
WDTCSR = bit (WDIE) | bit (WDP3) | bit (WDP0); // set WDIE, and 8 seconds delay
wdt_reset(); // pat the dog
set_sleep_mode (SLEEP_MODE_PWR_SAVE);
sleep_enable();
// turn off brown-out enable in software
MCUCR = bit (BODS) | bit (BODSE);
MCUCR = bit (BODS);
sleep_cpu ();
// cancel sleep as a precaution
sleep_disable();
}
](Gammon Forum : Electronics : Microprocessors : Power saving techniques for microprocessors)