I have read numerous articles on the Arduino watch dog timer and - when I use it in my code - it doesn't do what I expect.
I have a dust monitor which is connected to a serial port on an UNO with WiFi Rev2. The Uno talks to a listener programme running on a PC. Some of the programme logic is designed to initate a restart on either the Arduino or the PC if either the other party - or the dust monitor - stops doing what it should be doing
This is an example function where the Arduino tries to restart if it doesn't get a data line on the serial port for more than 70 seconds. The diagnostic log shows it does exactly what is expected and logs the message: Restart - No Dylos message for 70 seconds. But it does not restart. (I force this condition by powering down the dust monitor but - when it is powered up - the code works perfectly).
Happy to provide all of the code but I thought I would start with just this snippet as that seems to be where the problem is. There is an #include <avr/wdt.h> statement in the global section of the code.
I am missing something here and I don't know what it is.
Is there a reason why the Arduino needs to be reset if a peripheral is misbehaving? It's like "if your car does not start, go back into the house and reset the earth leakage" There might be different / better solutions for the problem that you're trying to solve.
Maybe elsewhere in the code you disable the WDT again? Have you tried a simple code to test WDT functionality?
Hi Sterretje. Thank you for your input.
I have been writing programmes in a variety of languages for just on 50 years. I am relatively new to the Arduino space but - based on my experience - I concluded that having four devices (sensor, Arduino, WiFi router & PC) in a workshop environment with the possibility of power interruptions and me not always being present in case someone unknowingly turned something off - I wanted to put as many logic steps in place as possible for the system to get back running again when issues of any sort occurred.
I found your comments border-line offensive.
However, in the mean time, I found another post at Watchdog Timer in Arduino | Arduino that solved the problem. I have viewed probably five to seven different examples of the use of the WDT process. Before this most recent find, I had never seen anyone suggest using wdt_disable(); with a delay after it to "clear the decks" at the start of setup.
I added this to my code and it now works perfectly.
This is an excellent example of why I come to this space. It is not for design advice. It is to try and pick the brains of other folk who faced similar difficulties as myself in what I think is one of the most-poorly documented environments in which I have worked in my lifetime.
And - FYI - I have tested several different test sketches, even more-simple than the example above, that just "did the basics" and not one of them worked. Now they do.
You obviously been very fortunate with the the rest of the environments you have worked with, but remember this started as a hobby platform and not necessarily a professional tool. Also, any one can contribute code, libraries etc. to the Arduino eco-system and post it somewhere so the quality. especially in the area of documentation, will inevitably vary.
Most people are happy not to have spend days studying the datasheets of the MCUs populating the Arduino board, where questions such as your watch dog timer problems could be answered. They are happy to find a code example which they can adapt for their requirements. There Google is quite good. But, really, the Arduino layer is a relatively thin layer on top of the MCU, its tool chain with a (optional) boot-loader thrown in, so there is not that much to document.
I rather wish that the Arduino API included a "self_reboot();" function.
It could do appropriate watchdog magic on older AVRs, and use the "reset controller" features that are present in newer AVRs (like the 4809 on the Uno WiFi2, and most ARMs.)
Having to continually tell people "to reboot, do this weird thing with the WDT (only be careful to also do X and Y) and infinite looping" is silly.
(alas, there is this ambiguity as to whether "reboot" means "run the bootloader to maybe get a new sketch" or "re-run the current sketch immediately." Watchdog use usually implies the latter. SW request maybe the former.)
To johnwasser. The delay before the wdt_enable statement is to allow the serial port time to send the diagnostic message.
Further, since my last post, further study has shown the following. Having found the reference to the need for a wdt_disable early in the code, I tried that and it worked in test sketches but didn't work in the production sketch. Further work has shown that I need a wdt_disable before every instance of wdt_enable. It seems cumbersome, but I now use this structure and it works reliably:
Serial.println( F( "Failed to open TCP connection" ) );
wdt_disable();
delay(3000);
wdt_enable(WDTO_500MS);
delay(500);
I remain with a feeling of weirdness about the whole thing.