Viewing 3 posts - 1 through 3 (of 3 total)
  • Author
    Posts
  • #8541
    adam.g
    Participant

    Hi there,

    I’m currently using LowPower.h to put my Arduino to sleep and await an external interrupt from an RTC to wake up. However, in the event that my program hangs, or encounters some other issue, I’d like to have the WDT perform a hard reset of the Arduino. Could you tell me if the LowPower.h library is able to reset an Arduino?

    Cheers,
    Adam

    #8558
    LIM PHANG MOH
    Keymaster

    The library currently uses the WDT as an interrupt timer to wake up (SLEEP_8S, SLEEP_4S, etc) rather than a reset.
    During non-sleep operation, you could use the WDT as a reset source but it’s not covered by the library. For sleep operation, instead of using SLEEP_FOREVER and depend solely on the external RTC, you could instead use SLEEP_xS instead although that is not the same as WDT reset but it uses the same exact WDT internal timer to do that.

    #8577
    adam.g
    Participant

    Thanks for your reply!

    After I made this post, I spent the next 48 hours studying the Watchdog Timer and the AVR wdt.h, sleep.h, power.h and interrupt.h libraries to get a better understanding of how everything worked. I was able to implement a simple solution with the AVR libraries that uses the WDT as an interrupt timer with a loop in the ISR that will check a flag to determine if the program is actually asleep. If it detects the program has frozen, it will enable the Watchdog System Reset Enable bit in the WDTCSR register. It’s working well so far and I now see how I could use the LowPower.h library to simplify the sleep commands.

    Cheers,
    Adam

    
    ISR(WDT_vect)
    {
      wdtIsrWasCalled = true;
      // Check if system reset is required
      if (sleeping == true)
      {
        wdt_reset();
        sleeping = false;
      }
      else
      {
        // Enable WDT System Reset Mode
        MCUSR = 0;                          // Clear Reset Flags of MCU Status Register (MCUSR)
        WDTCSR |= (1 << WDCE) | (1 << WDE); // Start timed sequence allowing changes to Watchdog Timer Control Register (WDTCSR)
        // Clear Watchdog Interrupt Enable (WDIE), set Watchdog System Reset Enable (WDE) and clear Watchdog Timer Prescalers WDP3, WDP2, WDP1 and WDP0 to select a 16 ms timeout period
        WDTCSR = (0 << WDIE) | (1 << WDE) | (0 << WDP3) | (0 << WDP2) | (0 << WDP1) | (0 << WDP0); 
        while (1);                          // System reset will occur after 16 ms
      }
    }
    
Viewing 3 posts - 1 through 3 (of 3 total)
  • You must be logged in to reply to this topic.