RTC draining a coin cell battery in one day?

Hi,

This is my first post, so apologies if I violate any forum etiquette.

I've breadboarded a DS3231M RTC using a basic SOIC8 breakout board, and I've hooked up the chip to an Arduino Uno following the DS3231M's datasheet:

[RTC Ard]
VCC--3.3V
GND--GND
SCL--A5
SDA--A4

with a 100nF ceramic capacitor decoupling the VCC pin of the RTC. I've also connected a CR2032 coin cell battery to the VBAT and GND pins of the RTC.

I've uploaded the following sketch to the Uno just to test functionality:

#include <Wire.h>
#define RTC_SET false  //change to true once to manually set the time, then set=false and re-upload
 
void setup(){
  Wire.begin();
  Wire.beginTransmission(0x68);
  Wire.write(0x0E); 
  Wire.write(0b00011100);    // clear EOSC bit 
  Wire.endTransmission();  
  if(RTC_SET){ set_rtc_time(byte(00), byte(54), byte(13), byte(4), byte(22), byte(4), byte(15)); }
  Serial.begin(19200);
}
 
void loop(){  
  char buf[30];
  get_rtc_time(buf);
  Serial.print("timestamp: ");
  Serial.println(buf);
  delay(1000);
}

void get_rtc_time(char *buffer){
  // send request to receive data starting at register 0
  Wire.beginTransmission(0x68); // 0x68 is DS3231 device address
  Wire.write((byte)0); // start at register 0
  Wire.endTransmission();
  Wire.requestFrom(0x68, 7); // request info
 
  while(Wire.available())  { 
    int seconds = Wire.read(); // get seconds
    int minutes = Wire.read(); // get minutes
    int hours = bcdToDec(Wire.read() & 0b111111);//Wire.read();   // get hours
    int dotw = bcdToDec(Wire.read());
    int dotm = bcdToDec(Wire.read());
    int mnth = bcdToDec(Wire.read());
    int yr = bcdToDec(Wire.read());
   
    //hours = //(((hours & 0b00100000)>>5)*20 + ((hours & 0b00010000)>>4)*10 + (hours & 0b00001111)); // convert BCD to decimal (assume 24 hour mode)
    seconds = (((seconds & 0b11110000)>>4)*10 + (seconds & 0b00001111)); // convert BCD to decimal
    minutes = (((minutes & 0b11110000)>>4)*10 + (minutes & 0b00001111)); // convert BCD to decimal
    yr += 2000;

    if(seconds >= 10 && minutes >= 10){sprintf(buffer, "%d/%d/%d %d:%d:%d", yr, mnth, dotm, hours, minutes, seconds);}
    if(seconds >= 10 && minutes < 10){sprintf(buffer, "%d/%d/%d %d:0%d:%d", yr, mnth, dotm, hours, minutes, seconds);}
    if(seconds < 10 && minutes < 10){sprintf(buffer, "%d/%d/%d %d:0%d:0%d", yr, mnth, dotm, hours, minutes, seconds);}
    if(seconds < 10 && minutes >= 10){sprintf(buffer, "%d/%d/%d %d:%d:0%d", yr, mnth, dotm, hours, minutes, seconds);}
  }
}


void set_rtc_time(byte seconds, byte minutes, byte hours, byte dotw, byte dotm, byte mnth, byte yr){  // sets time and date data to DS3231
  Wire.beginTransmission(0x68);
  Wire.write(0); // set next input to start at the seconds register
  Wire.write(decToBcd(seconds)); // set seconds
  Wire.write(decToBcd(minutes)); // set minutes
  Wire.write(decToBcd(hours)); // set hours
  Wire.write(decToBcd(dotm)); // set day of week (1=Sunday, 7=Saturday)
  Wire.write(decToBcd(dotm)); // set date (1 to 31)
  Wire.write(decToBcd(mnth)); // set month
  Wire.write(decToBcd(yr)); // set year (0 to 99)
  Wire.endTransmission(); 
}

// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)  {return ( (val/16*10) + (val%16) );}

//opposite of bcdToDec
byte decToBcd(byte val){return( (val/10*16) + (val%10) );}

Everything works fine on a fresh coin cell battery -- the sketch can set and get the RTC's time, and the device keeps time with USB cable disconnected from the Uno. The trouble is that the battery's voltage is dropping sharply -- I've been intermittently testing the CR2032 voltage today, and it's dropped from 3V to 2.1V in the past few hours.

Clearly something is amiss. I'm not an EE (humble environmental engineer here) but my first guess was that the internal pullup resistors on the Uno's I2C lines weren't in use when the Uno was powered off. I tried to remedy this situation by adding 22k pullup resistors from the SCL and SDA pins on the RTC to the VCC pin. This didn't seem to affect the I2C transmission (yeah) but also didn't seem to affect the battery's quick demise (boo).

Does anyone have a suggestion? I've seen some diagrams that suggest serial resistors on the I2C lines, or a diode between the VBAT and VCC pins, but this isn't my forte and I'd appreciate some guidance.

Thanks in advance,
Chris

I've recently built the same circuit, and had no such problems. It worked well on a PCduino, Mega 2560, and an Uno. There's nothing you need to worry about on the I2C lines from the processor. The DS takes care of power down conditions by itself. So you can forget about the pullup resistors you added. There are already SMT pullup resistors on board anyway (Uno).

So I would be looking for stupid mistakes in the build. Although with so few components, it's hard to imagine what you could have done. Of course, start tracing from the battery.

aarg:
There are already SMT pullup resistors on board anyway (Uno).

Can't find any SMD resitors on my UNOs.
I read somewhere that the internal pullup resistors are enabled by the I2C code.
The two MEGAs I own have 10k SMD resistors on each line.
Leo..

Wawa:
Can't find any SMD resitors on my UNOs.
I read somewhere that the internal pullup resistors are enabled by the I2C code.
The two MEGAs I own have 10k SMD resistors on each line.
Leo..

I stand corrected. There are none on the UNO.

You have connected all the unused pins to ground as indicated in the datasheet?

Floating inputs are classic way to cause a micro-power CMOS circuit to consume
4 or 5 orders of magnitude more current from the supply than they are meant to.

Don't leave CMOS inputs floating.

RN1 (4 x 10K), RN2 (4 x 1K), RN3 (4 x 22) , RN4 (4 x 1K) and R2 (1M) are all SMD resistors on the Uno.

CrossRoads:
RN1 (4 x 10K), RN2 (4 x 1K), RN3 (4 x 22) , RN4 (4 x 1K) and R2 (1M) are all SMD resistors on the Uno.

Yes I know, but the UNO has no resistors connected to it's I2C lines.
At least I can't find them on the schematic.
The Mega does. Two 10k resistors in a 4x10k SMD ResistorNetwork.
I didcovered that when designing an I2C LED driver board.
Leo..

MarkT:
You have connected all the unused pins to ground as indicated in the datasheet?

Floating inputs are classic way to cause a micro-power CMOS circuit to consume
4 or 5 orders of magnitude more current from the supply than they are meant to.

Don't leave CMOS inputs floating.

It is true. However on the DS3231, they are truly not connected. The grounding is only to improve noise immunity.

aarg:
It is true. However on the DS3231, they are truly not connected. The grounding is only to improve noise immunity.

Well it was a good theory!

aarg:
The grounding is only to improve noise immunity.

No the grounding is to make it work, by giving a current path.

iamchriskelley:
I've hooked up the chip to an Arduino Uno following the DS3231M's datasheet:

[RTC Ard]
VCC--3.3V
GND--GND
SCL--A5
SDA--A4

If I have a look into the datasheet I cannot see anything about that VCC of the controller is different to VCC of the RTC, but I see a Reset-Reset connection in the "Typical Operating Circuit" diagram, and while considering that no pin on any IC may be operated at higher voltage than VCC+0.5V I'd strongly recommend cabling like that (though hardware is not my strength, I'm better in software coding):
[RTC Ard]
VCC--5 V
GND--GND
SCL--A5
SDA--A4
RST--Reset

Most likely your RTC is resetting all the time due to missing RST-Reset connection while operated on battery backup power.

MarkT:
You have connected all the unused pins to ground as indicated in the datasheet?

Floating inputs are classic way to cause a micro-power CMOS circuit to consume
4 or 5 orders of magnitude more current from the supply than they are meant to.

Don't leave CMOS inputs floating.

Thank you for the advice. There seems to be some disagreement in the thread about the importance of grounding the unused pins on the DS3231M.

In the "Pin Description" section of the datasheet, it says of the 32kHz pin "It may be left open if not used", and of the INT/SQW pin "If not used, this pin can be left unconnected". These two pins have pullup resistors in the "Typical Operating Circuit" on page 1, and the RST pin has an internal 50kOhm pullup resistor. I believe that the Chronodot leaves these pins floating. And just to be clear, I'm using the 8-pin version of the DS3231, which has no extra "NC" pins that need grounding.

I raise these points not to be contrary, just be clear. I just checked the circuit this morning and the coin cell battery is at 0.8V, as good as dead. Thank you all for posting, and I would welcome any additional advice.

jurs:
If I have a look into the datasheet I cannot see anything about that VCC of the controller is different to VCC of the RTC, but I see a Reset-Reset connection in the "Typical Operating Circuit" diagram, and while considering that no pin on any IC may be operated at higher voltage than VCC+0.5V I'd strongly recommend cabling like that (though hardware is not my strength, I'm better in software coding):
[RTC Ard]
VCC--5 V
GND--GND
SCL--A5
SDA--A4
RST--Reset

Most likely your RTC is resetting all the time due to missing RST-Reset connection while operated on battery backup power.

I hadn't noticed that connection, thank you. The RST pin is active low, though, with an internal pullup resistor to VCC. If I connect RST to Reset on a powered-off Uno, would that be equivalent to pulling RST low? I'll check on this after getting another CR2032.

In the "Pin Description" section of the datasheet, it says of the 32kHz pin "It may be left open if not used", and of the INT/SQW pin "If not used, this pin can be left unconnected".

If it mentions in the data sheet that a specific pin can be left unconnected then it is fine to leave it unconnected. Where you are not using an input pin and the data sheed does not mention it then it is always good practice to connect it to something.

What is the exact part number on the battery? LIR2032?

I ask as if this is a module that already came with an LIR2032, there is a potential discharge circuit on the module. It is meant to charge an LIR2032, but pretty much kills CR or BR versions. There is a resistor you can remove to the battery charge circuit if you want to use a normal battery not a rechargeable.

-fab

fabelizer:
What is the exact part number on the battery? LIR2032?

I ask as if this is a module that already came with an LIR2032, there is a potential discharge circuit on the module. It is meant to charge an LIR2032, but pretty much kills CR or BR versions. There is a resistor you can remove to the battery charge circuit if you want to use a normal battery not a rechargeable.

Reading the first post from OP doesn't indicate this:
"OP: I've breadboarded a DS3231M RTC using a basic SOIC8 breakout board"

The problem could just as well be a dud chip or conductive flux remains under the chip.

// Per.

Fresh flux doesn't conduct, unless its badly burnt - flux is normally removed
so that it can't degrade over years/decades and start leaking electrons.

The DS3231 datasheet says,

Avoid running signal traces under the package, unless
a ground plane is placed between the package and the
signal line. All N.C. (no connect) pins must be connected
to ground.

However, I know that it operates without them connected, because I breadboarded a prototype that way. I think I will go back and correct that when I get my better soldering iron back.

Considering that, it's likely that those pins are connected to some kind of internal local ground plane, or more simply that the unused pins are in close enough proximity to the actual crystal connections, that there could be interference coupled into the circuit. Grounding them would effectively eliminate such interference.

It's worth considering the part about adjacent lines as well. Low power crystal oscillators are very sensitive circuits.

Having said that, it doesn't seem to have anything to do with the original question about power drain.

aarg:
It's worth considering the part about adjacent lines as well. Low power crystal oscillators are very sensitive circuits.

Having said that, it doesn't seem to have anything to do with the original question about power drain.

Yes, to be clear I took a chip without supporting circuitry and soldered it to an Adafruit SOIC-8 breakout board. The breakout board has traces for an TSSOP-8 chip on the other side -- no ground planes, traces underneath the RTC. All eight pins of the breakout board were connected to independent rows on a breadboard.

After reading the previous comments I decided to use a freshly (and better-) soldered DS3231M and move the breakout board off of a breadboard and use jumper wires to connect the RTC to the Uno and the coin cell. I'm not sure to what extent parasitic losses from the breadboard (especially from the unused INT/SQW, 32KHz, and RST pins) could have affected things; like the traces under the RTC I would expect these losses to affect the ability of the RTC to accurately keep time (they didn't) rather than dramatically affect the battery life.

I'll check on the reconfigured device (and a Chronodot I wired up for comparison) tomorrow.

iamchriskelley:
I'm not sure to what extent parasitic losses from the breadboard (especially from the unused INT/SQW, 32KHz, and RST pins) could have affected things; like the traces under the RTC I would expect these losses to affect the ability of the RTC to accurately keep time (they didn't) rather than dramatically affect the battery life.

No such losses are predicted by the manufacturers data sheet. Nor is there any cautionary note about leaving them disconnected. INT and 32Khz are explicitly permitted to be unconnected. RST has no clear language except that it has an internal pullup (however this would make it safe).

The outputs that are open collector wouldn't draw power from Vcc or Vbat anyway. Not unless you wired them that way.