DS3231 RTC No Interrupts on Battery ZS-042 Module

Hello everyone!

Time and again, this forum has helped me wherever I got stuck with my Arduino projects. So a big thanks to all of the people who contribute and help thousands like me.

I want to wake up a sleeping uC (Uno) using interrupts from a DS3231 on ZS-042 module but so far I have been unsuccessful to get it to work. On switching off power to the module i.e. on battery power interrupts are not generated/ uC doesn't wake up. I am aware of the pull-up to VCC problem on this module and have removed resistor pack 1 from the module according to this thread and am using an internal pull-up on the interrupt pin 0 on the Arduino.

I am using the library written by JChristensen available here GitHub - JChristensen/DS3232RTC: Arduino Library for Maxim Integrated DS3232 and DS3231 Real-Time Clocks

Note: This is for DS3231 as well; not just 3232.

The uC sleeps in power down mode as system is powered by AAA batteries;
Hence the RTC cannot be left 'on'. //Interrupts are successfully fired when the module is hooked to 5v

A big thanks to anyone who can contribute anything!

The code I am using to test interrupts is given below: Also here: code used to test

#include <DS3232RTC.h>        //http://github.com/JChristensen/DS3232RTC
#include <Streaming.h>        //http://arduiniana.org/libraries/streaming/
#include <Time.h>             //http://playground.arduino.cc/Code/Time
#include <Wire.h>             //http://arduino.cc/en/Reference/Wire

#define SQW_PIN 2
#define RTC_POW 5

void setup(void)
{
    Serial.begin(9600);
    pinMode(RTC_POW, OUTPUT);
    digitalWrite(RTC_POW, HIGH);
    printDateTime( RTC.get() );
    Serial << " --> Current RTC time." << endl;

    //Disable the default square wave of the SQW pin.
    RTC.squareWave(SQWAVE_NONE);
    //Attach an interrupt on the falling of the SQW pin.
    //digitalWrite(SQW_PIN, HIGH);    //redundant with the following line
    pinMode(SQW_PIN, INPUT_PULLUP);
    attachInterrupt(INT0, alarmIsr, FALLING);

    
    //Set an alarm at every 20th second of every minute.
    RTC.setAlarm(ALM1_MATCH_HOURS, 20, 14, 0, 1);    //daydate parameter should be between 1 and 7
    RTC.alarm(ALARM_1);                   //ensure RTC interrupt flag is cleared
    RTC.alarmInterrupt(ALARM_1, true);

    //Set an alarm every minute.
    RTC.setAlarm(ALM2_EVERY_MINUTE, 0, 0, 0, 1);    //daydate parameter should be between 1 and 7
    RTC.alarm(ALARM_2);                   //ensure RTC interrupt flag is cleared
    RTC.alarmInterrupt(ALARM_2, true);
    digitalWrite(RTC_POW, LOW);

}

volatile boolean alarmIsrWasCalled = false;

void alarmIsr()
{
//  detachInterrupt(INT0);
    alarmIsrWasCalled = true;
}

void loop(void)
{
    if (alarmIsrWasCalled){
      digitalWrite(RTC_POW, HIGH);
        if (RTC.alarm(ALARM_1)) {
            printDateTime( RTC.get() );
            Serial << " --> Alarm 1!" << endl;
        }
        if (RTC.alarm(ALARM_2)) {
            printDateTime( RTC.get() );
            Serial << " --> Alarm 2!" << endl;
        }
        alarmIsrWasCalled = false;
        digitalWrite(RTC_POW, LOW);
    }
}

void printDateTime(time_t t)
{
    Serial << ((day(t)<10) ? "0" : "") << _DEC(day(t)) << ' ';
    Serial << monthShortStr(month(t)) << " " << _DEC(year(t)) << ' ';
    Serial << ((hour(t)<10) ? "0" : "") << _DEC(hour(t)) << ':';
    Serial << ((minute(t)<10) ? "0" : "") << _DEC(minute(t)) << ':';
    Serial << ((second(t)<10) ? "0" : "") << _DEC(second(t));
}

The DS3231 has open drain outputs, which means you have to have a pullup resistor from the SQW/INT output to the Arduino Vcc for an interrupt to work.

I see you have followed the modification procedures described in this blog post, but have you tried adding a pullup resistor as described above? INPUT_PULLUP might not be enough.

Hello jremington and thanks for the reply!

Yes, I performed all the modifications as described in the blogpost you linked in your reply with the exception of removing the power indicator led as I am switching off power to the module anyway. :slight_smile:

I followed your suggestion and used a 1k resistor to pull up D2 (INT0) on the Uno upto Vcc on the board.

However, the result is still the same:
Interrupts when module powered on.
No interrupts when powered off. :confused:

Any other suggestions I could try?

Thanks!

Those mods worked fine for me, using what appears to be the identical RTC module, so are you absolutely sure that the SQW/INT output is changing state properly? Check by simply programming the RTC to output a 1 Hz square wave on SQW, rather than fiddling with alarm code.

Check the continuity from the module connector (better, from the Arduino) to the actual IC SQW pin using a multimeter, to make certain that the mods didn't introduce a short circuit or break a PC board trace.

If you have another, unmodified version of the DS3231 board, you can test the code (and alarm output) with the board powered normally.

Hello again,

I programmed the module for the 1Hz wave and it works just fine with Vcc applied to the board.

Thankfully, the connection from the IC SQW pin on the DS3231 was intact when tested with a multimeter.

I don't have an unmodified version. All of them have resistor pack 1 removed.

Although, it is worthy to state that, with your previous suggestion of an external pull-up to Vcc, one out of 5 of my ZS-042 modules generated interrupts on battery power, as desired! Also, all of them were running on the same code.

But I am unable to spot any difference between that 1 good module and the rest, as I feel that the difference must be in hardware.

@Edit:
On further testing with the non-functioning modules, I saw that the flags for the interrupts get set (A1F and A2F correspondingly) in the status register but the INT pin does not go low hence the arduino does not see an interrupt.

But I am unable to spot any difference between that 1 good module and the rest, as I feel that the difference must be in hardware.

That is good news (that you got one to work) and bad news.

People have always wondered whether the chips on these cheap modules might somehow be fakes or rejects, as the module price on eBay is lower that the cost of the chip itself, purchased from the legitimate manufacturer.

I programmed the module for the 1Hz wave and it works just fine with Vcc applied to the board.

How about on battery power? Does this work on the alarm-output-not-functioning modules?

jremington:
How about on battery power? Does this work on the alarm-output-not-functioning modules?

It's like, on battery power, the SQW/INT pin doesn't work at all.

jremington:
People have always wondered whether the chips on these cheap modules might somehow be fakes or rejects, as the module price on eBay is lower that the cost of the chip itself, purchased from the legitimate manufacturer.

And i have 5 of these. xD My hard luck. But this is what is readily available in my area. As I stated earlier, the module still does set the corresponding alarm flags in the status register. It's just that the SQW pin is not pulled low as desired.

Thank you so much for taking out the time to help!
Cheers!

sirDragonHeart:
On further testing with the non-functioning modules, I saw that the flags for the interrupts get set (A1F and A2F correspondingly) in the status register but the INT pin does not go low hence the arduino does not see an interrupt.

Was the INTCN, A1IE & A2IE bits also set in the control register (0x0E) to enable the Alarm match to also trigger the interrupt?

Also I think BBSQW needs setting to 1 to enable square wave output when battery powered.

@Riva OMG Thank you so much for your reply!

Riva:
Also I think BBSQW needs setting to 1 to enable square wave output when battery powered.

This was IT !! Gosh, can't believe it! I was stuck at this problem for so long! Excellent work at spotting this; it was quite unclear to me from the datasheet!

To others who see this thread, the JChristensen library did not have a function to set the BBSQW pin so I wrote this one:

/*
Sets/resets the BBSQW pin in the control register
*/
byte DS3232RTC::setBBSQW(bool state)
{
    //Get original contents
    byte t = readRTC(RTC_CONTROL);
    if (state)
        //Set bit 6 i.e. the BBSQW
        t |= (1 << BBSQW);
    else
        t &= ~(1 << BBSQW);

    return (writeRTC(RTC_CONTROL, t));
}

Riva:
Was the INTCN, A1IE & A2IE bits also set in the control register (0x0E) to enable the Alarm match to also trigger the interrupt?

Yes these bits were also set.

Finally, following @jremington's suggestion of the pull-up resistor to Vcc on SQW, and setting the BBSQW bit on the RTC, interrupts are generated as desired even after switching off Vcc!

Once again thank you so much, all of you! You guys are love! <3

P.S. Super-psyched! :smiley: :smiley:

Excellent! Page bookmarked for future reference.

Hello,

I really want to say a huge THANK YOU to all of you.

I've been looking for this post for more than a year !!!

All the guys on other tutorials just remove the R1 resistor bloc and they don't ever talk about any problem...

THANK YOU,THANK YOU!

Finally I can sleep peacefully ! It was SOOOO frustrating !

Regards,