DS3231 RTC - EXTREMELY slow readout

Hello guys,

I have a really strange issue with a DS3231 RTC clock (probably the famous ZS-042) connected to an Arduino Leonardo. After experimenting with some libraries I finally got the unit to work, I can set and read the time out of it. However I quickly noticed that the program started to randomly lag. I loaded the example shipped with the library and it produced the same symptom. As a test I added the below:

before = millis();
DateTime now = rtc.now();
Serial.print("Time it took: ");
Serial.println(millis()-before);

And the results were shocking... jumping between 1 ms and 16000 ms! I can't even make a clock this way, as it's possible that it refreshes the clock every 16 seconds...

RTC is connected to the Leonardo's hardware SCL and SDA pins, VCC is 5V. Laonardo was powered from USB and an external 9V battery, also tried to remove or insert the CR2032 from the RTC. Checked with 3 different RTC libraries, even with the "native" wire method. No luck.

Any ideas? The RTC could be faulty, or...?

Cheers!

Do you have a UNO or any other arduino to test with? Just to eliminate issue with your Leonardo?

Do you have one program with just the 4 lines above and simple setup (serial and RTC)?

Post the whole code and say where you got the library.
You've shown only that the 'now()' method of the library you found takes some time to return.

Hello,

At the moment I'm using Adafruit's library, available here: GitHub - adafruit/RTClib: A fork of Jeelab's fantastic RTC Arduino library. The source code is the example of DS3231 included in the library:

// Date and time functions using a DS3231 RTC connected via I2C and Wire lib
#include <Wire.h>
#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.println();
    delay(3000);
}

The tutorial at Tutorial – Using DS1307 and DS3231 Real-time Clock Modules with Arduino | tronixstuff.com - using the simple Wire library - is producing the same symptoms at the function readDS3231time.

The original source what I was experimenting with is:

#include <SPI.h>
#include <PCD8544_SPI.h>
#include <Wire.h>
#include <RTClib.h>

PCD8544_SPI_FB lcd;
RTC_DS3231 rtc;

int PIRPin = 2;

void setup() {
  lcd.begin(false, 0xBF, 0x04, 0x14);
  lcd.begin();
  pinMode(PIRPin,INPUT);
  rtc.begin();
  if (rtc.lostPower()) {
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }
}

void loop() {
  DateTime now = rtc.now();
  lcd.clear();
  if (digitalRead(PIRPin) == HIGH) {
    lcd.gotoXY(0,0);
    lcd.print("I can see you!");
  } else {
    lcd.gotoXY(0,0);
    lcd.print("Now you are");
    lcd.gotoXY(0,1);
    lcd.print(" hidden :(");
  }
  lcd.gotoXY(0,2);
  lcd.print(String(now.year())+"."+String(now.month())+"."+String(now.day()));
  lcd.gotoXY(0,3);
  lcd.print(String(now.hour())+":"+String(now.minute())+":"+String(now.second()));
  lcd.renderAll();
  delay(1000);
}

P.s.: Unfortunately I have no other Arduino boards to test with, however nothing else seemed to cause these delays until now.

which version of the IDE do you have?

Sorry, completely forgot to mention that :o 1.6.9

I do not see where either of those programs measures the time that it takes to get the time.

aehimself:
Sorry, completely forgot to mention that :o 1.6.9

get the latest just for the sake of it as well as the library.

can you try out that code? (Serial at 115200 in the console)

// import adafruit RTCLib library
#include "RTClib.h" // https://github.com/adafruit/RTClib 
RTC_DS3231 rtc;

void setup() {
  Serial.begin(115200);
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1); // can't go further
  }
}

void loop() {
  static DateTime now;
  unsigned long startMicros;

  startMicros = micros();
  now = rtc.now();
  Serial.println(micros() - startMicros);
  delay(1000);
}

On a Mega and with a RTC_DS3231 it gives me 1048 to 1052 micro seconds to execute (with the 4 micro sec precision of micro)

Okay, I made a huge step forward. The code above produced the expected results:

1048
1052
4228828
1052
2644796
1052
4378928
1052
3105952
1052
1048
1052
3522844
1048

...until I decided to unplug the PIR sensors signal wire from Digital Port 2... Since then I am receiving the desired results, only between 1048 to 1060!

I started to think about interrupts, and https://www.arduino.cc/en/Main/ArduinoBoardLeonardo actually confirms that there is an interrupt available on Digital Port 2. Is it possible that it is working without calling AttachInterrupt? :o I was planning to use all digital inputs in my project, it would be really bad news for me :frowning:

It looks like you're just wasting processor cycles printing to the LCD all the time that pin 2 is HIGH (or LOW)
Stop doing that, and see how things pick up.

It seems I managed to find the answer. Nothing is faulty, but the issue is connected with the DS3231... well, the way it is connected.

On Arduino Leonardo, I do have separate SCL and SDA pins (which the RTC is using) but they are still "hardwired"... to digital pins 2 and 3, according to http://www.instructables.com/id/Step-by-Step-Guide-to-the-Arduino-Leonardo/step4/SDASCL-Pins-are-Different. I moved the PIR sensor to digital pin 4 and everything started to work like a charm.

The delay was caused because the PIR sensor forced the signal to HIGH on SDA and the RTC was unable to talk.

Good news - issue is solved! Bad news - I lost 4 of the 14 digital pins already :frowning:

Good - indeed would have been nice to know about the other stuff connected to the arduino...

we could have hinted at this..

Bad news - I lost 4 of the 14 digital pins already

The analog pins can also be used as digital pins.