Go Down

Topic: RTC draining a coin cell battery in one day? (Read 5521 times) previous topic - next topic

iamchriskelley

Apr 22, 2015, 11:27 pm Last Edit: Apr 23, 2015, 01:16 am by iamchriskelley
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:

Code: [Select]

#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

aarg

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.
  ... with a transistor and a large sum of money to spend ...
Please don't PM me with technical questions. Post them in the forum.

Wawa

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


aarg

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.
  ... with a transistor and a large sum of money to spend ...
Please don't PM me with technical questions. Post them in the forum.

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.
[ I DO NOT respond to personal messages, I WILL delete them unread, use the forum please ]

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.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

Wawa

#6
Apr 23, 2015, 07:21 am Last Edit: Apr 23, 2015, 07:23 am by Wawa
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..

aarg

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.
  ... with a transistor and a large sum of money to spend ...
Please don't PM me with technical questions. Post them in the forum.

MarkT

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!
[ I DO NOT respond to personal messages, I WILL delete them unread, use the forum please ]

Grumpy_Mike

The grounding is only to improve noise immunity.
No the grounding is to make it work, by giving a current path.

jurs

#10
Apr 23, 2015, 06:13 pm Last Edit: Apr 23, 2015, 06:15 pm by jurs
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.

iamchriskelley

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.


iamchriskelley

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.

Grumpy_Mike

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

fabelizer

#14
Apr 25, 2015, 03:03 am Last Edit: Apr 25, 2015, 03:08 am by 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.

-fab

Go Up