Go Down

Topic: Prescaler on Watchdog timer interrupt?? (Read 4838 times) previous topic - next topic

marsbar


I'm wondering if someone knows how to change the prescaler on the watchdog timer enabled as an interrupt?

So far I have been successful enabling the WDT as an interrupt but I can't get the Prescaler to work.

I'm trying to make the WDT interrupt every 1 second so I can make a 24 hr clock with it. In the reference manual it says you can prescale it down to 1 second by setting 1<<WDP2 and 1<<WDP1, but it seems as tho it has no prescaler at all.

Here is a portion of my code so far:

void setup()
{
 cli();          // stop interrupts
 WDTCSR  = (1<<WDCE);     // watchdog change enable
 WDTCSR  = (0<<WDP3)|(1<<WDP2) | (1<<WDP1); // set
                  //prescaler to 1 second
 WDTCSR  = (1<<WDIE) | (0<<WDE);   // enable wdt interrupt
 sei();        // start interrupts

}

/*WDT interrupt*/

ISR(WDT_vect)
{
}

ANY HELP WOULD BE GREATLY APPRECIATED!!  

etracer

I think you're confusing the hardware timers (TIMER0 & TIMER1) with the watchdog timer.

The watchdog is mainly designed to reset the chip if it freezes. The hardware timers are meant for programmatic events (like being triggered every second).

marsbar

it's very possible my friend. I'm attaching the documentation of what I read from the ATmega datasheet.. this is the reason i thought that I could use it as an interrupt.

Thx!

10.9.2 WDTCSR - Watchdog Timer Control Register

WDIF WDIE WDP3 WDCE WDE WDP2 WDP1 WDP0 = WDTCSR

? Bit 6 - WDIE: Watchdog Interrupt Enable
When this bit is written to one and the I-bit in the Status Register is set, the Watchdog Interrupt is
enabled. If WDE is cleared in combination with this setting, the Watchdog Timer is in Interrupt
Mode, and the corresponding interrupt is executed if time-out in the Watchdog Timer occurs.

Watchdog Timer Configuration

WDTON(1)        WDE        WDIE           Mode                     Action on Time-out

     1                  0             0              Stopped                        None

     1                  0             1              Interrupt Mode           Interrupt

     1                  1             0              System Reset Mode       Reset

     1                  1             1              Interrupt                    interrupt
                                                       System Reset             then go
                                                       Mode                        to system
                                                                                       reset

     0                  x             x            System Reset Mode         Reset

? Bit 5, 2..0 - WDP3..0: Watchdog Timer Prescaler 3, 2, 1 and 0

The WDP3..0 bits determine the Watchdog Timer prescaling when the Watchdog Timer is running.

Watchdog Timer Prescale Select

WDP3 WDP2 WDP1 WDP0         Number of WDT     Typical Time-out at
                                             Oscillator Cycles     VCC = 5.0V

  0         0      0        0             2K (2048) cycles       16 ms
  0         0      0        1             4K (4096) cycles       32 ms
  0         0      1        0             8K (8192) cycles       64 ms
  0         0      1        1            16K (16384) cycles    0.125 s
  0         1      0        0            32K (32768) cycles    0.25 s
  0         1      0        1            64K (65536) cycles    0.5 s
  0         1      1        0            128K (131072) cycles 1.0 s
  0         1      1        1            256K (262144) cycles 2.0 s
  1         0      0        0            512K (524288) cycles 4.0 s
  1         0      0        1            1024K (1048576) cycles 8.0 s

etracer

Well I guess you can use it for a "time-based" interrupt. But that's what the hardware timers really are for. They can also generate a number of different interrupts based on how you configure them.

The watchdog timer is really designed to allow some event to happen if the watchdog doesn't get reset before it expires. Normally the "something" is reset the chip. The code then must reset the timer frequently (at least faster than the timeout) to prevent the watchdog from firing. This is sometimes referred to as "feeding the dog". Then if the chip crashes or the code goes awry, the watchdog timer will expire and fire the "something" (reset the chip).

The other problem with using the watchdog is that if it triggers a reset it's still enabled when the chip restarts. The bootloader doesn't disable it or regularly "feed the dog" since it doesn't expect the watchdog to be enabled. This can then lead to an endless loop of resets that can only be resolved by reburning the bootloader with a programmer.

So the short answer is the hardware timers are designed to be used for what you're trying to do, not the watchdog timer.

etracer

Ignore the part about having to reburn the bootloader. That only applies if the watchdog fuses were set which isn't a normal Arduino occurrence.

You will still get into an annoying reset loop, but it can be cured by power cycling the chip (which is annoying if your trying to upload a program).

westfw

Also note that the watchdog timer uses an internal, uncalibrated, RC clock that has a very low accuracy compared to the crystal-based "normal" timers; it will probably make a lousy "24 hour clock."

Code: [Select]
WDTCSR  = (1<<WDCE);     // watchdog change enable
WDTCSR  = (0<<WDP3)|(1<<WDP2) | (1<<WDP1); // set
                 //prescaler to 1 second
WDTCSR  = (1<<WDIE) | (0<<WDE);   // enable wdt interrupt
Your second write to WDTCSR is overwriting the prescaler bits, I think.  And/or apparently you need to set WDE to change the prescaler, even if you're going to immediately clear it.    See the bottom of page 49 of the Atmega168 datasheet.  This sequence seems to work:
Code: [Select]
cli();          // stop interrupts
WDTCSR  = (1<<WDCE | 1<<WDE);     // watchdog change enable
WDTCSR  = 1<<WDIE | (0<<WDP3)|(1<<WDP2) | (1<<WDP1); // set  prescaler to 1 second
sei();        // start interrupts


marsbar

Thanks so much for the advise! I will probably stick to other interrupts beings that the watchdog is not entended for that reason.

Thx for all the help my friends!!  :D

Phlogi

Has anyone managed to get an interrupt from a wdt?

I'm trying with:
Code: [Select]
     cli();      // important: disable interrupts
     WDTCSR = (1 << WDCE); // watchdog change enable
     WDTCSR |= (1 << WDIE) | (0 << WDE); // enable wdt interrupt
     sei();

and:
Code: [Select]
ISR(WDT_vect)
{
     wdt_disable();
     Serial.println("Got watchdog reset...");
     delay(700);
}


Groove

Per Arduino ad Astra

Go Up