2

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 !

  • Try to sleep in IDLE mode, or to attach the interrupt in LOW mode. – Edgar Bonet Aug 30 '19 at 10:31
  • I tried both of your advice but none of them worked for me... – JamesONeil Sep 1 '19 at 19:54
0

If you use the DS3232RTC library(https://github.com/JChristensen/DS3232RTC) then you can setup an alarm which is like an alarm. I have put a good tutorial on how to do that below.

https://thekurks.net/blog/2018/2/5/wakeup-rtc-datalogger

There is also other threads on arduino.cc you should check out. They might have additional work-arounds.

https://forum.arduino.cc/index.php?topic=333654.0

https://forum.arduino.cc/index.php?topic=99588.0

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.