NodeMCU resets itself

Hey guys I have a problem on my test project. I have 3 different component to control in my NodeMCU

1-)Pump
2-)Led1
3-)FIDE(other LED)

In below code, everything seems fine with working below 1 hour. But when I increase the time to 18 hour (you may see the below code) , it does not seem work, i believe it resets itself.

Can you guys help me to solve it ? Thanks!

#if defined(ESP8266)
#include <ESP8266WiFi.h>  //ESP8266 Core WiFi Library
#include <ESP8266WebServer.h>  //Local WebServer used to serve the configuration portal      
#else
#include <WiFi.h>      //ESP32 Core WiFi Library
#include <WebServer.h> //Local DNS Server used for redirecting all requests to the configuration portal (  https://github.com/zhouhan0126/DNSServer---esp32  )
#endif
#include <ESP8266WiFi.h>  //ESP8266 Core WiFi Library
#include <ESP8266WebServer.h>  //Local WebServer used to serve the configuration portal  
#include <DNSServer.h> //Local WebServer used to serve the configuration portal (  https://github.com/zhouhan0126/DNSServer---esp32  )
#include <WiFiManager.h>   // WiFi Configuration Magic (  https://github.com/zhouhan0126/DNSServer---esp32  ) >>  https://github.com/zhouhan0126/DNSServer---esp32  (ORIGINAL)
#include <ESP8266HTTPClient.h>
#include <ArduinoJson.h>
#include <DHT.h>


const String baseUrl = “xxxxx”;
const String arduinoKey ="20200728102624511e69ebad07cc64bb7ae485257a4f06ae2";
const String urlControl="ProductControl/";

void setWiFi(){
  WiFiManager wifiManager;
  wifiManager.autoConnect(“wireless”);
}

const int rlyOn = HIGH;
const int rlyOff = LOW;

#define DHTPIN D1
#define DHTTYPE DHT21
DHT dht(DHTPIN, DHTTYPE,11);
unsigned long sensorMillis;
unsigned long sensorInterval;

unsigned long LedLastMillis;
unsigned long LedOnInterval;
unsigned long LedOffInterval;

#define RLY_WTRPUMP D2
#define RLY_LED D4
#define RLY_FIDE D8

#define BTN_LED D6
int prevBtnLed;

#define BTN_WTRPUMP D5
int prevBtnWtrPump;
unsigned long pumpLastMillis;
unsigned long pumpOnInterval;
unsigned long pumpOffInterval;

#define BTN_FIDE D7
int prevBtnFide;
unsigned long fideLastMillis;
unsigned long fideOnInterval;
unsigned long fideOffInterval;

#define WaterLevelPin D0

void registerDefaultValues(){ //intervals set for 3 components
  sensorMillis = 0;
  sensorInterval = 60000 * 15ul ; // 15 min

  pumpLastMillis = 0;
  pumpOnInterval = 60000 * 10ul ; // 10 min
  pumpOffInterval = 60000 * 50ul ; // 50 min
  
  LedLastMillis = 0;
  LedOnInterval = 3600000 * 18ul; // 18 hour
  LedOffInterval = 3600000 * 6ul; // 6 hour
  
  fideLastMillis = 0;
  fideOnInterval =3600000 * 18ul ; // 18 hour
  fideOffInterval =3600000 * 6ul; // 6 hour
}
void setUp(){
  dht.begin();
  
  pinMode(RLY_LED, OUTPUT);
  pinMode(BTN_LED, INPUT);
  
  pinMode(RLY_WTRPUMP, OUTPUT);
  pinMode(BTN_WTRPUMP, INPUT);
  
  pinMode(RLY_FIDE, OUTPUT);
  pinMode(BTN_FIDE, INPUT);

  pinMode(WaterLevelPin,INPUT_PULLUP);
}
  

  void manuelLedAutomation(){
      int rlyCurrent = digitalRead(RLY_LED);
      unsigned long currentMillis = millis();   
      unsigned long difInterval = (currentMillis - LedLastMillis); 
      
     int btnStatus=digitalRead(BTN_LED);
      if(btnStatus==1) 
      {
        if(rlyCurrent == LOW){ 
          if(difInterval >= LedOffInterval){
            LedLastMillis = currentMillis;
            digitalWrite(RLY_LED,rlyOn);
          }
          else if(prevBtnLed==1)
          {
            digitalWrite(RLY_LED,rlyOn);
            prevBtnLed=0;
          }
        }
        else 
        { // Işık açık ise
          if(difInterval >= LedOnInterval){
            LedLastMillis = currentMillis;
            digitalWrite(RLY_LED,rlyOff);
          }
        }
      }
     else{
       digitalWrite(RLY_LED,rlyOff);
       prevBtnLed=1;
     }
  }
  
  void manuelFideAutomation(){
      unsigned long currentMillis = millis(); 
      unsigned long difInterval = (currentMillis - fideLastMillis);
      int rlyCurrent = digitalRead(RLY_FIDE);
      
      int btnStatus = digitalRead(BTN_FIDE);
      if(btnStatus==1)
      {
        if(rlyCurrent == LOW)
        {
          if(difInterval >= fideOffInterval){
            fideLastMillis = currentMillis;
            digitalWrite(RLY_FIDE,rlyOn);
          }
          else if(prevBtnFide==1){
            digitalWrite(RLY_FIDE,rlyOn);
            prevBtnFide=0; 
          }
        }
        else
        { 
         if(difInterval >= fideOnInterval){
            fideLastMillis = currentMillis;
            digitalWrite(RLY_FIDE,rlyOff);
          }
        }
      }
      else{
         digitalWrite(RLY_FIDE,rlyOff);
         prevBtnFide=1;
      }
  }
  
  void manuelPumpAutomation(){
      unsigned long currentMillis = millis(); 
      unsigned long difInterval = (currentMillis - pumpLastMillis); 
      int rlyCurrent = digitalRead(RLY_WTRPUMP);
      
      int btnStatus=digitalRead(BTN_WTRPUMP);
      if(btnStatus==1)
      {
        if(rlyCurrent == LOW){
          if(difInterval >= pumpOffInterval)
          {
            pumpLastMillis = currentMillis;
            digitalWrite(RLY_WTRPUMP,rlyOn);
          }
          else if(prevBtnWtrPump==1){
            digitalWrite(RLY_WTRPUMP,rlyOn);
            prevBtnWtrPump=0; 
          }
        }
        else
        {
          if(difInterval >= pumpOnInterval)
          {
            pumpLastMillis = currentMillis;
            digitalWrite(RLY_WTRPUMP,rlyOff);
          }
        }
      }
      else
      {
         digitalWrite(RLY_WTRPUMP,rlyOff);
         prevBtnWtrPump=1;
      }
  }

void saveWaterLevelAlert(){
  if(WiFi.status() == WL_CONNECTED){
  String url = baseUrl+"Arduino/alert";
    DynamicJsonDocument doc(2048);
    doc["arduinoKey"] = arduinoKey;
    doc["type"] = 1;
    doc["MessageTemplateCode"] = "CriticalWaterLevel";
    
    String request="";
    serializeJson(doc, request);
  
    HTTPClient http;
    http.begin(url);
    http.addHeader("Content-Type","application/json");
    int httpCode = http.POST(request);
    if(httpCode == 200){
      String response = http.getString();
    }
   
    http.end();
  }
}

void snoozeWaterLevelAlert(){
  if(WiFi.status() == WL_CONNECTED){
    String url = baseUrl+"Arduino/alert/snooze";
    DynamicJsonDocument doc(2048);
    doc["arduinoKey"] = arduinoKey;
    doc["type"] = 1;
    doc["MessageTemplateCode"] = "CriticalWaterLevel";
    
    String request="";
    serializeJson(doc, request);
    
    HTTPClient http;
    http.begin(url);
    http.addHeader("Content-Type","application/json");
    int httpCode = http.POST(request);
    if(httpCode == 200){
      String response = http.getString(); 
    }
    http.end();
  }
}
void checkWaterLevel(){
  int waterLevel = digitalRead(WaterLevelPin);
  if(waterLevel == LOW ){
      saveWaterLevelAlert();
  }
  else if(waterLevel == HIGH ){
    snoozeWaterLevelAlert();
  }
}


void setSensorData(){
  if(WiFi.status() == WL_CONNECTED){
    // SENSOR SET
    float h = dht.readHumidity();
    float t = dht.readTemperature();
    if (!isnan(h) && !isnan(t)) {
      int temperature = (t * 100);
      int humidity = (h * 100);
      DynamicJsonDocument doc(2048);
      doc["ArduinoKey"] = arduinoKey;
      doc["Temperature"] = temperature;
      doc["Humidity"] = humidity;
      
      String request="";
      serializeJson(doc, request);
      
      HTTPClient http;
      String url = baseUrl+"Sensor";
      http.begin(url);
      http.addHeader("Content-Type","application/json");
      int httpCode = http.POST(request);
      if(httpCode == 200){
         String response = http.getString();
      }
      http.end();
    }
  }  
}

void setup() {
  //Serial.begin(115200);
  setWiFi();
  setUp();
  registerDefaultValues();
}

void loop() {
  unsigned long currentMillis = millis();
  unsigned long difSensor = (currentMillis - sensorMillis); // send sensor everytime.
  if(difSensor>=sensorInterval)
  {
    sensorMillis=currentMillis;
    setSensorData();
    checkWaterLevel();
  }
   manuelPumpAutomation();
  manuelLedAutomation();
  manuelFideAutomation();
}

any crash log on the console?

Can you tell me what is the point of doing this ?

f(httpCode == 200){
         String response = http.getString();
      }

J-M-L:
any crash log on the console?

There is no beginSerial(), so how would there be a console?

OP- How do you know it's resetting itself? Add beginSerial to the setup() and sprinkle some Serial.print statements in your code where you suspect a problem.

Deva_Rishi:
Can you tell me what is the point of doing this ?

f(httpCode == 200){

String response = http.getString();
      }

Just test code. forgot to delete..

SteveMann:
There is no beginSerial(), so how would there be a console?

Well my point was to lead OP to think that may be there should be...

While i am at it ... can you explain the #if defined ?

#if defined(ESP8266)
#include <ESP8266WiFi.h>  //ESP8266 Core WiFi Library
#include <ESP8266WebServer.h>  //Local WebServer used to serve the configuration portal     
#else
#include <WiFi.h>      //ESP32 Core WiFi Library
#include <WebServer.h> //Local DNS Server used for redirecting all requests to the configuration portal (  https://github.com/zhouhan0126/DNSServer---esp32  )
#endif
#include <ESP8266WiFi.h>  //ESP8266 Core WiFi Library
#include <ESP8266WebServer.h>  //Local WebServer used to serve the configuration portal

I am not against compiler directives per se, but they do obstruct a view of what is really happening at times, and here you've seem to have doubled up all together, which means it won't compile for an ESP32 anyway.
Please for your own overview and ours, keep all #define 's in one area, keep all your global variables grouped together, group your global objects. And for my personal taste, first setup() and loop() and then any other functions. and eh, LedOnInterval = 3600000 * 18ul; // 18 hourshouldn't that be LedOnInterval = 3600000ul * 18ul; // 18 hourdeclaring 18 as an unsigned long does make the multiplication 32-bit, but the 3600000 doesn't fit into the standard integer.

Deva_Rishi:
And for my personal taste, first setup() and loop() and then any other functions.

That’s a very bad habit to take

The IDE does a trick for you to look for functions and inject code to pre-declare them so that the compiler does not bark at you when you call an undefined function.

The rule is to declare something before you use it so either declare functions at the top or in a .h you import or define them before the setup() and loop() where you’ll likely use them.

and eh, LedOnInterval = 3600000 * 18ul; // 18 hourshouldn't that be LedOnInterval = 3600000ul * 18ul; // 18 hourdeclaring 18 as an unsigned long does make the multiplication 32-bit, but the 3600000 doesn't fit into the standard integer.

although I would approve the UL In 3600000ul to show programmer intent, it’s technically not needed as the C++ rule is that the compiler will take the smallest integral representation (starting with int) to fit the number literal so here it would be an int on 32 bit architecture and a long for standard AVR based Arduino and then the multiplication by an unsigned long promote the whole operation to unsigned long which is the destination type. (3600000 does fit on an int on an ESP platform since int are 32 bits - it’s not an AVR)

J-M-L:
Well my point was to lead OP to think that may be there should be...

I usually fail at 'subtle'.

J-M-L:
That’s a very bad habit to take

I agree that to an experienced C++ programmer this is a bad practice, but not a "very bad habit". If all the user's programming will be using the Arduino IDE, then it will be very rare that they need to declare functions. If ever.

String class, on the other hand. (Speaking of bad habits).

This code is a style nightmare. Pick one form of bracketing, one form of indentations, on form for names, one place for globals, one place for defines etc.

pinMode(RLY_LED, OUTPUT);
//...
int rlyCurrent = digitalRead(RLY_LED);

Why are you reading your own output? It is better to have a global int that you toggle HIGH and LOW and can reference directly, and plug into your digitalWrite() etc. saves you from bugs.

int relayState;
const int rlyOn = HIGH;
const int rlyOff = LOW;
//...
if (relayState == rlyOff) {
  relayState = rlyOn;
  digitalWrite(RLY_LED, relayState);
  //...
unsigned long currentMillis = millis();   
unsigned long difInterval = (currentMillis - LedLastMillis);
//...
if(difInterval >= LedOffInterval){
  LedLastMillis = currentMillis;

Why? Why not do it inline? Not only does this make the code harder to read, but it also make the code much harder to maintain, modify or port.

if(millis() - LedLastMillis >= LedOnInterval) {
  LedLastMillis = millis();
  //...

What is with the buttons? is prevBtnFide your method of debounce? You say your code works at one interval of time, but not at another. What does working code look like? It is so hard to read I really have no clue.