Watchdog Trouble

Hello,

I have a Arduino Mega board (ATMEL 2560) and I try to implement a watchdog without to change the bootloader.
Here bellow the code :

#include <avr/wdt.h>
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
/
initialise le watchdog
* sur 8s
*/
void setup_watchdog() {
Serial.println(WDTCSR, HEX);
wdt_reset();

// disable all interrupts
cli();
wdt_reset();
MCUSR &= ~(1<<WDRF);
// Entre dans le mode configuaration
WDTCSR |= (1 << WDCE) | (1 << WDE);
// configure
WDTCSR = (1 << WDE) | (0 << WDP3) | (0 << WDP2) | (1 << WDP1) | (1 << WDP0); // 8s
// enable all interrupts
sei();
Serial.println(WDTCSR, HEX);
}

And in the loop there is only setup_watchdog() (not the reset) in order to see if the board is resetting.
And after the tempo, surprise, the board is blocked … not reset …

Have you got some ideas to help me ?

:~ no answer.
I try to re-tell my question : "Is it possible to have a watchdog system which reset the arduino board without change the bootloader ?"

Thanks in advance for your help.
Loïc

Is it possible to have a watchdog system which reset the arduino board without change the bootloader ?

I think that would depend on which bootloader you are using. Why do you want to periodically reset the Arduino anyway?

It is almost always better to fix the problem that the reset is needed for.

Thanks for your answer.
I have a arduino Mega with ATMEL 2560 with the standard bootloader - I don't know which version.

In my application, sometimes, the board is freeze, perhaps due to ESD.
So, the watchdog has a period of 8s and allows to keep the control on the system (avoid to have a consign too high during a long time)
I try to program the watchdog register (see post above) and I don't try to do work it ...
If you have any idea, I will be happy.

Loïc

In my application

which you didn't post...

the board is freeze

You know this because?

perhaps due to ESD.

Then, protecting it from electrostatic discharge is a more advisable action.

And in the loop there is only setup_watchdog() (not the reset) in order to see if the board is resetting.

So, loop() is a really small function, but, you couldn't be bothered to include it. Or setup().

And after the tempo, surprise, the board is blocked ... not reset ...

Hmmm. What tempo?

Thanks for your answer and I see that I didn't precise.
I make a thermostat for my house. And I write a program in the Arduino Mega. All functions work very well. But sometimes, without any reason the software stops. I put a shield around the wires, capacitors on the alim and always the same.
So, I know that in the Atmel there is a watchdog system to reset the board and if my application is blocked once per week, I find acceptable to reset it. But I don't arrive to program this watchdog for any time. Ideally, this time have to 8s.
Do you know if the watchdog is working with standard bootloader of arduino mega or should I put a 555 monostable to reset board ?

Loic85:
But sometimes, without any reason the software stops.

I suggest you find the reason and fix it. Your sketch is the most likely cause, but I suggest you also post details of the external hardware and connected devices in case there is a problem there.

I think it is perfectly reasonable of you to want to use the watchdog, although there may be other problems that need fixing, either in your code or in the hardware.

You might want to take a look at the end of this thread: Arduino Forum because the problem sounds similar.

yes I agree with you, it is better to solve hardware problem in order to have no blocking. But even if I find the problem, this is important to have a security in case of blocking.
I already read the post http://arduino.cc/forum/index.php/topic,126892.0.html, but I don’t see my answer.

#include <avr/wdt.h>

void setup()
{
   Serial.begin(9600);
   wdt_reset();   
  // disable all interrupts
  cli();
  wdt_reset(); 
  MCUSR &= ~(1<<WDRF);
  WDTCSR |= (1 << WDCE) | (1 << WDE);
  WDTCSR = (1 << WDE) | (1 << WDP3) | (1 << WDP2) | (1 << WDP1) | (1 << WDP0);  // 8s
  // enable all interrupts
  sei();
}
void loop()
{
    Serial.println("I am in the loop");
    while(1) {
       // to have the reset !!!
       Serial.println(millis());
    }
}

My question is simple : where I do a mistake in this code on arduino mega with normal bootloader because the board doesn’t reset but it blocks at 8s, doesn’t reset !

What do you mean by "blocks at 8s"? How do you know that it isn't stuck in a reset loop?

Loic85:
My question is simple : where I do a mistake in this code on arduino mega with normal bootloader because the board doesn’t reset but it blocks at 8s, doesn’t reset !

I haven’t used the watchdog at all, and it’s obvious that you have looked into this further than I have, but is there some reason you aren’t calling wdt_enable() to set the watchdog duration?

Also, I still suggest you should try to resolve the original problem for which the reset is a workaround.

  1. If (in the code you posted) do you get “blocking” at 8s, if you remove the watchdog code?.

  2. Post the real code!

  3. Post your hardware design.

Mark

First, I thank you all of you for your answers.
I try my little code on arduino uno and arduino mega. On arduino uno, there is no problem, the board is resetting after 8s.
With the same little code on the arduino mega, the board is blocking after 8s.
See the screen capture here attach.
Why with arduino mega, the little code doesn’t work :

#include <avr/wdt.h>

void setup()
{
   Serial.begin(9600);
   wdt_reset();   
  // disable all interrupts
  cli();
  wdt_reset(); 
  MCUSR &= ~(1<<WDRF);
  WDTCSR |= (1 << WDCE) | (1 << WDE);
  WDTCSR = (1 << WDE) | (1 << WDP3) | (1 << WDP2) | (1 << WDP1) | (1 << WDP0);  // 8s
  // enable all interrupts
  sei();
}
void loop()
{
    Serial.println("I am in the loop");
    while(1) {
       // to have the reset !!!
       Serial.println(millis());
    }
}

Loic85:
First, I thank you all of you for your answers.
I try my little code on arduino uno and arduino mega. On arduino uno, there is no problem, the board is resetting after 8s.
With the same little code on the arduino mega, the board is blocking after 8s.
See the screen capture here attach.
Why with arduino mega, the little code doesn't work :

Perhaps because the latest Uno bootloader disables the watchdog timer, and the Mega bootloader doesn't?

If I understand, I cannot use the watchdog in reset mode on my arduino mega board without change the bootloader ?

Have you tried disabling the watchdog at the start of setup(), using the code I gave in the thread I linked to in an earlier post?

Yes, I do (see the code below).
:astonished: I must confess you that there is something that escapes me. Indifferently of boot, if I write in the watchdog registers the good values, the µP must be done a reset. Why doesn’t it done ?

#include <avr/wdt.h>

void setup()
{
   Serial.begin(9600);

  // Turn off watchdog timer  <--- recopy to your post
  cli();
  wdt_reset();
  MCUSR = 0;    // clear watchdog reset flag
  WDTCSR |= (1 << WDCE) | (1 << WDE);
  WDTCSR = 0x00;
  sei();
   // set the watchdog to 8s
   wdt_reset();   
  // disable all interrupts
  cli();
  wdt_reset(); 
  MCUSR &= ~(1<<WDRF);
  WDTCSR |= (1 << WDCE) | (1 << WDE);
  WDTCSR = (1 << WDE) | (1 << WDP3) | (1 << WDP2) | (1 << WDP1) | (1 << WDP0);  // 8s
  // enable all interrupts
  sei();
}
void loop()
{
    Serial.println("I am in the loop");
    while(1) {
       // to have the reset !!!
       Serial.println(millis());
    }
}

Sorry for my insistence, but I am always blocking =(
Is there any body who arrive to do worked a reset watchog on arduino mega ? If yes, please could you give me a simple example.
Thanks in advance.

What’s all the mucking around with registers? Here is an example that works on a Uno:

#include <avr/wdt.h>

void setup ()
{
  Serial.begin (115200);
  wdt_enable(WDTO_1S);  // reset after one second, if no "pat the dog" received
 }  // end of setup

void loop ()
  {
    
  Serial.println ("Entered loop ...");
  
  Serial.println ("Point A");
  delay (500);
  Serial.println ("Point B");
  delay (400);
  
  wdt_reset();  // give me another second to do stuff (pat the dog)
  
  Serial.println ("Point C");
  delay (500);
  Serial.println ("Point D");
  delay (400);
  
  while (true) ;   // ohno!, went into a loop
      
  }  // end of loop

I tested that on my Mega and it didn’t work. I suspect there is a problem with the bootloader and then watchdog timer. There are some known problems with the watchdog timer and the bootloader.

That sketch bricks my Mega in a rather annoying way. You can recover by re-uploading the bootloader but there is clearly something wrong.

You can also recover by:

  • Open a sketch that doesn't use the watchdog (eg. Blink)
  • Unplug the USB (so the board is powered off)
  • Hold down the reset button with one hand
  • Keeping it held down, plug in the USB
  • Start uploading
  • Release the reset button a moment or two after it says "uploading"
  • With luck, the new sketch will be uploaded