Go Down

Topic: External Interrupt Pin Wake UP ATmega328P deep sleep (Read 1 time) previous topic - next topic

trungdn

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);
}

}

2. 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.

mryazdani

#1
Jan 10, 2018, 10:08 am Last Edit: Jan 10, 2018, 12:44 pm by mryazdani
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.

trungdn

@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.

mryazdani

#3
Jan 12, 2018, 10:33 am Last Edit: Jan 12, 2018, 04:45 pm by 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.

trungdn

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);
}

Go Up