RTClib reset time power interrupted

Hola!

This is a fairly common project, with a common problem as well. Why doesn't the program continue to count the time after the power supply is interrupted? Obviously I tried to solve the problem by searching on google, but without progress.
I do the following: connect the arduino nano to the pc, load the code, then put it in the circuit and with an external source of 12Vdc I supply the circuit through the Nano`s Vin pin. How to set the time in setup (): manual, auto or not?

#include "TM1637.h"
#include <DHT.h>

#define DHTPIN A2     // what pin we're connected the DHT output
#define DHTTYPE DHT11   // DHT 11
//#define DHTTYPE DHT22   // DHT 22
DHT dht(DHTPIN, DHTTYPE);

//{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
//0~9,A,b,C,d,E,F,"-"," ",degree,r,h

#define CLK 2//Pins for TM1637     
#define DIO 3
TM1637 tm1637(CLK, DIO);

// Date and time functions using a DS3231 RTC connected via I2C and Wire lib
#include <Wire.h>
#include "RTClib.h"
RTC_DS3231 rtc;
int hh, mm;


unsigned long clockBlinkStart;
const unsigned long clockBlinkDuration = 500; // milliseconds
bool showPoint;

unsigned long TempHumidityStart;
const unsigned long TempHumidityDuration = 3000;  // milliseconds

bool showTemperature; // true = show temperature, false = show humidty
bool showTime;  // true = display time, false = display Temp/Humidity


void setup()
{
  Serial.begin(9600);
  tm1637.init();
  tm1637.set(BRIGHT_TYPICAL);
  //BRIGHT_TYPICAL = 2,BRIGHT_DARKEST = 0,BRIGHTEST = 7;

  delay(1500);//Delay to let system boot

  dht.begin();

  rtc.begin();
    // Check if the RTC lost power and if so, set the time:
  if (rtc.lostPower()) {
    Serial.println("RTC lost power, lets set the time!");
    // The following line sets the RTC to the date & time this sketch was compiled:
    //rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    //rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
    }
  // manual adjust
  // January 21, 2014 at 3am you would call:
  //rtc.adjust(DateTime(2020, 2, 29, 19, 31, 0));
  // automatic adjust
  rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));

  showPoint = true;
  showTime = true;
  showTemperature = true;
  displayTime( rtc.now() );
}

void loop() {

  unsigned long currentMillis = millis();

  DateTime now = rtc.now();

  int hh = now.hour();
  int mm = now.minute();
  int ss = now.second();

  if ( showTime == true ) {
    // display the time
    if ( currentMillis - clockBlinkStart >= clockBlinkDuration ) {
      clockBlinkStart = currentMillis;
      showPoint = !showPoint;
      displayTime(now);
    }

    // see if it is time to display temperature and humidity, every minute
    if ( ss == 0 ) {
      showTime = false;
      showTemperature = true;
      displayTempHumidity();
      TempHumidityStart = currentMillis;
    }
  }

  // check temperature/humidity display time
  if ( showTime == false ) {
    if ( currentMillis - TempHumidityStart >= TempHumidityDuration ) {
      TempHumidityStart = currentMillis;
      if ( showTemperature == true ) {
        // we have been showing temerature, so time to show humidity
        showTemperature = false;
        displayTempHumidity();
        TempHumidityStart = currentMillis;
      }
      else {
        // we already showed humidity so cycle back to displaying time
        showTime = true;
      }
    }
  }
}


void displayTime(DateTime now) {
    
  int hh = now.hour();
  int mm = now.minute();

  if ( showPoint == true ) tm1637.point(POINT_ON);
  else  tm1637.point(POINT_OFF);

  if ((hh / 10) == 0) tm1637.display(0, 17);
  else
    tm1637.display(0, hh / 10);  // hour

  tm1637.display(1, hh % 10);
  tm1637.display(2, mm / 10); // minutes
  tm1637.display(3, mm % 10); //
    Serial.print(hh);
    Serial.print(':');
    Serial.print(mm);
    Serial.println();

}


void displayTempHumidity() {
  
  int value;

  if ( showTemperature == true ) {
    value = dht.readTemperature();
    //   value = 23;
  }
  else {
    value = dht.readHumidity();
    //   value = 48;
  }
  tm1637.display(0, value / 10);
  tm1637.display(1, value % 10);
  if ( showTemperature == true ) {
    tm1637.display(2, 18); // put degree
    tm1637.display(3, 12); // put a C at the end
  }
  else {
    tm1637.display(2, 19); // r
    tm1637.display(3, 20); // h
  }
  Serial.println(value);
}

I'm not exactly sure what your issue is. If the RTC lost power, the code will set the time. If you have a battery installed in your RTC module, powering off the circuit will not cause the RTC to lose power so when you power back up, that part of the code will not execute.

Is that what you are seeing? Or something else?

rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));

This line is setup() is not within any conditional statement, and will run and reset to the original compile time every time the Arduino cycles power.

Set the time once, then comment out any setting of time in the code. Then reload the commented code.

The DS3231 is quite accurate, and if there is a battery installed it will keep the time through a shut down.

blh64:
I'm not exactly sure what your issue is. If the RTC lost power, the code will set the time. If you have a battery installed in your RTC module, powering off the circuit will not cause the RTC to lose power so when you power back up, that part of the code will not execute.

Is that what you are seeing? Or something else?

blh64:
I'm not exactly sure what your issue is. If the RTC lost power, the code will set the time. If you have a battery installed in your RTC module, powering off the circuit will not cause the RTC to lose power so when you power back up, that part of the code will not execute.

Is that what you are seeing? Or something else?

I use a ds3231 module that has its own battery. My circuit consists of: arduino nano, ds3231, dht11 and tm1637 + 12vdc power supply.
Pay attention to the steps I take to upload the code, maybe I`m doing something wrong.

In setup () I can set rtc.adjust in manual or automatic mode. In automatic mode, I load the code into nano (ds3231 is not connected yet), I connect nano to the circuit and it works fine (I have a small time delay until I connect nano to the circuit, 15s for uploading the code, 20s for connecting to the circuit and power supply, but is ok) . So, I power on the circuit let`s say at 9:45, after a few minutes I interrupt the power supply, and the clock returns at 9:45. Why is this happening ?

cattledog:

rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));

This line is setup() is not within any conditional statement, and will run and reset to the original compile time every time the Arduino cycles power.

Set the time once, then comment out any setting of time in the code. Then reload the commented code.

The DS3231 is quite accurate, and if there is a battery installed it will keep the time through a shut down.

I upload the code like this:
// manual adjust
// January 21, 2014 at 3am you would call:
//rtc.adjust(DateTime(2020, 2, 29, 21, 30, 0));
// automatic adjust

rtc.adjust(DateTime(F(DATE), F(TIME)));

Comment the line above, reload the code and I`m getting 0:00. Manual adjust, same thing, set time 21:30, upload, comment the line, and reload.

What do you see when you run the RTCLib.h library example for the DS3231? What happens with a power cycle?

Is the RTC battery replaceable? Maybe it is in backwards.

cattledog:
What do you see when you run the RTCLib.h library example for the DS3231? What happens with a power cycle?

This is the code from RTClib examples:

// Date and time functions using a DS3231 RTC connected via I2C and Wire lib
#include "RTClib.h"

RTC_DS3231 rtc;

char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

void setup () {

#ifndef ESP8266
while (!Serial); // for Leonardo/Micro/Zero
#endif

Serial.begin(9600);

delay(3000); // wait for console opening

if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
while (1);
}

if (rtc.lostPower()) {
Serial.println("RTC lost power, lets set the time!");
// following line sets the RTC to the date & time this sketch was compiled
rtc.adjust(DateTime(F(DATE), F(TIME)));
// This line sets the RTC with an explicit date & time, for example to set
// January 21, 2014 at 3am you would call:
// rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
}
}

void loop () {
DateTime now = rtc.now();

Serial.print(now.year(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.day(), DEC);
Serial.print(" (");
Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
Serial.print(") ");
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.println();

Serial.print(" since midnight 1/1/1970 = ");
Serial.print(now.unixtime());
Serial.print("s = ");
Serial.print(now.unixtime() / 86400L);
Serial.println("d");

// calculate a date which is 7 days and 30 seconds into the future
DateTime future (now + TimeSpan(7,12,30,6));

Serial.print(" now + 7d + 30s: ");
Serial.print(future.year(), DEC);
Serial.print('/');
Serial.print(future.month(), DEC);
Serial.print('/');
Serial.print(future.day(), DEC);
Serial.print(' ');
Serial.print(future.hour(), DEC);
Serial.print(':');
Serial.print(future.minute(), DEC);
Serial.print(':');
Serial.print(future.second(), DEC);
Serial.println();

Serial.print("Temperature: ");
Serial.print(rtc.getTemperature());
Serial.println(" C");

Serial.println();
delay(3000);
}

It does the same thing, when I shut down the power the clock returns to the moment when the program was compiled.
Could be the battery of the module?

cristian10001:
Could be the battery of the module?

Did you read reply #6?

It appears that the chip is not running under battery power. As suggested, check the polarity, and verify the voltage of the battery. Try a new battery if you have one.

It's possible that there is a repairable defect in the module. Have you confirmed that you can measure Vbat at the actual pin of the chip? If Vbat is not present, there may be a defective battery holder, wiring problem or trace which can be fixed.

If Vbat is present at the chip pin, and the time is not correct after you set the time, remove power, and restart under Vcc, then you may have a counterfeit/defective chip.

This is the module I have, a small battery attached to those metal parts. I measured the battery voltage and it's 135-140 millivolts, I guess it's not good, I think it should have 2.5 volts minimum. I will try to remove the battery socket and replace it, maybe I can fix the problem.
If the 12vdc voltage drops, is it possible for the circuit to absorb energy from the battery?

Too bad, it looks otherwise like a good module. I have ordered other boards with the small solder tab batteries and they are all dead now. I suspect they don't disable the oscillator in software for storage like they should. What do you mean, "If the 12vdc voltage drops, is it possible for the circuit to absorb energy from the battery?"? No idea what you're thinking about there. The battery is not rechargeable if that is what you mean.

So, I replaced the module battery, but the problem was not solved. I attached the circuit diagram.

I tried something easy: connect ds3231 to arduino, plug arduino to pc, upload the example from RTClibrary, it works fine. I disconnect the arduino from the PC, wait a few minutes, connect it again, same thing, it starts from the moment until I cut off the power. I mention that the only power supply of the arduino is via usb.

Nano_TM1637_PCB.pdf (17.6 KB)

When you replaced the battery, did you get ~3V on the Vbat pin? It sounds like you may have a defective module. Either the battery is not properly connected to ground and Vbat or there is some sort of short somewhere that is draining your battery.

When you replaced the battery, did you get ~3V on the Vbat pin?

This is the first thing to confirm.

If indeed there is voltage at the Vbat pin there is one possible control register setting which could stop the oscillator under battery operation. It would be very unusual for this bit to have been set.

You could also have a defective chip with stuck bit in the status register for the oscillator stop flag. I have also seen counterfeit DS1307 chips which would not run under battery power.

If you can confirm voltage, you might want to look at the values in registers 0x0E and 0x0F, but you are starting to get into the weeds.

When you run the example code, are you remembering to comment out the time setting part when you check for the time, the second time you upload it to the board?

if (rtc.lostPower()) {
    Serial.println("RTC lost power, lets set the time!");
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  }

The library example code places the rtc.adjust() within a conditional test of Oscillator Stop Flag Bit7 in the status register. If the flag is not set during a power down, the code should not reset the time.

RTC_DS3231::lostPower(void) {
  return (read_i2c_register(DS3231_ADDRESS, DS3231_STATUSREG) >> 7);
}

aarg:
When you run the example code, are you remembering to comment out the time setting part when you check for the time, the second time you upload it to the board?

I tried to upload the code with this line uncommented rtc.adjust(DateTime(2020, 3, 5, 6, 12, 0)); (setting the clock for beginning) and then reload the code with the line commented (a method that I found on internet), but the clock is showing 0:00. All I have left is to find a way to manually adjust the clock, using buttons or something, just finished the pcb, but nothing left to solder, so disappointing.
I guess I`ll come back asking how to add buttons :slight_smile: .

cristian10001:
So, I replaced the module battery, but the problem was not solved. I attached the circuit diagram.

I tried something easy: connect ds3231 to arduino, plug arduino to pc, upload the example from RTClibrary, it works fine. I disconnect the arduino from the PC, wait a few minutes, connect it again, same thing, it starts from the moment until I cut off the power. I mention that the only power supply of the arduino is via usb.

I had the same problem a few days ago, and solved it by removing the resistor and opening the battery feeding circuit of the DS3231 module, which would send 4.5 to 5V TO the battery in an attempt to recharge it. You can do that, or get a rechargeable one (like a LIR2032). Probably no code changes from what you got from the examples. I've attached a picture of how it looks afterwards in here.

However, I did notice something: if I feed the arduino via USB, it works perfectly, doesn't reset the date and time, keeps track of it as it should... but if I try and feed it 12V with a power supply, whenever it starts, the time and date will reset to the compilation time.

So I believe what can be done here is, either you 'fix' your module and use your USB normally, or you can also program it once with the (TIME) and (DATE) adjustment, and right after that, REPROGRAM it, except this time with this line commented, so even if you enter the adjustment loop, you won't actually set it to compilation time again every time you start it.

I'm still trying to figure out why the 12V option is not quite working for me, but I guess there's no harm in using the USB port for now.

cristian10001:
I tried to upload the code with this line uncommented rtc.adjust(DateTime(2020, 3, 5, 6, 12, 0)); (setting the clock for beginning) and then reload the code with the line commented (a method that I found on internet), but the clock is showing 0:00. All I have left is to find a way to manually adjust the clock, using buttons or something, just finished the pcb, but nothing left to solder, so disappointing.
I guess I`ll come back asking how to add buttons :slight_smile: .

I think you have a hardware problem, probably the module. You never responded to the comments in reply #13, 14...