Perhaps this code helps. I used the DS3231 lib from the Seeeduino Stalker that supports IRQ:
http://www.seeedstudio.com/wiki/images/c/c9/SeeeduinoStalkerV2.1_Software%28Arduino_1.0%29.zip
and the rocketscream LowPower lib:
https://github.com/rocketscream/Low-Power
// pins hard coded
// D2 RTC IRQ
// D13 debug LED
// libraries
// RTC
#include // I2C (for RTC)
#include // RTC itself
DS3231 RTC; // create RTC object for DS3231
static DateTime interruptTime; // next interrupt time
// power saving
#include
// we need some variable as char to pass it to payload easily
char timestampChar[20]; // should handle yyyy/mm/dd hh:mm:ss and null terminator
void setup () {
// debug
Serial.begin(9600);
pinMode(13, OUTPUT); // debug led
// rtc, irq
Wire.begin();
RTC.begin();
pinMode(2, INPUT_PULLUP); // initialize INT0 (D2 on the most Arduino's) to accept external interrupts
// set periodic interrupt intervals
//RTC.enableInterrupts(EveryMinute); // options: EverySecond, EveryMinute, EveryHour
// or specify only the first interrupt time in case EverySecond, EveryMinute, EveryHour
// does not fit your needs, then specify it also in void INT0_ISR()
DateTime start = RTC.now();
// add x seconds (interval time) to start time
interruptTime = DateTime (start.get() + 60);
}
void loop () {
// output timestamp
getTimestamp();
Serial.println(timestampChar);
// do other things here, e.g. reading sensors
// debug
// blink LED to indicate sensor reading is done
// delet this after prototyping to save power
digitalWrite(13, HIGH);
Serial.flush(); // flush serial before sleeping
LowPower.powerDown(SLEEP_60MS, ADC_OFF, BOD_OFF); // delay 60 ms
digitalWrite(13, LOW);
// prepare next interrupt time
RTC.clearINTStatus(); // this function call is a must to bring INT pin high after an interrupt
RTC.enableInterrupts(interruptTime.hour(),interruptTime.minute(),interruptTime.second()); // set the interrupt (h,m,s)
attachInterrupt(0, wakeUp, LOW); // enable INT0, required to handle level triggered interrupts
// go sleeping
// debug
Serial.print("\nSleeping ... ");
Serial.flush(); // flush serial before sleeping
// power down with ADC and BOD disabled
LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);
// waiting for the next interrupt
// tzzzzz ... tzzzzz ...
// wakeup
detachInterrupt(0);
// calculate next interrupt time
interruptTime = DateTime(interruptTime.get() + 5);
delay(10); // this delay is required to allow CPU to stabilize
Serial.println("Awake from sleep.\n");
}
// timestamp
void getTimestamp() {
DateTime currentTime = RTC.now(); // get the current date-time
snprintf(timestampChar, sizeof(timestampChar), "%d/%02d/%02d %02d:%02d:%02d", currentTime.year(), currentTime.month(), currentTime.date(), currentTime.hour(), currentTime.minute(), currentTime.second()); // write to char array
}
// interrupt service routine for external interrupt on INT0 triggered from RTC
// keep this as short as possible, possibly avoid using function calls
void wakeUp() {
// handler for the pin interrupt
}
A RTC is the best solution of cause, in case you do not have it the TimeAlarms lib can do a similar but not so precise job (without power saving): https://www.pjrc.com/teensy/td_libs_TimeAlarms.html Unfortunately the TimeAlarms lib can not deal with IRQs that would be a nice feature.
In case your logging intervals must not be super accurate and can differ +/- some seconds the Narcoleptic lib can help. Nice thing vs rocketscream LowPower lib https://code.google.com/p/narcoleptic/ is that you can specify free time slots and you have not to divide up in 8s pieces as you have to do it with the rocketscream lib.