External Interrupt Pin Wake UP ATmega328P deep sleep

Hi,

I'm building a temperature logger.

I have a question regrading to deep sleep mode and interrupt pin.

Sorry for my bad explain but it is a little bit confused.

I have 2 situation.

  1. Using Watch Dog Timer to wake up every 2 minutes. (working)

code layout

void loop (){

screen display(){

  • Logging
  • Change interval

if(logging){
check sensor;
print to screen;
sleep(2min);

}
if(changeinterval){
update interval (1,2,4 min);
}

}

  1. Using external interrupt Pin (Not working)

So I have a interrupt wake up inside a if(!check) loop. However, whenever I try to use PIN 11 to wake up from deep sleep mode when sleepNow() executed. I see the LED PIN 19 is blink but after that LED PIN 15 blink after that. It means the interrupt wake up not in the loop if(!check) but somehow it restart the program again. Thanks

#include <avr/sleep.h>
int check = 0;
// interrupt service routine in sleep mode
void wake ()
{
sleep_disable (); // first thing after waking from sleep:
detachInterrupt (digitalPinToInterrupt (11)); // stop LOW interrupt on D11
} // end of wake

void setup(){
Serial.begin(9600);
pinMode(19, OUTPUT);
pinMode(15, OUTPUT);
pinMode(14, INPUT);
digitalWrite(14, HIGH);
pinMode(11, INPUT);
digitalWrite(11, HIGH);
}

void loop(){
test();
check = digitalRead(14);

if (!check){
sleepNow();
}
else {}

}

void test(){
digitalWrite(15, HIGH);
delay(1000);
digitalWrite(15,LOW);
delay(1000);
}

void sleepNow(){
set_sleep_mode (SLEEP_MODE_PWR_DOWN);
noInterrupts (); // make sure we don't get interrupted before we sleep
sleep_enable (); // enables the sleep bit in the mcucr register
attachInterrupt (digitalPinToInterrupt (11), wake, LOW); // wake up on low level on D11
interrupts (); // interrupts allowed now, next instruction WILL be executed
sleep_cpu (); // here the device is put to sleep

digitalWrite(19, HIGH);
delay(1000);
digitalWrite(19,LOW);
delay(1000);
}

Thank you very much.

Hi

I haven't used this function you explained above but you can use "LowPower" library for going into deep sleep it's very simple and easy to use. Here is the code.

#include <Rtc_Pcf8563.h>
#include "LowPower.h"

Rtc_Pcf8563 rtc;
void PowerDown();
void wakeUp() { }

void setup() {
// put your setup code here, to run once:
for(int i =0; i <= 13; i++)
if(i != 11 || i != 3)
{
pinMode(i, OUTPUT);
digitalWrite(i, 1);
}
// Enable pin 3 as Interrupt1
pinMode(3, INPUT); // set pin to input
digitalWrite(3, HIGH); // turn on pullup resistors
rtc.initClock();
}

void loop() {
// put your main code here, to run repeatedly:
rtc.setTime(0, 0, 0);
rtc.setAlarm(1, 99, 99, 99);
PowerDown();
rtc.clearAlarm();
}

void PowerDown() {
attachInterrupt(digitalPinToInterrupt(3), wakeUp, FALLING);
LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);
detachInterrupt(1);
}

This code use interrupt 1 (pin 3) and pcf8563 RTC module for wakeup after a minute. You can change to whatever you like or real time.

@mryazdani

Thank you very much.

Your code is working well. But actually, I have a different problem.
An easier way to explain.

For example, I have a counting count++ in loop.

If I use RTC to go to deep sleep, it will continue to count after wake up.
But button interrupt is different.

attachInterrupt(digitalPinToInterrupt(3), wakeUp, FALLING);
when it enable Interrupt, it tries to run void wakeUp which is nothing and count will be reset and run from the beginning.

Hope it will make more sense.

Thank you very much.

I can't understand your code because the braces is not correct to find out which code runs under what condition. and also it's not a real code and it is a prototype. But I can only tell you can use a variable and change it into wakeUp() function. In this way into your code you can understand that an interrupt has happened.

mryazdani:
I can't understand your code because the braces is not correct to find out which code runs under what condition. and also it's not a real code and it is a prototype. But I can only tell you can use a variable and change it into wakeUp() function. In this way into your code you can understand that an interrupt has happened.

Thank you very much @mryazdani.

Because I have really long code so that's why I could not post full code here. But here is the example I just wrote.

So I have a interrupt wake up inside a if(!check) loop. However, whenever I try to use PIN 11 to wake up from deep sleep mode when sleepNow() executed. I see the LED PIN 19 is blink but after that LED PIN 15 blink after that. It means the interrupt wake up not in the loop if(!check) but somehow it restart the program again. Thanks

#include <avr/sleep.h>
int check = 0;
// interrupt service routine in sleep mode
void wake ()
{
sleep_disable (); // first thing after waking from sleep:
detachInterrupt (digitalPinToInterrupt (11)); // stop LOW interrupt on D11
} // end of wake

void setup(){
Serial.begin(9600);
pinMode(19, OUTPUT);
pinMode(15, OUTPUT);
pinMode(14, INPUT);
digitalWrite(14, HIGH);
pinMode(11, INPUT);
digitalWrite(11, HIGH);
}

void loop(){
test();
check = digitalRead(14);

if (!check){
sleepNow();
}
else {}

}

void test(){
digitalWrite(15, HIGH);
delay(1000);
digitalWrite(15,LOW);
delay(1000);
}

void sleepNow(){
set_sleep_mode (SLEEP_MODE_PWR_DOWN);
noInterrupts (); // make sure we don't get interrupted before we sleep
sleep_enable (); // enables the sleep bit in the mcucr register
attachInterrupt (digitalPinToInterrupt (11), wake, LOW); // wake up on low level on D11
interrupts (); // interrupts allowed now, next instruction WILL be executed
sleep_cpu (); // here the device is put to sleep

digitalWrite(19, HIGH);
delay(1000);
digitalWrite(19,LOW);
delay(1000);
}