Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to correctly tell if the battery is drained or not? #10

Open
zekageri opened this issue Jan 3, 2024 · 1 comment
Open

How to correctly tell if the battery is drained or not? #10

zekageri opened this issue Jan 3, 2024 · 1 comment

Comments

@zekageri
Copy link

zekageri commented Jan 3, 2024

I have an arduino project with ESP32 and I'm using this library ( which is great btw ).
Currently on power on I'm doing the following

boolean RTC::begin(){
    Wire.begin(rtcSDA_Pin, rtcSCL_Pin);
    Wire.setClock(400000);
    if( !rtc.begin() ){
        Serial.printf("[RTC] - Failed to initialize RTC\n");
        return false;
    }
    Serial.printf("[RTC] - RTC initialized\n");
    checkBattery();
    rtc.clockEnable(true);
    return true;
}

void RTC::checkBattery(){
    Serial.printf("[RTC] - Battery is %s\n", rtc.isRunning()?"charged":"drained");
}

If i call rtc.clockEnable(true); the library will tell me that the battery is ok even if it is drained.
But if i don't set the clock to true it will never be ok, even if i replace the battery.

What is the recommended way of handling the low battery? I want to report to the users that they should replace it even at runtime.
So i would call the check battery function periodically.

@Erriez
Copy link
Owner

Erriez commented Jan 3, 2024

@zekageri Thanks for using my library.

The DS3231 datasheet contains more information about battery operation. For example function isRunning() returns the inverted value of bit OSF (Oscillator Status Flag) in the status register. When isRunning() returns false (OSF bit is set), it means:

  1. The first time power is applied. (Read: first time VBAT or VCC power is applied)
  2. The voltages present on both VCC and VBAT are insufficient to support oscillation. (In this case no I2C communication possible)
  3. The EOSC bit is turned off in battery-backed mode. (explicitly stop the oscillator by calling clockEnable(false))
  4. External influences on the crystal (i.e., noise, leakage, etc.) (not battery related)

You're checking the battery state correct in function checkBattery() at boottime. Only when the oscillator was stopped, function rtc.clockEnable(true) should be called (this starts the oscillator, bit EOSC set in control register) and the RTC date/time should be re-programmed. Function clockEnable(true) also clears the OSF status register here. That's the reason why the next rtc.isRunning() returns true.

Calling isRunning() periodically at run-time returns the oscillator state which may be stopped by points 3 and 4. Theoretically, I think there is no way to detect a low-battery state at run-time to inform users to replace the battery. The RTC keeps running as long as:

  1. VCC and or VBAT are powered and crystal works properly. After next power-cycle, the battery state can be read.
  2. The battery can be replaced at run-time when VCC is powered and no need to re-program date/time.

Maybe an idea to add an ADC to measure the battery voltage? I'm not sure how fast the ADC pin drains the battery.

Success!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants