Best way to Sleep & Wake Arduino using single Interrupt pin?

Thread Starter

abuhafss

Joined Aug 17, 2010
307
Hi

I plan to make Arduino Nano, sleep and then wake using pin 3 as interrupt.

TEST CODE:
#include <avr/sleep.h>
#define interruptPin 3

unsigned long wakeUpMillis = 0;
bool IntAttached = true; // Interrupt is attached

void setup()
{
  Serial.begin(115200);//Start Serial Comunication
  pinMode(LED_BUILTIN,OUTPUT);
  pinMode(interruptPin,INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), goToSleep, LOW);
}

void loop()
{
  digitalWrite(LED_BUILTIN,HIGH);
  delay(500);
  digitalWrite(LED_BUILTIN,LOW);
  delay(500);

  if (!IntAttached && millis() - wakeUpMillis > 2000)
  {
    noInterrupts();
    attachInterrupt(digitalPinToInterrupt(interruptPin), goToSleep, LOW);
    interrupts();
    IntAttached = true;
  }
}

void goToSleep()
{
  sleep_enable();//Enabling sleep mode
  noInterrupts();
  attachInterrupt(digitalPinToInterrupt(interruptPin), wakeUp, LOW);
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  Serial.println("Going to sleep..... zzzZZZZ");
  delay(2000);
  interrupts();
  sleep_cpu();//activating sleep mode
  // Now the µController is asleep........zzzZZZZZZ
  //
  //
  // will resume from here
  //
  //
  Serial.println("just woke up!");
}

void wakeUp()
{
  noInterrupts();
  detachInterrupt(digitalPinToInterrupt(3));
  interrupts();
  IntAttached = false; // Interrupt is detached.

  Serial.println("Interrupt Fired");
  sleep_disable();
  wakeUpMillis = millis();
}
The problem is that the Nano goes to sleep but wakes up immediately, when the button is pushed to make sleep.

I have even tried as below:

digitalRead+debounce => Go to Sleep
Interrupt => Wake up

But is still not working.

What is best way to make Arduino sleep/wake using a single push button?
 

Papabravo

Joined Feb 24, 2006
21,225
When you are awake you need to disable the interrupt and monitor the pin as an ordinary digital input. When the buttons is depressed and debounced you begin the process of going to sleep and the very last thing you do is enable the interrupt to wake you up. When you wake up, you will be in an interrupt service routine where you can clean things up, disable the interrupt, and return from the interrupt to where you were when you went to sleep.
 

Phil-S

Joined Dec 4, 2015
238
Nick Gammon (gammon.au) covers Atmel sleep comprehensively.
Definitely worth a look for that and other Arduino subjects.
 
Top