Two diodes, cathodes to VBAT, anodes to battery resp. Vcc. Autoselection of whichever is highest. A 100nF cap between VBAT and GND should be enough to bridge any switching gaps.
I should add I haven't done extensive testing of the arrangement, it's this switchover that worries me most: risk of losing the time if the voltage drops for just the shortest moment.
A guy named Ed Mallon has something called the Cave Pearl Project which involves underwater data logging of some kind. One of his Youtube videos describes modifying the popular ZS-042 RTC module to take advantage of the reduced current draw when the DS3231 is powered from Vbat instead of Vcc.
His mod uses regular 1N4148 diodes, but Schottky diodes would be better.
An alternative to his mod would be to just power up the Vcc line only when you need to communicate with the DS3231 over I2C. That could be done by connecting an Arduino GPIO pin to the DS3231 Vcc pin. If you're using that module, you'll have to use Vcc to power the pullup resistors anyway, and the little bit of extra current drawn through Vcc during the I2C traffic won't make any difference so long as you power through Vbat at all other times.
If you use the alarm pin to wake up the Arduino, you'll probably need to cut the trace to the alarm pin's pullup resistor - if you've powered down Vcc, that resistor will in effect be a pull-down resistor, which is not what you want. But this all relates to the ZS-042 board. if you aren't using that, it may be simpler.
I've tested this Vbat stuff, and like wvmarle I can't find any problem with it. I've even used the DS3231 to control the power to the Arduino by connecting the INT/SQW pin to a P-channel mosfet gate, and that works fine too. So I think it makes good sense to take advantage of the low current draw at the Vbat pin if you can. But you'll have to test it to make sure timekeeping keeps going when the power switches back and forth between the battery and the Arduino.
Nobody has ever explained why there is such a big difference in current between Vbat and Vcc. The only guess I could make is that there are comparators that are constantly comparing the voltages at Vbat and Vcc, and maybe those comparators are powered by Vcc. But that's just a guess.
wvmarle:
Two diodes, cathodes to VBAT, anodes to battery resp. Vcc. Autoselection of whichever is highest. A 100nF cap between VBAT and GND should be enough to bridge any switching gaps.
I should add I haven't done extensive testing of the arrangement, it's this switchover that worries me most: risk of losing the time if the voltage drops for just the shortest moment.
Very good, I see what you're saying now. I'll keep an eye on whether the the RTC loses the time or not, thanks!
ShermanP:
A guy named Ed Mallon has something called the Cave Pearl Project which involves underwater data logging of some kind. One of his Youtube videos describes modifying the popular ZS-042 RTC module to take advantage of the reduced current draw when the DS3231 is powered from Vbat instead of Vcc.
His mod uses regular 1N4148 diodes, but Schottky diodes would be better.
An alternative to his mod would be to just power up the Vcc line only when you need to communicate with the DS3231 over I2C. That could be done by connecting an Arduino GPIO pin to the DS3231 Vcc pin. If you're using that module, you'll have to use Vcc to power the pullup resistors anyway, and the little bit of extra current drawn through Vcc during the I2C traffic won't make any difference so long as you power through Vbat at all other times.
If you use the alarm pin to wake up the Arduino, you'll probably need to cut the trace to the alarm pin's pullup resistor - if you've powered down Vcc, that resistor will in effect be a pull-down resistor, which is not what you want. But this all relates to the ZS-042 board. if you aren't using that, it may be simpler.
I've tested this Vbat stuff, and like wvmarle I can't find any problem with it. I've even used the DS3231 to control the power to the Arduino by connecting the INT/SQW pin to a P-channel mosfet gate, and that works fine too. So I think it makes good sense to take advantage of the low current draw at the Vbat pin if you can. But you'll have to test it to make sure timekeeping keeps going when the power switches back and forth between the battery and the Arduino.
Nobody has ever explained why there is such a big difference in current between Vbat and Vcc. The only guess I could make is that there are comparators that are constantly comparing the voltages at Vbat and Vcc, and maybe those comparators are powered by Vcc. But that's just a guess.
That's a pretty good video, all very clearly explained. I'd briefly read some of Cave Pearl stuff before, but hadn't seen the video. And yes, it is the ZS-042 board that I'm using. Thanks again!
It may be that the longest battery life would result from having a very low dropout 3.3V (or lower) linear regulator, with an enable pin, which powers everything except the DS3231. So even the Pro Mini would be shut down between logging events, along with the sensors and the SD card. The regulator would be controlled by the INT/SQW pin of the DS3231, and it would be powered from its coin cell except during I2C sessions. The INT/SQW pin is open drain, active low. So it is grounded when the alarm time is reached, and otherwise tristate. So it would work directly with an active-low regulator enable pin, but would need a PNP in between if the enable is active high.
Once the alarm has triggered, the INT/SQW pin stays low until the alarm flag is cleared. So when the Arduino wakes up, it would do its logging thing, then set the new alarm time, and only then, as its final official act, clear the alarm flag, which would disable the regulator and turn off the power.
Instead of doing Mallon's mod, you could power the ZS-042's Vcc pin from an Arduino I/O pin. That would bring the I2C pullups to the right voltage. Of course you would disable the ZS-042 "charging" circuit and the power-on indicator LED. You would also need to disconnect the pullup on INT/SQW - see pic.
ShermanP:
It may be that the longest battery life would result from having a very low dropout 3.3V (or lower) linear regulator, with an enable pin, which powers everything except the DS3231. So even the Pro Mini would be shut down between logging events, along with the sensors and the SD card. The regulator would be controlled by the INT/SQW pin of the DS3231, and it would be powered from its coin cell except during I2C sessions. The INT/SQW pin is open drain, active low. So it is grounded when the alarm time is reached, and otherwise tristate. So it would work directly with an active-low regulator enable pin, but would need a PNP in between if the enable is active high.
Once the alarm has triggered, the INT/SQW pin stays low until the alarm flag is cleared. So when the Arduino wakes up, it would do its logging thing, then set the new alarm time, and only then, as its final official act, clear the alarm flag, which would disable the regulator and turn off the power.
Instead of doing Mallon's mod, you could power the ZS-042's Vcc pin from an Arduino I/O pin. That would bring the I2C pullups to the right voltage. Of course you would disable the ZS-042 "charging" circuit and the power-on indicator LED. You would also need to disconnect the pullup on INT/SQW - see pic.
That all makes good sense Sherman. Although I'm curious if the Pro Mini would actually get to fully execute the code to enter deep sleep after the regulator has been disabled. I'm thinking that a large enough capacitor (10uF perhaps) across Vcc and GND will keep the Pro Mini powered long enough to be able to shut down?
I had been planning to power the Pro Mini permanently (I've measured deep sleep current at 28uA), and use a regulator with an enable pin for the RTC and SD card modules. But if the Pro Mini can enter deep sleep reliably with your method, then that saves 28uA!
The Pro Mini wouldn't go into deep sleep. It would be powered down. It would send the I2C command to the DS3231 to clear the alarm flag, then go into a delay() function which would not complete because power would be cut while the delay() is running. Then when the alarm triggers, the regulator would turn on, and the Pro Mini would power up again. It would read in the current time from the RTC, do its data logging function, calculate the time of the next alarm, send that to the RTC, then clear the alarm flag.
This doesn't really save much current on the Pro Mini because with the regulator and power LED removed it will go into Power Down sleep at about 1uA. But if you leave it running, then you either have to have another regulator for the Pro Mini, or you have to deal will level shifting issues between the Pro Mini and the SD card, and possibly other sensors, etc. It just seems simpler if everything runs off one regulator, and everything powers up and down together. Everything is at 3.3V, so nothing has to be level shifted. I say everything, but that excludes the D3231, which runs off its coin cell when the regulator is off. (But it too runs at 3.3V when the regulator is on and the Pro Mini powers it through its Vcc pin for I2C communications.)
All regulators with ENable pins I've found have active-high ENables. So the DS3231 INT pin would need to power a PNP transistor, which when activated would take the EN pin high. You would also need a base resistor, and a pull-down resistor on the EN pin (unless the regulator has a built-in pull-down, as some do).
For future reference, here's a sketch that puts the Pro Mini to sleep. If the regulator is removed along with the power LED, it should sleep at less than 1uA.
#include <avr/sleep.h>
#include <avr/wdt.h>
int i;
void setup(){
for (i = 0; i < 20; i++) { // all pins to one rail or the other
pinMode(i,OUTPUT);
digitalWrite(i,LOW);
}
ADCSRA = 0; // disable ADC for power saving
wdt_disable(); // disable WDT for power saving
set_sleep_mode (SLEEP_MODE_PWR_DOWN); // Deep sleep
sleep_enable();
sleep_bod_disable(); // disable brownout detector during sleep
sleep_cpu(); // now go to sleep
}
void loop(){
}
It sounds to me that dealing with some level shifting for the SD card could be the easier solution...
The Arduino would have to go through its setup() routine, and re-initialise all other sensors, before it's ready to start taking readings. Writing to SD card will have to be done every single time as all the memory gets lost, no gathering of data and then once every few readings write it to SD card (saves on power hungry writes).
What I personally like in a datalogger is a heartbeat signal: keep WDT running, wake up every 8 or 16 seconds, flash an LED at 2 mA for 30-60 ms (Arduino can even go to sleep during this flash using the WDT - this flash is long enough to be clearly visible to the eye), and back to sleep. Costs a few µA extra overall current but you know the thing is active.
ShermanP:
The Pro Mini wouldn't go into deep sleep. It would be powered down. It would send the I2C command to the DS3231 to clear the alarm flag, then go into a delay() function which would not complete because power would be cut while the delay() is running. Then when the alarm triggers, the regulator would turn on, and the Pro Mini would power up again. It would read in the current time from the RTC, do its data logging function, calculate the time of the next alarm, send that to the RTC, then clear the alarm flag.
Of course, yes! That clarifies things - I confused myself for a moment there. Thanks!
wvmarle:
What I personally like in a datalogger is a heartbeat signal: keep WDT running, wake up every 8 or 16 seconds, flash an LED at 2 mA for 30-60 ms (Arduino can even go to sleep during this flash using the WDT - this flash is long enough to be clearly visible to the eye), and back to sleep. Costs a few µA extra overall current but you know the thing is active.
That is something that had occurred to me... the device could be sitting there for months doing nothing because it ran into some kind of error after just 1 day - and I'd be none the wiser until I took out the SD card and saw that data was missing. So a flashing LED would be an easy visual check (à la Homer's everything's OK alarm).
wvmarle:
It sounds to me that dealing with some level shifting for the SD card could be the easier solution...
The Arduino would have to go through its setup() routine, and re-initialise all other sensors, before it's ready to start taking readings. Writing to SD card will have to be done every single time as all the memory gets lost, no gathering of data and then once every few readings write it to SD card (saves on power hungry writes).
What I personally like in a datalogger is a heartbeat signal: keep WDT running, wake up every 8 or 16 seconds, flash an LED at 2 mA for 30-60 ms (Arduino can even go to sleep during this flash using the WDT - this flash is long enough to be clearly visible to the eye), and back to sleep. Costs a few µA extra overall current but you know the thing is active.
If the Pro Mini is going to be always on, then you could either do the level shifting, or just use a second regulator for the Pro Mini - it wouldn't need an enable pin since it would be on all the time. Then you could use some version of Ed Mallon's two-diode mod for the DS3231 so it would run off 3.3V applied to the Vbat pin. Then, as you say, you could power up the SD card as infrequently as you can stand, and save the accumulated data to it.
But if you want to avoid having to reinitialize various sensors, then both the Pro Mini and the sensors have to stay powered up, in various states of deep sleep, if available at all. But current-wise the money is in the SD card. A good card may go into some kind of sleep mode on its own, but I don't have any that do that. So if the SD card idles at 20mA, the main thing will be to control that with an ENabled regulator to have any decent battery life. What you do with everything else may not matter so much in comparison unless the sensors don't sleep either, and draw lots of current.