Looking for help with the attached sketch. Trying to understand the sleep and watchdog commands to use in a project. In this test sketch, the program is supposed to light LED 3 times in a loop and then proceed to a sleep instruction. A watchdog timer is supposed to then wait 8 seconds and wakeup the circuit from sleep. Program does the LED loop ok, but then zooms past the sleep command and watchdog timer and goes back to the LED loop immediately. Program does get inside the delayWDT() function but zooms right through it.
Any help would be greatly appreciated. I've looked online but it seems there are different approaches used by various people and it's getting confusing to me.
Thanks.
UPdate: moving the code from the attachment to this area. I hope this helps. Thanks.
// 04.25.2016 Sleep code from element14.com. This sketch works. Comes out of sleep mode by grounding the interrupt pin 2.
// Source: https://www.element14.com/community/thread/40538/l/arduino-sleep-pin-interrupt?displayFullThread=true
// JIMC - Now need to incorporate the Watchdog timer to wake up circuit instead of using the grounding pin to wakeup the circuit.
// Source: Using the Forcetronics example...Part 3 youtube for a Watchdog timer and create a delayWDT function having sleep and wakeup instructions
#include <avr/sleep.h> // Sleep library
#include <avr/wdt.h> // Watchdog library
#include <avr/interrupt.h>; // Interrupt library
// Note: Commenting out all code related to the Element14.com example sleepNow sketch. Using the Forcetronics Watchdog delay function to sleep and wake. See source above.
// int wakePin = 2;
int led=13;
// void wakeUpNow() {
// }
void setup() {
wdt_disable(); // The datasheet recommends disabling WDT right away in case of a low probability event that could cause premature timeout activation
// pinMode(wakePin, INPUT_PULLUP);
pinMode(led, OUTPUT);
// attachInterrupt(0, wakeUpNow, LOW);
Serial.begin(9600); // Initiate Serial Monitor
}
// Code from Element14.com commented out. We are using the Forcetronics code for a Watchdog delay routine for power reduction (the Arduino delay uses a lot of power)
// Create sleepNow function
// void sleepNow() {
// set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Selecting the lowest power setting
// sleep_enable(); // Enable sleep function
// attachInterrupt(0, wakeUpNow, LOW); // Set interrupt function, pin 2
// sleep_mode(); // Go to sleep. Will wake up upon interrupt activation via Watchdog timer in this sketch.
// sleep_disable(); // Disable sleep for now after Watchdog timer interrupt activation
// detachInterrupt(0); // Deactivate Watchdog timer interrupt for now
// }
void loop() {
// Set loop for 2.2 sec on/off LED cycle for 3 loops, total 6.6 seconds - then enters sleep mode until Watchdog timer interrupt is issued after 8 seconds (WDT0_8S)
for (int i = 0; i < 3; i++) {
digitalWrite(led,HIGH);
Serial.print("Blink ");
delay(200);
digitalWrite(led,LOW);
delay(2000);
}
Serial.println(" Loop complete - go to delay function to sleep");
Serial.print(" ");
// sleepNow(); // Code from Element14.com commented out. We are using the Forcetronics code for a whatdog delay routine for power reduction (the Arduino delay uses a lot of power)
delayWDT(WDTO_8S); // Using the WDT sleep function, argument is Byte type variable from the WDT library. WDTO_8S is the argument for an 8 second delay.
// Other arguments in the library: WDTO_15MS, WDTO_30MS, WDTO_60MS, WDTO_120MS, WDTO_250MS, WDTO_500MS, WDTO_1S, WDTO_2S, WDTO_4S, WDTO_8S
}
// Create delayWDT function, with argument 'timer' for type 'byte'
void delayWDT(byte timer) {
Serial.println("Entered delayWDT function");
sleep_enable(); // Enable sleep function
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Selecting the lowest power setting
// ADCSRA &= ~(1<<ADEN); // Optional - comment out - turns off ADC (analog to digital circuit) before going to sleep to save some power - Sets ADEN bit to '0'
WDTCSR |= 0b00011000; // Sets the WDE bit and then clear it when set the pre-scalar. Note: WDCE bit must also be set if changing WDE bit.
WDTCSR = 0b01000000 | timer; // OR timer prescalar byte value with interrupt selection bit set
// WDTCSR = 0b01000110; For information only - commented out - this sets the WDT to 1 second for example
wdt_reset(); // Reset the WDT
Serial.println("Entering sleep");
sleep_cpu(); // enter sleep mode. Next piece of code that is executed is the ISR when the Watchdog timer interrupt wakes the circuit up from sleep
sleep_disable(); // disable sleep mode
Serial.println("Woken up");
// ADCSRA |= (1<<ADEN); // Optional - see ADCSRA line above - optional - turn ADC back on
}
// Create the Interrupt Service Routine (ISR)
ISR (WDT_vect) {
wdt_disable();
// MCUSR = 0; // Optional - clears WDT flag since it is disabled - See Forcetronics Part 3 Video on youtube
}
Element14dotcom.ino (4.07 KB)