Disattivare interrupt in modalità sleep

Slave a tutti! è da un po’ che non scrivo sul forum :slight_smile: ieri volevo sperimentare le modalità sleep di arduino per un progetto che avevo in mente e che richiede un risparmio di energia essendo alimentato da una lipo. Così ho messo su un circuitino semplicissimo: ho semplicemente collegato i pin 12 e 11 di arduino rispettivamente al data e clock di un 74hc164n (un registro SIPO) alle cui prime tre uscite ho collegato tre led per la visualizzazione dello stato logico. E infine ho messo un pulsante al pin 3 e un interruttore che al pin 2(di interrupt).
Il codice è ilseguente:

#include <buttons.h>
#include <avr/sleep.h>
#define CLOCK_PIN 11
#define DATA_PIN 12

Button but;
int data;
unsigned long time;

void setup(){
  Serial.begin(9600);
  pinMode(10,OUTPUT);
  digitalWrite(10,HIGH);
  pinMode(CLOCK_PIN,OUTPUT);
  pinMode(DATA_PIN,OUTPUT);
  but.assign(3); but.setMode(OneShot); but.turnOnPullUp();
  but.check();
  data = 0;
  Serial.println("Si parte!");
}

void loop(){
  for(data = 0; data < 8; data++){
    shiftOut(DATA_PIN,CLOCK_PIN,MSBFIRST,data);
    time = millis();
    while(millis() - time <= 500){
      if(but.check() == ON)
        enter_sleep();
    }
  }
}

void enter_sleep(){
  set_sleep_mode(SLEEP_MODE_STANDBY);
  attachInterrupt(0,wake_up,CHANGE);
  sleep_enable();
  sleep_mode();
  
  sleep_disable();
}

void wake_up(){
   detachInterrupt(0);
}

In altre parole i tre led del registro iniziano ad accendersi e a “contare” fino a 7 in binario, nel momento in cui premo il pulsante sul pin 3 attivo l’interrupt sul pin2(per “svegliare” arduino) e arduino và in modalità sleep STANDBY(tutti i clock spenti).
Fin qui tutto apposto: i led sono fermi e arduino dorme tranquillo xD così pigio l’interruttore, cambio di stato il pin2 e arduino si sveglia. Il problema è che in modalità STANDBY dopo 2-3 volte che ripeto tale ciclo arduino permane nel suo sonno e non si sveglia più nonostante io pigio l’interruttore…
In modalità di sleep PWR_DOWN(che si differenzia dalla STANDBY per la disabilitazione del clock principale) succede la stessa cosa solo che succede dopo tipo 10-11 cicli di sveglia-dormi.
Non fiducioso però della disattivazione dell’interrupt all’interno della routine dell’interrupt stesso allora ho modifica il codice semplicemente togliendo la disabilitazione all’interno della routine e aggiungendola all’esterno:

#include <buttons.h>
#include <avr/sleep.h>
#define CLOCK_PIN 11
#define DATA_PIN 12

Button but;
int data;
unsigned long time;

void setup(){
  Serial.begin(9600);
  pinMode(10,OUTPUT);
  digitalWrite(10,HIGH);
  pinMode(CLOCK_PIN,OUTPUT);
  pinMode(DATA_PIN,OUTPUT);
  but.assign(3); but.setMode(OneShot); but.turnOnPullUp();
  but.check();
  data = 0;
  Serial.println("Si parte!");
}

void loop(){
  for(data = 0; data < 8; data++){
    shiftOut(DATA_PIN,CLOCK_PIN,MSBFIRST,data);
    time = millis();
    while(millis() - time <= 500){
      if(but.check() == ON){
        enter_sleep();
        detachInterrupt(0);
      }
    }
  }
}

void enter_sleep(){
  set_sleep_mode(SLEEP_MODE_STANDBY);
  attachInterrupt(0,wake_up,CHANGE);
  sleep_enable();
  sleep_mode();
  
  sleep_disable();
}

void wake_up(){
}

A questo punto il codice funziona alla perfezione e non si blocca più…
Chi mi può spiegare perchè? xD Cosa comporta la disattivazione di un interrupt all’interno della susa stessa routine? Mi sfugge qualcosa? Grazie in anticipo per le risposte :slight_smile:

Qui ci vuole Leo. :wink: