Need help escaping watchdog timer in sleep.

I am trying to learn how to limit power consumption automatically and have run into not being able to have watchdog esape and start the next 8 second count. I’m not 100% sure where I am breaking since I am using an Attiny85 instead of a full Uno.

I’m not sure which part(s) I am missing below is the code I am trying to run.

   #include <avr/sleep.h> 
    #include <avr/wdt.h> 
    #include <avr/power.h> 
    #define LED 4 
    
    int count = 0;
    long counterlimit = 7 * 1; //for one minute time out 7* 8 seconds for max watchdog time out

    void setup(void) {
      pinMode(LED, OUTPUT); //led to blink
      ADCSRA = 0; // disable the analog to digital Converter (powersavings for sleep mode)
      setup_watchDogTimers();
    }
    
    void loop(void) {
      wdt_reset();
      if (count >= counterlimit) {
        digitalWrite(LED, HIGH);
        delay(1000);
        digitalWrite(LED, LOW);
        delay(1000);
        count = 0;
      }
      enterSleep();
      count++; 
    }

     void enterSleep(void)
    { 
      set_sleep_mode(SLEEP_MODE_PWR_DOWN); 
      sleep_enable();
      sleep_cpu();
      sleep_disable();
    }

Sorry missed the end of my code.

   void setup_watchDogTimers(void)
    {
      cli();
     wdt_reset(); 
     delay(500);
      WDTCR |= (1<<WDCE) | (0<<WDE);  
      WDTCR = (1<<WDIE) | (1<<WDE) | (1<<WDP3) | (0<<WDP2) | (0<<WDP1) | (1<<WDP0);   // removed "S" from WDTCSR (attiny requires "WDTCR", Uno requires "WDTCSR".
      sei();//enable interrupts 1001 equals 8 seconds acutally seeing about 9 seconds. '
     }

I am using the attiny cores from used the attiny core from here http://code.google.com/p/arduino-tiny/ .

Depending on why you need the watchdog, you should either turn the watchdog off when you go to sleep or wake the processor once in a while to pat the dog.

There is also the WDT interrupt which may or may not be helpful. I don’t know if it will wake you up from sleep or not.

My whole purpose is just to save as much power between blinks trying to have a blink once every minute or two. see if I can get a battery to last a few months before it is used up.

as I've been hammering things out I have removed and replaced the following in the code (because I really have no idea what it does and don't see how it is being called if ever)

ISR(WDT_vect) {
  f_wdt=1;  // set global flag
}

Read the datasheet. The watchdog can fire an interrupt in addition to or in lieu of resetting the board. Here all it is doing is setting a flag to let you know that the watchdog has reset your board. That's silly since there is already such a bit in one of the control registers that you can check for the same purpose.

If all you're doing is blinking a light, how terribly sensitive are you to the board locking up? You could do away with the watchdog entirely.

It is just a learning experiment on my part.

Wouldn't be anything sensitive about locking the board up could just unplug it and plug it in again.

but everything I have been reading on low power consumption has thrown me towards watch dog but 90% of the other examples always have some kind of external force break the sleep mode. I was trying to have it just wait a minute or more and then wake blink then sleep again.

If there is another better know power saving process out there I would be more then willing to investigate.

You can have it wake on one of the timer interrupts I think. That sounds like what you are looking for.

I think people sometimes use the watchdog timer because you can run it out to 8 seconds. But in that case you wouldn't be patting the dog ever. You'd be using the WDT interrupt vector to wake the board. I don't really know anything about how that works.

I have found this site http://winn.ws/blog/2014/12/01/watchdog-arduino/ it gets me to almost what I think I want to be at. using the following code

#include <avr/sleep.h>
#include <avr/wdt.h>
#define adc_disable() (ADCSRA &= ~(1<<ADEN))


int pinLed = 4;
volatile boolean f_wdt = 1;

void setup(){
  pinMode(pinLed,OUTPUT);
  setup_watchdog(9);
  adc_disable();
}

void loop(){
  if (f_wdt==1) {
    f_wdt=0;
    digitalWrite(pinLed, HIGH);
    delay(500);
    digitalWrite(pinLed,LOW);
    system_sleep();
  }
}

void system_sleep() {
  set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode
  sleep_enable();
  sleep_mode();
  sleep_disable();
}

void setup_watchdog(int ii) {
  byte bb;
  int ww;
  if (ii > 9 ) ii=9;
  bb=ii & 7;
  if (ii > 7) bb|= (1<<5);
  bb|= (1<<WDCE);
  ww=bb;
  MCUSR &= ~(1<<WDRF);
  // start timed sequence
  WDTCR |= (1<<WDCE) | (1<<WDE);
  // set new watchdog timeout value
  WDTCR = bb;
  WDTCR |= _BV(WDIE);
}
   
// Watchdog Interrupt Service / is executed when watchdog timed out
ISR(WDT_vect) {
  f_wdt=1;
}

It gives me a blink every 9.25 seconds at 1Mhz for the attiny. I have no idea what setup_watchdog does but will be working in the main loop to see if I can somehow increment the sleep to multiples of the 9.25 seconds as that is what I am really after.

Thank you Delta_G got what I believe I need now just need to document what I understand for myself.

For anyone reading this with the same issue this is the undocumented code I wound up using. (I don’t have a functional multimeter atm so I can’t tell how much energy I am actually using.

#include <avr/sleep.h>
#include <avr/wdt.h>
#define adc_disable() (ADCSRA &= ~(1<<ADEN))


int pinLed = 4;
volatile boolean f_wdt = 1;

int counter = 0;
long counterlimit = 4 * 1;


void setup(){
  pinMode(pinLed,OUTPUT);
  setup_watchdog(9);
  adc_disable();
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
}

void loop(){
  if (f_wdt==1) {
    if(counter >= counterlimit) {
    f_wdt=0;
    digitalWrite(pinLed, HIGH);
    delay(500);
    digitalWrite(pinLed,LOW);
    system_sleep();
    } else {
    counter++;  
    system_sleep();
    }
  }
 
}

void system_sleep() {
  set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode
  sleep_enable();
  sleep_mode();
  sleep_disable();
}

void setup_watchdog(int ii) {
  byte bb;
  int ww;
  if (ii > 9 ) ii=9;
  bb=ii & 7;
  if (ii > 7) bb|= (1<<5);
  bb|= (1<<WDCE);
  ww=bb;
  MCUSR &= ~(1<<WDRF);
  // start timed sequence
  WDTCR |= (1<<WDCE) | (1<<WDE);
  // set new watchdog timeout value
  WDTCR = bb;
  WDTCR |= _BV(WDIE);
}
   
// Watchdog Interrupt Service / is executed when watchdog timed out
ISR(WDT_vect) {
  f_wdt=1;
}

I have a similar project that blinks an LED on an ATtiny85 using the watchdog timer.

http://www.gammon.com.au/forum/?id=12769

Thanks Nick. Your soldering skill are very impressive I hope to get there sometime. Excellent idea for finding light when main power has gone out.

Can you clarify for me what line/function actually cancels the sleep time of the attiny? I am still confused.

The watchdog interrupt cancels the sleep. This line cancels the watchdog:

   wdt_disable();  // disable watchdog