DS1307 Reseting after power loss

Hello I have a low-cost DS1307. After power loss it restart to 1/1/2000 and does not ticking. I read everywhere the CH bit should be set to 0 but can't find any information how to do that. Is there a sketch to do that ?

I am looking at the DS1307 data sheet and see no mention of a CH bit. Can you show where you read about it?

Do you have a backup battery properly connected to the RTC?

You may have counterfeit DS1307.

DS1307 Real Time Clock CH bit problem


Counterfeit electronics?!

Hi, Can you post your code please?

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

What are you using as a backup battery?

Thanks.. Tom... :)

Hello,

is it counterfeit ? I do not know I bought it from RoarKit Store, usually I do not have problem with their products.

Link to the product

The battery is connected and checked (and was even changed) and gives me 3,45v between the 2 red marks on the picture. I added some more soldering on the back of the module to be sure the battery was correctly connected (too much flux).

The DS1307 is pinned like this :

Arduino → DS1307

GND → GND
5V → 5V
A4 → SDA
A5 – SCL

The code I use for testing is :

#include <Wire.h>
#include "RTClib.h"

RTC_DS1307 RTC;

void setup () {
    Serial.begin(9600);
    Wire.begin();
    RTC.begin();
  // Check to see if the RTC is keeping time.  If it is, load the time from your computer.
  if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    // This will reflect the time that your sketch was compiled
    // RTC.adjust(DateTime(__DATE__, __TIME__));
  }
}
void loop () {
    DateTime now = RTC.now(); 
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print('/');
    Serial.print(now.year(), DEC);
    Serial.print(' ');
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();    
    delay(1000);
}

The line // RTC.adjust(DateTime(DATE, TIME)); is of course uncommented during the first upload to set up the time.


Please try my code for testing such chips. It does not use an RTC library, and thus might be better at detecting certain problems.

#include <Wire.h>

// variables for storing the time
//   second  minute  hour    weekday  date    month   year
byte ss=0,   mi=0,   hh=0,   wd=6,    dd=1,   mo=1,   yy=0;
 
void setup()
{
  Wire.begin();
  Serial.begin(9600);
 
  // clear /EOSC bit
  // Sometimes necessary to ensure that the clock
  // keeps running on just battery power. Once set,
  // it shouldn't need to be reset but it's a good
  // idea to make sure.
//  Wire.beginTransmission(0x68); // address DS3231
//  Wire.write(0x0E); // select register
//  Wire.write(0b00011100); // write register bitmap, bit 7 is /EOSC
//  Wire.endTransmission();
}
 
void loop()
{
  // read the time from the RTC, if we can
  boolean gotTheTime = grabTime();
 
  if (gotTheTime) {
    // if we are here, then the time has been successfully read
    // and stored in global variables (ss, mi, hh, wd, dd, mo, yy)
    Serial.print("Got the time: ");
    printTime(); 
  }
  else {
    // if we are here, then we tried to read the time but couldn't
    Serial.println("Unable to read time from RTC");
  }
 
  delay(500);
}


boolean grabTime() {
  // get time from the RTC and put it in global variables

  // 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 seven bytes (ss, mi, hh, wd, dd, mo, yy)
  // check for a reply from the RTC, and use it if we can
  if (Wire.available() >= 7) {
    // if we're here, we got a reply and it is long enough
    // so now we read the time
    ss = bcd2bin(Wire.read()); // get seconds
    mi = bcd2bin(Wire.read()); // get minutes
    hh = bcd2bin(Wire.read()); // get hours
    wd = bcd2bin(Wire.read()); // get day of week
    dd = bcd2bin(Wire.read()); // get day of month
    mo = bcd2bin(Wire.read()); // get month
    yy = bcd2bin(Wire.read()); // get year (two digits)
    // indicate that we successfully got the time
    return true;
  }
  else {
    // indicate that we were unable to read the time
    return false;
  }
}


byte bcd2bin(byte x) {
  // converts from binary-coded decimal to a "regular" binary number
  return ((((x >> 4) & 0xF) * 10) + (x & 0xF)) ;
}


void printTime() {
  // just like it says on the tin
  Serial.print ("\'");
  if (yy<10) Serial.print("0"); Serial.print(yy,DEC); Serial.print("-");
  if (mo<10) Serial.print("0"); Serial.print(mo,DEC); Serial.print("-");
  if (dd<10) Serial.print("0"); Serial.print(dd,DEC); Serial.print("(");
  switch (wd) {
    case 1: Serial.print("Sun"); break;
    case 2: Serial.print("Mon"); break;
    case 3: Serial.print("Tue"); break;
    case 4: Serial.print("Wed"); break;
    case 5: Serial.print("Thu"); break;
    case 6: Serial.print("Fri"); break;
    case 7: Serial.print("Sat"); break;
    default: Serial.print("Bad"); 
  }
  Serial.print(") ");
  if (hh<10) Serial.print("0"); Serial.print(hh,DEC); Serial.print(":");
  if (mi<10) Serial.print("0"); Serial.print(mi,DEC); Serial.print(":");
  if (ss<10) Serial.print("0"); Serial.print(ss,DEC); Serial.println("");
}

So, first I used this code to test and to set up the register :

// DS1307 I2C Read and Write Timekeeper Registers 0x00-0X07

#include "Wire.h"
#define DS1307_I2C_ADDRESS 0x68
#define startRegister 0x00
#define endRegister 0x07

void setup()
{
  Wire.begin();
  Serial.begin(9600);
  Serial.print("Register");
  Serial.print("\t");
  Serial.println("Bit Values");
  Serial.println();

  writeNVRAM(0x00, B00000000);//enable oscillator and set seconds to 0
  //writeNVRAM(0x00, B10000000);//disable oscillator set CH bit

  for (int a = startRegister; a <= endRegister; a++)
  {
    byte b = readNVRAM(a);
    Serial.print("0X");
    if (a < 16)
      Serial.print("0");
    Serial.print(a, HEX);
    Serial.print("\t");
    Serial.print("\t");


    for (int i = 7; i >= 0; i-- )
    {
      Serial.print((b >> i) & 0X01);//shift and select first bit
    }
    Serial.println();
  }
}

void writeNVRAM(byte location, byte data)
// writes data to DS1307 NVRAM location
{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(location);
  Wire.write(data);
  Wire.endTransmission();
}

byte readNVRAM(byte location)//// reads data from DS1307 NVRAM location
{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(location);
  Wire.endTransmission();
  Wire.requestFrom(DS1307_I2C_ADDRESS, 1);
  Wire.read();
}

void loop() {
}

And I have this result :

0X00		00000000
0X01		00000000
0X02		00000000
0X03		00000000
0X04		00000000
0X05		00000000
0X06		00000000
0X07		00000000

Then I uploaded the previous simple code without setting up a new time :

#include <Wire.h>
#include "RTClib.h"

RTC_DS1307 RTC;

void setup () {
    Serial.begin(9600);
    Wire.begin();
    RTC.begin();
  // Check to see if the RTC is keeping time.  If it is, load the time from your computer.
  if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    // This will reflect the time that your sketch was compiled
    // RTC.adjust(DateTime(__DATE__, __TIME__));
  }
}
void loop () {
    DateTime now = RTC.now(); 
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print('/');
    Serial.print(now.year(), DEC);
    Serial.print(' ');
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();    
    delay(1000);
}

The clock is ticking and save its time when the power goes off. It ran 2 hours without main power on with no problem.

But, once I try to set up a new time with the code above, it starts again to fail saving time after power off.

Odometer, your code gives me correct results ;

Got the time: '00-01-01(Sun) 02:33:58

It is the actual time since I set up the register.

Update

I used the code found here http://www.instructables.com/id/Setting-the-DS1307-Real-Time-Clock-using-the-Seria/ to stp up the time and it after 15 min without power the DS1307 kept the time.

So I guess my problem is solved for now but I will wait few hours without power to be sure.

Unfortunately one of my DS1307 seems to be faulty because this procedure didn't work on it.

The post is a little older, but since it still shows up on Google's top position when searching for "counterfeit DS1307" I guess it is the right place to add the following:

Currently (Summer 2020) several sellers on Aliexpress ship fake chips with the following marking: DS1307 1951A4 +102BN

These chips are most likely random cheap chips with the misleading marking. I wasn't able to figure out if they have even any function.

General information about DS1307: Of course, Dallas (Maxim) is the one who developed it, but just like with almost any other chip, there are companies making compatible chips as well. Those are clearly not fakes or counterfeits, but their compatibility is usually not fully 100%.

For example, the DS1307N from HGSEMI (HuaGuan Semiconductor) is what we use a lot at universal-solder.ca because the price is only 1/3 of the DALLAS chip and they work just as expected - at least for our standard applications like the Arduino NANO based DIY PLC Kit

( MOD EDIT ! )