# DS3231 rtc program cannot run

**URL:** <https://forum.arduino.cc/t/ds3231-rtc-program-cannot-run/1419786>\
**Category:** Programming\
**Created:** [December 15, 2025, 12:49pm UTC](https://forum.arduino.cc/t/ds3231-rtc-program-cannot-run/1419786 "2025-12-15T12:49:39Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![bimosora](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/bimosora/32/1099004_2.png) [@bimosora](https://forum.arduino.cc/u/bimosora)\
**Post date:** [December 15, 2025, 12:49pm UTC](https://forum.arduino.cc/t/ds3231-rtc-program-cannot-run/1419786/1 "2025-12-15T12:49:39Z")

</div>

Previously my rdc ds3231 program was running with this code, I don't know why it suddenly became a problem like this

```arduino
========================================
INITIALIZING DS3231 RTC
========================================
 DS3231 detected!
 RTC has battery backup - time will persist

RTC Current Time: 00:00:00 52/83/2045

 RTC time is valid - using RTC time
   System time set from RTC: 00:00:00 52/83/2045
   Timestamp: -1463725696

========================================
AUTO NTP SYNC STARTED
========================================
Trying NTP server: pool.ntp.org
   Using timezone: UTC+7 (25200 seconds)
NTP Sync successful!
   Server: pool.ntp.org
   Time: 19:39:29 15/12/2025
NTP time saved to RTC
   (RTC overwritten from NTP)

RTC INVALID: Year out of range (2108)
RTC SUSPICIOUS: Time diff too large (1518316001 seconds)
   System: 19:40:25 15/12/2025
   RTC: 45:162:00 51/41/2108
Keeping system time (RTC probably corrupted)
RTC corrupted, resetting to system time...

```

**code**

```arduino
bool initRTC() {
  Serial.println("\n========================================");
  Serial.println("INITIALIZING DS3231 RTC");
  Serial.println("========================================");

  Wire.begin();

  Wire.beginTransmission(0x68);
  Wire.endTransmission();

  if (!rtc.begin(&Wire)) {
    Serial.println(" DS3231 not found!");
    Serial.println(" - SDA -> GPIO21");
    Serial.println(" - SCL -> GPIO22");
    Serial.println(" - VCC -> 3.3V");
    Serial.println(" - GND -> GND");
    Serial.println(" - BATTERY -> CR2032 (optional)");
    Serial.println("\n Running without RTC");
    Serial.println(" Time will reset to 00:00:00 01/01/2000 on power loss");
    Serial.println("========================================\n");

    if (xSemaphoreTake(timeMutex, portMAX_DELAY) == pdTRUE) {
      setTime(0, 0, 0, 1, 1, 2000);
      time_t tempTime = now();

      if (tempTime < 946684800) {
        timeConfig.currentTime = 946684800;
      } else {
        timeConfig.currentTime = tempTime;
      }

      xSemaphoreGive(timeMutex);
    }

    return false;
  }

  Serial.println(" DS3231 detected!");

  if (rtc.lostPower()) {
    Serial.println(" RTC lost power - battery may be dead or missing");
    Serial.println(" Install CR2032 battery for time persistence");
  } else {
    Serial.println(" RTC has battery backup - time will persist");
  }

  DateTime rtcNow = rtc.now();

  Serial.printf("\nRTC Current Time: %02d:%02d:%02d %02d/%02d/%04d\n",
                rtcNow.hour(), rtcNow.minute(), rtcNow.second(),
                rtcNow.day(), rtcNow.month(), rtcNow.year());

  // ================================
  // CHECK IF RTC TIME IS VALID
  // ================================
  if (rtcNow.year() >= 2000 && rtcNow.year() <= 2100) {
    Serial.println("\n RTC time is valid - using RTC time");

    if (xSemaphoreTake(timeMutex, portMAX_DELAY) == pdTRUE) {
      time_t rtcUnix = rtcNow.unixtime();

      setTime(rtcNow.hour(), rtcNow.minute(), rtcNow.second(),
              rtcNow.day(), rtcNow.month(), rtcNow.year());

      timeConfig.currentTime = rtcUnix;

      Serial.printf(" System time set from RTC: %02d:%02d:%02d %02d/%02d/%04d\n",
                    rtcNow.hour(), rtcNow.minute(), rtcNow.second(),
                    rtcNow.day(), rtcNow.month(), rtcNow.year());
      Serial.printf(" Timestamp: %ld\n", timeConfig.currentTime);

      xSemaphoreGive(timeMutex);

      if (displayQueue != NULL) {
        DisplayUpdate update;
        update.type = DisplayUpdate::TIME_UPDATE;
        xQueueSend(displayQueue, &update, 0);
      }
    }
  } else {
    Serial.println("\n RTC time invalid (year out of range)");
    Serial.println(" Resetting to default time: 00:00:00 01/01/2000");

    DateTime defaultTime(2000, 1, 1, 0, 0, 0);
    rtc.adjust(defaultTime);

    if (xSemaphoreTake(timeMutex, portMAX_DELAY) == pdTRUE) {
      setTime(0, 0, 0, 1, 1, 2000);
      time_t tempTime = now();

      if (tempTime < 946684800) {
        timeConfig.currentTime = 946684800;
      } else {
        timeConfig.currentTime = tempTime;
      }

      Serial.println(" System time set to 00:00:00 01/01/2000");
      Serial.printf(" Timestamp: %ld\n", timeConfig.currentTime);
      Serial.println(" RTC will maintain this until NTP sync");

      xSemaphoreGive(timeMutex);

      if (displayQueue != NULL) {
        DisplayUpdate update;
        update.type = DisplayUpdate::TIME_UPDATE;
        xQueueSend(displayQueue, &update, 0);
      }
    }
  }

  Serial.println("========================================\n");
  return true;
}

```

**code**

```arduino
void ntpTask(void *parameter) {
  esp_task_wdt_add(NULL);

  while (true) {
    esp_task_wdt_reset();

    uint32_t notifyValue = ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(30000));

    if (notifyValue == 0) {
      esp_task_wdt_reset();
      continue;
    }

    ntpSyncInProgress = true;
    ntpSyncCompleted = false;

    Serial.println("\n========================================");
    Serial.println("AUTO NTP SYNC STARTED");
    Serial.println("========================================");

    if (xSemaphoreTake(timeMutex, portMAX_DELAY) == pdTRUE) {
      bool syncSuccess = false;
      int serverIndex = 0;

      while (!syncSuccess && serverIndex < NTP_SERVER_COUNT) {
        esp_task_wdt_reset();

        Serial.printf("Trying NTP server: %s\n", ntpServers[serverIndex]);

        timeClient.setPoolServerName(ntpServers[serverIndex]);
        int offsetSeconds = timezoneOffset * 3600;
        timeClient.setTimeOffset(offsetSeconds);
        Serial.printf(" Using timezone: UTC%s%d (%d seconds)\n",
                      timezoneOffset >= 0 ? "+" : "", timezoneOffset, offsetSeconds);
        timeClient.begin();

        unsigned long startTime = millis();
        bool updateResult = false;

        while (millis() - startTime < 5000) {
          updateResult = timeClient.forceUpdate();
          if (updateResult) break;

          esp_task_wdt_reset();
          vTaskDelay(pdMS_TO_TICKS(100));
        }

        if (updateResult) {
          time_t ntpTime = timeClient.getEpochTime();

          timeConfig.currentTime = ntpTime;
          setTime(timeConfig.currentTime);
          timeConfig.ntpSynced = true;
          syncSuccess = true;
          timeConfig.ntpServer = String(ntpServers[serverIndex]);

          Serial.println("NTP Sync successful!");
          Serial.printf(" Server: %s\n", ntpServers[serverIndex]);
          Serial.printf(" Time: %02d:%02d:%02d %02d/%02d/%04d\n",
                        hour(ntpTime), minute(ntpTime), second(ntpTime),
                        day(ntpTime), month(ntpTime), year(ntpTime));

          if (rtcAvailable) {
            DateTime dt(year(ntpTime),
                        month(ntpTime),
                        day(ntpTime),
                        hour(ntpTime),
                        minute(ntpTime),
                        second(ntpTime));

            rtc.adjust(dt);

            Serial.println("NTP time saved to RTC");
            Serial.println(" (RTC overwritten from NTP)");
          }

          DisplayUpdate update;
          update.type = DisplayUpdate::TIME_UPDATE;
          xQueueSend(displayQueue, &update, 0);

          Serial.println("Post-NTP: Checking prayer times...");

          if (prayerConfig.latitude.length() > 0 && prayerConfig.longitude.length() > 0) {

            Serial.println(" City configured: " + prayerConfig.selectedCity);
            Serial.println(" Updating prayer times with correct date...");

            xSemaphoreGive(timeMutex);

            esp_task_wdt_reset();

            getPrayerTimesByCoordinates(
              prayerConfig.latitude,
              prayerConfig.longitude);

            Serial.println("Prayer times updated post-NTP sync");

            xSemaphoreTake(timeMutex, portMAX_DELAY);

          } else {
            Serial.println("No city coordinates - skipping prayer update");
            xSemaphoreGive(timeMutex);
            xSemaphoreTake(timeMutex, portMAX_DELAY);
          }

          Serial.println("========================================\n");
          break;
        }

        serverIndex++;
        esp_task_wdt_reset();
        vTaskDelay(pdMS_TO_TICKS(500));
      }

      if (!syncSuccess) {
        Serial.println("All NTP servers failed!");
        Serial.println(" Keeping current time");
        Serial.println("========================================\n");
      }

      ntpSyncInProgress = false;
      ntpSyncCompleted = syncSuccess;

      xSemaphoreGive(timeMutex);

    } else {
      Serial.println("Failed to acquire time mutex");
      Serial.println("========================================\n");

      ntpSyncInProgress = false;
      ntpSyncCompleted = false;
    }

    esp_task_wdt_reset();
  }
}

```

**code**

```arduino
void rtcSyncTask(void *parameter) {
  TickType_t xLastWakeTime = xTaskGetTickCount();
  const TickType_t xFrequency = pdMS_TO_TICKS(60000); // Every 1 minute

  while (true) {
    if (rtcAvailable) {
      DateTime rtcTime = rtc.now();

      if (xSemaphoreTake(timeMutex, pdMS_TO_TICKS(100)) == pdTRUE) {
        time_t systemTime = timeConfig.currentTime;
        time_t rtcUnix = rtcTime.unixtime();

        // ========================================
        // VALIDASI KETAT
        // ========================================
        bool rtcValid = true;

        if (rtcTime.year() < 2000 || rtcTime.year() > 2100) {
          Serial.println("RTC INVALID: Year out of range (" + String(rtcTime.year()) + ")");
          rtcValid = false;
        }

        long timeDiff = abs(systemTime - rtcUnix);
        if (systemTime >= 946684800 && timeDiff > 3600) {
          Serial.printf("RTC SUSPICIOUS: Time diff too large (%ld seconds)\n", timeDiff);
          Serial.printf(" System: %02d:%02d:%02d %02d/%02d/%04d\n",
                        hour(systemTime), minute(systemTime), second(systemTime),
                        day(systemTime), month(systemTime), year(systemTime));
          Serial.printf(" RTC: %02d:%02d:%02d %02d/%02d/%04d\n",
                        rtcTime.hour(), rtcTime.minute(), rtcTime.second(),
                        rtcTime.day(), rtcTime.month(), rtcTime.year());
          Serial.println("Keeping system time (RTC probably corrupted)");
          rtcValid = false;
        }

        // ========================================
        // Hanya update jika RTC valid DAN selisih kecil
        // ========================================
        if (rtcValid && timeDiff > 2) {
          timeConfig.currentTime = rtcUnix;
          setTime(rtcUnix);

          Serial.println("System time synced from RTC");
          Serial.printf(" RTC: %02d:%02d:%02d %02d/%02d/%04d\n",
                        rtcTime.hour(), rtcTime.minute(), rtcTime.second(),
                        rtcTime.day(), rtcTime.month(), rtcTime.year());

          DisplayUpdate update;
          update.type = DisplayUpdate::TIME_UPDATE;
          xQueueSend(displayQueue, &update, 0);

        } else if (!rtcValid) {
          Serial.println("RTC corrupted, resetting to system time...");

          DateTime fixedTime(
            year(systemTime),
            month(systemTime),
            day(systemTime),
            hour(systemTime),
            minute(systemTime),
            second(systemTime));

          rtc.adjust(fixedTime);
          Serial.println("RTC reset to system time");
        }

        xSemaphoreGive(timeMutex);
      }
    }

    vTaskDelayUntil(&xLastWakeTime, xFrequency);
  }
}

```

---

<div class="post-metadata">

**Author:** ![hammy](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/hammy/32/238813_2.png) [@hammy](https://forum.arduino.cc/u/hammy)\
**Post date:** [December 15, 2025, 7:11pm UTC](https://forum.arduino.cc/t/ds3231-rtc-program-cannot-run/1419786/2 "2025-12-15T19:11:04Z")

</div>

Try running the example code given with the library to set the clock to a current time .  
Then upload your code again .  
Your code doesn’t seem like the time difference between the clock and server times .  
Check your cr2032 battery is ok

---

<div class="post-metadata">

**Author:** ![GolamMostafa](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/golammostafa/32/239011_2.png) [@GolamMostafa](https://forum.arduino.cc/u/GolamMostafa)\
**Post date:** [December 15, 2025, 7:14pm UTC](https://forum.arduino.cc/t/ds3231-rtc-program-cannot-run/1419786/3 "2025-12-15T19:14:18Z")

</div>

Run the following test program and check that RTC3231 is ok.

```arduino
#include <Wire.h>
#include "RTClib.h"
RTC_DS3231 rtc;
DateTime myDT;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
byte lastReadSecond = 0;

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

void loop ()
{
  myDT = rtc.now();
  if (lastReadSecond != myDT.second())//wait 1-sec as long as they are equal = 1s has not gones
  {
    showTime();
  }
}

void showTime()
{
  //update to the new second
  myDT = rtc.now();
  lastReadSecond = myDT.second();
  //------------------------------
  Serial.print(myDT.year(), DEC);
  Serial.print('/');
  //-----------------------------
  Serial.print(myDT.month(), DEC);
  Serial.print('/');
  Serial.print(myDT.day(), DEC);
  Serial.print(" (");
  Serial.print(daysOfTheWeek[myDT.dayOfTheWeek()]);
  Serial.print(") ");
  //-----------------------------
  byte myHour = myDT.hour();
  if (myHour < 10)
  {
    Serial.print('0'); //show leading zero
  }
  Serial.print(myHour, DEC);
  Serial.print(':');
  //-----------------------------
  byte myMin = myDT.minute();
  if (myMin < 10)
  {
    Serial.print('0'); //show leading zero
  }
  Serial.print(myMin, DEC);
  Serial.print(':');
  //--------------------------
  byte mySec = myDT.second();
  if (mySec < 10)
  {
    Serial.print('0'); //show leading zero
  }
  Serial.print(mySec, DEC);
  //----------------------------
  Serial.println();
}

```

---

<div class="post-metadata">

**Author:** ![bimosora](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/bimosora/32/1099004_2.png) [@bimosora](https://forum.arduino.cc/u/bimosora)\
**Post date:** [December 15, 2025, 10:39pm UTC](https://forum.arduino.cc/t/ds3231-rtc-program-cannot-run/1419786/4 "2025-12-15T22:39:01Z")

</div>

Previously my rdc ds3231 program was running with this code, I don't know why it suddenly became a problem like this

```arduino
========================================
INITIALIZING DS3231 RTC
========================================
 DS3231 detected!
 RTC has battery backup - time will persist

RTC Current Time: 00:00:00 52/83/2045

 RTC time is valid - using RTC time
   System time set from RTC: 00:00:00 52/83/2045
   Timestamp: -1463725696

========================================
AUTO NTP SYNC STARTED
========================================
Trying NTP server: pool.ntp.org
   Using timezone: UTC+7 (25200 seconds)
NTP Sync successful!
   Server: pool.ntp.org
   Time: 19:39:29 15/12/2025
NTP time saved to RTC
   (RTC overwritten from NTP)

RTC INVALID: Year out of range (2108)
RTC SUSPICIOUS: Time diff too large (1518316001 seconds)
   System: 19:40:25 15/12/2025
   RTC: 45:162:00 51/41/2108
Keeping system time (RTC probably corrupted)
RTC corrupted, resetting to system time...

```

**code**

```arduino
bool initRTC() {
  Serial.println("\n========================================");
  Serial.println("INITIALIZING DS3231 RTC");
  Serial.println("========================================");

  Wire.begin();

  Wire.beginTransmission(0x68);
  Wire.endTransmission();

  if (!rtc.begin(&Wire)) {
    Serial.println(" DS3231 not found!");
    Serial.println(" - SDA -> GPIO21");
    Serial.println(" - SCL -> GPIO22");
    Serial.println(" - VCC -> 3.3V");
    Serial.println(" - GND -> GND");
    Serial.println(" - BATTERY -> CR2032 (optional)");
    Serial.println("\n Running without RTC");
    Serial.println(" Time will reset to 00:00:00 01/01/2000 on power loss");
    Serial.println("========================================\n");

    if (xSemaphoreTake(timeMutex, portMAX_DELAY) == pdTRUE) {
      setTime(0, 0, 0, 1, 1, 2000);
      time_t tempTime = now();

      if (tempTime < 946684800) {
        timeConfig.currentTime = 946684800;
      } else {
        timeConfig.currentTime = tempTime;
      }

      xSemaphoreGive(timeMutex);
    }

    return false;
  }

  Serial.println(" DS3231 detected!");

  if (rtc.lostPower()) {
    Serial.println(" RTC lost power - battery may be dead or missing");
    Serial.println(" Install CR2032 battery for time persistence");
  } else {
    Serial.println(" RTC has battery backup - time will persist");
  }

  DateTime rtcNow = rtc.now();

  Serial.printf("\nRTC Current Time: %02d:%02d:%02d %02d/%02d/%04d\n",
                rtcNow.hour(), rtcNow.minute(), rtcNow.second(),
                rtcNow.day(), rtcNow.month(), rtcNow.year());

  // ================================
  // CHECK IF RTC TIME IS VALID
  // ================================
  if (rtcNow.year() >= 2000 && rtcNow.year() <= 2100) {
    Serial.println("\n RTC time is valid - using RTC time");

    if (xSemaphoreTake(timeMutex, portMAX_DELAY) == pdTRUE) {
      time_t rtcUnix = rtcNow.unixtime();

      setTime(rtcNow.hour(), rtcNow.minute(), rtcNow.second(),
              rtcNow.day(), rtcNow.month(), rtcNow.year());

      timeConfig.currentTime = rtcUnix;

      Serial.printf(" System time set from RTC: %02d:%02d:%02d %02d/%02d/%04d\n",
                    rtcNow.hour(), rtcNow.minute(), rtcNow.second(),
                    rtcNow.day(), rtcNow.month(), rtcNow.year());
      Serial.printf(" Timestamp: %ld\n", timeConfig.currentTime);

      xSemaphoreGive(timeMutex);

      if (displayQueue != NULL) {
        DisplayUpdate update;
        update.type = DisplayUpdate::TIME_UPDATE;
        xQueueSend(displayQueue, &update, 0);
      }
    }
  } else {
    Serial.println("\n RTC time invalid (year out of range)");
    Serial.println(" Resetting to default time: 00:00:00 01/01/2000");

    DateTime defaultTime(2000, 1, 1, 0, 0, 0);
    rtc.adjust(defaultTime);

    if (xSemaphoreTake(timeMutex, portMAX_DELAY) == pdTRUE) {
      setTime(0, 0, 0, 1, 1, 2000);
      time_t tempTime = now();

      if (tempTime < 946684800) {
        timeConfig.currentTime = 946684800;
      } else {
        timeConfig.currentTime = tempTime;
      }

      Serial.println(" System time set to 00:00:00 01/01/2000");
      Serial.printf(" Timestamp: %ld\n", timeConfig.currentTime);
      Serial.println(" RTC will maintain this until NTP sync");

      xSemaphoreGive(timeMutex);

      if (displayQueue != NULL) {
        DisplayUpdate update;
        update.type = DisplayUpdate::TIME_UPDATE;
        xQueueSend(displayQueue, &update, 0);
      }
    }
  }

  Serial.println("========================================\n");
  return true;
}

```

**code**

```arduino
void ntpTask(void *parameter) {
  esp_task_wdt_add(NULL);

  while (true) {
    esp_task_wdt_reset();

    uint32_t notifyValue = ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(30000));

    if (notifyValue == 0) {
      esp_task_wdt_reset();
      continue;
    }

    ntpSyncInProgress = true;
    ntpSyncCompleted = false;

    Serial.println("\n========================================");
    Serial.println("AUTO NTP SYNC STARTED");
    Serial.println("========================================");

    if (xSemaphoreTake(timeMutex, portMAX_DELAY) == pdTRUE) {
      bool syncSuccess = false;
      int serverIndex = 0;

      while (!syncSuccess && serverIndex < NTP_SERVER_COUNT) {
        esp_task_wdt_reset();

        Serial.printf("Trying NTP server: %s\n", ntpServers[serverIndex]);

        timeClient.setPoolServerName(ntpServers[serverIndex]);
        int offsetSeconds = timezoneOffset * 3600;
        timeClient.setTimeOffset(offsetSeconds);
        Serial.printf(" Using timezone: UTC%s%d (%d seconds)\n",
                      timezoneOffset >= 0 ? "+" : "", timezoneOffset, offsetSeconds);
        timeClient.begin();

        unsigned long startTime = millis();
        bool updateResult = false;

        while (millis() - startTime < 5000) {
          updateResult = timeClient.forceUpdate();
          if (updateResult) break;

          esp_task_wdt_reset();
          vTaskDelay(pdMS_TO_TICKS(100));
        }

        if (updateResult) {
          time_t ntpTime = timeClient.getEpochTime();

          timeConfig.currentTime = ntpTime;
          setTime(timeConfig.currentTime);
          timeConfig.ntpSynced = true;
          syncSuccess = true;
          timeConfig.ntpServer = String(ntpServers[serverIndex]);

          Serial.println("NTP Sync successful!");
          Serial.printf(" Server: %s\n", ntpServers[serverIndex]);
          Serial.printf(" Time: %02d:%02d:%02d %02d/%02d/%04d\n",
                        hour(ntpTime), minute(ntpTime), second(ntpTime),
                        day(ntpTime), month(ntpTime), year(ntpTime));

          if (rtcAvailable) {
            DateTime dt(year(ntpTime),
                        month(ntpTime),
                        day(ntpTime),
                        hour(ntpTime),
                        minute(ntpTime),
                        second(ntpTime));

            rtc.adjust(dt);

            Serial.println("NTP time saved to RTC");
            Serial.println(" (RTC overwritten from NTP)");
          }

          DisplayUpdate update;
          update.type = DisplayUpdate::TIME_UPDATE;
          xQueueSend(displayQueue, &update, 0);

          Serial.println("Post-NTP: Checking prayer times...");

          if (prayerConfig.latitude.length() > 0 && prayerConfig.longitude.length() > 0) {

            Serial.println(" City configured: " + prayerConfig.selectedCity);
            Serial.println(" Updating prayer times with correct date...");

            xSemaphoreGive(timeMutex);

            esp_task_wdt_reset();

            getPrayerTimesByCoordinates(
              prayerConfig.latitude,
              prayerConfig.longitude);

            Serial.println("Prayer times updated post-NTP sync");

            xSemaphoreTake(timeMutex, portMAX_DELAY);

          } else {
            Serial.println("No city coordinates - skipping prayer update");
            xSemaphoreGive(timeMutex);
            xSemaphoreTake(timeMutex, portMAX_DELAY);
          }

          Serial.println("========================================\n");
          break;
        }

        serverIndex++;
        esp_task_wdt_reset();
        vTaskDelay(pdMS_TO_TICKS(500));
      }

      if (!syncSuccess) {
        Serial.println("All NTP servers failed!");
        Serial.println(" Keeping current time");
        Serial.println("========================================\n");
      }

      ntpSyncInProgress = false;
      ntpSyncCompleted = syncSuccess;

      xSemaphoreGive(timeMutex);

    } else {
      Serial.println("Failed to acquire time mutex");
      Serial.println("========================================\n");

      ntpSyncInProgress = false;
      ntpSyncCompleted = false;
    }

    esp_task_wdt_reset();
  }
}

```

**code**

```arduino
void rtcSyncTask(void *parameter) {
  TickType_t xLastWakeTime = xTaskGetTickCount();
  const TickType_t xFrequency = pdMS_TO_TICKS(60000); // Every 1 minute

  while (true) {
    if (rtcAvailable) {
      DateTime rtcTime = rtc.now();

      if (xSemaphoreTake(timeMutex, pdMS_TO_TICKS(100)) == pdTRUE) {
        time_t systemTime = timeConfig.currentTime;
        time_t rtcUnix = rtcTime.unixtime();

        // ========================================
        // VALIDASI KETAT
        // ========================================
        bool rtcValid = true;

        if (rtcTime.year() < 2000 || rtcTime.year() > 2100) {
          Serial.println("RTC INVALID: Year out of range (" + String(rtcTime.year()) + ")");
          rtcValid = false;
        }

        long timeDiff = abs(systemTime - rtcUnix);
        if (systemTime >= 946684800 && timeDiff > 3600) {
          Serial.printf("RTC SUSPICIOUS: Time diff too large (%ld seconds)\n", timeDiff);
          Serial.printf(" System: %02d:%02d:%02d %02d/%02d/%04d\n",
                        hour(systemTime), minute(systemTime), second(systemTime),
                        day(systemTime), month(systemTime), year(systemTime));
          Serial.printf(" RTC: %02d:%02d:%02d %02d/%02d/%04d\n",
                        rtcTime.hour(), rtcTime.minute(), rtcTime.second(),
                        rtcTime.day(), rtcTime.month(), rtcTime.year());
          Serial.println("Keeping system time (RTC probably corrupted)");
          rtcValid = false;
        }

        // ========================================
        // Hanya update jika RTC valid DAN selisih kecil
        // ========================================
        if (rtcValid && timeDiff > 2) {
          timeConfig.currentTime = rtcUnix;
          setTime(rtcUnix);

          Serial.println("System time synced from RTC");
          Serial.printf(" RTC: %02d:%02d:%02d %02d/%02d/%04d\n",
                        rtcTime.hour(), rtcTime.minute(), rtcTime.second(),
                        rtcTime.day(), rtcTime.month(), rtcTime.year());

          DisplayUpdate update;
          update.type = DisplayUpdate::TIME_UPDATE;
          xQueueSend(displayQueue, &update, 0);

        } else if (!rtcValid) {
          Serial.println("RTC corrupted, resetting to system time...");

          DateTime fixedTime(
            year(systemTime),
            month(systemTime),
            day(systemTime),
            hour(systemTime),
            minute(systemTime),
            second(systemTime));

          rtc.adjust(fixedTime);
          Serial.println("RTC reset to system time");
        }

        xSemaphoreGive(timeMutex);
      }
    }

    vTaskDelayUntil(&xLastWakeTime, xFrequency);
  }
}

```

> [@bimosora](#):
>
> `initRTC`

this is the result

```arduino
2025/12/16 (Tuesday) 05:38:00
2025/12/16 (Tuesday) 05:38:01
2025/12/16 (Tuesday) 05:38:02
2025/12/16 (Tuesday) 05:38:03
2025/12/16 (Tuesday) 05:38:04
2025/12/16 (Tuesday) 05:38:05
2025/12/16 (Tuesday) 05:38:06
2025/12/16 (Tuesday) 05:38:07
2025/12/16 (Tuesday) 05:38:08

```

---

<div class="post-metadata">

**Author:** ![bimosora](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/bimosora/32/1099004_2.png) [@bimosora](https://forum.arduino.cc/u/bimosora)\
**Post date:** [December 17, 2025, 12:06am UTC](https://forum.arduino.cc/t/ds3231-rtc-program-cannot-run/1419786/5 "2025-12-17T00:06:08Z")

</div>

Battery is normal, rtc.adjust doesn't work

---

<div class="post-metadata">

**Author:** ![xfpd](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/xfpd/32/1120236_2.png) [@xfpd](https://forum.arduino.cc/u/xfpd)\
**Post date:** [December 17, 2025, 2:56am UTC](https://forum.arduino.cc/t/ds3231-rtc-program-cannot-run/1419786/6 "2025-12-17T02:56:58Z")

</div>

Why is Post #4 a repeat of Post #1?

> [@bimosora](#):
>
> rtc.adjust doesn't work

Why do you think it is not working?  
What values are `systemTime` and `rtcUnix` before their subtraction?  
Maybe `timeDiff` needs to be `unsigned long` so it is not negative when large

---

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/system/32/1140315_2.png) [@system](https://forum.arduino.cc/u/system)\
**Post date:** [June 15, 2026, 2:57am UTC](https://forum.arduino.cc/t/ds3231-rtc-program-cannot-run/1419786/7 "2026-06-15T02:57:54Z")

</div>

Closed on June 15, 2026, 2:57am UTC

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.
