Go Down

Topic: Tutorial: Basic Watchdog Timer Setup (Read 132093 times) previous topic - next topic

ddan39

Hi, nice tutorial, thanks!

Is there a reason NOT to use wdt_enable() instead of writing the bits to WDTCSR? It was nice to learn how to do it by setting the different bits and knowing about cli() etc. but the single function is kinda nice :P
Working on hydrogen electrolyzer & fuel cell projects at the Hydrogen House Project - http://hydrogenhouseproject.org

celafon

The wdt_enable() is just a macro doing the same thing. So do as you please :)

faro93

#32
Jan 13, 2016, 07:59 pm Last Edit: Jan 14, 2016, 12:27 am by faro93
Hello,

I'm digging up this topic from 09 2015.
Here is my code :

Code: [Select]
#include <avr/wdt.h>

boolean ledState = LOW;
int ledPin = 13;

volatile int loop_count;
volatile boolean wdtState = false;

void watchdogSetup () {
 cli ();
 wdt_reset ();
 WDTCSR |= (1<<WDCE) | (1<<WDE);
 WDTCSR = (1<<WDIE) | (1<<WDE) | (0<<WDP3) | (1<<WDP2) | (1<<WDP1) | (1<<WDP0);
 sei ();
}

ISR (WDT_vect) {
 wdtState = true;
 loop_count ++;
}

void setup () {
 Serial.begin (9600);
 Serial.println ("Starting up ...");
 pinMode (ledPin, OUTPUT);
 digitalWrite (ledPin, ledState);
 watchdogSetup ();
 loop_count = 0;
}

void loop () {
 if (wdtState) {
   wdtState = false;
   Serial.print ("WDT ISR : ");
   Serial.println (loop_count);
   wdt_reset ();
 }
 
 if (loop_count == 10 ) {
   while (1) {
     ledState = !ledState;
     digitalWrite (ledPin, ledState);
     delay (500);
   }
 }
 
 ledState = !ledState;
 digitalWrite (ledPin, ledState);
 delay (100);
}


As you can see, WDE and WDIE are set. So, when my program goes into the infinite while loop, my Nano v3 should reset as there is no wdt_reset call.

Instead of that, the Nano seems to go into a strange status because the led 13 blinks without the delays I programmed (also if I don't program led blink too).

When WDE is set to 0, the program goes into the infinite while loop and the system doesn't reset (only watchdog interrupts are allowed in this case).

I wonder why my Nano card does that. I can't figure why the WDE set to 1 does not work. So, after reading and searching the internet, I did not found anyone that has this kind of problem. Do you think my Nano card is out of service for watchdog resets ? If not, can you see what is wrong in my code ? If my code is good, do you understand what happens ? Does my code work well on your own arduino ?

I own a Saintsmart Nano v3.

Thank you for your help. I'm a bit lost.

BR,
Fabrice.

nickgammon

Please edit your post, select the code, and put it between [code] ... [/code] tags.

You can do that by hitting the "Code" icon above the posting area. It is the first icon, with the symbol: </>


Sounds like you have one of the bootloaders that doesn't reset the watchdog timer. The flash you see is the bootloader initial flash of pin 13. Then it resets again and flashes it again.
Please post technical questions on the forum, not by personal message. Thanks!

More info: http://www.gammon.com.au/electronics

faro93

I burnt my nano clone (sainsmart nano v3) bootloader and did some other tests :
- set WDIE and WDE to 1 : nano goes in fast reset (as supposed by Nick Gammon in last post)
- set WDIE to 0 and WDE to 1 : same effect
- set WDIE to 1 and WDE to 0 : nano works in the right way and there is no need to wdt_reset() as no system reset is wanted.

I deduced that my nano does not support WDE sets to 1 (so no wdt system reset is possible).
Is it only my nano clone (I mean sainsmart nano v3) that works this way or all nanos work this way ?

I did the same things on a MEGA2560 and there is no problem.

Thank you for your contributions.

BR,
Fabrice.

nickgammon

Please post technical questions on the forum, not by personal message. Thanks!

More info: http://www.gammon.com.au/electronics

MRo47


aniket_1

void wdtEnable()
{
 wdt_reset(); // reset the WDT timer
 MCUSR &= ~(1<<WDRF);  // because the data sheet said to
 // Enter Watchdog Configuration mode:
 WDTCSR |= (1<<WDCE) | (1<<WDE) | (1<<WDIE);
 // Set Watchdog settings: interrupte enable, 0110 for timer
 WDTCSR = (1<<WDIE) | (0<<WDE) | (1<<WDP3) | (0<<WDP2) | (0<<WDP1) | (1<<WDP0);
}

void wdtStart()
{
 cli();
 wdt_reset(); // reset the WDT timer
 MCUSR |= (1 << WDRF);
 WDTCSR = (1<<WDIE)|(1<<WDCE)|(1<<WDE)|(1<<WDP3)|(0<<WDP2)|(0<<WDP1)|(1<<WDP0);
 sei();
}

void wdtStop()
{
 cli();
 wdt_reset(); // reset the WDT timer
 MCUSR &= (0xFF & (0<<WDRF));
 WDTCSR |= (1<<WDCE)|(1<<WDE)|(0<<WDIE);
 WDTCSR =  (0<<WDE)|(0<<WDIE);
 sei();
}

nickgammon

Is there a question there? Please use code tags.
Please post technical questions on the forum, not by personal message. Thanks!

More info: http://www.gammon.com.au/electronics

montango

I just bought an elegoo UNO (that should work like arduino) and tested the blink example, then I wrote a code for the RGB-fade example that was described without a code in the documentation that came with the starter kit.

I noticed that the LED L still flashes after a while even if the sketch says nothing about it, so I figured out that the watchdog resets the board so the sketch restarts (usually in the middle of it). I tried adding various commands to disable the watchdog, or to reset as often as possible its counter, but there is no effect.

I tried to load the standard blink-code for the L LED (1 second on, 1 second off), and I notice that after 32 seconds the L LED flashes.

The best I could do is by disconnecting the USB cable and plugging it back, the watchdog seems to be asleep for much longer (about 120 Seconds), but eventually wakes up after a while (after that, it seems to reset the sketch every 32 seconds). I got these time estimations by using the standard blink sketch.

Does it mean the hardware is faulty?

Should I send it back?

Thanks for your help.

Scottkne

Hi, I have been looking for just this.. I don't trust my life with a watchdog timer that may or may not reset. I do trust a simple but true 555 timer. Thank You for researching this....

mu234

Hello!

I was thinking to use the WDT to "reset" the oscillator in Tiny, because my app is using millis() all the time, however, I am wondering, if millis() can take 40 and more days before it goes "ballistic", than I am not worried, however, I am wondering should some kind of a protection with regard to time be put in place, something like the one that is below, or should I not worried, because I expect the user to use the product in 40 days :), and then the mills() is "reseted"... anyway, I would like to have a stable loop !

Any kind of advice would be useful :)

Best.

The millis() overflow can be neatly handled like this:

Code: [Select]
// static variable
unsigned long lastFiredTime;

...

// in loop or some such place
unsigned long now = millis ();
unsigned long interval = now - lastFiredTime;
lastFiredTime = now;


Because of the way unsigned integers overflow, the variable "interval" will be correct, regardless of whether millis() has overflowed or not. That is, unless the interval itself exceeds 49.7 days (because that is all that will fit in it).

Certainly nothing freezes if it overflows, it is just an integer arithmetic overflow. They happen all the time.

Coding Badly

Any kind of advice would be useful :)
If you want help with your code then post your code.

Do not hijack.


guy_c

Few notes while reading za_nic's nice watchdog tutorial



GiovanniG11

on Mega 2650 whatshdog is a special hardware timer dedicated to it (which can operate even if interrupts are disabled) or it depends on timer0?
Thank you

Go Up