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

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!

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);

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.