//**********************Arduino Code*******************************
#include <avr/wdt.h> //Watch dog timer functions
#include <EEPROM.h> //library for using EEPROM
// Pin 13 has an LED connected on most Arduino boards.
int led = 13;
volatile int wSetting = 1; //variable to store WDT setting, make it volatile since it will be used in ISR
void setup() {
wdt_disable(); //Datasheet recommends disabling WDT right away in case of low probabibliy event
pinMode(led, OUTPUT); //set up the LED pin to output
pinMode(2,INPUT_PULLUP); //setup pin 2 for input since we will be using it with our button
getSettings(); //start serial settings menu to choose WDT setting
//setup the watchdog Timer based on the setting
if(wSetting == 1) setWDT(0b01000000); //set for interrupt
else if(wSetting == 2) setWDT(0b00001000); //set for reset
else setWDT(0b01001000); //set for interrupt and then reset
}
void loop() {
if(!digitalRead(2)) { //check if button to reset WDT was pressed
digitalWrite(led, LOW); // turn the LED off by making the voltage LOW
wdt_reset(); //Reset the WDT
}
}
//This function gets the WDT setting from the user using Serial comm
void getSettings() {
Serial.begin(57600);
Serial.println("We just started up......");
byte b; //variable to store interrupt / reset tracker
if(EEPROM.get(10, b)) { //check if interrupt occurred before reset
Serial.println("...and an interrupt occurred.....");
b = 0; //reset variable
EEPROM.put(10,b);
}
Serial.println("Select the WDT setting: 1 --> interrupt, 2 --> reset, 3 --> interrupt and reset");
//wait for user to input setting selection
while (!Serial.available()) { }
wSetting = Serial.parseInt(); //get entry and ensure it is valid
if(wSetting < 1 || wSetting > 3) {
wSetting = 1;
}
Serial.print("WDT setting is ");
Serial.println(wSetting);
Serial.println();
Serial.end(); //don't want to mix serial comm and interrupts together
}
/*
void setSleepInterval(byte timer) {
sleep_enable(); //enable the sleep mode
set_sleep_mode(SLEEP_MODE_PWR_DOWN); //set the type of sleep mode. Default is Idle. power down saves the most power
ADCSRA &= ~(1<<ADEN); //Turn off ADC before going to sleep (set ADEN bit to 0). this saves even more power
WDTCSR |= 0b00011000; //Set the WDE bit and then clear it when set the prescaler, WDCE bit must be set if changing WDE bit
WDTCSR = 0b01000000 | timer; //This sets the WDT to the interval specified in the function argument
wdt_reset(); //Reset the WDT
sleep_cpu(); //enter sleep mode. Next code that will be executed is the ISR when interrupt wakes Arduino from sleep
sleep_disable(); //disable sleep mode
ADCSRA |= (1<<ADEN); //Turn the ADC back on
}*/
//this function setups up and starts the watchdog timer
void setWDT(byte sWDT) {
WDTCSR |= 0b00011000;
WDTCSR = sWDT | WDTO_2S; //Set WDT based user setting and for 2 second interval
wdt_reset();
}
//This is the interrupt service routine for the WDT. It is called when the WDT times out and is in interrupt mode.
//This ISR must be in your Arduino sketch or else the WDT will not work correctly
ISR (WDT_vect)
{
digitalWrite(led, HIGH);
if(wSetting == 3) {
byte b = 1;
EEPROM.put(10, b);
}
//wdt_disable();
} // end of WDT_vect