user53837: i am trying to make a stop watch with a stop/start button and a reset button
i have made this
#include "RTClib.h"
//Setup the Real Time Clock, DS3231
RTC_DS3231 rtc;

const byte SQWinput = 2;  // Must be External Interrupt

volatile uint32_t  MillisecondsAtStartOfSecond = 0;
 
 unsigned long secondss=0 ;
 unsigned long minutess=0 ;
 
 unsigned long  hourss =0;
 unsigned long ms;

boolean passed_second=true;
boolean start=true;


const byte ledPin = 13;

const byte startButton = 7;


const byte resetButton = 3;
// Instantiate another Bounce object


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

// The SQW pin, when set to 1 Hz mode, has a falling edge at the beginning of every second.
void SQWFallingISR()
{
  MillisecondsAtStartOfSecond = millis();
}

void setup ()
{
  Serial.begin(9600); // Set Serial Monitor to 115200
  delay(200);

  pinMode(7, INPUT);
  digitalWrite(7, HIGH);
  pinMode(3, INPUT);
  digitalWrite(3, HIGH);
 


  
  if (! rtc.begin())
  {
    Serial.println("Couldn't find RTC");
    Serial.flush();
    abort();
  }

  if (rtc.lostPower())
  {
    Serial.println("RTC lost power, let's set the time!");
    // When time needs to be set on a new device, or after a power loss, the
    // 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(2022, 4, 03, 21, 14, 0));
  }

  // Configure SQW pin on the DS3231 to output a 1Hz squarewave 
  rtc.writeSqwPinMode(DS3231_SquareWave1Hz);

  // Get MillisecondsAtStartOfSecond on the falling edge of SQW.
  attachInterrupt(digitalPinToInterrupt(SQWinput), SQWFallingISR, FALLING);
}



void loop ()
{
  DateTime now = rtc.now();


    ms = millis();
 
  noInterrupts();
  // How long since the second started?
  
 
  ms -= MillisecondsAtStartOfSecond;
  interrupts();

  if(digitalRead(7) != HIGH)   //START BUTTON
{    displayTime (now, ms);
     Serial.println("stopwatch  ");
  
  Serial.print(hourss);
  Serial.print(':');
  Serial.print(minutess);
  Serial.print(':');
  Serial.print(secondss);
  Serial.print(':');
  Serial.println(ms);
}

 if(digitalRead(3) != HIGH)   //RESET BUTTON
{
     Serial.println("stopwatch  ");
  
  Serial.print(0);
  Serial.print(':');
  Serial.print(0);
  Serial.print(':');
  Serial.print(0);
  Serial.print(':');
  Serial.println(0);
  ms=0;
}
 // displayTime (now, ms);
  /*Serial.println("stopwatch  ");
  
  Serial.print(hourss);
  Serial.print(':');
  Serial.print(minutess);
  Serial.print(':');
  Serial.print(secondss);
  Serial.print(':');
  Serial.println(ms);
  Serial.println("*********************************");
  Serial.println("Clock & Date  ");*/
   

  }

void displayTime(DateTime &now, unsigned long ms)
{
  ms = ms % 1000;  // Ignore full seconds
  
  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(':');
  if (now.minute() < 10)
    Serial.print('0');
  Serial.print(now.minute(), DEC);
  Serial.print(':');
  if (now.second() < 10)
    Serial.print('0');
  Serial.print(now.second(), DEC);
 // Serial.println();
  Serial.print(':');
  if (ms < 100)
    Serial.print('0');
  if (ms < 10)
    Serial.print('0');
  Serial.print(ms, DEC);
  Serial.println();
  Serial.println("*********************************");

  if(ms>998) {
      secondss++;
     
  }
    if(secondss>59) {
     secondss=0;
      minutess++;
 
    }
    if(minutess>59) {
     minutess=0;
      hourss++;}

    }

but it is not working properly
the time is not incrementing after ms reaches 999
what is causing this?

user7508: This code is quite confusing, as you are using both millis() and an
RTC as time sources.
Your problem may come from here:
ms -= MillisecondsAtStartOfSecond;

If the internal clock of your Arduino is a bit off, it may happen that
an RTC second is only 999 milliseconds from millis(). If that happens,
then ms will never hit 999, and will instead go straight from 998
to 0.
Or maybe it's here:
ms = ms % 1000;  // Ignore full seconds
// ...
if (ms > 998) {
    secondss++;
}

If you sketch is busy (maybe it is communicating with the RTC), it may
not run this code precisely at millisecond 999. And 999 is the only
value of ms that can possibly increment secondss.
For a stopwatch, you don't really need the RTC data. You can implement
it entirely on the basis of millis(), and that would simplify things:
bool stop_watch_running;
uint32_t stop_watch_last_update;
uint16_t stop_watch_ms;
uint8_t stop_watch_s;
uint8_t stop_watch_min;
uint8_t stop_watch_h;

void stop_watch_reset() {
    stop_watch_running = false;
    stop_watch_ms = 0;
    stop_watch_s = 0;
    stop_watch_min = 0;
    stop_watch_h = 0;
}

void stop_watch_start() {
    stop_watch_last_update = millis();
    stop_watch_running = true;
}

// Call this periodically.
void stop_watch_update() {
    if (!stop_watch_running)
        return;
    uint32_t now = millis();
    stop_watch_ms += now - stop_watch_last_update;
    stop_watch_last_update = now;
    while (stop_watch_ms >= 1000) {
        stop_watch_ms -= 1000;
        stop_watch_s++;
        if (stop_watch_s >= 60) {
            stop_watch_s = 0;
            stop_watch_min++;
            if (stop_watch_min >= 60) {
                stop_watch_min = 0;
                stop_watch_h++;
            }
        }
    }
}

void stop_watch_stop() {
    stop_watch_update();
    stop_watch_running = false;
}

If you know a bit about C++ classes, you may want to turn this into a
class, and replace the stop_watch_ prefix with StopWatch::.

53837: <p>i am trying to make a stop watch with a stop/start button and a reset button</p>
<p>i have made this</p>
<pre><code>#include &quot;RTClib.h&quot;
//Setup the Real Time Clock, DS3231
RTC_DS3231 rtc;

const byte SQWinput = 2;  // Must be External Interrupt

volatile uint32_t  MillisecondsAtStartOfSecond = 0;
 
 unsigned long secondss=0 ;
 unsigned long minutess=0 ;
 
 unsigned long  hourss =0;
 unsigned long ms;

boolean passed_second=true;
boolean start=true;


const byte ledPin = 13;

const byte startButton = 7;


const byte resetButton = 3;
// Instantiate another Bounce object


const char daysOfTheWeek[7][12] = {&quot;Sunday&quot;, &quot;Monday&quot;, &quot;Tuesday&quot;, &quot;Wednesday&quot;, &quot;Thursday&quot;, &quot;Friday&quot;, &quot;Saturday&quot;};

// The SQW pin, when set to 1 Hz mode, has a falling edge at the beginning of every second.
void SQWFallingISR()
{
  MillisecondsAtStartOfSecond = millis();
}

void setup ()
{
  Serial.begin(9600); // Set Serial Monitor to 115200
  delay(200);

  pinMode(7, INPUT);
  digitalWrite(7, HIGH);
  pinMode(3, INPUT);
  digitalWrite(3, HIGH);
 


  
  if (! rtc.begin())
  {
    Serial.println(&quot;Couldn't find RTC&quot;);
    Serial.flush();
    abort();
  }

  if (rtc.lostPower())
  {
    Serial.println(&quot;RTC lost power, let's set the time!&quot;);
    // When time needs to be set on a new device, or after a power loss, the
    // following line sets the RTC to the date &amp; time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date &amp; time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2022, 4, 03, 21, 14, 0));
  }

  // Configure SQW pin on the DS3231 to output a 1Hz squarewave 
  rtc.writeSqwPinMode(DS3231_SquareWave1Hz);

  // Get MillisecondsAtStartOfSecond on the falling edge of SQW.
  attachInterrupt(digitalPinToInterrupt(SQWinput), SQWFallingISR, FALLING);
}



void loop ()
{
  DateTime now = rtc.now();


    ms = millis();
 
  noInterrupts();
  // How long since the second started?
  
 
  ms -= MillisecondsAtStartOfSecond;
  interrupts();

  if(digitalRead(7) != HIGH)   //START BUTTON
{    displayTime (now, ms);
     Serial.println(&quot;stopwatch  &quot;);
  
  Serial.print(hourss);
  Serial.print(':');
  Serial.print(minutess);
  Serial.print(':');
  Serial.print(secondss);
  Serial.print(':');
  Serial.println(ms);
}

 if(digitalRead(3) != HIGH)   //RESET BUTTON
{
     Serial.println(&quot;stopwatch  &quot;);
  
  Serial.print(0);
  Serial.print(':');
  Serial.print(0);
  Serial.print(':');
  Serial.print(0);
  Serial.print(':');
  Serial.println(0);
  ms=0;
}
 // displayTime (now, ms);
  /*Serial.println(&quot;stopwatch  &quot;);
  
  Serial.print(hourss);
  Serial.print(':');
  Serial.print(minutess);
  Serial.print(':');
  Serial.print(secondss);
  Serial.print(':');
  Serial.println(ms);
  Serial.println(&quot;*********************************&quot;);
  Serial.println(&quot;Clock &amp; Date  &quot;);*/
   

  }

void displayTime(DateTime &amp;now, unsigned long ms)
{
  ms = ms % 1000;  // Ignore full seconds
  
  Serial.print(now.year(), DEC);
  Serial.print('/');
  Serial.print(now.month(), DEC);
  Serial.print('/');
  Serial.print(now.day(), DEC);
  Serial.print(&quot; (&quot;);
  Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
  Serial.print(&quot;) &quot;);
  Serial.print(now.hour(), DEC);
  Serial.print(':');
  if (now.minute() &lt; 10)
    Serial.print('0');
  Serial.print(now.minute(), DEC);
  Serial.print(':');
  if (now.second() &lt; 10)
    Serial.print('0');
  Serial.print(now.second(), DEC);
 // Serial.println();
  Serial.print(':');
  if (ms &lt; 100)
    Serial.print('0');
  if (ms &lt; 10)
    Serial.print('0');
  Serial.print(ms, DEC);
  Serial.println();
  Serial.println(&quot;*********************************&quot;);

  if(ms&gt;998) {
      secondss++;
     
  }
    if(secondss&gt;59) {
     secondss=0;
      minutess++;
 
    }
    if(minutess&gt;59) {
     minutess=0;
      hourss++;}

    }
</code></pre>
<p>but it is not working properly</p>
<p>the time is not incrementing after ms reaches 999</p>
<p>what is causing this?</p>
 7508: <p>This code is quite confusing, as you are using both <code>millis()</code> and an
RTC as time sources.</p>
<p>Your problem may come from here:</p>
<pre class="lang-cpp prettyprint-override"><code>ms -= MillisecondsAtStartOfSecond;
</code></pre>
<p>If the internal clock of your Arduino is a bit off, it may happen that
an RTC second is only 999 milliseconds from <code>millis()</code>. If that happens,
then <code>ms</code> will never hit 999, and will instead go straight from 998
to 0.</p>
<p>Or maybe it's here:</p>
<pre class="lang-cpp prettyprint-override"><code>ms = ms % 1000;  // Ignore full seconds
// ...
if (ms &gt; 998) {
    secondss++;
}
</code></pre>
<p>If you sketch is busy (maybe it is communicating with the RTC), it may
not run this code precisely at millisecond 999. And 999 is the only
value of <code>ms</code> that can possibly increment <code>secondss</code>.</p>
<p>For a stopwatch, you don't really need the RTC data. You can implement
it entirely on the basis of <code>millis()</code>, and that would simplify things:</p>
<pre class="lang-cpp prettyprint-override"><code>bool stop_watch_running;
uint32_t stop_watch_last_update;
uint16_t stop_watch_ms;
uint8_t stop_watch_s;
uint8_t stop_watch_min;
uint8_t stop_watch_h;

void stop_watch_reset() {
    stop_watch_running = false;
    stop_watch_ms = 0;
    stop_watch_s = 0;
    stop_watch_min = 0;
    stop_watch_h = 0;
}

void stop_watch_start() {
    stop_watch_last_update = millis();
    stop_watch_running = true;
}

// Call this periodically.
void stop_watch_update() {
    if (!stop_watch_running)
        return;
    uint32_t now = millis();
    stop_watch_ms += now - stop_watch_last_update;
    stop_watch_last_update = now;
    while (stop_watch_ms &gt;= 1000) {
        stop_watch_ms -= 1000;
        stop_watch_s++;
        if (stop_watch_s &gt;= 60) {
            stop_watch_s = 0;
            stop_watch_min++;
            if (stop_watch_min &gt;= 60) {
                stop_watch_min = 0;
                stop_watch_h++;
            }
        }
    }
}

void stop_watch_stop() {
    stop_watch_update();
    stop_watch_running = false;
}
</code></pre>
<p>If you know a bit about C++ classes, you may want to turn this into a
class, and replace the <code>stop_watch_</code> prefix with <code>StopWatch::</code>.</p>
