Arduino Uno not wake up second time after recover from sleep mode

I try to wake up my device from deep sleep mode by using the SWQ pin of DS3231 as an interrupt on pin 2 of chip atmega328p. At the moment the device is able to wake up at the first time -> doing some stuff -> back to sleep -> can not wake up for second time. I can not see where is the mistake about the logic. Can someone please help me figure out the problem with it :frowning: I am using the RTClibExtended library. Here is the code :

#include <SPI.h>
#include <RTClibExtended.h>
#include <Wire.h>
#include <LowPower.h>
#include <SD.h>
#include <stdlib.h>
#include <avr/interrupt.h>      // library for interrupts handling
#include <avr/sleep.h>          // library for sleep
#include <avr/power.h>          // library for power control
//----------------------------------------------------
#define LOG_INTERVAL 2000//1s
#define SYNC_INTERVAL 2000
//----------------------------------------------------
#define wakePin 2    //use interrupt 0 (pin 2) and run function wakeUp when pin 2 gets LOW
#define ledPin A0    //debugging LED
#define mosfet 9     //motor pin
#define power 8      //peripheral control pin
#define chipSelect 10 //SS pin for MicroSD card module
//-----------------------Error Message----------------
File logfile;
void error(char *str)
{
  Serial.print("error: ");
  Serial.println(str);
  while(1);
}
//RTC----
byte AlarmFlag = 0;
int sec_log = 60;
int sec_cnt = 0;
int sec_log2 = 60;
int sec_cnt2 = 0;
int motor_flag = 0;
//-----
//---------------Ultrasonic Sensor Pins---------------
const int trigPin1 = 4;
const int echoPin1 = 5;
long duration1;
int distance1;

const int trigPin2 = 6;
const int echoPin2 = 7;
long duration2;
int distance2;
//-----------------RTC declaration--------------------
RTC_DS3231 rtc;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
int interval_sec=4; //An alarm every 4 sec
int i=1;
//----------------------------------------------------
void setup () {
  Wire.begin();       //start the I2C bus
  Serial.begin(9600); //start the Serial module

  //delay(3000); // wait for console opening

  /**RTC**/
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }
  rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));//set RTC date and time to compile time

  //----------------------------
  pinMode(power, OUTPUT);
  pinMode(mosfet, OUTPUT);
  pinMode(ledPin, OUTPUT);
  digitalWrite(mosfet, LOW);
  //-----Ultrasonic Sensors------
  pinMode(trigPin1, OUTPUT);
  pinMode(echoPin1, INPUT);
  pinMode(trigPin2, OUTPUT);
  pinMode(echoPin2, INPUT);
  //-----SD card module----------
  Serial.println("Initializing SD card...");
  pinMode(chipSelect, OUTPUT);
  if(!SD.begin(chipSelect))
  {
    error("Card failed or not present");
  }
  Serial.println("Card Initialized.");
  char filename[] = "DATA00.CSV";
  for (uint8_t i = 0; i<100; i++)
  {
    filename[4] = i/10 + '0';
    filename[5] = i%10 + '0';
    if(!SD.exists(filename))
    {
      logfile = SD.open(filename, FILE_WRITE);
      break;
    }
  }
  if(!logfile)
  {
    error("couldnt create file");
  }
  Serial.print("Logging to: ");
  Serial.println(filename);
//------------------------------  
  /**INTERRUPT**/
  //Set pin D2 as INPUT for accepting the interrupt signal from DS3231
  pinMode(wakePin, INPUT);
  //-----
  digitalWrite(ledPin, HIGH);//switch on the LED for 1s for indicating that the sketch is ok and running
  delay(1000);
  //-----
  //clear any pending alarms
  rtc.armAlarm(1, false);
  rtc.clearAlarm(1);
  rtc.alarmInterrupt(1, false);
  rtc.armAlarm(2, false);
  rtc.clearAlarm(2);
  rtc.alarmInterrupt(2, false);

  //Set SQW pin to OFF 
  //The output of the DS3231 INT pin is connected to this pin
  //connected to arduino D2 pin for wake-up
  rtc.writeSqwPinMode(DS3231_OFF);

  //---
  DateTime now = rtc.now();
  DateTime nextAlarm = now + TimeSpan(0, 0, 0, interval_sec);
  rtc.setAlarm(ALM1_MATCH_HOURS, nextAlarm.second(), nextAlarm.minute(), nextAlarm.hour(), 1);   //set your wake-up time here 
  rtc.alarmInterrupt(1, true);
  
  //-----
  Serial.println("Initialisation complete.");
  delay(100); //Allow for serial print to complete.
}

void loop () {
    
    DateTime now = rtc.now();
    attachInterrupt(0, wakeUp, LOW);//use interrupt 0 (pin 2) and run function wakeUp when pin 2 gets LOW 
    digitalWrite(ledPin, LOW);      //turn of the LED for indicating that we enter the sleep mode
    LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);//arduino enters sleep mode here
    detachInterrupt(0);             //execution resumes from here after wake up
    
     if(AlarmFlag >= 1){
       restartroutine();
       Serial.print("TESTING");
       Serial.println();
      }
      else if(AlarmFlag == 0){
      //alarm triggered, runs sensors to scan the object within 1 hours
      while (now.minute()>0 && now.minute() < 55){
           now = rtc.now();//check time again
           
           distance1 = range(trigPin1, echoPin1, power);
           distance2 = range(trigPin2, echoPin2, power);     
           Serial.print("Distance 1:");
           Serial.print( distance1);
           Serial.print(" Distance 2:");
           Serial.println( distance2);
           
           if(distance1<10 && distance2<10){
              motor_flag=1; //run motor when object within the certain range
           }
           if (motor_flag==1){
              motorrunroutine();
           }
           else if(motor_flag==2){
              motor_flag=0;
            //  Serial.print(AlarmFlag);
             // Serial.println();
              break;
           }
        }
      }
  
    //when exiting the sleep mode we clear the alarm
    rtc.armAlarm(1, false);
    rtc.clearAlarm(1);  
    rtc.alarmInterrupt(1, false); 
    
 
}
//log date and time when motor runs into sd card
void logmotor(){
  DateTime now = rtc.now();
  logfile.print('"');
  logfile.print(now.day(), DEC);
  logfile.print("/");
  logfile.print(now.month(), DEC);
  logfile.print("/");
  logfile.print(now.year(), DEC);
  logfile.print("   ");
  logfile.print(now.hour(), DEC);
  logfile.print(":");
  logfile.print(now.minute(), DEC);
  logfile.print(":");
  logfile.print(now.second(), DEC); 
  logfile.print('"');
  logfile.flush();
  logfile.print("\n");
  logfile.close();     
}
//function to make motor runs only for 4s and also log data into sd card
void motorrunroutine(){
  DateTime now = rtc.now();
  if(sec_cnt<4){
    digitalWrite(mosfet, HIGH);//motor runs only for 4s
  }
  else{
    logmotor();
    AlarmFlag++;
    motor_flag = 2;
    sec_cnt=0;
    stopmotor();
  }
  if(sec_log!=now.second()){
    sec_cnt++;
    sec_log=now.second();
  }
}
//function used to set the alarm flag back to 0 after 4s
void restartroutine(){
  DateTime now = rtc.now();
  if(sec_log2!=now.second()){
    sec_cnt2++;
    sec_log2=now.second();
  }  
  if(sec_cnt2>=4){
    AlarmFlag=0;
    sec_cnt2=0;
  }
}
//stop motor function
void stopmotor(){
  digitalWrite(mosfet, LOW);
}
//ultrasonic sensor control
unsigned long range(byte trigPin, byte echoPin, byte vcc)
  {
    digitalWrite(vcc, LOW);
    delay(50);
    digitalWrite(trigPin, LOW);
    delayMicroseconds(2);
    digitalWrite(trigPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin, LOW);    
    unsigned long duration = pulseIn(echoPin, HIGH);
    digitalWrite(vcc, HIGH);
    delay(100);
    return duration * 0.034 / 2;
   }
// here the interrupt is handled after wakeup
void wakeUp()        
{
}

The process of the system is: wake up at the first time -> activate ultrasonic sensor to scan object -> when object is detected -> run motor -> log the time when motor runs into sd card -> back to sleep -> wake up second time.

If i remember correctly the interrupt output of the DS3231 is open drain. You must have a pullup resistor on the connection for it to work. INPUT_PULLUP On D2 might do the trick (and usually trigger on falling rather than LOW)

I've not read the code in details as I'm not familiar with your library, is the flag removed automatically and you checked you do get a nice ticking on the pin?

I only get the nice ticking on the pin only for the first time(which is the one at first 4 seconds). The problem is I can not reset the AlarmFlag back to 0. Which mean the program does not enter the part

if(AlarmFlag >= 1){
   restartroutine();
 }

However, if I put the serialprint inside that statement. It is able to print out the testing string that I put inside there but not enter the restartroutine() function.

Is there anyway that I can set the alarm to wake my device let say at 6pm. Then the device will run from 6pm to 8pm. But if the sensors detect object -> motor runs -> should back to sleep straight away ->wake up in next day at 6pm.
Up to now I can able to wake the device at 6pm -> do stuff -> back to sleep -> CAN NOT WAKE UP :frowning:

anyone please help me???

what have you done? did you check that link? there are basic exploration you need to do on how the RTC alarm functions could work to your benefit...

At the moment I switch the method from polling the pin SQW of RTC to using the flag. The result is still the same which is I only can wake up the device at the first 4s -> do some thing -> back to sleep and can not wake up the next time.
The new code is:

#include <SPI.h>
#include <RTClibExtended.h>
#include <Wire.h>
#include <LowPower.h>
#include <SD.h>
#include <stdlib.h>
#include <avr/interrupt.h>      // library for interrupts handling
#include <avr/sleep.h>          // library for sleep
#include <avr/power.h>          // library for power control
//----------------------------------------------------
//#define LOG_INTERVAL 2000//1s
//#define SYNC_INTERVAL 2000
//----------------------------------------------------
#define wakePin 2    //use interrupt 0 (pin 2) and run function wakeUp when pin 2 gets LOW
#define ledPin A0    //debugging LED
#define mosfet 9     //motor pin
#define power 8      //peripheral control pin
#define chipSelect 10 //SS pin for MicroSD card module
//-----------------------Error Message----------------
File logfile;
void error(char *str)
{
  Serial.print("error: ");
  Serial.println(str);
  while(1);
}
//RTC----
byte AlarmFlag = 0;
int sec_log = 60;
int sec_cnt = 0;
int sec_log2 = 60;
int sec_cnt2 = 0;
int motor_flag = 0;
//-----
//---------------Ultrasonic Sensor Pins---------------
const int trigPin1 = 4;
const int echoPin1 = 5;
long duration1;
int distance1;

const int trigPin2 = 6;
const int echoPin2 = 7;
long duration2;
int distance2;
//-----------------RTC declaration--------------------
RTC_DS3231 rtc;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
int interval_sec=4; //An alarm every 4 sec
int interval_sec2=2; //An alarm every 2 sec
//----------------------------------------------------
void setup () {
  Wire.begin();       //start the I2C bus
  Serial.begin(9600); //start the Serial module

  /**RTC**/
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }
  rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));//set RTC date and time to compile time

  //----------------------------
  pinMode(power, OUTPUT);
  digitalWrite(power,HIGH);//0V
  pinMode(mosfet, OUTPUT);
  pinMode(ledPin, OUTPUT);
  digitalWrite(mosfet, LOW);//off
  //-----Ultrasonic Sensors------
  pinMode(trigPin1, OUTPUT);
  pinMode(echoPin1, INPUT);
  pinMode(trigPin2, OUTPUT);
  pinMode(echoPin2, INPUT);
  //-----SD card module----------
  Serial.println("Initializing SD card...");
  pinMode(chipSelect, OUTPUT);
  if(!SD.begin(chipSelect))
  {
    error("Card failed or not present");
  }
  Serial.println("Card Initialized.");
  char filename[] = "DATA00.CSV";
  for (uint8_t i = 0; i<100; i++)
  {
    filename[4] = i/10 + '0';
    filename[5] = i%10 + '0';
    if(!SD.exists(filename))
    {
      logfile = SD.open(filename, FILE_WRITE);
      break;
    }
  }
  if(!logfile)
  {
    error("couldnt create file");
  }
  Serial.print("Logging to: ");
  Serial.println(filename);
//------------------------------  
  /**INTERRUPT**/
  //Set pin D2 as INPUT for accepting the interrupt signal from DS3231
  pinMode(wakePin, INPUT);
  //-----
  digitalWrite(ledPin, HIGH);//switch on the LED for 1s for indicating that the sketch is ok and running
  delay(1000);
  //-----
  //clear any pending alarms
  rtc.armAlarm(1, false);
  rtc.clearAlarm(1);
  rtc.alarmInterrupt(1, false);
  rtc.armAlarm(2, false);
  rtc.clearAlarm(2);
  rtc.alarmInterrupt(2, false);

  //Set SQW pin to OFF 
  //The output of the DS3231 INT pin is connected to this pin
  //connected to arduino D2 pin for wake-up
  rtc.writeSqwPinMode(DS3231_OFF);

  //set alarm 1---first 4s
  DateTime now = rtc.now();
  DateTime nextAlarm = now + TimeSpan(0, 0, 0, interval_sec);
  rtc.setAlarm(ALM1_MATCH_HOURS, nextAlarm.second(), nextAlarm.minute(), nextAlarm.hour(), 1);   //set your wake-up time here 
 // rtc.isArmed(1);
  rtc.alarmInterrupt(1, true);
  //set alarm 2-----after the 1st alarm 2 mins
 // DateTime nextAlarm2 = now + TimeSpan(0, 0, interval_sec2, 0);
  //rtc.setAlarm(ALM1_MATCH_HOURS, nextAlarm2.second(), nextAlarm2.minute(), nextAlarm2.hour(), 1);   //set your wake-up time here 
  //rtc.isArmed(2);
 // rtc.alarmInterrupt(2, true);  
  //-----
  Serial.println("Initialisation complete.");
  delay(100); //Allow for serial print to complete.
}
volatile boolean alarmISRwascalled = false;

void loop () {
   
  if(alarmISRwascalled){
    attachInterrupt(0, wakeUp, LOW);//use interrupt 0 (pin 2) and run function wakeUp when pin 2 gets LOW 
    digitalWrite(ledPin, LOW);      //turn of the LED for indicating that we enter the sleep mode
    LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);//arduino enters sleep mode here
    detachInterrupt(0);             //execution resumes from here after wake up

    //when exiting the sleep mode we clear the alarm
    rtc.armAlarm(1, false);
    rtc.clearAlarm(1);
    rtc.alarmInterrupt(1, false); 
    
    DateTime now = rtc.now();  
    if(alarmISRwascalled == true){
      while (now.minute()>0 && now.minute() < 58){
       now = rtc.now();//check time again
       distance1 = range(trigPin1, echoPin1, power);
       distance2 = range(trigPin2, echoPin2, power);     
       Serial.print("Distance 1:");
       Serial.print( distance1);
       Serial.print(" Distance 2:");
       Serial.println( distance2);
       if(distance1<10 && distance2<10){
          motor_flag=1;
       }
       if (motor_flag==1){
          motorrunroutine();
       }
       else if(motor_flag==2){
          motor_flag=0;
          alarmISRwascalled = false;
          break;  
       }
      }        
    }
  }
}
//log date and time when motor runs into sd card
void logmotor(){
  DateTime now = rtc.now();
  logfile.print('"');
  logfile.print(now.day(), DEC);
  logfile.print("/");
  logfile.print(now.month(), DEC);
  logfile.print("/");
  logfile.print(now.year(), DEC);
  logfile.print("   ");
  logfile.print(now.hour(), DEC);
  logfile.print(":");
  logfile.print(now.minute(), DEC);
  logfile.print(":");
  logfile.print(now.second(), DEC); 
  logfile.print('"');
  logfile.flush();
  logfile.print("\n");
  logfile.close();     
}
//function to make motor runs only for 4s and also log data into sd card
void motorrunroutine(){
  DateTime now = rtc.now();
  if(sec_cnt<4){
    digitalWrite(mosfet, HIGH);//motor runs only for 4s
  }
  else{
    logmotor();
    motor_flag = 2;
    sec_cnt=0;
    stopmotor();
  }
  if(sec_log!=now.second()){
    sec_cnt++;
    sec_log=now.second();
  }
}
//function used to set the alarm flag back to 0 after 4s
void restartroutine(){
  DateTime now = rtc.now();
  if(sec_log2!=now.second()){
    sec_cnt2++;
    sec_log2=now.second();
  }
  
  if(sec_cnt2>=4){
    alarmISRwascalled = true;
    sec_cnt2=0;
  }
}
//stop motor function
void stopmotor(){
  digitalWrite(mosfet, LOW);
}
//ultrasonic sensor control
unsigned long range(byte trigPin, byte echoPin, byte vcc)
  {
    digitalWrite(vcc, LOW);
    delay(50);
    digitalWrite(trigPin, LOW);
    delayMicroseconds(2);
    digitalWrite(trigPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin, LOW);    
    unsigned long duration = pulseIn(echoPin, HIGH);
    digitalWrite(vcc, HIGH);
    delay(100);
    return duration * 0.034 / 2;
   }
// here the interrupt is handled after wakeup
void wakeUp()        
{
  alarmISRwascalled = true;
}

what about my comment in #1 for open drain? did you investigate?

sorry to reply late, I did have the pull up resistor at the SQW pins.
the schematic for the RTC part is: