7

I am trying to set up a way to reboot arduino on command. The code below should do that but it seems like my arduino just get's stuck in some sort of a loop where I cant upload or get any serial output. The green led (pin 13) flashes very fast. The only way to stop this is to cut power to the device, even reset button does not work. This happens only when "R" is received via serial or if wdt_reset() function is commented out.

#include <avr/io.h>
#include <avr/wdt.h>

int ledPin = 3;

void setup()
{
  MCUSR=0;
  wdt_disable();
  Serial.begin(57600);
  Serial.println("BOOT!");
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);
  delay(500);
}

void loop(){
  if (Serial.available() > 0){
    char cmd = Serial.read();
    if (cmd == 'R'){
      Serial.println("R received!");
      wdt_enable(WDTO_1S);
      delay(2000);
      Serial.println("1 SEC.");
    }
  }
  wdt_reset();
  digitalWrite(ledPin, HIGH);
}

What am I doing wrong?

5
  • 1
    I think I ran into this a while ago, to upload a new sketch (without the watchdog stuff) I held down the reset button until right before the IDE began its "uploading" state.
    – sachleen
    Commented Jun 12, 2014 at 20:43
  • Also see the note at the bottom of this post: ariverpad.wordpress.com/2012/02/26/…
    – sachleen
    Commented Jun 12, 2014 at 20:44
  • @sachleen yes, I followed that write up but am a little confused where that code goes. I assume it does not go into the sketch? I would prefer not to edit source files as that would affect every arduino I program.
    – DominicM
    Commented Jun 13, 2014 at 10:43
  • Yes that would modify the bootloader and affect other sketches as well, but only if you're using the watchdog.
    – sachleen
    Commented Jun 13, 2014 at 14:59
  • @sachleen Does that mean the bootloader would need to be re-flashed?
    – DominicM
    Commented Jun 13, 2014 at 23:24

4 Answers 4

4

One of the most obvious issues here is that you are enabling the watchdog timer with a delay of 1S and then you are asking the micro controller to sleep for 2S, printing something and then going back into the loop. This, in theory, should be fine(your wdt should trigger a reboot during the 2 second wait) but I've seen it cause issues.

Additionally some bootloaders(notably the Optiboot bootloader on Uno and newer boards) can have issues with watchdog timers causing the wdt to remain enabled after reset even though the setup loop disables it. To start with - try increasing the wdt time to something greater than 2S(you should be able to do WDTO_8S) and see if the issue persists.

EDIT - The OP is using an Arduino Pro Mini clone. The included bootloader on the Arduino Pro Mini does not support system restarts by the WDT. Essentially, on a device with a bootloader that does not support WDT restarts, the board will restart but the timer / reset will not causing the board to continuously reset on reboot. There are alternative bootloaders for Arduino boards that may resolve this issue. Another solution is to use a different method to reboot the board.

8
  • So if it can cause issues, what method does not cause issues? I just tried 8 seconds with 9 second delay with same results. 8 seconds would bee too long anyways as I don't actually need any delay after serial command.
    – DominicM
    Commented Jun 12, 2014 at 23:32
  • One of the first questions would be - what board is it and what bootloader are you running on it? Additionally - what happens with a simpler version of the watchdog code? For example one that is not reading an input but is rather looping a print statement n times and then resetting? Here(megunolink.com/how-to-detect-lockups-using-the-arduino-watchdog) is an example of a very simple use of the watchdog timer - what happens when you run something like this?
    – Nahkki
    Commented Jun 13, 2014 at 4:02
  • I am using arduino pro mini clone with default bootloader (not sure what it is). With the copy pasted sample from the link it locks up just the same after a couple of seconds after power on.
    – DominicM
    Commented Jun 13, 2014 at 10:55
  • A quick google on your product shows others with the same issue. The bootloader on the Arduino Pro Mini does not support system restarts supported by the watchdog timer. Essentially they restart the system but do not restart the timer causing the board continuously reset on reboot. I have not used an Arduino Pro mini nor have I had much luck with offbrands(nothing wrong with them, just bad luck on my part) so I can't recommend another bootloader offhand but a quick google search shows that there are folks who have found a functioning bootloader for the device that supports the WDT.
    – Nahkki
    Commented Jun 13, 2014 at 12:14
  • Is the bootloader required for watchdog at all? Could I just get rid of bootloader altogether, as long a I can program it over bluetooth that would be the best option for me.
    – DominicM
    Commented Jun 13, 2014 at 12:19
2

Enabling watchdog timer system restart and waiting in a loop until reset is a legitimate way of SW resetting the µC as is using watchdog for catching µC's misbehavior which can be caused by various reasons.

However, some precautions have to be made when using watchdog system reset because on all AVRs that also have watchdog interrupt the watchdog with prescaler set to 0000 = 16 ms remains active after watchdog system reset condition. It is therefore responsibility of a programmer to clear MCUSR and to disable watchdog timer as soon as possible after occurrence of such a condition. Since LPM routines for initializing .data and .bss sections can last longer than watchdog timeout interval, the code for disabling the watchdog must be placed in .init3 section and the contents of MCUSR can optionally be saved for later reset source examination. Here is the code that does the described:

uint8_t mcusr_copy __attribute__ ((section (".noinit")));
void disable_wdt(void) \
     __attribute__((naked)) \
     __attribute__((section(".init3")));
void disable_wdt(void) {
  mcusr_copy = MCUSR;
  MCUSR = 0x00;
  wdt_disable();
}

However, the problem may arise when using a bootloader which does not account for the possibility of watchdog system reset condition. If that is the case, watchdog timeout will happen inside bootloader (which is executed the first) before the above code will have the chance to disable the watchdog timer and µC will be stuck in an endless reset loop. Since reseting the µC will not clear WDRF flag in MCUSR register (it can be cleared only in software or by Power-on reset) the only way will then be to cycle the power and upload a new code when watchdog timer is still not activated by previous code. WDRF in MCUSR register must be cleared before wdt_disable() because WDE can not be cleared if WDRF is still set - therefore the order of the instrucions in the above code is very important. The function placed in .init3 section must not be called from later code.

0

Remove watchdogs flag at init is one solution. I am using optiboot 8.0 and it works perfect.

// Function Pototype
void wdt_init(void) __attribute__ ((naked, used, section(".init3")));

// Function Implementation
void wdt_init(void)
{
    MCUSR = 0;
    wdt_disable();
    return;
}
-1

You can restart the Arduino with this command:

asm volatile ("  jmp 0");
1
  • 1
    This only does soft reset and will not reset it to defaults completely.
    – DominicM
    Commented Jun 14, 2014 at 22:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.