DS3231 alarm interupt not triggering on backup battery

Hello, i've been struggling to get a DS3231 RTC based module (HW-084) to trigger interputs when running on the backup battery. but no matter what i try to do, it seems to only be working when powered by the arduino.

And there are quite a lot of resources online but they kinda contradict each other... some say the DS3231 cannot generate interrupts on battery... some say they can. but i cannot get it to run no matter what configuration i give to it.

so i would like to ask those who managed to get it to run on battery... what is the exact configuration that is needed for the interrupts to trigger.

there are 2 modifications that are done to the boards.. i have removed the resistor from the battery charging circuit.. as i am using a CR2032, and i have scratched off the trace on tn R2 resistor array as indicated over here.

i am uploading the code as well as 2 serial outputs.
the DS3231 is powered by a pin on the arduino.(its a nano btw)

in both cases the RTC is powered down after 5 seconds.
in one case the alarm is set to 3 seconds.
this one is triggered properly because the RTC is not running on battery

in the 2nd one the alarm is to 10 seconds
this one is not triggered properly because the RTC is running on battery.

in both outputs i am reading configuration status at startup and after setup configuration and i am looking at A1F to decide if a interrupt occurred.

since i am not yet allowed to upload files as a new user, i have uploaded my code and the 2 outputs to pastebin
code: #include <DS3231.h>#include <Wire.h>#define STAY_AWAKE 6 #define DEBUG - Pastebin.com
10 second alarm: alarm is set to 10 secondsRTC is powerd down after 5 secondsalarm fails in t - Pastebin.com
3 second alarm : alarm is set to 3 secondsRTC is powered down after 5 secondsalarm triggers i - Pastebin.com

the RTC library i am using is this one

Can you post an annotated schematic as you have it wired, becure to show power supplies and grounds? Frizzys do not contain all the needed information.

The INT/SQW and 32KHz outputs are open-drain, so you will need a pullup resistor in order for them to work correctly. This can be pulled up to Vcc of the Arduino, not the DS3231.

the electronic schematic should not be relevant to the issue as everything is happening at software level.

but very well i will share what i have so far...
Im using an auto shutdown circuit that was made by chris workbench and i have adapted it to my needs.

The blue line is not yet connected and i need more testing to make sure that is working as intended, but from early tests it seems to work

i believe that is only needed if you are trying to generate an actual interrupt on the arduino, which is not what i am trying to do... i am trying to get the DS3231 to generate an interrupt on the INT line...

If i understood correctly i want it to pull the line to -3 volt which then pulls down the transistor which controls the power to the arduino.

Is the Arduino actually powering down for at least 5 seconds to allow time for the alarm to occur?

Be careful with that schematic, you have 9 volts from the battery going through the switch directly to pin 6 of the Nano, and even worse when pin 6 is pulled low you are shorting the +9 volts directly to ground.

I'm not really seeing what you are attempting to do. Looks like you want the alarm to cut power to the arduino at a specific time, regardless of what the arduino is doing. Seems it would make more sense to have the arduino cut its power via pin 6.

I agree with david_2018 that your circuit appears to be trying to power down the Arduino when the alarm time is reached. Normally you would want the Arduino to turn on at that time.

The INT/SQW pin goes low when the alarm triggers. And that certainly does work on coin cell power. Here is a circuit I have used. The INT pin goes low, which turns on the power. Then when you are ready to shut down, you just clear the alarm flag, which lets INT turn off again, which shuts down power.

i am trying to turn the arduino on when the trigger happens, thats the final goal,but for now all i want to see is that the interupt occurs properly.

Yes i have waited for around 20 seconds after the arduino shut itself down.

and noted i will attempt to change the current schematic with the one that Sherman provided.. i just need to go grab me a Mosfet.

However even if the electronics is not right.. that still does not explain why A1F does not get set when the time has passed when running on battery mode.

Have you read the DS3231 datasheet?
What does it say about it?
Because no one can know more than the manufacturer himself.

Regards

yes i have.. i have already broken down the 2 registers in my status checking the information about those can be found in the datasheet

but the only mention of battery powered mode and interrupts working together was in the revision review 4... aside from that i failed to find any indication that they would work... or perhaps my weak understanding of electronics prevented me from understanding stuff in the datasheet which were not explicitly mentioned .

that is why i came here and i asked.

I think that if it's not mentioned it's because it does not have that functionality since, on the contrary, it does mention how to activate the square wave output under battery backup operation.

Here is another version of the circuit. It uses an N-channel mosfet instead of the NPN transistor. Something like a 2N7000 or BS170 should work. It's actually better because it doesn't ever drain any current from the coin cell.

I've looked at the three sketches you posted links to, and don't understand how you are testing whether the INT pin has gone low. I don't see any pinMode(xx,INPUT_PULLUP) instructions anywhere, or any digitalRead() instructions. Can you explain how your software does the test?

Oh. I just noticed in your output that the /EOSC bit (bit 7) of the Control register appears to be set. That means the RTC oscillator stops running when it's powered by the coin cell. You need to clear that bit so the clock will continue to run on backup power. It should be cleared if you remove the coin cell for a minute, then replace it, and set the time again. Or, you can run this sketch:

// DS3231
// clear /EOSC bit so the oscillator runs on battery power
//    or toggle /EOSC to opposite state

#include <Wire.h>

byte control;

void setup() {

  Serial.begin(9600);
  delay(1000);
  Wire.begin();
  delay(100);

  readControl();                     // read control register
//  control &= 0x7F;                   // clear /EOSC bit, or
  control ^= 0x80;                   //toggle /EOSC bit

  Wire.beginTransmission(0x68);      // address DS3231
  Wire.write(0x0E);                  // select register
  Wire.write(control);               // write register bitmap, bit 7 is /EOSC bit
  Wire.endTransmission();
  readControl();
}

void loop() {
}

void readControl() {

  Wire.beginTransmission(0x68);      // address DS3231
  Wire.write(0x0E);                  // select register
  Wire.endTransmission();
  delay(10);
  Wire.requestFrom(0x68, 1);
  control = Wire.read();
  delay(10);
  Serial.println (control, HEX);
}

i've already ordered mosfets both p channel and n channel and they should arrive in a couple of days.
and to answer your question as to how the software detects the interrupt... it only checks theoretically, by looking at the A1F bit. the software does not use the interrupt generated.

and i've checked the thing with the EOSC bit.. i remember trying in both version with EOSC on 1 and on 0 with same result in both cases, it is controlled with the function on line 114.

but i will double check that line and see if that makes a difference.

Well, in both output files you posted, /EOSC is always reported as high. That means the oscillator will freeze when you remove power from the Vcc pin. So if you turn off Vcc power before the set alarm time, it will never get to the alarm time.

so i was able to redo the test and i actually found the issue and fixed it... it was not just EOSC.. when i changed line 114 the EOSC changed to 0 but the interrupt did not come, so that alone did not fix the issue...

But then i noticed that INTCN was also changed to 0 for some reason... so i had to go into the library and check to see exactly what is happening and there it was

void DS3231::enableOscillator(bool TF, bool battery, byte frequency) {
	// turns oscillator on or off. True is on, false is off.
	// if battery is true, turns on even for battery-only operation,
	// otherwise turns off if Vcc is off.
	// frequency must be 0, 1, 2, or 3.
	// 0 = 1 Hz
	// 1 = 1.024 kHz
	// 2 = 4.096 kHz
	// 3 = 8.192 kHz (Default if frequency byte is out of range)
	if (frequency > 3) frequency = 3;
	// read control byte in, but zero out current state of RS2 and RS1.
	byte temp_buffer = readControlByte(0) & 0b11100111;
	if (battery) {
		// turn on BBSQW flag
		temp_buffer = temp_buffer | 0b01000000;
	} else {
		// turn off BBSQW flag
		temp_buffer = temp_buffer & 0b10111111;
	}
	if (TF) {
		// set ~EOSC to 0 and INTCN to zero.
		temp_buffer = temp_buffer & 0b01111011;
	} else {
		// set ~EOSC to 1, leave INTCN as is.
		temp_buffer = temp_buffer | 0b10000000;
	}
	// shift frequency into bits 3 and 4 and set.
	frequency = frequency << 3;
	temp_buffer = temp_buffer | frequency;
	// And write the control bits
	writeControlByte(temp_buffer, 0);

when the oscilator is set to on it also sets the INTCN to 0 which was messing everything off...

changing that bit mask to 0x01111111 fixed the problem...
now interrupts work properly even on battery mode

and furthermore that schematic that i posted.. i dropped the voltage from 9V to 4.5V(3xAAA batteries) as to protect the pin ,connected the the SQW to base of the NPN and now the interrupt on the DS3231 is turning on the arduino and everything is working perfectly as intended...

so to recap my question and solution...
what is the initial configuration that needs to be done so the interutps would work on battery.
its this
EOSC:0 BBSQW:1 CONV:0 RS2:0 RS1:0 INTCN:1 A2IE:1 A1IE:1

1 Like

Congratulations. But I think you meant that with the lower voltage you now connect the INT/SQW pin to the base of the PNP transistor, and don't use the NPN at all. So when the alarm triggers, and INT/SQW goes low, that turns on the power.

The INT/SQW pin will stay low, and the power will stay on, until something clears the alarm flag. So to turn off power after setting the next alarm time, the last thing the Arduino would do is clear the alarm flag. But some libraries have a bad habit of automatically clearing the alarm flag as part of other functions, such as when setting the new alarm time. So if power turns off early, that would be something to check.

Yes. A typical wake up circuit has a latching characteristic, wherein the initial trigger is not necessary to maintain power.

Rather a means to turn off or reset that latch is provided in the hardware, and the microprocessor can reach out and shut itself off.

Our esteemed colleague @er_name_not_found heroically ran this to ground years ago (!) in an epic thread I amaze myself by finding in a few just now:

TBH I forget if there was ever an ultimate perfect result, but there sure are enough examples and ideas on there and it might be worth a glance.

a7

1 Like

But in the case of the DS3231, the initial trigger - the INT pin - does stay latched until the alarm flag is cleared. So the processor need do nothing to maintain power, and no additional hardware is needed. But when ready for shutdown, it sends the clear flag command over I2C, then goes into a delay of some kind which will never complete because the power will shut off.

Does the state of BBSQW actually make any difference as long as EOSC is low and INTCN is high?