DS3231 Time on Serial Monitor skips 00 when 59 sec arrives -- why?

1. I am preparing a tutorial on DS3231 RTC Module (Fig-1); where, time of the day is being shown on the Serial Monitor at 1-sec interval as a test purpose. The 1-sec time delay interval has been implemented using DS3231's own time.

4digitDS3231.png
Figure-1:

2. The problem is with the display of "second" on the Serial Monitor (Fig-2); where, the display does not go through 00 when 59 sec arrives. The time is being shown as (for example) 12:00:59 (2-sec delay) 12:01:01 instead of 12:00:59 ---> 12:01:00 ---> 12:01:01.

SMds3231.png
Figure-2:

3. The Sketch

#include <Wire.h>
#include "RTClib.h"
byte prSec = 0;
RTC_DS3231 rtc;

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

void setup ()
{
  Serial.begin(9600);
  rtc.begin();
  // rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  rtc.adjust(DateTime(2021, 12, 31, 11, 59, 57));//set date-time manualy:yr,mo,dy,hr,mn,sec
}

void loop ()
{
  showTime();
  timeDelay();
}

//===================================================
void showTime()
{
  DateTime nowDT = rtc.now();
  Serial.print(nowDT.hour(), DEC); Serial.print(':');
  //-------------------------------------------------
  byte myMin = nowDT.minute();
  if (myMin < 10)
  {
    Serial.print('0');
  }
  Serial.print(nowDT.minute(), DEC); Serial.print(':');
  //--------------------------------------------------
  byte mySec = nowDT.second();
  if (mySec < 10)
  {
    Serial.print('0');
  }
  Serial.println(nowDT.second(), DEC);
}
//---------------------------------------------
void timeDelay()
{
  prSec = bcdSecond();   //current second of RTC
  while (bcdSecond() - prSec != 1)
  {
    ;
  }
  prSec = bcdSecond(); //delay(1000);
}

byte bcdSecond()
{
  DateTime nowTime = rtc.now();
  if (nowTime.second() == 0 )
  {
    prSec = 0;
    return prSec;
  }
  else
  {
    DateTime nowTime = rtc.now();
    return nowTime.second();
  }
}
//==========================================

Any help would be highly appreciated.

SMds3231.png

4digitDS3231.png

While I look for the library you are using and an RTC, would it please you to try the scatch you posted with the following change of your Serial.begin(9600)?

Serial.begin(115200);

Be sure to adjust the baud rate in the Serial Monitor window. :wink:

TIA.

a7

 byte mySec = nowDT.second();
  if (mySec < 10)
  {
    Serial.print('0');
  }
  Serial.println(nowDT.second(), DEC);

Why are you calling nowDT.second() again when you already have the value of the second in mySec ?

@alto777

Changing Bd to 115200 did not help! Anyway, thanks for the interest in solving my problem.

smds.png

smds.png

UKHeliBob:

 byte mySec = nowDT.second();

if (mySec < 10)
 {
   Serial.print('0');
 }
 Serial.println(nowDT.second(), DEC);



Why are you calling nowDT.second() again when you already have the value of the second in mySec ?

I have changed the referred line to the following; but, the problem is still there.

Serial.println(mySec); //(nowDT.second(), DEC);

dsew.png

Any direction towards which my codes should be oriented?

dsew.png

Never mind.

I changed one function which was like really weird, so here's

byte bcdSecond()
{
  DateTime nowTime = rtc.now();
     return nowTime.second();
}

What did I break by throwing out all your logic?

I also changed how you waste most of a second to a way I saw some where else, viz:

 while (bcdSecond() == prSec)
  {
    ;
  }

This also may have broken something else you were trying to avoid or accomplish. You had

 while (bcdSecond() == prSec != 1)
  {
    ;
  }

Which did not scan. That is to say I did not immediately see the point.

HTH

a7

Any direction towards which my codes should be oriented?

 byte mySec = nowDT.second();
  if (mySec < 10)
  {
    Serial.print('0');
  }
  Serial.println(mySec);

@UKHeliBob

I have changed the line to the following; but, the problem is still there.

Serial.println(mySec);

dsew.png

dsew.png

@alto777

I am studying your codes of Post#5 with devotion and will let you know the result tomorrow inshallah. Now, it is 2:50 am (after mid night) in my country. I am nearly an old man and need to go to bed.

Thank you very much.

“ I am nearly an old man and need to go to bed.”

There is no nearly.

The DateTime class has functions that return contents of a structure filled by the (one) call to etc.now();

I also thought it looked fishy. Or was there something else I still miss?

Edit: never mind, I see. He could drop the local variable he further uses and always call the function, or always use the value he gets from one call. In either event, the value will not be different if the DateTime is not changed.

a7

Old is the new young.

a7

The problem is in timeDelay().

I haven't gone through it in detail, but is you just have delay(1000) inside that function the print out shows the 00 second.

The problem is this line:

  while (bcdSecond() - prSec != 1)

When prSec is 59 and bcdSecond() is 59, 59-59 is not equal to 1 so the loop repeats.
When bcdSecond() rolls over to 0 it sets prSec to 0.
Now prSec is 00 and bcdSecond() is 00, 00-00 is not equal to 1 so the loop repeats.
Eventually, bcdSecond() rolls over to 1.
Now prSec is 00 and bcdSecond() is 01, 01-00 is equal to 1 so the loop finally stops.

You can fix it by changing it to:

  while (bcdSecond() == prSec)

And be sure to remove the setting of prSec out to bcdSecond, otherwise, it will continue to skip second 00.

#include <Wire.h>
#include "RTClib.h"


RTC_DS3231 rtc;


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


void setup ()
{
  Serial.begin(9600);
  rtc.begin();
  // rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  rtc.adjust(DateTime(2021, 12, 31, 11, 59, 57));//set date-time manualy:yr,mo,dy,hr,mn,sec
}


void loop ()
{
  showTime();
  timeDelay();
}


//===================================================
void showTime()
{
  DateTime nowDT = rtc.now();
  Serial.print(nowDT.hour(), DEC);
  Serial.print(':');
  //-------------------------------------------------
  byte myMin = nowDT.minute();
  if (myMin < 10)
  {
    Serial.print('0');
  }
  Serial.print(nowDT.minute(), DEC); 
  Serial.print(':');
  //--------------------------------------------------
  byte mySec = nowDT.second();
  if (mySec < 10)
  {
    Serial.print('0');
  }
  Serial.println(nowDT.second(), DEC);
}


//---------------------------------------------
void timeDelay()
{
  byte prSec = bcdSecond();   //current second of RTC
  while (bcdSecond() == prSec) {}
}


byte bcdSecond()
{
  DateTime nowTime = rtc.now();
  return nowTime.second();
}
//==========================================

@ alto777

As per your Post#5, I have modified/included the following line at the relevant place of my sketch. The new sketch is tested and it works.

while (bcdSecond() == prSec)   //in place of while (bcdSecond() - prSec !=1){;} 
{
    ;
}

Bravo!! :slight_smile:

@johnwasser

So much gratitude for reposting the complete sketch (Post#13) with the inclusion of the following modified line along with detailed analysis for such modification. Tested and it works.

while (bcdSecond() == prSec)   //in place of while (bcdSecond() - prSec !=1){;}
{

}

Bravo!! :slight_smile:

I would like to remember Leibnitz and Newton (who independently developed the Calculus) in this context of my DS3231 related problem; where, @alto777 and @johnwasser have also independently developed the same solution to my problem of DS3231 time display.

Thanks and Bravo! ( :slight_smile: ) to you all (@johnwasser, @alto777, @cattledog, @larryd, @UKHeliBob) for your generous interest and participation in the solution of my problem.

Why make it so complicated, especially for a tutorial ?

void loop()
{
  time_t now = rtc.get();
  static time_t past = now;

  if ( now != past )
  {
    past = now;
    showTime();
  }
}

Sixteen posts, and all you want to do is tell the time? how can this be so difficult? Surely Jack Christensen said all that could possibly be said many years ago. I have never heard of this problem, I didn't listen to everything Jack had to say, and I don't even use his libraries, but, if there is a problem, I bet he had the answer. So, what is really going on here?

will this do? https://bildr.org/2011/03/ds1307-arduino/

guix:
Why make it so complicated, especially for a tutorial ?

Different people have different approaches; but, they all lead to the same solution which is of interest for the user.

Something that was very complicated yesterday for a seasoned Scientist, the same thing is so simple today for a student.

This is how science, engineering, and and technology progress.

Nick_Pyner:
[...] I don't even use his libraries, [...]

If it is an engineering project, the engineer can omit the use of Library functions as he is capable enough to write codes of his own to control the device; but, Library functions are proven useful tools for the beginners/trainees.