1

I am trying to create a temperature-humidity monitor using Arduino and I want to power it using a battery. So, power efficiency is of interest. I am trying to put the Arduino to sleep for x-time (10sec for testing now). I am using a DS3231 alarm as an interrupt on pin 2 to wake-up. I am using the tutorial here along with its associated RTClibExtended library. Here is the code I am using:

#include "DHT.h"
#include <RTClibExtended.h>
#include <Wire.h>
#include <LowPower.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 DHTPIN 7 // what pin we're connected to
#define DHTTYPE DHT22 // DHT 22 (AM2302)
#define wakePin 2 //use interrupt 0 (pin 2) and run function wakeUp when pin 2 gets LOW
RTC_DS3231 rtc;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
int interval_sec=10; //An alarm every 10 sec
DHT dht(DHTPIN, DHTTYPE);
void setup () {
 Serial.begin(9600);
 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__)));
 /**INTERRUPT**/
 //Set pin D2 as INPUT for accepting the interrupt signal from DS3231
 pinMode(wakePin, INPUT);
 Wire.begin();
 //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 (in my case it was set by default to 1Hz)
 //The output of the DS3231 INT pin is connected to this pin
 //It must be connected to arduino D2 pin for wake-up
 rtc.writeSqwPinMode(DS3231_OFF);
 Serial.println("Initialisation complete.");
 delay(100); //Allow for serial print to complete.
}
void loop () {
 DateTime now = rtc.now();
 Serial.print(now.year(), DEC);
 Serial.print('/');
 Serial.print(now.month(), DEC);
 Serial.print('/');
 Serial.print(now.day(), DEC);
 Serial.print(" (");
 Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
 Serial.print(") ");
 Serial.print(now.hour(), DEC);
 Serial.print(':');
 Serial.print(now.minute(), DEC);
 Serial.print(':');
 Serial.print(now.second(), DEC);
 Serial.println();
 /**Temperature and Humidity**/
 // Reading temperature or humidity takes about 250 milliseconds!
 // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
 float h = dht.readHumidity();
 // Read temperature as Celsius
 float t = dht.readTemperature();
 // Read temperature as Fahrenheit
 //float f = dht.readTemperature(true);
 // Check if any reads failed and exit early (to try again).
 //if (isnan(h) || isnan(t) || isnan(f)) {
 if (isnan(h) || isnan(t)) {
 Serial.println("Failed to read from DHT sensor!");
 return;
 }
 Serial.print("Humidity: ");
 Serial.print(h);
 Serial.print(" %\t");
 Serial.print("Temperature: ");
 Serial.print(t);
 Serial.println(" *C\t");
 delay(3000); // wait for console
 /**INTURRUPT**/
 DateTime nextAlarm = now + TimeSpan(0, 0, 0, 10);
 Serial.print("Alarm at:");
 Serial.println(nextAlarm.hour());
 Serial.println(nextAlarm.minute());
 Serial.println(nextAlarm.second());
 rtc.setAlarm(ALM1_MATCH_HOURS, nextAlarm.minute(), nextAlarm.hour(), nextAlarm.second()); //set your wake-up time here
 rtc.alarmInterrupt(1, true);
 delay(3000); // wait for console
 attachInterrupt(0, wakeUp, LOW); //use interrupt 0 (pin 2) and run function wakeUp when pin 2 gets LOW 
 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);
 Serial.println();
 delay(3000);
}
void wakeUp() // here the interrupt is handled after wakeup
{
}

The Arduino is going to sleep as expected, but not waking up. Where am I going wrong?

Here is the output:

Initialisation complete. 2017年6月7日 (Wednesday) 12:42:49 Humidity: 36.90 % Temperature: 25.60 *C
Alarm at:12
42
59

asked Jun 7, 2017 at 7:29

2 Answers 2

0

After trying for a few hours, I was able to figure it out.

The change required is:

rtc.setAlarm(ALM1_MATCH_HOURS, nextAlarm.second(), nextAlarm.minute(), nextAlarm.hour (), 1); //set wake-up time here

So, in the original code, the order of arguments as well as the number of arguments passed to rtc.setAlarm() was wrong. Even though we are not interested in the "day" part (last argument) for setting the alarm, it requires a value. Using ALM1_MATCH_HOURS ensures that we match the alarm time to seconds, minutes, and hours ignoring the day part.

Improvement

Instead of hardcoding the alarm interval, the global variable called interval_sec can be set at the top and used to set the alarm time:

DateTime nextAlarm = now + TimeSpan(0, 0, 0, interval_sec);
answered Jun 7, 2017 at 12:34
0

In RTClibExtended.h it is important to always include all arguments: seconds, minutes, hours, daydate. If 0 value is used then this means "always" for that argument.

Example:

RTC.setAlarm(ALM1_MATCH_SECONDS, 30, 00, 0, 0); // activate every minute at 30 seconds
RTC.setAlarm(ALM2_MATCH_MINUTES, 0, 01, 0, 0); // activate every hour at 01 minutes
RTC.setAlarm(ALM1_MATCH_HOURS, 33, 18, 0); // activate every day at 18:33

(note: this example is copied from RTClibExtended.h examples, author does not adhere to his own rule to include seconds, even in ALM2. But it works). Any suggestions or corrections are welcomed!

sempaiscuba
1,0429 gold badges21 silver badges32 bronze badges
answered Dec 30, 2017 at 7:56

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.