Resolved: Deep sleep interrupt

Hi all,

Using ATMega329PAU. I am trying to use a rising pin state on D2 (Ard Pin 2, Interrupt Pin 0) to wake device. I am finding code below does not sleep when D2 is connected to ground throughout. Printing the digital read value and checking on a bench meter shows the pin state to be a constant 0.

Question relates to GoingToSleep funtion below. Can you think of any reason why the code doesn’t sleep in the middle if the D2 pin state is 0?

I have tried CHANGE and RISING interrupt.

Thanks,
Ben.

#include <math.h>
#include <avr/sleep.h>
#define interruptPin 2 

#include "Arduino.h"
#include <avr/power.h>
#include <avr/sleep.h>
#include <avr/wdt.h>

volatile int f_wdt=1;

float vout = 0.0;
float vin = 0.0;
float RV1 = 100000.0; // resistance of R1 (100K)
float RV2 = 10000.0; // resistance of R2 (10K)
int value = 0;

int ThermistorPin = 0;
int Vo;
float R1 = 10000;
float logR2, R2, T, HT, CT;
float c1 = 1.009249522e-03, c2 = 2.378405444e-04, c3 = 2.019202697e-07;

int identifier = 88;

double thePower, tempC = 0, tempP = 0;
int count = 0;
char buffer1[30], buffer2[30];
 
int volt = 99;
int Irms = 999;                                     
int index;
char inchar;
String temp = "";
char pos[80];
 
byte start_with = 0;
byte end_with = 0;
byte CRC = 0;
int b;
float a,y=0;
 
String incomingByte = "";
unsigned int stringLength;
int started = 0;


int l1 = 0;
int l2Pin = 3;
int lPin = 2;
int s1Pin = 13;               
int s2Pin = 12;  
int s3Pin = 11;               
int s4Pin = 10;           
int rbPin = 9;
int pPin = 8;  
int lrPin = 5; 
int lgPin = 6; 
int lbPin = 7;
byte SENSE = 6;

int valve = 0;

ISR(WDT_vect) {                                           // watchdog interrupt service, executed when watchdog timed out
  if(f_wdt == 0) {
    f_wdt=1;
  }
}

void enterSleep(void)                                     // timed sleep func
{
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  sleep_mode();
                                                          // continue after sleep
  sleep_disable();
  power_all_enable();                                     // re-enable the peripherals.
}

void setupWatchDogTimer() {                               // setup the Watch Dog Timer (WDT) to 8s
  MCUSR &= ~(1<<WDRF);                                    // clear the reset flag on the MCUSR, the WDRF bit (bit 3)
  WDTCSR |= (1<<WDCE) | (1<<WDE);                         // configure the Watchdog timer Control Register (WDTCSR)
  /**
   *  Setting the watchdog pre-scaler value with VCC = 5.0V and 16mHZ
   *  WDP3 WDP2 WDP1 WDP0 | Number of WDT | Typical Time-out at Oscillator Cycles
   *  0    0    0    0    |   2K cycles   | 16 ms
   *  0    0    0    1    |   4K cycles   | 32 ms
   *  0    0    1    0    |   8K cycles   | 64 ms
   *  0    0    1    1    |  16K cycles   | 0.125 s
   *  0    1    0    0    |  32K cycles   | 0.25 s
   *  0    1    0    1    |  64K cycles   | 0.5 s
   *  0    1    1    0    |  128K cycles  | 1.0 s
   *  0    1    1    1    |  256K cycles  | 2.0 s
   *  1    0    0    0    |  512K cycles  | 4.0 s
   *  1    0    0    1    | 1024K cycles  | 8.0 s
  */
  WDTCSR  = (1<<WDP3) | (0<<WDP2) | (0<<WDP1) | (1<<WDP0);// Set the watchdog pre-scaler
  WDTCSR |= _BV(WDIE);                                    // enable the WD interrupt (note: no reset)
}

void(* resetFunc) (void) = 0;//declare reset function at address 0

void Going_To_Sleep(){
    Serial.println("Sleep");
    delay(1000);
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);      // setting sleep mode (full sleep)
    noInterrupts ();                          // make sure no interrupt before sleep
    sleep_enable();                           // enable sleep mode

    EIFR = bit (INTF0);                       // clear flag for interrupt 0
    
    attachInterrupt(0, wakeUp, CHANGE);       // attach an interrupt to pin d2
    delay(1000);  
    interrupts ();                            // interrupts allowed now, next instruction WILL be executed
    sleep_cpu();                              // activate sleep mode
    sleep_disable();                          // disable sleep mode (next line of code executed after the interrupt)
    Serial.println("Awake");
    delay(1000);
}

void wakeUp(){
  detachInterrupt(0); //Removes the interrupt from pin 2;
}

void takeRead(){
  Vo = analogRead(ThermistorPin);
  R2 = R1 / (1023.0 / (float)Vo - 1.0);
  logR2 = log(R2);
  T = (1.0 / (c1 + c2*logR2 + c3*logR2*logR2*logR2));
  T = T - 273.15;
}
 
void setup() {
  pinMode(lPin, OUTPUT);
  pinMode(s1Pin, OUTPUT);
  pinMode(s2Pin, OUTPUT);
  pinMode(s3Pin, OUTPUT);
  pinMode(s4Pin, OUTPUT);
  pinMode(rbPin, OUTPUT);
  pinMode(pPin, OUTPUT);
  pinMode(lbPin, OUTPUT);
  pinMode(lgPin, OUTPUT);
  pinMode(lrPin, OUTPUT);
  digitalWrite(lPin, LOW);
  digitalWrite(s1Pin, LOW);
  digitalWrite(s2Pin, LOW);
  digitalWrite(s3Pin, LOW);
  digitalWrite(s4Pin, LOW);
  digitalWrite(pPin, LOW);
  digitalWrite(rbPin, LOW);
  digitalWrite(lbPin, HIGH);
  digitalWrite(lgPin, HIGH);
  digitalWrite(lrPin, HIGH);
  pinMode(interruptPin,INPUT);  

  Serial.begin(115200);
  delay(1000);
  for (int i=0; i < 2; i++){               
    digitalWrite(lgPin, LOW);
    delay(800);
    digitalWrite(lgPin, HIGH);
    delay(400);
  }
  delay(5000);
  
  Serial.print("Int. state ");
  Serial.println(digitalRead(2));
  delay(500);   
  
  setupWatchDogTimer();
  
//  digitalWrite(s1Pin, LOW);                 // config solenoid 1 closed
//  digitalWrite(s2Pin, HIGH);
//  digitalWrite(s3Pin, LOW);                 // config solenoid 2 closed
//  digitalWrite(s4Pin, HIGH);
//  delay(10);
//  digitalWrite(s1Pin, LOW);
//  digitalWrite(s2Pin, LOW);
//  digitalWrite(s3Pin, LOW);
//  digitalWrite(s4Pin, LOW);
//
//  delay(10); 
//  digitalWrite(pPin, HIGH);                 // power solenoid
//  delay(50);              
//  digitalWrite(pPin, LOW);
}
 
void loop() { 
    
    if(f_wdt != 1) {                                        // wait until  watchdog has triggered a wake up
      return;
    }

    Going_To_Sleep();

//////////////////////MAIN CODE///////////////////////////////// 

    resetFunc();                              // call reset
}

What is the purpose of implementing an unused watchdog timer? Why is the watchdog never padded (wdt_reset)? Why do you reset the MCU for each loop?

Thanks, you were right, it was the two watchdogs issue. I find them difficult.

As I tested different parts separately, there is interrupted sleep and timed sleep (while device waits for reponses during activation). By setting up watchdog timer for timed sleep after the interrupt in main loop. device is now working.

The interrupt only runs once between reboots.

The device spends days sleeping so I thought it would be most reliable to have a fresh start after each activation.