arduino real time clock ds3231 with lcd display quotation
Time is a critical element of our existence that will never get old, and with technology, we can find better and more intuitive ways to measure it. In one of our past tutorials, we looked at how the DS3231 real time clock module can be used with Arduino to display time on a 16×2 LCD display. Today, we will build an upgrade to that project using an Arduino Due, the DS3231 RTC module and a 3.2″colour TFT display in place of the 16×2 LCD display used in the previous project.
At the heart of today’s project is the DS3231 real time clock module which we will use to obtain the current time, date and temperature of the environment. The DS3231 real time clock module is one of the most popular real-time clock chips among makers and DIY enthusiasts. It is a low-cost, highly accurate, I2Cbased real-time clock (RTC) with a temperature-compensated crystal oscillator (TCXO) and crystal integrated into it. The module integrates a coin cell battery input which helps it retain date and time even when the main power to the device is interrupted. It maintains seconds, minutes, hours, day, date, month, and year information, automatically adjusting the date for months with fewer than 31 days, including corrections for leap year. It can be set to operate either in the 24-hour or 12-hour format with an active-low AM/PM indicator. It has been used in several projects on this website mostly, due to its accuracy, and its low power requirements which help it keep time accurately, for a longer period of time compared to other real-time clocks (RTC) modules.
Another key part/component that we will use in today’s tutorial is the Arduino Due. One of the important things, when designing electronic systems that have displays is ensuring, that there is no flicker or lag when updating information on the screen and one of the best ways to ensure that, is to use a fast enough micro-controller. Putting this into consideration, for this project, we will use the very fast Arduino Due board. The Arduino Due has one of the fastest CPU in the Arduino family. The Due runs on an 84MHz CPU compared to the 16MHz CPU speed of the Arduino UNO, and as such, it is able to update the screen without any visible flickering.
The most important update to the previous project, however, is the 3.2″color LCD display being used. The display gives us the ability to create a better, bigger and colourful user interface for our clock at a cheap price as it costs about 7$ on banggood.
The goal for this project is to build a real-time clock with a user-friendly interface capable of displaying (without lag or flickering) the current time, date, temperature including the minimum and maximum temperature recorded in a particular environment over time.
The 3.2″ TFT, like most other TFT displays, comes as a shield which can be easily mounted on the Arduino Due. This, however, makes it difficult to access the IOs of the Arduino after the display has been mounted, as it tends to cover the front face of the board. To solve this, so that the DS3231 module can be connected, male headers are used (after bending them as shown in the picture below) to connect the RTC module to the Arduino.
To easily write the code for this project, we will use two libraries: the Bodmer TFT HX8537 library for the TFT display and the Sodaq DS3231 library to easily interface with the DS3231 module. Both libraries can be downloaded via the links attached to their names above. The Bodmer library is a version of the UTFT library specially modified for the Arduino Due as this particular display is incompatible with the UTFT library.
With the libraries installed, relaunch the IDE to begin writing the code. The code for this project is quite simple but bulky, due to the functions used to create the user interface.
Next is the void setup function. We initiate communication with the RTC module and Initialize the display, setting our preferred orientation for the display and print the UI to the display.
With this done, we move to the void loop function. Under this function, we write the code to update all the parameters (after specific intervals) on the display including the min temperature, the max temperature, time and the date.
That’s it for this tutorial guys, there are several useful projects that can be built using this tutorial as a foundation. You could decide to add a buzzer to the project to create an alarm clock or make a to-do list based project, all out of this.
In this Arduino Tutorial we will learn how to use the DS3231 Real Time Clock Module. You can watch the following video or read the written tutorial below.
The first question that comes here is why we actually need a separate RTC for our Arduino Project when the Arduino itself has built-in timekeeper. Well the point is that the RTC module runs on a battery and can keep track of the time even if we reprogram the microcontroller or disconnect the main power.
The DS3231 is a low-cost, highly accurate Real Time Clock which can maintain hours, minutes and seconds, as well as, day, month and year information. Also, it has automatic compensation for leap-years and for months with fewer than 31 days.
Once we connect the module we need to program the Arduino Board to work with the Real Time Clock. However, when it comes to programing a communication between Arduino and an I2C module the code isn’t that small and easy. Luckily, there are already several libraries for the DS3231 RTC which can be found on the internet.
So once we download and install the library we can use its first demo example to initially activate the clock of the RTC module. In the setup section of the demo example code we can notice that there are three line that we need to uncomment in order to initially set the day of the week, the time and the data.
The first line is for setting the day of the week, the second line is for setting the time in hours, minutes and seconds, and the third line is for setting the date in days, months and years.
Now even if we disconnect the Arduino power and then reconnect it and run the Serial Monitor again we can notice that the time keeps going without being reset.
So now we have our Real Time Clock up and running and we can use in any Arduino Project. As a second example I connected an LCD to the Arduino and printed the time and the date on it.
You may return most new, unopened items within 30 days of delivery for a full refund. We"ll also pay the return shipping costs if the return is a result of our error (you received an incorrect or defective item, etc.).
You should expect to receive your refund within four weeks of giving your package to the return shipper, however, in many cases you will receive a refund more quickly. This time period includes the transit time for us to receive your return from the shipper (5 to 10 business days), the time it takes us to process your return once we receive it (3 to 5 business days), and the time it takes your bank to process our refund request (5 to 10 business days).
About: Maker 101; Beginner and intermediate level Maker projects! You can find projects such as "How to" and "DIY" on programmable boards such as Arduino, ESP8266, ESP32 and Raspberry Pi on this channel. The projects…
DS3231 Real Time Clock Module 3.3V 5V Precise, with battery is a Mini Real-Time Clock module designs for Raspberry Pi, but it also can be used to Arduino. DS3231 RTC IC Self-adjust 3.3V and 5V.Provide battery backup for continuous timing, Low-power consumption. Complete clock functions include seconds, minutes, hours, day, date, month and year timing, and provide valid to 2100.
This is the best battery-backed real-time clock (RTC) you can get that allows your Raspberry Pi project to record the time when power is lost. Perfect for data logging, clock building, NTP servers, time stamping, timers, and alarms, etc. Equipped with a genuine DS3231 RTC, it works great with the Raspberry Pi and has native kernel support.
A ±2ppm DS3231N for less than $1? Really? And most of these boards use the industrial SN variant, which is rated for the full -40°C to +85°C temp range. NOTE: There is now an M variant of this chip on the market which is more resistant to vibration, but the -M is only temperature compensated to ±5ppm.
So perhaps they are counterfeit chips, which are simply pin & code compatible? I also found rumors about “ghost” shifts, where legitimate manufacturer plants/equipment are used off the clock to produce extra parts. Or legitimate production runs which test out defective(if 10% of a run’s chips are bad, they often scrap the entire run) but someone intercepts the chips before they can be destroyed, and they resurface on the grey market. But even with all these possibilities in mind, I still have to make the Pearls as inexpensive as possible if they are going to be deployed in large numbers, and having an I2C eeprom on the board for the same money, made the temptation too great to resist.
When the RTC’s arrived they had an LIR2032 rechargeable battery underneath the board, and a LED power indicator above. I had a feeling that neither of these were going to be friendly to my power budget so I went hunting for the schematics to see what I could do to improve the situation. I quickly found an Instructables post which described how to remove the battery charging circuit from a very similar DS1307 module, and then I found the datasheets and schematic for this DS3231 module over at at a site in Europe. Most of the parts were pretty straight forward:
The power indicator (1) was pretty pointless, so that was the first thing to go. I already had pullups on the I2C lines, so they were not needed here, but they were in a combined 4 resistor block, which meant that to get rid of the pullups on SCL and SDA, I also had to remove the pullup on the alarm line. This had me a little concerned, as that alarm line is vital to the whole design. Without that resistor on SQW, I am relying on the weak internal processor pullups keep the alarm line high with:
Then I looked at the 200Ω resistor & 1N4148 diode (3) that are supposed to provide a trickle charge to the rechargeable battery, though the folks at BU suggest this is a bad idea. The LiR2032 that these modules ship with is 3.6v, and while capacity varies depending on where you buy them, most provide 35mah to 45mah capacity. Looking at the power draw from the DS3231, a fully charged battery would keep the unit backed up for at least 200 days (in a perfect world, with no self discharge, etc) But, it requires a 4.2v charging voltage for maximum charge, so vcc would have to be above 4.3-ish volts. I don’t anticipate my 3x AA power supply staying in that territory for the duration of a long deployment (especially if I end up powering the units from cheap AA’s) so there really was no compelling reason to keep the charging system in place. Once I de-soldered the resistor, I popped in a CR2032 (3v 240mAh) as a replacement which should backup the clock for several years of operation.
Then we come to the AT24C32N (2.7 to 5.5v) memory chipthat is also on this breakout board. Another of those 4 resistor bricks is lifting pins 1,2 and 3 to Vcc, so according to the eeprom datasheet this unit is being set to 0×57 on the I2C bus. There are pads there to ground out these lines if you need to reassign the address to something else.Although I have already determined that eeprom is not the power savior I hoped it might be (all that eeprom reading & writing uses about 1/3 the power of simply writing the data to the SD card in the first place)it’s presence lets me be really lazy on the coding and just pop any numbers or characters that I want into a PSTRING’d buffer which then gets sent to a standard eeprom page writing routine. This flexibility allows me to swap sensors with dramatically different output, while retaining essentially the same code to handle the eeprom loading and the transfer of data back out to the SD card. If you want more information about that you can head over my earlier post on buffering sensor data to an I2C eeprom for the gory details.
The May 2014 build of the data logging platform, which used a hacked Tinyduino light sensor board to regulate & pull up the I2C bus. SQW is soldered to interrupt pin 2. Later in 2014 I switched to Pro Mini style boards with 3.3 v regulators, so I left that four resistor block in place ( 2 in the schematic above) to provide I2C and SQW pullup.
To top it all off, the cascade ports on the far side of the module let me “just barely” fit the rtc, the I2C hub (with corners sanded off), and main TinyDuino stack onto the platform in the middle of my housing. I am lifting the voltage regulated I2C bus traces from the TinyDuino light sensor board, so I am also hunting around for an off the shelf vreg & level shifter combination to replace that hack (because that bit of soldering is a pita). But overall, I am very happy with this build, as all the central data logging functions have come together into a nice securely mounted package, that should withstand significant knocking about during the deployment dives. Of course there is plenty of field work testing still to be done, so time will tell (sorry, couldn’t resist…) if these cheap RTC’s will cause more trouble than they are worth.
It just occurred to me that sooner or later Tinycircuits will be releasing an RTC board, and that will give me a chance to directly compare these cheap boards to a “trusted” clock signal provided that their chip does not want the same bus address. Or if their clock wants the same I2C bus address as this eBay RTC, I could use a DS3234 on the SPI bus. I will post an update when I can run that test to spot clock drift, alarm errors, etc. Several sites have mentioned that real DS3231’s drift about 2 seconds per month, while the cheaper ds1307’s drift 7-10 seconds per day. If you have the right equipment, you can make the chip even more accurate by adjusting the aging offset register.
I just realized something else odd about my setup here. The I2c bus is held at 3.3 volts by the regulator on the tiny light sensor shield, but I am pulling up the SQW via the tinyduino cpu, which is following the voltage on the battery pack because the tiny CPU is unregulated. So the pull-up voltage on the alarm line is out of sync with the voltage seen by the rest of the DS3231 chip….hmmmm.
Addendum: 2014-07-01I created a veryinexpensive 3-component data logger with this RTC, a Pro Mini mcu board, and a cheap sd card adapter. And you can see a post about the latest version of that logger concept here which has added a power shutdown feature. In those Pro Mini based loggers I do not remove the I2C pullup resistor bank as shown earlier in this post(2 in the photo above), as the removal is only needed if you already have pullups in place, as I did when using the hacked Tinyduino light sensor board to drive the RTC. I have built many loggers now, and some of them have come close to 400,000 alarms & eeprom write cycles, so these cheap RTCs are proving to be pretty durable.
I have noticed that when I power this module from Vcc at 3.3v, it draws around 89 µA. But according to the datasheet,the RTC should only draw ~2 µA on average when powered from Vbat.(1µA baseline plus about 500µA for 100ms every 64 seconds when the crystal is doing temperature compensation)Nick Gammon found an elegant way to power a DS1307 by connecting Vcc to one of the Arduino pins , driven high in output mode when the system is active. (look about half way down the page) When the Arduino pin is low, the clock reverts to battery power, and goes into the low current timekeeping mode. But according to the datasheet, Bit 6 (Battery-Backed Square-Wave Enable) of control register 0Eh, can be set to 1 to force the wake-up alarms to occur when running the RTC from the back up battery alone. [note: This bit is disabled (logic 0) when power is first applied] So you can still use the RTC to wake the Arduino, even if you have de-powered it by bringing the pin low. I have tested this and it seems to work fine on my RTC modules, reducing the sleep current by about 70 µA.(or ~ 600 mAh per year = almost 1/4 of a AA) Tests are underway now to see if this is stable as a direct jumper to the pin without using a current limiter, which might give me a problem with inrush current unless I also add a resistor as N.G. did. Also keep in mind that this only works because the RTC was designed with backup power circuitry. In general, de-powering I2C Slaves is not a good idea because the pullup resistors keep the SDA and SCL lines high. When a regular I2C sensor has no power, you could leak current via SDA and SCL through the I2C device to GND.
And since my loggers are going in caves where the temperature does not change very quickly, I am bumping the temp conversion time from 64 to 512 seconds as per Application note 3644, in theory reducing the battery drain to < 1 µA. It’s a little unclear from that datasheet if this only really works on the DS3234 (?)but if it does this puts the battery discharge on par with electrolyte evaporation if Maxim’s coin cell lifespan estimates are to be believed.
And finally, doing this means that you are relying on the Cr2032 to power the clock for a substantial amount of time, so you need to make sure you are not using fake coin cell batteries. Name brand packaging is no guarantee of good batteries either! In learning this little lesson I discovered that you can not simply read a CR2032 coin cell with your volt meter to determine if it is healthy, as the no-load voltage stays above 3v even when the cells are nearly dead. As per the Energiser datasheet, I read the cell with a 400 Ω resistor pulse load(for 2 seconds). If that gives me >3v I call the cell good. If you are stuck out in the field without a meter, check if the battery bounces well.
I do wonder if its worth putting a 100uF multilayer ceramic capacitor on the coin cell to buffer the impact of the alarm events. But I don’t know how much I would then loose to capacitor leakage. Abracon seems to think its a good idea in their application note, claiming 11 µA leakage for a 100µF MLCC. But that is more than 3x the current draw of the DS3231 in timekeeping mode.
NOTE: If you try powering the entire breakout board from a digital pin, you are essentially turning the onboard SDA & SCL resistors into pulldown resistors and these fight against the Atmels internal pullup resistors on the 328 that get enabled by default in the two wire library. For details on how to fix that problem, check out this post on the Arduino playground: DS3231 drawing 200+µA through SDA/SCL Also note that I had to go all the way to (x86)\Arduino\hardware\arduino\avr\libraries\wire\utility to find the twi library on my machine, but if you power your DS3231 by lifting the pin from the board like I do, the library edit does not change the sleep current.
This 32k AT24C256 is pin for pin compatible with the 4K AT24C32 on this RTC module. For only $1, it’s really tempting me to do one more little modification to the RTC breakout, although on reflection I think it might be quite handy to have two easily accessed eeproms in the system, using the smaller one for persistent storage of calibration & configuration info, and the other much larger one for sensor data. Keeping the 4K eeprom will limit the I2C bus speed to 100 kHz, while the larger AT24256 opens up the possibility of raising the I2C bus speed to 400 kHz.
I simply let the wires I am already using to tap the I2C lines on the cascade port poke through, giving me solder points for the eeprom. Don’t forget to remove the 10K’s on the little eeprom board or you could be left with too much pull-up on the bus. 15mm M2 standoffs give enough room to comfortably tuck the EEprom board under the RTC breakout.
Testing confirms that the AT24C256 is a drop in replacement. The code I was already using to write data to the eeprom on the RTC breakout worked fine provided I changed the I2c address to 0x50 (while the 4k eeprom on the rtc breakout is 0x57 because its address lines are pulled up). In my case, the larger eeprom allows me to buffer 512 of my two-page write cycles before having to transfer the data out to the SD card. And after some testing, I have confirmed that both eeproms go into standby mode at 1 µA when they are not being accessed. The only challenge is that this many buffered readings represents several days worth of data…so I will need to come up with some kind of procedure for shutting down the loggers without losing information. One solution would be to add a function that flushes the entire eeprom to the SD card during setup. That way simply hitting the reset button would make sure that any residual data in the buffer gets saved before I disconnect the batteries.
In some of my older loggers that were put together ages ago, there is not enough space to easily do this jumpering right onto the RTC breakout, so I came up with some “in-line” eeprom upgrades that I could just drop in without changing any other wiring on the build.
I have recently run into another RTC related issue, which is how to set the RTC’s more accurately. Now that I have multiple data loggers on the go, the led pips show me that the loggers are as much as 4 seconds* different from each other, and that gets even more pronounced when I use different computers to upload sketches. Retrolefty has proposed one method for “syncing by hand” at the playground. I will post some results when I find out if the Whac-A-Mole method reduces my inter-unit time offsets.
One solution would be a sketch that uses an Ethernet shield and connects to an internet time server. Then you could get the offsets down to average round-trip time plus the serial communication. But I do not have an Ethernet shield, so that is a non-starter. Some use a GPS for an accurate time signature, or a dedicated time signal receiver. But my PC is already synced, so buying hardware just to reproduce information that is already available seems like overkill. A more logical approach would be to have two programs, one running in the PC environment then second running inside Arduino. Then both programs could communicate (PC -> sends time stamp via serial line -> Arduino reads value from serial line & sets clock to match).I have not found a set like this yet.
In addition, I would like to have all my loggers running UTC, but that’s easily address by just setting my machine to UTC before setting the clock. UTC avoids all the problems with ‘local’ daylight savings time, etc.
* It looks like I might have been causing that problem by opening the serial window to to check that the clock was updated properly. Makes me wonder why the RTC set sketch was written with serial output in the first place?
Someone at the allaboutcircuits.com forum has doneaccuracy verification testing on these cheap RTC boards and found the chip to be well within the DS3231’s “official” spec:
This is good to know, although of course one source/batch doesn’t confirm them all when you are dealing with cheep eBay knock-offs. For a different approach to testing, jremington over at the playground notes: “By comparing the rising edge of the RTC 1Hz square wave output to that of the 1 Hz PPS output of a GPS unit with a good satellite lock, you can determine within a few hours how much the RTC is drifting. ”
I have been noodling around with new sensor combinations for my next set of builds, and I thought I would post a quick overnight comparison of the DS3231 temperature register ( rated at ±3°C )to data from the Adafruit MCP9808( ± 0.25°C ).
You can see that the DS3231 has a much lower bit depth, but I was pleasantly surprised by how closely they tracked each other. If the datasheet claims are to be believed, the 9808 should be dead-on in this temperature range. This gives me more faith in the data from that humble RTC, which currently records ambient temperature in my drip sensors.
from Coding Badly at the Arduino forum. There should have been no “bumps” on that graph smaller than 0.25°C. But what I was actually getting a mix of xx.00, xx.25, xx.244 and xx.238 in my data. No half degrees, and no temps that read xx.75 You can see those temps are missing, as “steps” in that graph.
But I got the same result with that code too which is very puzzling to me?? Where are the .238 fractional temperatures coming from? Why do I never see xx.5 or xx.75 temperatures?
So it turns out that both examples of code above work fine, but the way I was converting the fractional part of the decimal (so I could print them as integers: printing real #’s takes too much ram) was incorrect. All my other temperature sensors provide at least three digits of information after the decimal place so I had been using fracTemp=(TEMP_degC – wholeTemp) * 1000; to extract the fractional data. But this did not work for the RTC fractional data. Changing it to fracTemp=(TEMP_degC*100) – (wholeTemp*100); converts the decimal part of the RTC temperature into integer values normally. Thanks to Stack Exchange for showing me that you need determine exactly how many decimal points you want to turn into the integer before you do a conversion like this, or the calculation yields weird results. In my case the error changed xx.05 into xx.0244, and xx.75 into xx.238. Fortunately that error was correctable, so here is what that graph should have looked like:
Recent fieldwork gave me a chance to check clock drift on six loggers using these RTC boards. All of these RTCs were set at the end of August and over the course of about 4 months, all of them lost between 30-40 seconds. That puts these cheap units over the minute per year territory that I see claimed for “real” DS3231 breakouts like the Chronodot, but not by enough to make me worry too much as this was a pretty crude test. These modules are still far better than any DS1307 alternatives.
I have been putting together some smaller underwater sensors using two inch pvc pipe, and the tight curved profile of the housing forced me to flip the RTC over. As soon as I did this, I realized that I should have been mounting the RTC this way all along, as it makes it easy to replace the coin cell without undoing the nuts on the standoff bolts. And if I am going to be pin-powering the RTC, I will probably need to change those coin cells regularly. It also lets me use shorter 12mm standoffs and still tuck everything under the RTC.
Steve Hicks over at envirodiy.org has posted on how to convert the DS3231’s epoch time (ie: #number of seconds since January 1, 2000) into unix time and here they convert unix time into Excel standard dates with [=CELL/(60*60*24)+”1/1/1970″ note: you have to have the RTC set to UTC for this to work]. Using epoch time lets you store or compare times as a single 32-bit number (another conversion method here) rather that dealing with 6 numbers and details like the number of days in each month and leap years. A very handy tip. You can view a datalogger script example using long epoch = now.unixtime();
But if yours does not, it is fairly easy to calculate an epoch time integer from the standard YY MM DD MM SS format, if you have your clocks set to UTC.
I have decided to pin power all of my next generation of loggers, including the long chains of DS18b20 temperature sensors I have been working on. But I still don’t know exactly how much impact generating the interrupts will have on the coin cell over time, so I have added a voltage divider connected to the backup coin cell on RTC board, with the center drawn off to an analog input pin on the Arduino. I am hoping these 4.7 MΩ resistors will add only 0.35µA draw to the ground line and perhaps double that when the ADC input capacitor is being charged for a reading. The readings wobble a bit without a capacitor to stabilize them, but I was afraid that leakage on an MLCCwould be larger than the RTC’s sleep current so I left it out. I read the pin three times with a 1ms delay, throwing away the first reading and averaging the next two, and that gets me a reading pretty close to what I see on an external volt meter. But CR2032‘s are lithium batteries, so I might need to put some kind of load on the coin cell to actually read it’s capacity. I was thinking I could do this by forcing a temperature conversion while the pin power is removed. (setting bit5 of reg 0Eh which draws 575 µA for 125-200 ms) This approach would waste some energy and create time delays, so I will do my first few test runs without the “load” to see if I can interpret the reading from that voltage divider without it.
There is another question about pin powering these RTC’s that is niggling at the back of my mind: What happens when I have Battery-Backed Square-Wave Enable set with:
so the RTC generates alarms when it is powered only by the backup battery, and then I disconnect power to the main Arduino before the next alarm? Presumably the alarm still gets generated, but nothing can respond and reset it. My hope is that the open-drain SQW pin, which should only sink current, does not somehow create a circuit through the Arduino that bleeds away power in this situation. Especially now that I have the voltage divider in place…?
To do the drift check, I screen grab the terminal window of a sketch that outputs the current RTC time with the windows system clock. Both are running UTC, and I make sure the computers clock was sync’d via web time servers.
I just returned from another fieldwork trip, and I had the chance to do proper RTC drift checks on twelve data loggers that were deployed in Dec. 2014. After three months of operation they all had offsets between -24 to -30 seconds, and the remarkable consistency across these units made me suspect that I was looking at something other than random errors. I reset the clocks with the little netbook I had on hand, and re-checked the clocks. Sure enough every one of them was reading the current time -24 seconds. I checked the time on the six new new loggers that I had prepared before the trip and every one of them was exactly nine seconds slow (my computer back home is much faster than the netbook I take into the field). When I reset those new loggers with the netbook every one of them became 24 seconds slow. So it looks like the time lag caused by the compile & upload of the RTC set sketch was responsible for the majority of the offsets I reported back in December, and that these DS3234SN RTC’s actually have a drift somewhere between 0-5 seconds over a three month deployment. This is well within the manufacturers spec. And now that I know the compile time is the limiting factor, at least I can be certain that the units all have the same negative time offset before each deployment.
NOTE: With further testing I have found that if you simplyhit the verify button before you hit the upload button,the resulting RTC time offset is reduced to 1/2 (or more for slower systems). On my home based system this reduced lag caused by the compile & upload from ~20 seconds to about 9 seconds. I expect to see even more of a difference on my really slow netbook. In theory you can improve things even more by removing the verify option as you upload. The RTC time setting sketch is the only place where I would risk errors to get to a faster upload time, since I immediately have to replace the RTC “setting” sketch with a “read time only” sketch to confirm it worked anyway.
Update 2016-10-14:I’ve been referring here to the setTime sketch that used to be provided with MrAlvin’s library. This sets the RTC to the compile time with the command
RTC.adjust(DateTime(__DATE__, __TIME__)); His new version has a method of setting the time using the serial monitor, which removes the compile time lag time problem. I’ve gotten used to using setTime & getTime , so I still keep a copy of those older utilities on my GitHub. Paul Stoffregens DS1307 library uses the same compile time method to set the DS3231, but you have to install his Time library as well.
The datasheet reccomends a delay before setting: “Communication with the I²C should be held off at least for the first 2 seconds after a valid power source has been established. It is during the first 2 seconds after power is established that the accurate RTC starts its oscillator, recalls calibration codes, initiates a temperature sensor read, and applies a frequency correction.”
This is the record from the RTC, and I am surprised the batteries did not pop with the loggers internal temp hitting 60°C. The good news is that even after subjecting the RTC to this ordeal, the drift for this unit was the same as the units that were left down in the caves. This logger went back out for another stint in the tropical sun, as I am a firm believer in testing my builds to their limits.
That last deployment saw several loggers run successfully with pin powered RTC’s so I though I should post the little code snippet I use to do that. I have the de-powering embedded inside the function that puts my loggers to sleep
So there you have it. After 3 months of reliable operation, and no coin cells killed off in the process, I am calling this good. BTW this is how I currently connect the RTC boards to the Arduino:
After finding Rob Tillarts multispeed I2C bus scanner, I was happy to notice that all my I2C devices showed up on the higher speed scans. So I have started pushing the bus to faster 400 khz speeds with TBWR=2 on the 8Mhz boards, and TBWR=12 on the 16Mhz boards right after Wire.begin(); The DS3231 is rated for it. The larger AT24C256 eeprom that I have been adding to my loggers is also rated to that speed, but even the smaller AT24c32 on the RTC board seems to work ok at the higher I2C bus speeds, though it is only rated to 100kHz. Since I had been using the I2C communication delays as part of my led pips, I could immediately see shortened operating time (my pips became too short to see) . I have some doubts about whether a humble 8Mhz Arduino can run the I2C bus that fast. Without a scope, or some way to determine the capacitance on the lines, there’s no way to know if I’m actually reaching 400khz with the 4.7kΩ pullups on that RTC breakout. But with quite a few run tests going well thus far, I think add the TBWR settings to my standard code build to shorten mcu up time.
Since these boards are always covered with flux, I picked up a cheap ($15) ultrasonic cleaner and used it on a batch of 12 of these boards with 90% Isopropyl alcohol. After the cleaning I put the used fluid in a jar, and this batch of goo settled out. I know that ultrasonic cleaning is very bad for oscillators, but flux corrosion is lethal too…
I have done a few more tests using a 2x 4.7MΩ divider to monitor the coin cell. The divider definitely works but as expected it also bleeds 0.32µA from the coin cell when the Arduino is powered & sleeping. If I remove power from the whole Arduino, the current drain from the battery through the divider rises to almost double that at 0.56µA. Pin Powering the RTC during uptime and letting it go into timekeeping mode (3 µA) while the Arduino sleeps (with the coincell divider in place) appears to be causing a 5-7mV drop per day on the CR2032 coin cell. With the 2300 mV minimum for the DS3232’s vBatt, that probably means the coin cells will only provide about 4-5 months of pin powering before the little cells need to be replaced. This is a somewhat irritating as I thought I would get more time than that from the 240 mAh coin cells. I am suspecting there are other drains occurring somewhere.
One trick I can try is to set the coincell reading analog pin to INPUT_PULLUP with a pinmode setting while the Arduino sleeps. This would raise the middle of the voltage divider to 3.3v – above the coincell. This will also send 0.7µA from the analog pin through the grounded leg of the divider. When I tried this I found that it also pushes about 0.03µA back towards the coin cell’s positive battery terminal where I have the divider connected. I don’t know if that power is flowing into the lithium coin cell (which is probably bad for CR2032’s – but perhaps it would be ok with an LIR2032?)or into the RTC somehow (?) So this strategy would shut down the divider power leakage from the coin cell and hand it off to the much larger main batteries. This is much lower than the 89µA that the RTC draws if you power it via the Vcc line, but it seems a bit dodgey to flip flop between analog and digital modes on that pin all the time.
I will have to do more tests before I trust that this is not hurting the RTC or the Arduino. Having the lithium coin cells catch fire when their voltage got low would not make my day either. And if I was going to have a small constant drain from one of the pins I might as well just replace the coin cell backup battery with a capacitor – which could be kept charged by the pin that I am currently using to check the backup battery voltage. That way I’d never have to worry about changing the RTC batteries once I got the system rolling…hmmmm…I wonder what the capacitor leakage current would be?
Most of the new batch have this 2 x 4.7 MΩ divider in place and I am now confident that it will be Ok to deploy those units, which likely will not be retrieved till the end of the year. Btw there is a fantastic page over at ganssle.com testing the behavior of CR2032 batteries at low currents. Granssle’s article on Issues in Using Ultra-Low Power MCUs is worth reading. Hackaday’s post on TI processors shows how far the art in low power operation goes. Ignoring self discharge, a CR2032 should be able to last about 4 years if the average draw stays below 5 µA, and the divider is adding ~ 0.7 µA to the RTC’s base load. Actually the DS3231 datasheet specifies the average battery current is less than 3.0 mico-amps, so a typical 200 mAh CR2032 should be able to supply that for about seven years.
Just a quick update on that coin cell reading. I continued that test (on a logger with 20 DS18B20 temp sensors) and the coin cell voltage rose after the break then fell again to about 3040mv:
So at least I am not seeing a catastrophic fail when trying to read the coin cell, but I am still left with the question of whether this reading actually means anything, given that the loading on these lithium cells is a mere 3μA when the RTC is in timekeeping mode. (If straight ADC reads don’t work, I might try the LED/resistor method so that the coincell is loaded during the readings) I still might be shortening the lifespan of my loggers below my one year target with the pin powering technique if the coin cells can’t go the distance. At 150-200 mAh /cell, there should be no problem…but I have made the mistake of counting those chickens before. And I still might need that 1µF cap across the lower resistor, which in theory will cost me ~1nA in leakage.
I prep these RTC’s in runs of 10 to 20 pieces, as this makes the best use of the isopropyl alcohol in the ultrasonic bath. While I was de-soldering resistors on the latest batch (to disable that useless charging circuit) I realized that the first part of the UNO based Datalogger Tutorial (that I put together to help some teacher friends of mine bring Arduinos into the classroom) gives you great platform for testing a bunch of these RTC’s quickly. You can just pop them onto the breadboard in quick succession before you invest any time cleaning them up. You don’t even need to put the battery in! And the code that I posted to Github for that logger is about the simplest example you are likely to find of how to use this RTC breakout to wake a sleeping Arduino.
Just stumbled across a post at Arduino Stackexchange on combining day-month-year data into strings, and using that as a date-stamp file name. This could be handy for “threshold/event” based loggers, as opposed to the more typical take a sample every X minutes approach. I think this method is limited by fat16 to generating a max of 512 entries in the root directory.
The MS5803 is a 24bit pressure sensor which has a metal ring in contact with the air, while the TMP is 12-bit sensor embedded under 3-4mm of epoxy, and the DS3231 RTC is inside the housing body
so I am impressed again with the temp accuracy of those humble RTCs. This is also a really great illustration of what you gain when you add more bits to your temperature record.
Over at raspberry-pi-geek.com they did some benchmarks with four I2C RTC’s: the DS1307, the PCF8563, the DS3231, and the MCP79400. Their graphs show the DS3231 as the overall winner, suggesting that this is is a result of the temperature compensation. It will be interesting to see if they do the tests over again with temp variation to see how this affects the RTCs accuracy.
Just stumbled across a playground forum thread where user Tominakasi tried replacing the backup battery with a capacitor . He reached 24 hours of operation with a 0.22F , but I would need significantly more time than that in a logger application. If I play with some datasheet numbers over at Maxim’s Super Capacitor Calculator, it looks like it might be feasible with a one farad cap. But folk’s over at Sparkfun, seem to think that leakage current would be a serious problem. Since I am already tracking the coin cell voltage with a resistor divider on the top of these boards, I think I will pickup a 5v 1F super cap and try an experiment to find out how long it actually takes for it fall to the RTC’s 2.3v minimum. It would not take much to connect one end of that cap to a separate digital pin and then top it up when necessary because the Arduino will keep a pin driven high even while sleeping. Probably not worth doing for a regular logger, but if I was building something completely potted in epoxy… hmmmm…
There must be a million great clock projects out there, but I stumbled across a couple recently that looked like they would be fun to build. The idea embedded in the Laser Cut Clock by [Buckeyeguy89] really has legs, and I think it could go on to some very interesting higher levels of complexity. And I am sure that I am not alone in drooling over the Ferrofluid Clock by Zelf Koelma, to the point of wondering how I could drive batch of small electromagnets with an Arduino…
This was from a 2×4.7 MΩ set, so I am more confident that we will go a year even with the added drain from the divider. I have since switched over to using 10 meg Ω resistors, but there is some question of whether the ADC sample & hold caps can will get enough current to read that properly. I’ve been dating the coin cells with a marker to help keep a tab on their lifespan.
Just had to post a link to the Arduino Sport Watch Instructableby Alexis Ospitia which combines this DS3231 board with a pro-mini and one of the ubiquitous Nokia 5110 LCDs.
There are a host of changes coming as the ATmega 328p becomes the 328pb. But relevant to this thread, the full-swing oscillator driver circuitry is being removed. While this won’t affect a low&slow application like data loggers, it might spur a few more people to look into the 32K output from these boards. If that’s your thing, there are some interesting frequency measurement guidelines over at sitime.com
Just had to add a shout out here to Luke Millers Tide Clock as a great use for the DS3231 breakout, and a great addition to his Open Wave Height logger project. There are only a handful of us focusing on underwater logging, and his work on the MS5803 was a great contribution.
Times in Excel are factional values of 24 hours. One hour of time is 1/24, and 1 minute of time is 1/(24*60) = 1/1440 – so always enter time increments ‘as fractions’ in the cell rather than numbers. There is an interesting time-related function in Excel that is really useful to know about if you are trying
…use a helper column and then filter on the results of the helper column. Assuming your date/time record starts at A2, and column B is available, then enter the time interval you wish to filter on in cell B1 (e.g 10 or 30 etc). Then enter the following formula in cell B2 and copy it down the rest of the column:
This will provide a TRUE/FALSE value if the time conforms to the interval value contained in cell B1. Then filter all the records based on the TRUE values in column B.
I tend to run my bench tests pretty fast to give new builds a real workout, but then I end up with far more data than I need for calibration / normalization. This little trick works a charm to bring that back to more typical 15 minute sample intervals.
And while we are on the topic of time in Excel, it’s worth mentioning that the program sometimes refuses to convert time stamps from commercial loggers into its native number format. In that case you end up having to extract and convert each piece of text data with a=DATE(year, month, day) and =TIME(hours, minutes, seconds).As an example, converting some weather station times tamps that looked like this 01.01.2009 02:00ended up needing this beast:
A much trickier problem is dealing with badly formed dates that are already in Excel’s native format. Aside from randomly missing data, the second most common problem with weather station data that you download from other sources is that the time serial number (where 2014-1-1 8:00 is actually stored as 41640.3333) has an odd rounding error or other random cruft somewhere down at the 9th decimal place. This will mess up any kind of sorting/comparing in formulas even if the dates are being displayed perfectly fine. The trick is to convert both sets of excel dates into plain text with B5=TEXT(C3,”dd/mm/yyyy hh:mm”), and then re-convert that text back into date & time as described above [with C5=DATEVALUE(LEFT(B5,10)) & D5=TIMEVALUE(MID(B5,12,8))] then concatenate them back together with =C5+D5. Then your hidden-flaw excel date serials, become perfect excel dates again, and all your sorting, etc. starts working again. Don’t forget to check for local vs UTC/GMT timestamps. If you need to add 6.5 hours to a time stamp, that’s done with =C5 + TIME(6,30,0)
Another common problem for loggers used in the field is when your RTC gets reset to the Jan 1st 2000 by a hard bump that momentarily dislodges the backup coin cell contact. You will know the installation date/time based on your field notes, but then you have to re-constitute the timestamps from scratch. The key to doing for long periods is not to use excels drag-fill feature as this will create substantial and ever increasing errors in the generated time stamp. Create the first time stamp ‘manually’ and then to add one minute to the previous cell, use this formula:=previous cell +1/1440, if you want to add one second to cell, use this formula: =A2+1/86400. There will still be a small rounding errors in each subsequently generated time stamp but using fractions will use all of the bits available to excel – so those errors will be small.
And since we are on the topic of useful Excel tricks, another one that is often needed with environmental data sets is determining local daily maxima values with multi-cell peaks. Then you can label those events in your time series. If you need peak detection of a time series to happen ‘live’ on your logger, then a modified median filter is the way to go.
Excel sometimes refuses to parse dates that arrive as ascii data from a datalogger, even when they are perfectly formatted. In situations where excel simply will not interpret timestamps that look like a ‘date’, sound like a ‘date’, and probably even smells and tastes like a ‘date’ – then try using a helper column with the formula =DATEVALUE(date_text) But hey, there are worse problems to have with excel…right?
I was showing a friend how to set the time this RTC recently, when we made the surprising discovery that you can not easily set the system clock on an Apple to UTC. You can select London, England, however England uses daylight savings time and as a result uses GMT (UTC+0) during the winter and British Summer Time (UTC+1) during the summer. (aka selecting London as the city to base my timezone does not provide UTC year round, only in the winter). A bit of hunting revealed that there are other cities in the GMT timezone that do not use daylight savings time such as Ouagadougou, Burkina Faso, and there are other fixes out there if you are willing to go under the hood. But its just hard to believe that Apple made it so hard to set a computer to the global time standard…weird.
I tweak the code on most of my loggers between deployments so often only the more unusual sensor combinations get run for long periods of time without a clock reset . The last round of fieldwork had me updating several of those old dogs, most of whom had been running for more than a year, and this let me do some RTC drift checks. There were two end members for the set; with one unit losing 1.1 seconds per month, and another gaining 1.4 seconds per month. Most of the other loggers drifted forward by ~ 1/2 second per month. So my two worst-case units have drift rates about twice as large as the 0.026 seconds per day they saw at SwitchDoc Labs, but most of my units are in good agreement with their benchmarks. HeyPete.com is doing detailed testing, and usually sees +/- 0.5ppm (~16 seconds a year of drift) which is less than the +/- 2ppm allowed in the spec. He has also
All of these loggers were in a very stable thermal environment (ie. a cave) at around 24°C. Depowering the RTC does not seem to increase the drift, (in factDavid Pillingfound that timekeeping on these boards actually improves when you disable the lithium coin cell charging circuit) and the coin cells look like they will last well past two years with this level of drain, but it’s still uncertain exactly when they will quit due to flat lithium discharge curve.
(The log shown above is from a very dynamic site with several entrances to provide airflow, but most of the other temp. records hover near the bit toggling point all year. )
Hackaday released a post on the quartz crystal resonators which provide the heartbeat for RTC modules and Kerry Wong demonstrates how to adjust the aging offset register with a HP 5350B in high resolution mode. The aging offset register is at 0x10 and the valid values for the parameter ranges from -128 to 127. That # is converted into 2’s complement before sending to DS3232. Each adjustment step changes the clock frequency by roughly 0.1ppm -which translates into roughly between 0.002 to 0.003 Hz. If I understand things correctly, the aging offset is most often used to correct problems with RTC that are running more slowly as they age, and that does seem to be the most common offset I observe in deployed units.
I just noticed that the RTClib from Adafruit supports the use of this RTC with an ESP8266, which will come in handy in future. And there is another library out that makes use of the eeprom on these boards for circular buffer logging. Given the limitations of the ESP, a combination of those two could prove very useful…
After looking at the old logger code I have posted on the projects Github, Mark Behbehani emailed more elegant way to update the next alarm time using modulo, rather a cascade of if statements:
// Update only variable of interest for secintval Sec, for min interval Min,s=00void SetNextAlarmTime(DateTime now) { // this replaces my cascade code
That’s the first time I’ve seen modulo being used, and I think it’s quite elegant. (with the quid pro quo that the modulus (%) operator is quite demanding on the 8-bit AVRs)
Following on that modulo comment, I came across a post using it toencode dates with only 7 alpha characters, as opposed to the standard 10 digits you would see with the ascii version of a Unixtime date. Of course, if you take samples at whole minute intervals, you can use Unixtime/(sample interval*60) with no data loss. If you take samples every 15 min, then you are dividing the unix time by 900; reaching the same 7 character size without any complicated algorithm.
I just noticed that Energisers CR2031 coin cell datasheet lists something interesting: Max Reverse Charge: 1 µA With the number of people warning about non-rechargeable cells exploding if you put them in a trickle charge circuit, I’ve simply been removing the charge circuit resistor. But with their 20-30 ohms of internal series resistance, I am now wondering if the relatively low 3.3v Vcc on my promini’s means that the voltage drop on the resistor & 1N4148 diode combination would give me enough wiggle room to keep the coin cell below that rev charge spec, while still supplying the 0.3µA timekeeping current to the RTC from the main AA batteries when that supply is available.
…Thinking about it a bit more, I guess what I am really after is a simple modification that provides a Diode-OR behavior to switch between the coin cell & the 3.3v rail on the chip’s Vbat line. If I cut the trace from the positive terminal of the coin cell and jumper a 1n5817 across to the common pad on the existing charger circuit, I think we would have the best of both worlds. There would be some drop across the 200Ω resistor & 4148 diode, so the 3.3v rail would deliver less than that to Vbat, and this would drag the coincell/shottky combination down, but once they equalize that the drain on the coincell should go to zero. Perhaps, I should add a little cap in there to smooth the voltage transitions?
Switching to a brand new coin cell (read unloaded at 3.265v)and there is no reverse leakage when the loggers Vcc is powering the charge circuit, but a small forward current from the battery to the main pad of 0.01µA. The coin cell is now applying a higher voltage to the common pad than the 3.028 it would receive through the 200Ω resistor/1N4148 diode combination. So I think that a new coin cell will eventually be pulled down to match the charger pad voltage, but since the normal discharge plateau for Cr2032’s is at 2.9v, and the Vcc supplied pad stays around 3.03v, the coin-cell should never really have the opportunity to discharge if the logger is powered by the main AA battery.
Looks like heypete is at it again with some serious drift testing of these RTC’s. I’m already convinced these cheap modules reach the bar for environmental data logging, but clearly that’s not good enough for a physicist. I’ll be keen to see his results. (Addendum: HeyPete just posted some 5-month test results: Five of the seven crystal-based DS3231 chips ran fast, while two ran slow. All three of the MEMS-based DS3231M chips ran slow. However all of the units were withing the spec for the respective chips: +/- 63 seconds per year for the DS3231SN, and +/-2.6 minutes per year on the -M variant ) If you want the highest accuracy out of these chips in your own design, it’s worth knowing that high frequency noise from I2C (for example) can couple to the internal crystal oscillator making the RTC run fast. Because of this the datasheet warns that you should avoid running signal traces under the package unless a ground plane is placed between the package and that signal line. Sattler also has some doubts about the buffering on those cheap knock of boards, which may make them susceptible to more direct interference from I2C coms.
At the other end of the spectrum, the DS3231 can also output a 32.768 kHz signal. This can be used to create accurate sub-second intervals by connecting that pulse to the XTAL1 input on the 328P, and then you sleep the cpu until the TIMER2 rolls over. Timer2 is only 8-bit, but by changing the prescaler value and the preloaded count you can set the period at which the interrupt fires to suit your project’s needs. Also, if you wanted a larger interrupt period, you can experiment with Timers 1,3,4, and 5 which have a 16-bit width and can count up to 0xFFFF, 65535 decimal. Just be sure to note which pins they are tied to
I made an error during some recent run tests, where I forgot to connect the RTC’s Vcc line jumper to the digital pin for power (see addendum: 2017-04-15) . The test ran without a hitch for several days (>6000 RTC temp readings & alarms) with the Vcc pin left floating, and power provided only through the Vbat line. I had assumed that high-speed I2C communications would fail in this situation, but after digging through the data sheet – it turns out that the DS3231 is fully functional on Vbat. With this realization in mind, I have changed the way I modify these RTC boards for low power sleeping:
Power LED disconnected & trace between Cr2032 & Vbat is cut. Positive coin cell post is then re-connected to Vbat through a 1N4148 diode, Vcc pin on DS3231 is disconnected from the board and re-connected to the common ground via one leg of the capacitor. The 0.1uF cap runs between GND and the Vbat line. With the board configured this way, the module’s sleep current is <1 µA when the I2C signal clock stops (with periodic spikes up to the 575 µA temperature conversion current). That sleep current is drawn from the main power rail via the old “charging” circuit diode, so the Cr2032 coin cell should not discharge at all when the logger is powered.
I had initially used the Shottky diodes because of their “instant” switch-over, but their leakage current is on the order of two to three times higher than with ‘normal’ diodes. And the Shottky’s lower voltage drop was forcing the RTC battery to discharge down to the voltage created when the 3.3v rail passed through the 200 ohm resistor & 1N4148 on the module’s charger circuit. (this pass-through is ~2.97v) By using another 4148 on the coin cell, with it’s matching 0.3v forward drop, I could preserve the coin cell battery at it’s higher nominal starting voltage. The DS3231’s Vcc pin is now connected to GND, rather than being tied to a digital pin on the Arduino for power during logger run-time operations.
I’ve added a small cap because memory within the DS3231 is susceptible to corruption if the VBAT line becomes unstable, which typically happens when removing or inserting the battery. The datasheet states to either change the battery when VCC is providing the power, or to use a capacitor on the VBAT line, to protect against that switch-bounce type noise when changing the battery.
Of course, If you wanted to live dangerously and leave that Vcc leg floating (…like I did by accident – and it still worked in a noisy urban environment…) the bare minimum low-power mod would be to simply flick the charge circuit’s 200ohm resistor off the board with the tip of an iron and then snip the Vcc leg with some side cutters. The RTC would probably still get you 4-5 years of operation running full time from the CR2032 ( or you could try to stuff a 600mAh CR2450 in there… ) Coin-cell holders occasionally lose contact very briefly under vibration, so if you cut the Vcc leg – put a .1 μF capacitor across the coin-cell holder. That value of capacitance will give you about 80 ms grace, which should be longer than the holder will lose contact.
I found an interesting note about errors caused with RTC communication if the Arduino suffers a voltage brown-out during coms when the DS3231 is in battery backed operation (which I am now using with the board modifications described above…)
“The I2C interface is accessible whenever either VCC or VBAT is at a valid level. If a micro-controller connected to the DS3231 resets because of a loss of VCC or other event, it is possible that the micro-controller and DS3231 I2C communications could become unsynchronized, e.g., the micro-controller resets while reading data from the DS3231. When the micro-controller resets, the DS3231 I2C interface may be placed into a known state by toggling SCL until SDA is observed to be at a high level. At that point the micro-controller should pull SDA low while SCL is high, generating a START condition.”
“Communication with the I²C should be held off at least for the first 2 seconds after a valid power source has been established. It is during the first 2 seconds after power is established that the accurate RTC starts its oscillator, recalls calibration codes, initiates a temperature sensor read, and applies a frequency correction.”
I just received another batch of these boards with the DS3231M ±5ppm MEMS oscillator (±0.432 Second/Day =157.68 seconds per year ) rather than the DS3231SN ±2ppm shown in the photos for the eBay listing. This kind of bait-n-switch is very common with grey market electronic parts vendors from China, and as heypete describes there is a significant difference between the two chips. Aside from the accuracy differences, the DS3231N/SN version can be used as both an RTC and a TCXO but the DS3231M is only an RTC. This means that the N/SN chips can output one of several temperature compensated frequencies on the INT#/SQW pin, but the DS3231M can only output a 1 Hz signal. In theory the MEMS version has better shock/impact resistance, and that’s actually a factor for some of our more rugged deployment locations. So despite my reservations about the lower accuracy, we might actually have a use case. There’s a few other quirks with the -M chip.
Another thing that rears its head is the issue of ultrasonic cleaning. These cheap RTC boards always arrived covered in flux, and that’s unlikely to be no-clean type stuff. I’ve been taking the risk of cleaning the RTC’s with 90% iso in a cheap little jewelry cleaner knowing that I might be harming the oscillators, but after more than 150 loggers, over 4 years, I’ve only had one confirmed RTC failure. MEMS are another big no-no for ultrasonic cleaning and who knows if the cleaner will hit a resonant frequency for that new oscillator…I probably need to start cleaning these boards by hand…
The RST pin is an Active-Low Reset pin. This pin is an open-drain input/output which has an internal 50k pull-up resistor to VCC. No external pull-up resistors should be connected. (and that’s exactly what I find on this DS3231 breakout module: the RST pin is not connected to anything)
The I2C interface is accessible whenever either VCC or VBAT is at a valid level. (Active Battery Current at 3.3V is 80μA, Timekeeping Battery Current, SCL = SDA = 0V is 3uA)
It’s worth noting that while the DS3231 can be set to generate time alarms while running from the backup battery, it can not drive any pulsed frequency outputs after this. Setting bit 3 of the status register to zero disables the 32k out.
So what it looks like is an “unconnected” Vcc pin triggers the power fail condition when the backup battery is inserted, but the VCC leg does not “float” because the RST pin is held low by the powerfail condition and the two are linked by an internal 50K resistor. The clocks oscillator can still be started by an I2C bus call, which you have to do to set the time anyway. So if you are OK with simply running down the CR2032