Hello everyone, this my first post so take it easy, I would like thoughts on where is a good place to put your wdt_reset() clearly it needs to be where it would be called before the watchdog timer times out, such as in the main loop however if there are delay()'s, loops and calls to other possibly blocking functions etc. causes issues, and the need for custom delay functions and careful structuring of loops and functions to ensure the WDT is reset.
My question is, how about putting it in Timer 2 ISR? I have this set to overflow at 32.768mS for some other purpose so it seems an ideal place to the reset the WDT. However if for some reason the CPU runs wild is it possible it would carry on servicing interrupts?
Putting a WDT reset in a timmer triggered interrupt is about the same as not using it. It should be called from your main loop. As far as blocking code that should not be there. Start by eliminating the blocking code first. Also if the WDT triggers what will the hardware do if it goes through the setup. Some hardware may lock up. My systems power down then back up to be sure the hardware etc is reset.
Yes, thanks for you reply, what i meant by "blocking code" was time consuming function calls say updating LCD's and using pulseIn() , delay() and similar functions. You say "Putting a WDT reset in a timer triggered interrupt is about the same as not using it" Can you expand on this? I assume you mean the timer ISR will always be executed no matter what the CPU is doing unless it stops completely? BTW i'm using a Nano (328P) it doesn't seem to lock up when the WDT expires it just resets. Regards
Not all hardware will lock up. I have seen where a transient causes one of the external ports to latch up. It required a power cycle to reset it, the reset pin did not do it. Also most designs do not have a reset on the external hardware.
Let say one of your devices does not return a result and your code is waiting on it, possibly a stuck button. the WDT gets reset on a regular basis by a timer interrupt, when it does its return from interrupt it goes back to the code still waiting on something and nothing else gets done. There was nothing to reset the hardware. Depending on the WDT timing slow functions may have to be split up. If the software were written properly it would report the stuck button as an error but who does that.
Many years ago I had a customer that would have a unit lock up and would not restart unless the battery was removed and it was reset. What happened is in the self test code (which was not supposed to be there) had a jump to itself, this was used to force the WDT on self test. A glitch caused the PC (Program Counter) to jump into that "non existent" snippet of code. This caused the system to lock in a given function and would not allow the machine to run.
The is nothing preventing you from having multiple wdt_reset() calls in your code, if you want to write code in such a way that it will stay within a function for an extended amount of time. If for some unimaginable reason you want a delay() that lasts longer than the wdt, you can split that up into multiple smaller delays with a call to wdt_reset() in between each.
Ok, so the timer interrupt will always be executed no matter what, (unless the CPU stops completely) I would still prefer to use the WDT on this project as it will run unattended forever, and I need to use pulseIn() the delay function is easy to fix/replace with one that resets the WDT can always set the WDT to 4 or 8 seconds on the Nano. Thanks for the reply
.
.or if you really think your code is bulletproof, you can slow down or turn the WDT off during those specific blocks of code. (8 seconds is a long time)
Speed it back up after the code has completed.
Non-blocking code is starting to sound pretty good now !
Yes, so the answer is, no you can't put the WDT reset in a timer ISR if you want the watchdog to work correctly and reset the CPU if it goes rouge because the ISR will be executed and WDT will always get cleared no matter what the CPU is doing elsewhere, It just seemed so elegant, but obvious now. Thankyou everyone
Maybe not but I can call this from all over my code and don't need to worry about the WDT timing out just use it like delay();
eg: mDelay(5000);
Anyway thanks again for the help I think my question re: resetting the WDT in an ISR has been answered, it seemed so easy but now I see it obviously won't work correctly.