Ds3231 not giving correct time with esp32

I am working with project were i need to start and stop relay if either of two conditions are met, one of which is to check duration elapsed since the respective timer started the time is counted in ds3231 but the problem is when i try to fetch time to update current time it return old/garbage time
below is the code for esp32


#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESP_Async_WebServer.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
#include <RTClib.h>

// Time zone
#define MY_NTP_SERVER "pool.ntp.org"
#define MY_TZ "IST-5:30"

// WiFi Name and Password
const char* ssid = "ssid";
const char* password = "pass";

// IP at which Node MCU hosts server
IPAddress staticIP(192, 168, x, x);
IPAddress gateway(192, 168, 1, x);
IPAddress subnet(255, 255, 255, x);

// Variable declaration
const char* PARAM_INPUT = "buttonID";
const char* PARAM_HOUR = "hour";  
const char* PARAM_MIN = "minute";

int Ihour = 0;
int Imin = 0;

const int TimerStartButton = 0; // Adjust pin numbers accordingly
const int QuickStartButton = 2;  // Adjust pin numbers accordingly
const int relayPin1 = 1;         // Adjust pin numbers accordingly
const int relayPin2 = 5;         // Adjust pin numbers accordingly
const int relayPin11 = 4;        // Adjust pin numbers accordingly
const int relayPin22 = 16;       // Adjust pin numbers accordingly
const int BackwardLimit = 13;    // Adjust pin numbers accordingly
const int ForwardLimit = 12;     // Adjust pin numbers accordingly
const int Transformer = 17;       // Adjust pin numbers accordingly

unsigned long t1Duration = 2;   
unsigned long t2Duration = 20;  
unsigned long t3Duration = 2;   
unsigned long t4Duration = 20;  
unsigned long t5Duration = 0;       

unsigned long t1StartTime;
unsigned long t2StartTime;
unsigned long t3StartTime;
unsigned long t4StartTime;
unsigned long t5StartTime;

bool T1TimerStarted = false;
bool T2TimerStarted = false;
bool T3TimerStarted = false;
bool T4TimerStarted = false;
bool T5TimerStarted = false;
bool executed1 = false;
bool executed2 = false;
bool executed3 = false;
bool executed4 = false;
bool executed5 = false;
bool TimerStartFlag = false;
bool QuickStartFlag = false;

AsyncWebServer server(80);

WiFiUDP ntpUDP;

RTC_DS3231 rtc;

unsigned long timeToSeconds(const DateTime& time) {
    // Calculate the total seconds since midnight
    unsigned long totalSeconds = time.hour() * 3600 + time.minute() * 60 + time.second();
    Serial.println(totalSeconds);
     //Serial.println(time.hour());
     //Serial.println(time.minute());
     //Serial.println(time.second());
    return totalSeconds;
}

void setup() {
    pinMode(Transformer, OUTPUT);
    digitalWrite(relayPin1, HIGH);
    digitalWrite(relayPin11, HIGH);
    digitalWrite(relayPin2, HIGH);
    digitalWrite(relayPin22, HIGH);
    digitalWrite(Transformer, HIGH);
    Serial.begin(115200);

    WiFi.config(staticIP, gateway, gateway, subnet);
    WiFi.begin(ssid, password);

    while (WiFi.status() != WL_CONNECTED) {
        delay(1000);
        Serial.println("Connecting to WiFi..");
    }

    Serial.println(WiFi.localIP());

    server.begin();

    rtc.begin();

    server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
        request->send(200, "text/plain", "Hello from NodeMCU!");
    });

    server.on("/index.html", HTTP_GET, [](AsyncWebServerRequest *request) {
        request->send(200, "text/plain", "Hello from index.html!");
    });

    server.on("/time", HTTP_GET, [](AsyncWebServerRequest *request) {
        String Shour;
        String Smin;

        if (request->hasParam(PARAM_HOUR) && request->hasParam(PARAM_MIN)) {
            Shour = request->getParam(PARAM_HOUR)->value();
            Smin = request->getParam(PARAM_MIN)->value();

            Ihour = Shour.toInt();
            Imin = Smin.toInt();

            Serial.print("hour - ");
            Serial.println(Ihour);
            Serial.print("minute - ");
            Serial.println(Imin);

            request->send(200, "text/plain", "Time received successfully");
        } else {
            request->send(400, "text/plain", "Bad Request");
        }
    });

    DefaultHeaders::Instance().addHeader("Access-Control-Allow-Origin", "*");

}

void loop() {
      DateTime now = rtc.now();
    unsigned long currentSeconds;
    if (now.hour() == Ihour && now.minute() == Imin && now.second() < 5 && !T1TimerStarted) {
        digitalWrite(Transformer, LOW);
        delay(3000);
        startT1(now);
        T1TimerStarted = true;
        currentSeconds = timeToSeconds(now);
    }

    if ((currentSeconds - t1StartTime >= t1Duration) && T1TimerStarted && !executed1) {
        startR1();
        startT2(now);
        T2TimerStarted = true;
        executed1 = true;
            currentSeconds = timeToSeconds(now);
    }


    if ((currentSeconds - t2StartTime >= t2Duration || digitalRead(BackwardLimit) != LOW) && T1TimerStarted && T2TimerStarted && !executed2) {
        stopR1();
        startT3(now);
        T3TimerStarted = true;
        executed2 = true;   
        currentSeconds = timeToSeconds(now);         
    }
    
    if ((currentSeconds - t3StartTime >= t3Duration) && T1TimerStarted && T2TimerStarted && T3TimerStarted && !executed3) {
        startR2();
        startT4(now);
        T4TimerStarted = true;
        executed3 = true;
        currentSeconds = timeToSeconds(now);
    }
    
    if ((currentSeconds - t4StartTime >= t4Duration || digitalRead(ForwardLimit) != LOW) && T1TimerStarted && T2TimerStarted && T3TimerStarted && T4TimerStarted && !executed4) {
        stopR2();
        startT5(now);
        T5TimerStarted = true;
        executed4 = true;
        currentSeconds = timeToSeconds(now);
    }
    
    if ((currentSeconds - t5StartTime >= t5Duration) && T1TimerStarted && T2TimerStarted && T3TimerStarted && T4TimerStarted && T5TimerStarted && !executed5) {
        T1TimerStarted = T2TimerStarted = T3TimerStarted = T4TimerStarted = T5TimerStarted = false;
        executed1 = executed2 = executed3 = executed4 = executed5 = false;
        delay(2000);
        digitalWrite(Transformer, HIGH);
    }
}

void startT1(DateTime now) {
    t1StartTime = timeToSeconds(now);
    Serial.println("T1 Start");
}

void startT2(DateTime now) {
    t2StartTime = timeToSeconds(now);
    Serial.println("T2 Start");
}

void startR1() {
    Serial.println("R1 Start");
    digitalWrite(relayPin1, LOW);
    digitalWrite(relayPin11, LOW);
}

void stopR1() {
    Serial.println("R1 Stop");
    digitalWrite(relayPin1, HIGH);
    digitalWrite(relayPin11, HIGH);
}

void startT3(DateTime now) {
    t3StartTime = timeToSeconds(now);
    Serial.println("T3 Start");
}

void startR2() {
    Serial.println("R2 Start");
    digitalWrite(relayPin2, LOW);
    digitalWrite(relayPin22, LOW);
}

void stopR2() {
    Serial.println("R2 Stop");
    digitalWrite(relayPin2, HIGH);
    digitalWrite(relayPin22, HIGH);
}

void startT4(DateTime now) {
    t4StartTime = timeToSeconds(now);
    Serial.println("T4 Start");
}

void startT5(DateTime now) {
    t5StartTime = timeToSeconds(now);
    Serial.println("T5 Start");
}


in above code i use timeToSeconds() to convert time given by ds3231 into seconds and then compare the difference of current time with the duration set previously as tnduration

Here is the Serial output that i get

Connecting to WiFi..
192.168.x.x
hour - 15
minute - 41
56463
T1 Start
56460
R1 Start
56463
T2 Start
56460
R1 Stop
56463
T3 Start
56460
R2 Start
56463
T4 Start
56460
R2 Stop
56463
T5 Start
56460

currentSeconds is not updated as you loop, it seems you got mixed up and are confusing that with Start Times of the subtasks.

void loop() {
    DateTime now = rtc.now();
    unsigned long currentSeconds = timeToSeconds(now);
    if (now.hour() == Ihour && now.minute() == Imin && now.second() < 5 && !T1TimerStarted) {
        digitalWrite(Transformer, LOW);
        delay(3000);
        startT1(now);
        T1TimerStarted = true;
        t1StartTime = timeToSeconds(now); // <==== NOTE THE START TIME OF T1
    }

    if ((currentSeconds - t1StartTime >= t1Duration) && T1TimerStarted && !executed1) {
        startR1();
        startT2(now);
        T2TimerStarted = true;
        executed1 = true;
        t2StartTime = timeToSeconds(now); // <==== NOTE THE START TIME OF T2
    }
...

PS: I've noticed

to be sure it's working on arduino where an int is only 16 bits you should force unsigned long maths

unsigned long totalSeconds = time.hour() * 3600ul + time.minute() * 60ul + time.second();

so basically i need to create another object similar to DateTime now = rtc.now(); for evert timer ie, t1 , t2, t3

no, just use the variables you had, but correctly

the test to see if the right duration has elapsed is

if (current_time - start_time >= duration) {...}

in your code you were not maintaining current_time and you were not registering the start_time.... So can't work.

1 Like

thank you. now it works fine
as you mention i was not updating the current time.

Enjoy!