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.
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.
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.
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 .
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
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.
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.