0

I am using the DS3231 RTC connected to an Arduino UNO R3 for a project. I won’t go into detail, but I need to save power, therefore I am using the DS3231 Alarm Interrupt to wake the Arduino from sleep. The Alarm Interrupt works fine when the Arduino is sleeping and connected to the 5V and GND pins of the Arduino, however it turns out that the DS3231 won’t fire a square wave interrupt when on battery power. In order to turn it on, I need to set bit 7 of the Control Register (0Eh) to logic 1, and bit 6 to logic one. I can’t find any documentation on how to do this, except for a few forums talking about it. What is the specific code to do this, and where would I place the code?

DS3231 Data Sheet (Control Register on p.13)

#include <Wire.h>
#include <RTClibExtended.h>
#include <LowPower.h>
#define wakePin 2 //use interrupt 0 (pin 2) and run function wakeUp when pin 2 gets LOW
#define ledPin 13 //use arduino on-board led for indicating sleep or wakeup status
RTC_DS3231 RTC; //we are using the DS3231 RTC
byte AlarmFlag = 0;
byte ledStatus = 1;
//-------------------------------------------------
void wakeUp() // here the interrupt is handled after wakeup
{
}
//------------------------------------------------------------
void setup() {
 //digitalWrite(wakePin,HIGH);
 //Set pin D2 as INPUT for accepting the interrupt signal from DS3231
 pinMode(wakePin, INPUT);
 //switch-on the on-board led for 1 second for indicating that the sketch is ok and running
 pinMode(ledPin, OUTPUT);
 digitalWrite(ledPin, HIGH);
 delay(1000);
 //Initialize communication with the clock
 Wire.begin();
 RTC.begin();
 RTC.adjust(DateTime(__DATE__, __TIME__)); //set RTC date and time to COMPILE time
 //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);
 //Set alarm1 every day at 18:33
 RTC.setAlarm(ALM1_MATCH_HOURS, 16, 19, 0); //set your wake-up time here
 RTC.alarmInterrupt(1, true);
}
//------------------------------------------------------------
void loop() {
 //On first loop we enter the sleep mode
 if (AlarmFlag == 0) {
 attachInterrupt(0, wakeUp, LOW); //use interrupt 0 (pin 2) and run function wakeUp when pin 2 gets LOW 
 digitalWrite(ledPin, LOW); //switch-off the led for indicating that we enter the sleep mode
 ledStatus = 0; //set the led status accordingly
 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);
 AlarmFlag++;
 }
 //cycles the led to indicate that we are no more in sleep mode
 if (ledStatus == 0) {
 ledStatus = 1;
 digitalWrite(ledPin, HIGH);
 }
 else {
 ledStatus = 0;
 digitalWrite(ledPin, LOW);
 }
 delay(500);
}

Also, how would I set it to go to sleep after the alarm?

Thanks!

P.s sorry about that Thomas, I'm a bit new here.

asked Feb 12, 2020 at 16:12
2
  • 2
    What RTC library are you using? Do you know how to directly address an I2C device using the Wire library? Commented Feb 12, 2020 at 16:36
  • You have a pullup resistor on the line also, yes? Commented Mar 16, 2020 at 19:27

1 Answer 1

0

I took a look at the FabioCuomo-DS3231 library, as I guess that is what you are using, and I saw nothing related to setting those two bits. However, you can take inspiration from the code in the library to implement the functionality yourself.

I would try this:

void enableAlarmInLowPower(void) {
 // Read the control register.
 Wire.beginTransmission(DS3231_ADDRESS);
 Wire.write(DS3231_CONTROL);
 Wire.endTransmission();
 Wire.requestFrom((uint8_t)DS3231_ADDRESS, (uint8_t)1);
 uint8_t value = Wire.read();
 Wire.endTransmission();
 // Update it.
 value |= bit(6) | bit(7); // set bits 6 and 7
 // Write it back.
 Wire.beginTransmission(DS3231_ADDRESS);
 Wire.write(DS3231_CONTROL);
 Wire.write(value);
 Wire.endTransmission();
}

Warning: not tested.

answered Feb 15, 2020 at 17:48

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.