/**/
#include <avr/wdt.h>
volatile bool isr_wdt_flag = false;
volatile uint32_t isr_wdt_micros = 0;
volatile bool isr_timer1_compa_flag = false;
volatile uint32_t isr_t1_micros = 0;
uint32_t previous_t1_micros = 0;
const char* ByteToBinaryStr(byte data)
{
static char buffer[9] = "";
buffer[8] = '\0';
char* pbuffer = buffer;
for (byte b = 128; b > 0; b >>= 1, pbuffer++)
{
*pbuffer = (data & b) ? '1' : '0';
}
return buffer;
}
void setup()
{
// put your setup code here, to run once:
Serial.begin(1152000);
Serial.println("WDT Test");
if (bitRead(MCUSR, WDRF))
{
Serial.println("System was reset due to watchdog timeout.");
Serial.println();
}
cli(); // Disable interrupts.
//
// Set Timer1 interrupt
//
// Clock frequency = 16 MHz
// Interrupt frequency = 1 kHz
// Prescaler = 64
//
// Timeout = 16 MHz / 64 / 1 kHz - 1 = 249
//
TCCR1A = 0; // Clear TCCR0A register.
TCCR1B = 0; // Clear TCCR0B register.
TCNT1 = 0; // Clear counter value.
OCR1A = 249; // Set timeout value.
TCCR1A = (1 << COM1A1); // CTC mode.
TCCR1B = (1 << WGM12) | (1 << CS11) | (1 << CS10); // CTC mode and prescaler.
TIMSK1 = (1 << OCIE1A); // Enable compare interrupt.
//Serial.println(WDTCSR);
wdt_reset();
//__asm__("wdr");
Serial.println(WDTCSR);
//wdt_enable(WDTO_15MS);
WDTCSR = (1 << WDCE) | (1 << WDE);
WDTCSR = (1 << WDIE) | (1 << WDP0) | (1 << WDE);
Serial.println(ByteToBinaryStr(WDTCSR));
sei(); // Enable interrupts.
}
void loop()
{
// put your main code here, to run repeatedly:
//Serial.println(ByteToBinaryStr(WDTCSR));
cli();
bool wdt_flag = isr_wdt_flag;
isr_wdt_flag = false;
uint32_t wdt_micros = isr_wdt_micros;
bool timer1_compa_flag = isr_timer1_compa_flag;
isr_timer1_compa_flag = false;
uint32_t t1_micros = isr_t1_micros;
sei();
if (wdt_flag)
{
Serial.print(wdt_micros);
Serial.print(" WDTCSR = ");
Serial.println(ByteToBinaryStr(WDTCSR));
wdt_flag = false;
//__asm__("wdr");
WDTCSR = 1 << WDIE;
//wdt_reset();
}
if (timer1_compa_flag)
{
//Serial.print("timer1_compa_flag ");
//Serial.println(t1_micros);
static uint16_t count = 0;
count++;
//Serial.print(count);
//Serial.print(": ");
//Serial.println(t1_micros - previous_t1_micros);
previous_t1_micros = t1_micros;
timer1_compa_flag = false;
}
}
ISR(WDT_vect)
{
//Serial.println("ISR timeout");
isr_wdt_flag = true;
isr_wdt_micros = micros();
WDTCSR = 0;
}
ISR(TIMER1_COMPA_vect)
{
static byte count = 0;
count++;
if (count == 25)
{
// Reset TWI;
}
isr_t1_micros = micros();
isr_timer1_compa_flag = true;
}
/**
// https://forum.arduino.cc/t/tutorial-basic-watchdog-timer-setup/63397/18
#include <avr/wdt.h>
int loop_count = 0;
int wdt_counter = 0;
void setup()
{
Serial.begin(115200);
Serial.println("Starting up...");
pinMode(13, OUTPUT);
digitalWrite(13, HIGH);
delay(500);
watchdogStart();
}
void watchdogStart(void)
{
cli(); // disable all interrupts
wdt_reset(); // reset the WDT timer
// WDTCSR configuration:
// WDIE = 1: //Interrupt Enable
// WDE = 1 : //Reset Enable
// WDP3 = 0 :
// For 2000ms Time-out WDP2 = 1 :
// For 2000ms Time-out WDP1 = 1 :
// For 2000ms Time-out WDP0 = 1 :
// For 2000ms Time-out
// Enter Watchdog Configuration mode:
WDTCSR = (1<<WDCE) | (1<<WDE); // Set Watchdog settings:
WDTCSR = (1<<WDIE) | (0<<WDE) | (0<<WDP3) | (1<<WDP2) | (1<<WDP1) | (1<<WDP0);
sei();
}
void watchdogArm(void)
{
cli(); // disable all interrupts
wdt_reset(); // reset the WDT timer
// WDTCSR configuration:
// WDIE = 1: //Interrupt Enable
// WDE = 1 : //Reset Enable
// WDP3 = 0 :
// For 2000ms Time-out WDP2 = 1 :
// For 2000ms Time-out WDP1 = 1 :
// For 2000ms Time-out WDP0 = 1 :
// For 2000ms Time-out
// Enter Watchdog Configuration mode:
WDTCSR |= (1<<WDCE) | (1<<WDE); // Set Watchdog settings:
WDTCSR = (1<<WDIE) | (1<<WDE) | (0<<WDP3) | (1<<WDP2) | (1<<WDP1) | (1<<WDP0);
sei();
}
void loop()
{
Serial.println(WDTCSR, 2);
for (int i = 0; i <= loop_count;i++){
digitalWrite(13,HIGH);
delay(100);
digitalWrite(13,LOW);
delay(100);
}
loop_count++;
wdt_reset();
watchdogStart();
wdt_counter = 0;
Serial.print(loop_count);
Serial.print(". Watchdog fed in approx. ");
//Serial.print(loop_count*200);
Serial.print(millis());
Serial.println(" milliseconds.");
}
ISR(WDT_vect) // Watchdog timer interrupt.
{
Serial.println("ISR WDT");
if (wdt_counter==0)
{
wdt_counter++;
watchdogArm();
}
// Include your code here - be careful not to use functions they may cause the interrupt to hang and // prevent a reset.
}
/**
// https://forum.arduino.cc/t/tutorial-basic-watchdog-timer-setup/63397/13
#include <avr/wdt.h>
unsigned long resetTime = 0;
#define TIMEOUTPERIOD 10000 // You can make this time as long as you want,
// it’s not limited to 8 seconds like the normal
// watchdog
#define doggieTickle() resetTime = millis(); // This macro will reset the timer
void(* resetFunc) (void) = 0; //declare reset function @ address 0
void watchdogSetup()
{
cli(); // disable all interrupts
wdt_reset(); // reset the WDT timer
MCUSR &= ~(1<<WDRF); // because the data sheet said to
// WDTCSR configuration:
// WDIE = 1 :Interrupt Enable
// WDE = 1 :Reset Enable - I won’t be using this on the 2560
// WDP3 = 0 :For 1000ms Time-out
// WDP2 = 1 :bit pattern is
// WDP1 = 1 :0110 change this for a different
// WDP0 = 0 :timeout period.
// Enter Watchdog Configuration mode:
WDTCSR = (1<<WDCE) | (1<<WDE);
// Set Watchdog settings: interrupte enable, 0110 for timer
WDTCSR = (1<<WDIE) | (0<<WDP3) | (1<<WDP2) | (1<<WDP1) | (0<<WDP0);
sei();
Serial.println("finished watchdog setup"); // just here for testing
}
ISR(WDT_vect) // Watchdog timer interrupt.
{
if(millis() - resetTime > TIMEOUTPERIOD)
{
Serial.println("This is where it would have rebooted"); // just here for testing
doggieTickle(); // take these lines out
// resetFunc(); // This will call location zero and cause a reboot.
}
else // these lines should
{
Serial.println("Howdy"); // be removed also
}
}
void setup()
{
watchdogSetup();
Serial.begin(57600);
Serial.println("Hello, in setup");
}
int firstTime = true;
void loop()
{
if (firstTime)
{
firstTime = false;
Serial.println("In loop waiting for Watchdog");
}
if (millis() - resetTime > 2000)
{
//doggieTickle(); // if you uncomment this line, it will keep resetting the timer.
}
}
/**
// https://create.arduino.cc/projecthub/rafitc/what-is-watchdog-timer-fffe20
#include <avr/wdt.h>
void setup()
{
Serial.begin(9600);
Serial.println("Setup started :");
// make a delay before enable WDT
// this delay help to complete all initial tasks
delay(2000);
wdt_enable(WDTO_4S);
}
void loop()
{
Serial.println("LOOP started ! ");
for(int i=0; i<=5; i++)
{
Serial.print("Loop : ");
Serial.print(i);
Serial.println();
delay(1000);
wdt_reset();
}
//infinity loop to hang MCU
while(1){}
}
/**/