JChristensen / DS3232RTC

Arduino Library for Maxim Integrated DS3232 and DS3231 Real-Time Clocks
GNU General Public License v3.0
392 stars 135 forks source link

RTC stops responding and needs to turn off power #91

Closed rtek1000 closed 3 years ago

rtek1000 commented 3 years ago

Hi,

I'm making a datalogger, and during code debug, I noticed that sometimes the RTC stops responding. To solve this, I have to turn off the RTC power.

I saw in the datasheet that there can be a desynchronization between the RTC and the microcontroller, which can be resolved without restarting the RTC:

Page 11:

I2C interface

If a microcontroller connected to the DS3231 resets because of a loss of VCC or other event, it is possible that the microcontroller and DS3231 I2C communications could become unsynchronized, e.g., the microcontroller resets while reading data from the DS3231.

When the microcontroller resets, the DS3231 I2C interface may be placed into a known state by toggling SCL until SDA is observed to be at a high level.

At that point the microcontroller should pull SDA low while SCL is high, generating a START condition.

Another alternative I'm experimenting with is the use of the RESET pin. I didn't find details explaining if the RESET pin also causes the date and time to be reset. I did a test and didn't reset the date or time, I believe it could be an alternative, but it would be nice to be able to solve this without the need for an additional microcontroller pin.

This RESET pin is a bit complex:

Page 10:

Pushbutton Reset Function

The DS3231 provides for a pushbutton switch to be connected to the RST output pin.

When the DS3231 is not in a reset cycle, it continuously monitors the RST signal for a low going edge.

If an edge transition is detected, the DS3231 debounces the switch by pulling the RST low.

After the internal timer has expired (PBDB), the DS3231 continues to monitor the RST line.

If the line is still low, the DS3231 continuously monitors the line looking for a rising edge.

Upon detecting release, the DS3231 forces the RST pin low and holds it low for tRST.

RST is also used to indicate a power-fail condition.

When VCC is lower than VPF, an internal power-fail signal is generated, which forces the RST pin low.

When VCC returns to a level above VPF, the RST pin is held low for approximately 250ms (tREC) to allow the power supply to stabilize.

If the oscillator is not running (see the Power Control section) when VCC is applied, tREC is bypassed and RST immediately goes high.

Assertion of the RST output, whether by pushbutton or power-fail detection, does not affect the internal operation of the DS3231.

Page 9:

Active-Low Reset.

This pin is an open-drain input/output.

It indicates the status of VCC relative to the VPF specification.

As VCC falls below VPF, the RST pin is driven low.

When VCC exceeds VPF, for tRST, the RST pin is pulled high by the internal pullup resistor.

The active-low, open-drain output is combined with a debounced pushbutton input function.

This pin can be activated by a pushbutton reset request.

It has an internal 50kΩ nominal value pullup resistor to VCC.

----> No external pullup resistors should be connected. <----

If the oscillator is disabled, tREC is bypassed and RST immediately goes high.

Any suggestions on how to implement this initialization described on page 11 of the datasheet?

Thank you.

https://datasheets.maximintegrated.com/en/ds/DS3231.pdf

rtek1000 commented 3 years ago

Page 10: "Assertion of the RST output, whether by pushbutton or power-fail detection, does not affect the internal operation of the DS3231."

This answers a question:

I didn't find details explaining if the RESET pin also causes the date and time to be reset.

rtek1000 commented 3 years ago

See please: https://stackoverflow.com/questions/33454883/i-cant-get-ds3231-rtc-to-work

void resetRTC() {

  pinMode(SDA, INPUT_PULLUP);
  pinMode(SCL, INPUT_PULLUP);
  do {
    SDA_HIGH();
    SCL_HIGH();
    if (SDA_READ()) {
      SDA_LOW();
      SDA_HIGH();
    }
    SCL_LOW();
  } while (SDA_READ() == 0);

}
JChristensen commented 3 years ago

Not sure I've seen this issue. Where was the RTC purchased?

rtek1000 commented 3 years ago

Not sure I've seen this issue. Where was the RTC purchased?

I bought from different places, symptoms are the same.

Thank you.

JChristensen commented 3 years ago

Is the issue consistent or intermittent? If intermittent, how intermittent?

rtek1000 commented 3 years ago

Is the issue consistent or intermittent? If intermittent, how intermittent?

As I understand it, it occurs as described in the datasheet, if the microcontroller restarts during an ongoing procedure.

Page 11:

If a microcontroller connected to the DS3231 resets because of a loss of VCC or other event, it is possible that the microcontroller and DS3231 I2C communications could become unsynchronized

rtek1000 commented 3 years ago

In my case the problem is easier to occur, because I am constantly restarting the microcontroller to test new code updates.

I believe this should happen to all developers, but some just ignore it, or are unaware of it.

I think it would be interesting to have this implementation in case the reading of any parameter fails, and especially on startup.

I will implement this routine to see if this problem stops occurring, in the last case I will use the reset pin.

Thank you.

void resetRTC() {

  pinMode(SDA, INPUT_PULLUP);
  pinMode(SCL, INPUT_PULLUP);
  do {
    SDA_HIGH();
    SCL_HIGH();
    if (SDA_READ()) {
      SDA_LOW();
      SDA_HIGH();
    }
    SCL_LOW();
  } while (SDA_READ() == 0);

}

Source: https://stackoverflow.com/questions/33454883/i-cant-get-ds3231-rtc-to-work

JChristensen commented 3 years ago
  1. It's worth checking the I2C return status after doing I/O to the RTC and retrying if necessary. Errors can occur on the I2C bus but I would expect these to be rare unless the circuit layout is horrible.
  2. I asked about the source of the part because there are a lot of suspect/counterfeit chips out there. A DS3231 from Mouser or Digikey costs $9-$10 USD. Yet there are sites selling them for $2-$3. I would not use these; I've tried some, and while some do seem to work, others have issues. If it sounds too good to be true...
  3. If you can supply a short, concise sketch that demonstrates the issue with reasonable consistency, without needing other hardware and libraries that I may not have, then I'd be willing to try and recreate the issue here.
  4. Having said all that, I do prefer to limit issues here to actual problems with the library. I don't have time to debug user code and circuitry.
JChristensen commented 3 years ago
  1. If the DS3231 is not an authentic component directly from Maxim or an authorized distributor with stringent product traceability and anti-counterfeit controls in place, then all bets are off and we should close this issue until and unless it can be duplicated with an authentic component.
rtek1000 commented 3 years ago
  1. If the DS3231 is not an authentic component directly from Maxim or an authorized distributor with stringent product traceability and anti-counterfeit controls in place, then all bets are off and we should close this issue until and unless it can be duplicated with an authentic component.

Ok, I'm going to close, I believe that limiting the implementation of this routine already provided for in the component's datasheet because the supplier is not official is regrettable, but that's ok, good rest, thank you.

JChristensen commented 3 years ago

There is a lot of junk out there, I've seen some real horror stories. If you're not using raw chips, then try a DS3231 breakout board from Adafruit, or SparkFun, etc., those should be fine. And if you can gin up a simple sketch that demonstrates the problem, I'd still be willing to try it here. Good luck.

rtek1000 commented 3 years ago

Just for the record, I tried to create a sketch to repeat the problem (Using an Arduino Nano and a ZS-042 Board), but I haven't been successful yet.

I need to consider:

Thus, it may be related to desynchronization with this low-power state, because the ZS-042 board has a fixed pull-up resistor, and when the circuit I'm using is turned off, the pull-up resistor is also de-energized, so DS3231 enters low power mode (Datasheet: page 3) and can wake up the microcontroller later (the uC is totally de-energized during this period).

Anyway, I've already implemented that routine described above (resetRTC), if the error continues to occur, I'll post it here again, apparently it didn't happen anymore.

Thank you.

JChristensen commented 3 years ago

When the I2C bus is idle, both SCL and SDA are high. Else, current would flow through the pullup resistors and minimum power would not be achieved. I am not aware that Vcc must be present for the INT/SQW output to work. I have designed a couple loggers where the MCU wakes via an interrupt generated from a DS3231/2. In these circuits, Vcc power is dropped from the RTC while the MCU sleeps to minimize power consumption. Here is one, hardware, firmware. Here is another, hardware, firmware.

rtek1000 commented 3 years ago

Using a custom circuit, the bus is left at 0V, so the current goes down.

(DS18B20 sensors are used, with 12 bits of resolution, so the microcontroller sleeps during the sensor conversion time.

The RTC is only read every one minute, so the RTC remains at rest the rest of the time, saving energy.)

Perform the test, leave the bus with pull-up resistors powered by the microcontroller, as described in the datasheet.

JChristensen commented 3 years ago

I guess I'm not understanding, so I have nothing else to add. Good luck with your project.

rtek1000 commented 3 years ago

Interesting choice of regulator. I noticed that your circuits use the MCP1640 regulator, step up.

I used the MCP1700 regulator, microcontroller with 3.3V power supply, and direct battery voltage (3.7V-4.2V) instead of 5V. But I had to use 5V for the USB ports, so I used an MT3608.

Thank you.