Skip to main content
Bumped by Community user
Bumped by Community user
Bumped by Community user
Tweeted twitter.com/StackArduino/status/1335418850737876992
Bumped by Community user
Bumped by Community user
Fixed syntax highlighting, added tag.
Source Link
VE7JRO
  • 2.5k
  • 19
  • 28
  • 31
#include <Wire.h>
#include <RtcDS3231.h>
#include <avr/sleep.h>

const byte interruptPin = 2;
volatile bool alarm = 0;
volatile byte counter = 0;

RtcDS3231<TwoWire> rtcObject(Wire);
 
void setup() {
 
  Serial.begin(9600);
  Serial.println("Initialisation");
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), handleInterrupt, FALLING);
 
  rtcObject.Begin();
 
  RtcDateTime timestamp = RtcDateTime(__DATE__, __TIME__);
  rtcObject.SetDateTime(timestamp);
 
  rtcObject.Enable32kHzPin(false);
  rtcObject.SetSquareWavePin(DS3231SquareWavePin_ModeAlarmOne);
 
  DS3231AlarmTwo alarm2(
    0,
    0,
    0,
    DS3231AlarmTwoControl_OncePerMinute);
 
  rtcObject.SetAlarmTwo(alarm2);
  rtcObject.LatchAlarmsTriggeredFlags();
 
}
 
void loop() {
  if (alarm == true){
    handleAlarm();
    if (counter == 1){
      mesure();
      counter = 0;
      delay(100);
      sleepNow();
    }
  }
}

void handleInterrupt() {
  alarm = true;
  counter ++;
  Serial.println(counter);
}

void handleAlarm() {
  alarm = false; 
  rtcObject.LatchAlarmsTriggeredFlags();
}

void mesure(){
  RtcDateTime timestamp = rtcObject.GetDateTime();
 
  Serial.print("time interrupt at: ");
  char time[10];
 
  sprintf(time, "%d:%d:%d",
          timestamp.Hour(),
          timestamp.Minute(),
          timestamp.Second()
         );
Serial.println(time);
}

void sleepNow() {
  Serial.println("Entering sleeping");
  delay(100);  
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);    // sleep mode is set here  
  sleep_enable();                         // enables the sleep bit in the mcucr register  
  attachInterrupt(digitalPinToInterrupt(interruptPin),wakeUpNow, FALLING);  // use interrupt 0 (pin 2) and run function  
  sleep_mode();                           // here the device is actually put to sleep!!  
  // THE PROGRAM CONTINUES FROM HERE AFTER WAKING UP  
 

  sleep_disable();         // first thing after waking from sleep: disable sleep...  
  detachInterrupt(digitalPinToInterrupt(interruptPin));      // disables interrupt 0 on pin 2 so the wakeUpNow code will not be executed during normal running time.  
} 

void wakeUpNow() {  
  // execute code here after wake-up before returning to the loop() function  
  // timers and code using timers (serial.print and more...) will not work here.  
  // we don't really need to execute any special functions here, since we  
  // just want the thing to wake up  
Serial.println("Woke up");
delay(100);
}
#include <Wire.h>
#include <RtcDS3231.h>
#include <avr/sleep.h>

const byte interruptPin = 2;
volatile bool alarm = 0;
volatile byte counter = 0;

RtcDS3231<TwoWire> rtcObject(Wire);
 
void setup() {
 
  Serial.begin(9600);
  Serial.println("Initialisation");
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), handleInterrupt, FALLING);
 
  rtcObject.Begin();
 
  RtcDateTime timestamp = RtcDateTime(__DATE__, __TIME__);
  rtcObject.SetDateTime(timestamp);
 
  rtcObject.Enable32kHzPin(false);
  rtcObject.SetSquareWavePin(DS3231SquareWavePin_ModeAlarmOne);
 
  DS3231AlarmTwo alarm2(
    0,
    0,
    0,
    DS3231AlarmTwoControl_OncePerMinute);
 
  rtcObject.SetAlarmTwo(alarm2);
  rtcObject.LatchAlarmsTriggeredFlags();
 
}
 
void loop() {
  if (alarm == true){
    handleAlarm();
    if (counter == 1){
      mesure();
      counter = 0;
      delay(100);
      sleepNow();
    }
  }
}

void handleInterrupt() {
  alarm = true;
  counter ++;
  Serial.println(counter);
}

void handleAlarm() {
  alarm = false; 
  rtcObject.LatchAlarmsTriggeredFlags();
}

void mesure(){
  RtcDateTime timestamp = rtcObject.GetDateTime();
 
  Serial.print("time interrupt at: ");
  char time[10];
 
  sprintf(time, "%d:%d:%d",
          timestamp.Hour(),
          timestamp.Minute(),
          timestamp.Second()
         );
Serial.println(time);
}

void sleepNow() {
  Serial.println("Entering sleeping");
  delay(100);  
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);    // sleep mode is set here  
  sleep_enable();                         // enables the sleep bit in the mcucr register  
  attachInterrupt(digitalPinToInterrupt(interruptPin),wakeUpNow, FALLING);  // use interrupt 0 (pin 2) and run function  
  sleep_mode();                           // here the device is actually put to sleep!!  
  // THE PROGRAM CONTINUES FROM HERE AFTER WAKING UP  
 

  sleep_disable();         // first thing after waking from sleep: disable sleep...  
  detachInterrupt(digitalPinToInterrupt(interruptPin));      // disables interrupt 0 on pin 2 so the wakeUpNow code will not be executed during normal running time.  
} 

void wakeUpNow() {  
  // execute code here after wake-up before returning to the loop() function  
  // timers and code using timers (serial.print and more...) will not work here.  
  // we don't really need to execute any special functions here, since we  
  // just want the thing to wake up  
Serial.println("Woke up");
delay(100);
}
#include <Wire.h>
#include <RtcDS3231.h>
#include <avr/sleep.h>

const byte interruptPin = 2;
volatile bool alarm = 0;
volatile byte counter = 0;

RtcDS3231<TwoWire> rtcObject(Wire);
 
void setup() {
 
  Serial.begin(9600);
  Serial.println("Initialisation");
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), handleInterrupt, FALLING);
 
  rtcObject.Begin();
 
  RtcDateTime timestamp = RtcDateTime(__DATE__, __TIME__);
  rtcObject.SetDateTime(timestamp);
 
  rtcObject.Enable32kHzPin(false);
  rtcObject.SetSquareWavePin(DS3231SquareWavePin_ModeAlarmOne);
 
  DS3231AlarmTwo alarm2(
    0,
    0,
    0,
    DS3231AlarmTwoControl_OncePerMinute);
 
  rtcObject.SetAlarmTwo(alarm2);
  rtcObject.LatchAlarmsTriggeredFlags();
 
}
 
void loop() {
  if (alarm == true){
    handleAlarm();
    if (counter == 1){
      mesure();
      counter = 0;
      delay(100);
      sleepNow();
    }
  }
}

void handleInterrupt() {
  alarm = true;
  counter ++;
  Serial.println(counter);
}

void handleAlarm() {
  alarm = false; 
  rtcObject.LatchAlarmsTriggeredFlags();
}

void mesure(){
  RtcDateTime timestamp = rtcObject.GetDateTime();
 
  Serial.print("time interrupt at: ");
  char time[10];
 
  sprintf(time, "%d:%d:%d",
          timestamp.Hour(),
          timestamp.Minute(),
          timestamp.Second()
         );
Serial.println(time);
}

void sleepNow() {
  Serial.println("Entering sleeping");
  delay(100);  
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);    // sleep mode is set here  
  sleep_enable();                         // enables the sleep bit in the mcucr register  
  attachInterrupt(digitalPinToInterrupt(interruptPin),wakeUpNow, FALLING);  // use interrupt 0 (pin 2) and run function  
  sleep_mode();                           // here the device is actually put to sleep!!  
  // THE PROGRAM CONTINUES FROM HERE AFTER WAKING UP  
 

  sleep_disable();         // first thing after waking from sleep: disable sleep...  
  detachInterrupt(digitalPinToInterrupt(interruptPin));      // disables interrupt 0 on pin 2 so the wakeUpNow code will not be executed during normal running time.  
} 

void wakeUpNow() {  
  // execute code here after wake-up before returning to the loop() function  
  // timers and code using timers (serial.print and more...) will not work here.  
  // we don't really need to execute any special functions here, since we  
  // just want the thing to wake up  
Serial.println("Woke up");
delay(100);
}
#include <Wire.h>
#include <RtcDS3231.h>
#include <avr/sleep.h>

const byte interruptPin = 2;
volatile bool alarm = 0;
volatile byte counter = 0;

RtcDS3231<TwoWire> rtcObject(Wire);
 
void setup() {
 
  Serial.begin(9600);
  Serial.println("Initialisation");
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), handleInterrupt, FALLING);
 
  rtcObject.Begin();
 
  RtcDateTime timestamp = RtcDateTime(__DATE__, __TIME__);
  rtcObject.SetDateTime(timestamp);
 
  rtcObject.Enable32kHzPin(false);
  rtcObject.SetSquareWavePin(DS3231SquareWavePin_ModeAlarmOne);
 
  DS3231AlarmTwo alarm2(
    0,
    0,
    0,
    DS3231AlarmTwoControl_OncePerMinute);
 
  rtcObject.SetAlarmTwo(alarm2);
  rtcObject.LatchAlarmsTriggeredFlags();
 
}
 
void loop() {
  if (alarm == true){
    handleAlarm();
    if (counter == 1){
      mesure();
      counter = 0;
      delay(100);
      sleepNow();
    }
  }
}

void handleInterrupt() {
  alarm = true;
  counter ++;
  Serial.println(counter);
}

void handleAlarm() {
  alarm = false; 
  rtcObject.LatchAlarmsTriggeredFlags();
}

void mesure(){
  RtcDateTime timestamp = rtcObject.GetDateTime();
 
  Serial.print("time interrupt at: ");
  char time[10];
 
  sprintf(time, "%d:%d:%d",
          timestamp.Hour(),
          timestamp.Minute(),
          timestamp.Second()
         );
Serial.println(time);
}

void sleepNow() {
  Serial.println("Entering sleeping");
  delay(100);  
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);    // sleep mode is set here  
  sleep_enable();                         // enables the sleep bit in the mcucr register  
  attachInterrupt(digitalPinToInterrupt(interruptPin),wakeUpNow, FALLING);  // use interrupt 0 (pin 2) and run function  
  sleep_mode();                           // here the device is actually put to sleep!!  
  // THE PROGRAM CONTINUES FROM HERE AFTER WAKING UP  
 

  sleep_disable();         // first thing after waking from sleep: disable sleep...  
  detachInterrupt(digitalPinToInterrupt(interruptPin));      // disables interrupt 0 on pin 2 so the wakeUpNow code will not be executed during normal running time.  
} 

void wakeUpNow() {  
  // execute code here after wake-up before returning to the loop() function  
  // timers and code using timers (serial.print and more...) will not work here.  
  // we don't really need to execute any special functions here, since we  
  // just want the thing to wake up  
Serial.println("Woke up");
delay(100);
}
Source Link

How to wake up Arduino with an rtc?

I am doing a data logger with an Arduino Mega2560 and I want to use a code to make it sleep when no measure is needed and wake it up with an RTC when time comes. The reason I want this is because I intend to run the code on a Pro Mini later so I need to save as much energy as I can. I am able to put the arduino to sleep using the alarm interrupt when a minute is passed but it doesn't wake up from sleep afterwards.

Here is the code I am using :

#include <Wire.h>
#include <RtcDS3231.h>
#include <avr/sleep.h>

const byte interruptPin = 2;
volatile bool alarm = 0;
volatile byte counter = 0;

RtcDS3231<TwoWire> rtcObject(Wire);
 
void setup() {
 
  Serial.begin(9600);
  Serial.println("Initialisation");
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), handleInterrupt, FALLING);
 
  rtcObject.Begin();
 
  RtcDateTime timestamp = RtcDateTime(__DATE__, __TIME__);
  rtcObject.SetDateTime(timestamp);
 
  rtcObject.Enable32kHzPin(false);
  rtcObject.SetSquareWavePin(DS3231SquareWavePin_ModeAlarmOne);
 
  DS3231AlarmTwo alarm2(
    0,
    0,
    0,
    DS3231AlarmTwoControl_OncePerMinute);
 
  rtcObject.SetAlarmTwo(alarm2);
  rtcObject.LatchAlarmsTriggeredFlags();
 
}
 
void loop() {
  if (alarm == true){
    handleAlarm();
    if (counter == 1){
      mesure();
      counter = 0;
      delay(100);
      sleepNow();
    }
  }
}

void handleInterrupt() {
  alarm = true;
  counter ++;
  Serial.println(counter);
}

void handleAlarm() {
  alarm = false; 
  rtcObject.LatchAlarmsTriggeredFlags();
}

void mesure(){
  RtcDateTime timestamp = rtcObject.GetDateTime();
 
  Serial.print("time interrupt at: ");
  char time[10];
 
  sprintf(time, "%d:%d:%d",
          timestamp.Hour(),
          timestamp.Minute(),
          timestamp.Second()
         );
Serial.println(time);
}

void sleepNow() {
  Serial.println("Entering sleeping");
  delay(100);  
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);    // sleep mode is set here  
  sleep_enable();                         // enables the sleep bit in the mcucr register  
  attachInterrupt(digitalPinToInterrupt(interruptPin),wakeUpNow, FALLING);  // use interrupt 0 (pin 2) and run function  
  sleep_mode();                           // here the device is actually put to sleep!!  
  // THE PROGRAM CONTINUES FROM HERE AFTER WAKING UP  
 

  sleep_disable();         // first thing after waking from sleep: disable sleep...  
  detachInterrupt(digitalPinToInterrupt(interruptPin));      // disables interrupt 0 on pin 2 so the wakeUpNow code will not be executed during normal running time.  
} 

void wakeUpNow() {  
  // execute code here after wake-up before returning to the loop() function  
  // timers and code using timers (serial.print and more...) will not work here.  
  // we don't really need to execute any special functions here, since we  
  // just want the thing to wake up  
Serial.println("Woke up");
delay(100);
}

I want to understand how to wake it up properly so I can later make it sleep first in the loop and wake it up only if an interrupt is detected from the rtc.

Thank you for your help !