Using WDT

Im looking back into WDT use for power savings. I want to make sure I understand this code properly. This uses the 8 second max setting but multiplies it by nbr_remaining in order to go above 8 seconds, so 5 times would be 40 seconds.

So this will start up, blink 2x, sleep for 40 seconds, blink 3x, sleep for 40 seconds, blink 3x...etc:

#include <avr/wdt.h>            // library for default watchdog functions
#include <avr/interrupt.h>      // library for interrupts handling
#include <avr/sleep.h>          // library for sleep
#include <avr/power.h>          // library for power control

int nbr_remaining; 

#define led 13

ISR(WDT_vect){
        // not hanging, just waiting
        // reset the watchdog
        wdt_reset();
}

void configure_wdt(void){
  cli();                           // disable interrupts for changing the registers
  MCUSR = 0;                       // reset status register flags
                                   // Put timer in interrupt-only mode:                                       
  WDTCSR |= 0b00011000;            // Set WDCE (5th from left) and WDE (4th from left) to enter config mode,
                                   // using bitwise OR assignment (leaves other bits unchanged).
  WDTCSR =  0b01000000 | 0b100001; // set WDIE: interrupt enabled
                                   // clr WDE: reset disabled
                                   // and set delay interval (right side of bar) to 8 seconds
  sei();                           // re-enable interrupts
 
}

void sleep(int ncycles){  
  nbr_remaining = ncycles; // defines how many cycles should sleep
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  power_adc_disable();
  while (nbr_remaining > 0){ // while some cycles left, sleep!
  sleep_mode();

  // CPU is now asleep and program execution completely halts!
  // Once awake, execution will resume at this point if the
  // watchdog is configured for resume rather than restart
 
  // When awake, disable sleep mode
  sleep_disable();
  
  // we have slept one time more
  nbr_remaining = nbr_remaining - 1;
 
  }
 
  // put everything on again
  power_all_enable();
 
}

void setup(){
  
  // use led 13 and put it in low mode
  pinMode(led, OUTPUT);
  digitalWrite(led, LOW);
  
  delay(1000);
  
  // configure the watchdog
  configure_wdt();

  // blink twice
  digitalWrite(led, HIGH);   
  delay(500);               
  digitalWrite(led, LOW);   
  delay(500); 
  digitalWrite(led, HIGH);   
  delay(500);               
  digitalWrite(led, LOW);   
  delay(500); 

}

void loop(){

  // sleep for a given number of cycles (here, 5 * 8 seconds) in lowest power mode
  sleep(5);

  // usefull stuff should be done here before next long sleep
  // blink three times
  digitalWrite(led, HIGH);   
  delay(500);               
  digitalWrite(led, LOW);   
  delay(500); 
  digitalWrite(led, HIGH);   
  delay(500);               
  digitalWrite(led, LOW);   
  delay(500); 
  digitalWrite(led, HIGH);   
  delay(500);               
  digitalWrite(led, LOW);   
  delay(500); 

}

Does it work ? Ie do you see 2 blinks, a long pause (40 seconds), then 3 blinks ?

Compare it with https://www.gammon.com.au/forum/?id=11497 Sketch 'H'

Yours appears to be missing at least a sleep_cpu()

Ok it blinks 2 and 3 times after 40 seconds, as expected. (Sorry, I wasnt at the house to try it).

Now I want to try it measuring power consumption. I've used a multimeter to measure amperage before, so Im using a nano. So I just plug it into a breadboard and run GND from a battery pack into GND of the nano and then + from the battery pack (thru the +/- of the multimeter) and into the 5V of the nano?