Arduino program freezing if RTC (DS3231) disconnected...?

Hi there,

I am working on a project that uses an RTC module (DS3231) to keep the date and time.

The module works fine, I can set the time and read it with no problems. For the record I am using a Mega Mini (2560 or whatnot) with I2C on pins 20 and 21 I believe.

The issue is that if I disconnect one of the I2C lines (or pull the RTC out of the breadboard for example), then my program just freezes and stops executing further instructions. I did a few searches and couldn't find any information on this issue, so I thought I would post here to see if anyone had any insight on it.

I've tried using both 5V and 3.3V for the RTC, as well as using pullup resistors, and these did not seem to help the issue. Is there a way to do something like a (try: initialize RTC, if failed: just skip all RTC instructions) or something like that? Or a way to safeguard my program if the RTC becomes disconnected?

Any and all thoughts welcome, thanks.

Yes, you can do that (probably).

2 Likes

Please post your sketch or a representative example that shows the problem. Please use code tags as described in https://forum.arduino.cc/t/how-to-get-the-best-out-of-this-forum/679966#posting-code-and-common-code-problems.

Which RTC library are you using?

It's never a good idea to disconnect wires while a board is powered.

  1. If you disconnect SCL or SDA the Mega will not receive ACKs and the I2C library will time out; the RTC library that you use might hang in there as it does not handle those scenarios properly.
  2. If you disconnect one of the power lines (Vcc, GND), you can cause permanent damage to the RTC or the Mega.
1 Like

There is also the possibility to set a timeout for I2C in case that would be the blocking cause.

1 Like

Would it help if you refrained from doing this?

1 Like

Removing wires while the Arduino and associated modules are powered can potentially damage them. As @sterretje pointed out, the system is likely working correctly, but the code may be waiting for a response from a device or component that is no longer connected. Double-check your wiring and ensure all required components are in place.

1 Like

Sure, of course that is reasonable. I am a professional software programmer with quite a few years of experience. My philosophy is that programs and systems should be designed and programmed to operate in as many situations and sets of conditions as possible. This includes the typical set of operating conditions, as well as atypical conditions and even ones that could be hazardous to equipment. In my line of work we have to plan for these things and minimize any damage that could come from unanticipated sets of conditions in the field.

In my case, if a wire gets unplugged then the rest of the program shouldn't just seize up and stop running. That would be incredibly sloppy programming in my opinion, even though I don't foresee any wires becoming unplugged during operation. There should at a minimum be error-checking included so that if any device who becomes absent would freeze the program, then all further instructions to and from that device will be ignored and replaced with some contingency code to mitigate these errors.

I tend to be a bit more 'paranoid' than many of my coworkers, and actually this has propelled me to the top of my department, because I build systems that work under all (or as many) conditions as possible. I understand that unplugging a wire is not typical (or recommended) operation of the modules, but I still want to account for that one way or another.

Hi all, here is a code sample that would cause the issue (unplugging at exactly 3:42 pm).

//
//  RTC freeze demo (DS3231)
//

#include <DS3231.h>     // initialize RTC
#include <Wire.h>

DS3231 rtc(SDA, SCL);   // (RTC) Define object

Time rtc_time;    // (RTC) Define date/time structure for RTC

void setup() 
{
Serial.begin(9600);

rtc.begin();      // Initialize the rtc object

rtc.setTime(15, 41, 45);
rtc.setDate(24, 11, 2024);

Serial.print(" rtc_time: ");
Serial.println(rtc.getTimeStr(FORMAT_LONG));
}

String rtc_time_str;  // using RTC time only

void loop() 
{
Serial.println(" --> top of loop()");

rtc_time_str = rtc.getTimeStr(FORMAT_LONG);

Serial.println("The current time is " + rtc_time_str);
Serial.println(" I will unplug an i2c line at 3:42p (15:42:00)");

delay(1000);
}

Here is a snippet from the Serial Monitor window. The program indeed froze at 3:42pm, when I unplugged the module SDA and SCL lines. Is there a way to error-trap and choose to skip all further instructions to/from this device in such a case? Thanks.

--> top of loop()
The current time is 15:41:57
I will unplug an i2c line at 3:42p (15:42:00)
--> top of loop()
The current time is 15:41:58
I will unplug an i2c line at 3:42p (15:42:00)
--> top of loop()
The current time is 15:41:59
I will unplug an i2c line at 3:42p (15:42:00)
--> top of loop()
The current time is 15:42:00
I will unplug an i2c line at 3:42p (15:42:00)
--> top of loop()

Please keep in mind Arduinos are designed for experimentation and learning, often used with breadboards and loose wires, which can become unreliable if vibrated. They are not built for harsh, dirty, or electrically noisy environments commonly found in industrial, automotive, or other commercial applications, making them unsuitable for such settings.

To ensure we can provide the most accurate assistance, please include detailed information about your setup. Specify the exact board, shield, wiring configuration, and power sources you are using. An annotated schematic is ideal, as it provides a clear overview of your setup, but be sure to also include links to the technical specifications of your hardware components. Can you post a clear photograph of your setup?

1 Like

I appreciate you backing me up on the "Arduinos are for experimentation and learning, and not for industrial environments etc." That is much appreciated.

When you ask for a circuit diagram, I don't see why that should be necessary. Let's assume that my 4-pin I2C module is hooked up correctly (as I can guarantee it is, since we see valid communication reading the date and time from the RTC). To me, that should rule out any wiring issues.

The issue seems to be around the I2C instructions / requests which cause the Arduino program to just freeze and not execute any further instructions. Assuming that my circuit is hooked up correctly (which it is), is there any advice you can offer me on bypassing instructions on an errant module?

There have been some good replies on bypassing the I2C instructions in cases where it is needed. For that I am very thankful. As far as posting Fritzing or other diagrams of my circuits, I really don't think it is needed as my issue pertains to something else entirely.

Thanks!

Since you’re a professional programmer and hardware expert, we’ll assume everything is wired correctly, with the appropriate pull-up resistors, and that the RTC module, with the correct battery, is the only module connected to the UNO.

Following your philosophy, instead of using the Wire library, you might consider writing your own "safe" version. This version would account for hardware failures, including issues in the communication channel, to prevent lockups. Implementing error handling and recovery mechanisms in your custom library would help ensure robustness in the event of unexpected hardware behavior.

1 Like

Thanks for your reply. All I meant by that was, when somebody who replied (Nick_Pyner) said something like "well how about if you didn't disconnect it?", that I am not a complete idiot and might have experience beyond random unplugging of wires, since I was asking about a specific project that I have been encountering an issue on.

If needed I could do all the research and hard work to write my own library in this case. Honestly, I'm sure that I won't be doing that. I was just hoping that if this issue, I2C devices needing to be constantly connected and any deviation of that causing failure of the core program, I thought that some mitigation strategies might be available given the experiences of the many users of this forum.

I appreciate all the input I have received based on this topic, and since I am only one flawed human being in this instance, I will be happy to do my best to find the best solution available given the requirements and the constraints of this project.

Thank you to everybody who has replied in good faith. If / when I get the system working as desired, I will be more than happy to post a video showing its intended operation.

Thanks again,

C

@slick_willy

Have you tried Wire.setWireTimeout() as I proposed a few days ago?

1 Like

I haven't yet, but I will. Should have some time in the next few days to try it out.

Also I have multiple light sensors (VEML 7700) with fixed I2C addresses, so I'll be using an I2C multiplexer for those. Should be fun.

I'll report back the results, thanks