Arduino not rebooting with watchdog enabled

I have a custom board that is switching an inductive load through a 10A@230V ac relay.
Due to a poor design, voltage spikes are causing the board to reboot from time to time (brown-out, watchdog and "unknown reason")

The problem here is that from time to time, the microcontroller freezes and no longer executes code (or at least, it seems so), even if the watchdog should be running.
I programmed the WDTON and BROWN-OUT fuses, so the watchdog should be always on.

Once the microcontroller is frozen, an external reset makes it work again.

My questions:

  • Is there any SOFTWARE fix to guarantee that the device never freezes. Am I using the watchdog incorrectly?

  • I read in the Atmega 328P datasheet about the 4 cycle restriction between the WDE writing and the prescaler bits writing (page 44), but It´s not clear to me if this restriction applies when WDON fuse is programmed.
    Also, I couldn´t find what the "wdt_enable (WDTO_2S);" instruction is doing under the hood.

  • Is it possible that the watchdog oscillator stops due to a voltage spike?

This is my code (the part to illustrate the watchdog problem)

Hardware: Custom board
microcontroller: ATmega 328P
Brown-out fuse: programmed
WDTON fuse: programmed

#include <avr/wdt.h>

#define R0          3 // Relay output 16A @ 230Vac (10A @ 230Vac)
#define R1          4 // Relay output 10A @ 230Vac (10A @ 230Vac)
#define R2          5 // Relay output 10A @ 230Vac (10A @ 230Vac)

byte outputs;

//-------------------------------------------------------------------------

void test(){
  
#define TEST_SWITCHING_INTERVAL  500

  static unsigned long previousMillisTest;
  static int count;

  unsigned long actualTemp = millis();
  if ((actualTemp - previousMillisTest) >= TEST_SWITCHING_INTERVAL){
    bitWrite (outputs, 0, !bitRead (outputs, 0)); Serial.print ("R0 = ");    Serial.print (bitRead (outputs, 0));
    bitWrite (outputs, 1, !bitRead (outputs, 1)); Serial.print ("   R1 = "); Serial.print (bitRead (outputs, 1));
    bitWrite (outputs, 2, !bitRead (outputs, 2)); Serial.print ("   R2 = "); Serial.print (bitRead (outputs, 2));
    Serial.print ("   count: "); Serial.print (count++);
    Serial.print ("  millis: "); Serial.println (previousMillisTest);
    previousMillisTest = actualTemp;
  }
 digitalWrite (R0, bitRead (outputs, 0));
 digitalWrite (R1, bitRead (outputs, 1));
 digitalWrite (R2, bitRead (outputs, 2));
}

//-----------------------------------------------------------------------

void setup(){ 

  uint8_t MCUSR_save;
  
  MCUSR_save = MCUSR;
  MCUSR = 0; 
  wdt_enable (WDTO_2S);

  Serial.begin (9600);
  
     if      (MCUSR_save & 0x01)  Serial.println ("*********Restarting . Power-on Reset*********");
     else if (MCUSR_save & 0x02)  Serial.println ("*********Restarting . External Reset*********");
     else if (MCUSR_save & 0x04)  Serial.println ("*********Restarting . Brown-out Reset*********");
     else if (MCUSR_save & 0x08)  Serial.println ("*********Restarting . Watchdog Reset*********");
     else if (MCUSR_save & 0x10)  Serial.println ("*********Restarting . JTAG Reset*********");
     else                         Serial.println ("*********Restarting . Unknown reason*********");
     Serial.print ("MCUSR = 0x"); Serial.println (MCUSR_save, HEX);
   
  initPins(); 
  initDevice(); 
  
  if (DEBUG) showConfig();

  // prevents flooding the RS485 bus if the device is continuously restarting
  delay (100);
  
  sendFrame (RESTARTED, 0); // sends the "restarted" event through the RS485 port

}

//---------------------------------------------------------------------------

void loop(){
  wdt_reset();
  test(); 
}

//---------------------------------------------------------------------------

I don’t know the answer , but have had similar problems with a voltmeter where I too used the watchdog timer as a “fix” that didn’t cure it .
Bear in mind that when it does reboot its a good idea to reset the watch dog at the start of setup - there are lot of examples on this about .

Really you need to deal with the spikes ( too) as eventually they will kill the processor anyway ( been there as well )

Relays with diodes , opto isolators , input protection , good power supply etc …

Nick Gammon answered here