Atmega328P-AU watchdog timer fails to reset after the initialised time period

Good Day,

I am busy working on a project, however I have run into a bit of a problem…

I am creating my own PCB for my project, however, I first developed my code on a Arduino Uno and verified that it works, before migrating over to a ATMEGA328P-AU SMD chip.

I used Mr Nick Gammon’s board programmer to upload the bootloader to my chip ( I am using the internal 8MHz oscillator) and everything went smooth. Most of the code works, including a timer. The only problem is that the WDT fails to reset the program (when I create intentional delays), it only causes the application to hang and also makes it impossible to reprogram the chip (I have to unplug the FTDI programmer and plug it back in to upload a sketch again, which is also quite annoying )

My code has not changed since testing on the Arduino Uno, except for the prescaler for my timer, which will have no effect on the watchdog timer.

Please see the code below, in which I setup my WDT and configure it (reset and interrupt):

#include <avr/wdt.h>

void setup() {
 
  Serial.begin(9600); 
  while (!Serial);
  setupTimer2(); 
  setupGPS();
  setupLoRa();
  setupWDT();
  
  
 }


void setupWDT(){  //I created this function just to keep everything tidy and then configured it for a 2s interrupt
  cli();        // Disable all interrupts
  wdt_reset();  // Reset watchdog timer
//  /*WDTCSR configuration
//  WDIE  = 1  -> Interrupt enable 
//  WDE   = 1  -> Reset enable
//  WDP3  = 0  -> Set four prescaler bits for specific timeout
//  WDP2  = 1
//  WDP1  = 1
//  WDP0  = 1
//   */
   WDTCSR |= (1<<WDCE) | (1<<WDE);

   WDTCSR = (1<<WDIE) | (1<<WDE) | (0<<WDP3) | (1<<WDP2) | (1<<WDP1)  | (1<<WDP0);
   sei(); 
}

“0<<WDP3” seems odd… Should this have been “1<<WDP3”?

EDIT: You are posting partial code, usually ppl think they post the parts of the code which contains the problem but this is rarely the case. You should probably figure out what causes a WDT-reset and mind that.

Hi, thanks for the reply!

The code is quite long, so I made a small sketch in order to illustrate the problem. And the 0<<WDP3 is there in order to set the WDT to a 2 second interval, as per the datasheet.

The code below has the following output, the program then hangs and I am unable to program the chip unless I unplug the FTDI chip and plug it back in:

Started
Main loop
Interrupt before reset
Main loop
#include <avr/wdt.h>

void setup() {

Serial.begin(9600);
Serial.println("Started");
setupWDT();

}

void loop() {
Serial.println("Main loop");
delay(3000);
}

void setupWDT(){
  cli();        // Disable all interrupts
  wdt_reset();  // Reset watchdog timer
//  /*WDTCSR configuration
//  WDIE  = 1  -> Interrupt enable 
//  WDE   = 1  -> Reset enable
//  WDP3  = 0  -> Set four prescaler bits for specific timeout
//  WDP2  = 1
//  WDP1  = 1
//  WDP0  = 1
//   */
   WDTCSR |= (1<<WDCE) | (1<<WDE);

   WDTCSR = (1<<WDIE) | (1<<WDE) | (0<<WDP3) | (1<<WDP2) | (1<<WDP1)  | (1<<WDP0);
   sei(); //Enable interupts;
}


ISR(WDT_vect){
 Serial.println("Interrupt before reset");
}

I think , perhaps, there are 2 "issues" 1. You say you use internal clock. Are you sure you have made the correct changes in the "fuses"? 2. I;m not sure, but I think there is a known problem with wdt and some smd chips used in nano and pro-mini boards. As solution it is suggested the user to load the "optiboot" bootloader and behave to the board as it is a uno.

you could search it further

Impossible to tell what the problem is when code is missing.. Try to add a software reset to the WDT ISR:

asm ("jmp 0");

And as said: Find the reason for the reset and eliminate it from happening instead of using the WDT reset as part of your device's stability.

Thanks for all your replies and efforts.

I managed to solve the problem by using Optiboot, upon returning to the forum I saw that "demkat1" also suggested this.

So for anyone struggling in the future with this get Optiboot (I used MiniCore) and if you are using the Arduino Uno as an ISP remember to add a capacitor between Reset and ground (I used a 0.1 uF cap).

In reply to Danois90, that was the full code that I posted in my reply to you. I decided that a smaller sketch would be easier to debug and it presented the same problem as in my main sketch.

Kind regards

demkat1: I think there is a known problem with wdt and some smd chips used in nano and pro-mini boards. As solution it is suggested the user to load the "optiboot" bootloader and behave to the board as it is a uno.

You're correct about the known problem with wdt and Nano (pre-2018 official boards and unofficial boards only) and Pro Mini. You're also correct that loading the optiboot bootloader is the solution. However, the problem has nothing to do with the chips. The problem is with the outdated "ATmegaBOOT" bootloader those boards come with. This is why when you switch to using the superior Optiboot bootloader, the problem is solved.

Reference: https://github.com/arduino/Arduino/issues/4492