I have been struggling to get my Adafruit 5v pro mini to loop in deep sleep mode several times, then awake to perform something then return to the deep sleep mode loop. While it is out of deep sleep mode I want the watchdog timer to be active to protect against system hangups. Although I can get in and out of deep sleep mode easy enough, and I can also use a loop that performs one deep sleep/awake cycle. I want to maximize the power savings by having a prolonged deep sleep period of several minutes. I have read many posts related to this subject, but have not yet found a response works for me. Attached is my code, which loops through the sleep cycle twice, but not if ISR(WDT_vect) on row 85 calls my hardwareReset() function. If my call to hardwareReset is used, my test loop on rows 25-30 times out as expected, but my waitSleep function no longer loops twice. Can anyone please offer guidance? Many thanks
// thanks to KeyChainino for basic code. I added ADC disable to further reduce power from 0.67mA to 0.54mA
//
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/wdt.h>
const int ledPin = 13;
const int resetPin = 9;
// the setup function runs once when you press reset or power the board
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(resetPin, OUTPUT);
digitalWrite(resetPin,HIGH);
Serial.begin(9600);
Serial.println("Resetting..");
delay(100);
}
// the loop function runs over and over again forever
void loop() {
digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(13, LOW); // turn the LED off by making the voltage LOW
for(int i=0; i<9; i++){; //set up loop to force timeout of WDT
delay(1000);
Serial.print("Loop ");
Serial.println(i);
delay(100);
}
waitSleep(2); //go sleep for x loops of WDT settings (8 sec max per loop)
}
void waitSleep(int sleep_cycles) {
while (sleep_cycles) {
goSleep();
sleep_cycles--;
}
}
void goSleep() {
watchdogSetup(); //enable watchDog
// disable ADC (analog to digital conversion)
byte old_ADCSRA = ADCSRA;
ADCSRA = 0;
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_mode();
//disable watchdog after sleep
wdt_disable();
ADCSRA = old_ADCSRA;
}
void watchdogSetup() {
//WDP3 - WDP2 - WPD1 - WDP0 - time
// 0 0 0 0 16 ms
// 0 0 0 1 32 ms
// 0 0 1 0 64 ms
// 0 0 1 1 0.125 s
// 0 1 0 0 0.25 s
// 0 1 0 1 0.5 s
// 0 1 1 0 1.0 s
// 0 1 1 1 2.0 s
// 1 0 0 0 4.0 s
// 1 0 0 1 8.0 s
// Reset the watchdog reset flag
bitClear(MCUSR, WDRF);
//The following bit have to be set at the same time otherwise the system doesn't set the right value
/* Start timed equence */
//Watchdog Change Enable to clear WD (by setting the WDCE bit) and Enable WD (by setting the WDE bit)
WDTCSR |= (1 << WDCE) | (1 << WDE);
//Set new watchdog timeout value to 8 seconds (WDP3 and WDP0 to 1) and enable interrupts instead of reset (WDIE to 1)
WDTCSR = (1 << WDIE) | (1 << WDP3) | (1 << WDP0) ;
}
void hardwareReset(){;
digitalWrite(resetPin,LOW);
}
ISR(WDT_vect) {
//hardwareReset();
}