Go Down

Topic: Using Watchdog Timer as a time base (Read 627 times) previous topic - next topic

MikeLittle

I was looking int using the watchdog timer as a simple time base for some ideas I have coming up. Wasn't too sure about how good it would be.

The code is a simple time loop. It blinks the on board LED on each heart beat. You can print out the time interval between the heart beats to see how long they were, based on the system clock - millis(). Also include the min and max interval. Just send it something form the serial monitor.

Mine seems to be running a little slow compared to the system clock. But it looks very stable. A couple of milliseconds either way.

For simple LED blinking, this could save someone the headache of keeping track of previous and current time stamps (mine are just for the measuring of the interval). It wouldn't be much good for time critical applications. I am going to use it for a simple traffic light state machine, spanning minutes of time. So a couple of milliseconds one way or the other doesn't really matter. And I don't need to have the lights on for any exact amount of time. They just need to be repeatable.

Sorry for the formatting. Tabs seem a little screwy.

Code: [Select]

#include <avr/wdt.h>            // library for default watchdog functions
#include <avr/interrupt.h>      // library for interrupts handling

// pin on which a led is attached on the board
#define led 13

// flags and variables
volatile bool HeartBeat = false; // timer has expired
bool LEDState = false;

unsigned long currentTime = 0; // current time stamp
unsigned long previousTime = 0; // last time stamp
unsigned long Interval = 0; // time between time stamps
unsigned long minTime = 0xffff; // minimum time interval
unsigned long maxTime = 0; // maximum time interval

// interrupt raised by the watchdog firing
// when the watchdog fires during sleep, this function will be executed
// remember that interrupts are disabled in ISR functions

ISR(WDT_vect)
{
// reset the watchdog, and set flag
wdt_reset();
HeartBeat = true;
}


// function to configure the watchdog:

void configure_wdt(void)
{
/* WDTCSR Watchdog Timer Control Register
bit 7 6 5 4 3 2 1 0
WDIF      WDIE      WDP3      WDCE       WDE      WDP2      WDP1    WDP0

WDFI Watchdog Interupt Flag
WDIE Watchdog Interupt Enable
WDP3 Watchdog Prescalar 3
WDCE Watchdog Change Enable - set with WDE for change
WDE Watchdog System Reset Enable
WDP2-0 Watchdog Prescalars 2-0
*/
  cli();                                          // disable interrupts for changing the registers
  MCUSR = 0;                                      // reset status register flags

  WDTCSR |= 0b00011000;                    // Set WDCE (5th from left) and WDE (4th from left) to enter config mode,

  WDTCSR = 0b01000000 | 0b00000111; // set WDIE: interrupt enabled
// clr WDE: reset disabled
// and set delay interval. see below

  sei();                                            // re-enable interrupts

  /* delay interval patterns:
16 ms: 0b00000000
32 ms: 0b00000001
64 ms: 0b00000010
125 ms: 0b00000011
250 ms: 0b00000100
500 ms: 0b00000101
1 Sec: 0b00000110
2 Sec: 0b00000111
4 Sec: 0b00100000
8 Sec: 0b00100001
  */
}

void setup()
{
  // use led 13 and put it in low mode
  pinMode(led, OUTPUT);
  digitalWrite(led, LOW);
 
  Serial.begin(115200);
  Serial.println("Starting");
 
  // configure the watchdog
  configure_wdt();
}

void loop()
{
static byte prOut;
if(HeartBeat)
{
HeartBeat = false;
previousTime = currentTime;
currentTime = millis();
Interval = currentTime - previousTime;
if(Interval <= minTime) minTime = Interval;
if(Interval >= maxTime) maxTime = Interval;

if(LEDState)
digitalWrite(led,HIGH);
else
digitalWrite(led,LOW);
LEDState = !LEDState;

if(Serial.available()) prOut = 10;

if(prOut)  // print the the current and next 9 readings
{
// 1st time print
if(Serial.available()) Serial.println("------");

//clean out receive buffer
while(Serial.available()) char c = Serial.read();

prOut --;

Serial.print("Interval = ");
Serial.println(Interval);
Serial.print("Min time = ");
Serial.println(minTime);
Serial.print("Max Time = ");
Serial.println(maxTime);
Serial.println();
}
}
}




Grumpy_Mike

Quote
this could save someone the headache of keeping track of previous and current time stamps (
Just what is so difficult about this?

This is just a silly idea. The watchdog reset is far too severe a tool to be useful in normal code. Stop tying to be clever and learn how to code properly.

holmes4

NEVER NEVER use TABs to format a program!

Mark

MikeLittle

Not using the reset. There is an option on the timer for interrupt only. Just do a ISR, reset the timer, and done.

Go Up