Could use some help. Pretty much tried everything I could find online I think.
This sketch simply activates a relay approx. every hour for 12 seconds. There is a 10 second loop with a short LED flash and then goes to sleep for 8 seconds. Wakeup via Watchdog timer set at 8 seconds. I've scrubbed out as much as I could from the sketch including any serial code that might have contributed to the conflict, an SD card data logger, etc but results are the same. Am running this on a breadboard atmega328p-pu setup powered by 4 AA rechargeable batteries. It seems to run fine for a few hours then goes into something of an extremely rapid loop...the relay is not activated in this loop, just the LED. I've read about memory leakage, WDT issues, reset issues, etc. so not sure where I can go next. Are the reset and disable commands properly set? Do I need to add any minor delays anywhere before proceeding? I am activating the relay every hour just for testing. Ultimately I want to set it for approximately every 12 hours. Timing precision is not required.
At the end of the sketch, I have a note from something I read online but not sure if it is the key or how to implement a solution.
Any help would be greatly appreciated. Thanks.
// In this sketch, the LED's flash every 10 seconds, then at each approximately 1 hour period, the relay is activated
// for 12 seconds. It uses the WDT at its maximum 8 second delay to wakeup the circuit from low power sleep.
// Source: citizen-sensing.org/2013/07/arduino-watchdog/
// Check this out for good explanation on the Watchdog timer and code.
// http://www.leonardomiliani.com/en/2013/impariamo-ad-usare-il-watchdog-2/
// SEE NOTE at the end on WDT reset issue
#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/wdt.h>
int j = 1; // Elapsed time multiplication factor
int j2 = 0; // previous j value
float tCumm = 0.0; // Cummulative time
float hSet = 1.0; // Set relay activation once per hour
float hSet2 = 0.0; // Previous hSet value
// Create sleepNow function
void sleepNow() {
wdt_reset();
wdt_disable();
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Selecting the lowest power setting
// Set watchdog parameters
MCUSR &= ~(1<<WDRF); // reset status flag
WDTCSR |= (1<<WDCE) | (1<<WDE); // required to enable configuration changes
WDTCSR = (1<<WDP0) | (1<<WDP3); // set the pre-scalar for 10, ie 8 seconds delay
WDTCSR |= (1<<WDIE); // enable interrupt mode
// Disable the ADC
ADCSRA &= ~(1<<ADEN); // Set bit 7 in ADC register to 1 to disable the ADC
// Ready for sleep
sleep_enable(); // Enable sleep function
sleep_mode(); // Go to sleep. Will wake up upon interrupt via Watchdog timer in this sketch.
// disable sleep after waking up
sleep_disable(); // Disable sleep for now after Watchdog timer interrupt activation
}
void setup() {
pinMode(4, OUTPUT); // set pin 4 as output for LED
pinMode(7, OUTPUT); // set pin 7 as output for relay
}
void loop() {
// 10 second LED flashing + sleep loop
for (int i = 0; i < 2; i++) {
digitalWrite(4, HIGH); // turn the LED on (HIGH is the voltage level)
delay(200); // wait for 0.2 sec
digitalWrite(4, LOW); // turn the LED off by making the voltage LOW
delay(200); // wait for 0.2 second
}
// Add delay for total approx 2 sec
delay(1200);
// Start sleep / Low power / Watchdog interrupt
sleepNow();
// Cummulative time in increments of 10 seconds
tCumm = ((2.0 + 8.0)*j)/3600.;
// Time multiplication factor. Used to increment tCumm. Never resets to zero.
j2 = j;
j = j2 + 1;
// Check to see if tCumm exceeds the user defined period (hSet) before activating relay
if (tCumm > hSet) {
// Activate relay for 12 seconds
digitalWrite(7, HIGH);
delay(12000);
digitalWrite(7,LOW);
// Reset hSet for next relay activation time
hSet2 = hSet;
hSet = hSet2 + 1.0;
}
}
ISR (WDT_vect) {
}
// NOTE from online discussion: The problem is that a RESET does not turn off the watchdog timer
// once it has been turned on, and neither does the bootloader. So you set things up to have
// the watchdog cause a reset in 15ms, and the reset occurs. Now the bootloader starts up, and starts
// its //LED-flashing, and OOPS another 15ms has gone by with no one feeding the watchdog, and it
// resets again. This repeats until a power cycle turns off the watchdog. (This behavior is
// explicitly described in the ATmega datasheet...)