UNO doesn't wake up out of sleepmode

Hello!

My project needs to measure distance every 15 minutes and write the result, together with a timestamp, to an SD card. To save power, it has to go to sleep in between the measurements and to wake up by an external interrupt provided by an RTC.

My project is based on an example you can find here: Project: Example using a RTC to wake-up an Arduino Data Logger — The Arduino Maker Man
Only instead of using the Pro Mini, I use an UNO. This just because I'm new to arduino and don't want to start on the mini before I am sure the sketch works. Taking it step by step.

Problem: After about an hour working correctly (and thus writing about 4 measurements correctly to the SD card), the UNO seems to stay in sleep mode and doesn't do anything anymore.

Setup:
UNO
9V battery
mini SD breakout
RTC DS3231
DHT11
UltraSonic US-015

Please find the code in attachment.

Thank you for helping me out!!

Datalog_sleep_20190725_test.txt (3.81 KB)

Please post your code.

#include <avr/sleep.h>
#include <DS3232RTC.h>  //RTC Library https://github.com/JChristensen/DS3232RTC
#include "DHT.h"        
#include <SPI.h>        
#include <SD.h>         
#include <TimeLib.h>
#include <NewPing.h>


#define DHTPIN 7     

#define interruptPin 2

#define DHTTYPE DHT11  
//#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321
DHT dht(DHTPIN, DHTTYPE); 

#define TRIGGER_PIN 6
#define ECHO_PIN 8
#define MAX_DISTANCE 400

float hum;
float temp;
float duur;
float distance;
float soundsp;
NewPing sonar (TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);



File myFile;
const int chipSelect = 10;

const int time_interval =10;// Sets the wakeup intervall in minutes

/*********************************************************************************************************************
 * SETUP
 *********************************************************************************************************************/

void setup() {
  Serial.begin(115200);//Start Serial Comunication
  pinMode(interruptPin,INPUT_PULLUP);//Set pin d2 to input using the buildin pullup resistor
  
  // initialize the alarms to known values, clear the alarm flags, clear the alarm interrupt flags
    RTC.setAlarm(ALM1_MATCH_DATE, 0, 0, 0, 1);
    RTC.setAlarm(ALM2_MATCH_DATE, 0, 0, 0, 1);
    RTC.alarm(ALARM_1);
    RTC.alarm(ALARM_2);
    RTC.alarmInterrupt(ALARM_1, false);
    RTC.alarmInterrupt(ALARM_2, false);
    RTC.squareWave(SQWAVE_NONE);
    
     time_t t; 
    t=RTC.get();
    RTC.setAlarm(ALM1_MATCH_MINUTES , 0, minute(t)+time_interval, 0, 0);
    // clear the alarm flag
    RTC.alarm(ALARM_1);
    // configure the INT/SQW pin for "interrupt" operation (disable square wave output)
    RTC.squareWave(SQWAVE_NONE);
    // enable interrupt output for Alarm 1
    RTC.alarmInterrupt(ALARM_1, true);
    
    dht.begin();//Start the DHT sensor   

    if (!SD.begin(chipSelect)) {
        Serial.println("initialization failed!");
        return;
    }
   

}


/*********************************************************************************************************************
 * LOOP
 *********************************************************************************************************************/

void loop() {
 delay(5000);
 SleepNow();
}


/*********************************************************************************************************************
 * FUNCTIONS
 *********************************************************************************************************************/

void SleepNow(){
    sleep_enable();
    attachInterrupt(0, wakeUp, LOW);
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);   
    
    cli();
    sleep_bod_disable();
    sei();
    
    sleep_cpu();
    
    measure();//function to measure distance
  
   time_t t;
    t=RTC.get();

    //Set New Alarm
    RTC.setAlarm(ALM1_MATCH_MINUTES , 0, minute(t)+time_interval, 0, 0);
  
  // clear the alarm flag
  RTC.alarm(ALARM_1);
  }

void wakeUp(){
  Serial.println("Interrrupt Fired");
   sleep_disable();
  detachInterrupt(0); 
 
 
}

You should not use Serial.print inside a ISR. An ISR should be fast, and do very little. In order to see if this is the cause of your issue, remove the serial.println.

Thanks for your advice. I have removed the Serial.print, but it makes no difference. This time after 3 interrupts it doesn't wake up anymore. :confused:

I noticed that this doesn't happen when I use a time-interval of 2 minutes instead of 15.

But what that means, I don't know.

I do not know much about RTC and setting alarms. But what happens if you add minute and time_interval. Perhaps you should print the result of that. If minute(t) is 59 and you add 10 what is the result. And what does that value translate to in the setting of the alarm.

Problem solved. Thank you Romonaga!!

When you just add the minutes with the time-interval, it will happen that you come to a sum of more than 59, while there are only 60 minutes in an hour. The moment that the time is e.g. 00:68:00 will never happen.

Thats why I added an if-statement that subtracts 60 from the sum of minute(t) and time_interval when that sum is more than 59. Result: 00:68:00 becomes 00:08:00 and the interrupt will be fired at the correct time.

Thanks again!

Jedidja:
I noticed that this doesn't happen when I use a time-interval of 2 minutes instead of 15.

Jedidja:
When you just add the minutes with the time-interval, it will happen that you come to a sum of more than 59, while there are only 60 minutes in an hour. The moment that the time is e.g. 00:68:00 will never happen.

Thats why I added an if-statement that subtracts 60 from the sum of minute(t) and time_interval when that sum is more than 59. Result: 00:68:00 becomes 00:08:00 and the interrupt will be fired at the correct time.

Hello, sorry for waking up the old thread, but I am having exactly the same problem - Arduino not waking up when "time_interval" is set to more than 10 minutes. Does one or two measurements and then it stops.

How should I modify the code:

const int time_interval =30;// Sets the wakeup intervall in minutes

void setup() {
    RTC.setAlarm(ALM1_MATCH_MINUTES , 0, minute(t)+time_interval, 0, 0);

    // clear the alarm flag
    RTC.alarm(ALARM_1);
 }
.......
void SleepNow(){

    //Set New Alarm
    RTC.setAlarm(ALM1_MATCH_MINUTES , 0, minute(t)+time_interval, 0, 0);
 
  // clear the alarm flag
  RTC.alarm(ALARM_1);
 }

Maybe something like this to both setup() and SleepNow():

const int time_interval =10
int sum_time;

setup () {
time_t t;
t=RTC.get();

sum_time = minute(t)+time_interval;
if (sum_time >= 59) {
sum_time = sum_time - 60
else {
sum_time = sum_time;
}

RTC.setAlarm(ALM1_MATCH_MINUTES, 0, sum_time, 0, 0);