How to keep the arduino active even if task is done momentarily?

Hi,
I'm using Arduino Mega to keep temperature and RH within a range in two consequent 4 hour windows (8 hours in total). This is a standard procedure and I need it running for a week in each test. So to make sure there will be no memory issues, I reset the arduino using watchdog timer. The first 4 hour cycle is working at 60 degree C without controlling RH (but with UV light exposure) and the second cycle is 4 hour cycle is working at 50 degree C and RH at 65%. The second cycle is a bit complicated and I am not sure how I can keep the arduino active even if the conditions are met during the cycle. I tried to use delay and use "if" command as much as possible to avoid freezing. But I ended up seeing the code stopping when the ideal conditions are reached. I appreciate any help in solving this problem.

//The following libaries are required for the operation of the chamber
#include <Arduino.h>
#include <Wire.h>
#include "Adafruit_SHT31.h"
#include <LiquidCrystal.h>

//Variable required for testing the Multiplexer
#define TCAADDR 0x70 //serial address of the TCA9458A Multiplexer
#include <avr/wdt.h>

//Temperature Sensor setup
bool enableHeater = false;


//Initialize the SHT31 sensor(s) *NOTE THAT IT MIGHT BE THE CASE THAT ONLY ONE INSTANCE NEED BE INITIALIZED*
Adafruit_SHT31 sht31_1 = Adafruit_SHT31();
Adafruit_SHT31 sht31_2 = Adafruit_SHT31();
Adafruit_SHT31 sht31_3 = Adafruit_SHT31();
//Adafruit_SHT31 sht31_4 = Adafruit_SHT31();

//define relay pins (these values are not changeable unless the requisite change has been made on the arduino board)
const byte Safety_Lights_Relay = 22;    // Relay I : https://www.mcmaster.com/8262T14/ ;  Safety Lights: Some 12VDC lights
const byte Heat_Mist = 26;              // Relay J : https://www.omega.ca/en/control-monitoring/relays/solid-state-relays/ssrl240-660/p/SSRL240DC25 ; Components (a heating pad and a solenoid valve): https://www.omega.ca/en/industrial-heaters/surface-heaters/flexible-heaters/srfra-srfga/p/SRFGA-508-10-P    &  https://www.mcmaster.com/4738K147/
const byte Chamber_Fan_Relay1 = 24;     // Relay G : https://www.mcmaster.com/8262T14/ ; Fan: https://www.digikey.ca/en/products/detail/qualtek/FAA1-08025NBMT31/2599974
const byte Humidifier_Fan_Relay = 25;   // Relay K : https://www.mcmaster.com/8262T14/ ; Fan: a 24 VDC fan
const byte Humidifier_Relay = 23;       // Relay V : https://www.celduc-relais.com/Technical_DataSheet/FA_SOM020200.pdf ; Humidifier: https://www.vevor.ca/ultrasonic-mist-maker-c_10257/mist-maker-fogger-10-head-ultrasonic-mist-humidifier-110v-w-transformer-p_010789401317?gclid=Cj0KCQjwxtSSBhDYARIsAEn0thQsOAX_IOUpdxwomKBn3O1nD1rKbnZhvn2D2-jlxk25Wg0w4PynO5kaAsS4EALw_wcB
const byte UV_Light_Relay = 27;         // Relay F : https://www.mcmaster.com/8262T14/ ; UV Lamps: two 340nm UVA lamps
const byte Chamber_Fan_Relay2 = 28;    //  Relay Y : https://www.mcmaster.com/8262T14/ ; Fan: https://www.digikey.ca/en/products/detail/qualtek/FMA1-08025WBHT12/10228356
const byte Heater_Relay = 29;          //  Relay H : https://www.digikey.com/en/products/detail/sensata-crydom/CKRD6010/1771443 ; Heater: https://www.omega.com/en-us/industrial-heaters/duct-and-enclosures-heaters/duct-heaters/ahf-heater/p/AHF-10120

//Time Constant Values
const unsigned long seconds = 1000; //number of milliseconds in a second
const unsigned long minutes = 60000; //number of milliseconds in a minute
const unsigned long hours = 3600000; //number of milliseconds in an hour

//Temperature & Humidity Variables
const float sensorTempVariance = 0.5; //variable to modify target temperature set points ******************
const float sensorHumVariance = 1.5; //variable to modify target temperature set points ******************
const float targetTemp1 = 60; //target temperature for dry cycle
const float targetTemp2 = 50; //target temperature for wet cycle
float targetTemp = 60; //system initializing temperature (This is the value that gets modified in the code with specific cycle temps)
const float targetHum = 65; //target humidity for wet cycle

const float sht3TempWeight1 = 4; //Weighting for the Right SHT3 sensor temperature value ******************
const float sht3TempWeight2 = 5; //Weighting for the Middle SHT3 sensor temperature value ******************
const float sht3TempWeight3 = 4; //Weighting for the Left SHT3 sensor temperature value ******************

const float sht3HumWeight1 = 5; //Weighting for the Right SHT3 sensor humidity value ******************
const float sht3HumWeight2 = 3; //Weighting for the Middle SHT3 sensor humidity value ******************
const float sht3HumWeight3 = 4; //Weighting for the Left SHT3 sensor humidity value ******************


const unsigned int heaterPulse = 5000; //Duration for heater to run before turning off ******************
unsigned int chamberFanPulseDuration = 1000; //Duration to turn on the chamber fan during humidity control (must be in milliseconds) ******************
unsigned int humFanPulseDuration = 1000; //Duration to turn on the humidifier fan during humidity control (must be in milliseconds) ******************
unsigned int mistLoading = 3000; //Duration to run the humidifier to load the mist chamber (must be in milliseconds) *****************

bool idealValues = false;

//Global Variables
unsigned long startTime = 0; //dummy variable that will eventually tell the arduino at which millisecond the test began
float cycleDuration = 3   ; //number of hours that each cycle will run ******************
float singleBatchTime = cycleDuration * 2 * 3600000; // [ms]
unsigned int cycleCount = 0; //initial value for cycle counter
const unsigned int totalCycleCount = 42; //number of total cycles for test
unsigned long int timeVar = 0;

//select pins used for LCD and define LCD values
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
int lcd_key = 5;  //Default value equivalent to pressing no button
int adc_key_in = 2000; //Arbitrary value assigned

//Values are arbitarily assigned but should not be changed as they are prolific throughout the code
#define btnDOWN 0
#define btnUP 1
#define btnLEFT 2
#define btnRIGHT 3
#define btnSELECT 4
#define btnNONE 5

//Code to initialize system before test cycle begins (will only be ran one time immediately after powering on)
void setup() {

  wdt_disable();
  //establish digital pins for relay control and set them all to low
  pinMode(Heater_Relay, OUTPUT);
  digitalWrite(Heater_Relay, LOW);
  pinMode(UV_Light_Relay, OUTPUT);
  digitalWrite(UV_Light_Relay, LOW);
  pinMode(Chamber_Fan_Relay1, OUTPUT);
  digitalWrite(Chamber_Fan_Relay1, LOW);
  pinMode(Humidifier_Fan_Relay, OUTPUT);
  digitalWrite(Humidifier_Fan_Relay, LOW);
  pinMode(Heat_Mist, OUTPUT);
  digitalWrite(Heat_Mist, LOW);
  pinMode(Safety_Lights_Relay, OUTPUT);
  digitalWrite(Safety_Lights_Relay, LOW);
  pinMode(Humidifier_Relay, OUTPUT);
  digitalWrite(Humidifier_Relay, LOW);
  pinMode(Chamber_Fan_Relay2, OUTPUT);
  digitalWrite(Chamber_Fan_Relay2, LOW);
  //establish unactive pins in INPUT_PULLUP mode to enable their internal resistor and eliminate stray noise signals
  pinMode(30, INPUT_PULLUP);
  pinMode(31, INPUT_PULLUP);
  pinMode(32, INPUT_PULLUP);
  pinMode(33, INPUT_PULLUP);
  pinMode(34, INPUT_PULLUP);
  pinMode(35, INPUT_PULLUP);
  pinMode(36, INPUT_PULLUP);
  pinMode(37, INPUT_PULLUP);
  pinMode(38, INPUT_PULLUP);
  pinMode(39, INPUT_PULLUP);
  pinMode(40, INPUT_PULLUP);
  pinMode(41, INPUT_PULLUP);
  pinMode(42, INPUT_PULLUP);
  pinMode(43, INPUT_PULLUP);
  pinMode(44, INPUT_PULLUP);
  pinMode(45, INPUT_PULLUP);
  pinMode(46, INPUT_PULLUP);
  pinMode(47, INPUT_PULLUP);
  pinMode(48, INPUT_PULLUP);
  pinMode(49, INPUT_PULLUP);
  pinMode(50, INPUT_PULLUP);
  pinMode(51, INPUT_PULLUP);
  pinMode(52, INPUT_PULLUP);
  pinMode(53, INPUT_PULLUP);
  pinMode(A8, INPUT_PULLUP);
  pinMode(A9, INPUT_PULLUP);
  pinMode(A10, INPUT_PULLUP);
  pinMode(A11, INPUT_PULLUP);
  pinMode(A12, INPUT_PULLUP);
  pinMode(A13, INPUT_PULLUP);
  pinMode(A14, INPUT_PULLUP);
  pinMode(A15, INPUT_PULLUP);
  pinMode(14, INPUT_PULLUP);
  pinMode(15, INPUT_PULLUP);
  pinMode(17, INPUT_PULLUP);
  pinMode(18, INPUT_PULLUP);

  //this section is to initialize the LCD display and Serial Monitor
  Serial.begin(115200); //baud rate is determined by the requirement of the UV sensors
  lcd.begin(16, 2);
  lcd.setCursor(0, 0);

  //Initialize the temperature & Humidity sensors
  sht31_1.begin();
  sht31_2.begin();
  sht31_3.begin();

  //Troubleshooting stuff
  //this section of code allows for testing of Multiplexer function and displays which of the 8 ports the sensors are connected to in the serial monitor (*please note that if physical changes were required that the corresponding values for "tcaselect" function will need to be adjusted)
  while (!Serial);
  delay(1000);
  Wire.begin();
  Serial.println(F("\nTCAScanner Ready!"));

  //Setting up the multiplexer for SHT3x sensors
  for (uint8_t t = 0; t < 8; t++) {
    tcaselect(t);
    Serial.print(F("TCA Port #"));
    Serial.println(t);
    for (uint8_t addr = 0; addr <= 127; addr++) {
      if (addr == TCAADDR) continue;
      Wire.beginTransmission(addr);
      if (!Wire.endTransmission()) {
        Serial.print(F("Found I2C 0x"));
        Serial.println(addr, HEX);
      }
    }
  }
  Serial.println(F("\ndone"));
  Serial.println(F(""));
  digitalWrite(Safety_Lights_Relay, HIGH);

} //End of Setup


//main loop that controls cycles
void loop() {

  //This is to reset the arduino every 8 hours
  timeVar = millis() - startTime;
  if (timeVar > singleBatchTime && cycleCount != 0) {
    wdt_enable(WDTO_250MS);
  }

  //This section reads the input from the LCD panel and performs specific actions
  while (cycleCount == 0 && averageTemp() < targetTemp) { //Waits for user to press SELECT while maintaining target temperature
    print2Serial(averageTemp(), averageHum());
    delay(1000);
    displayData(lcd_key);
    tempMaintenance(targetTemp);
  }
  if (cycleCount == 0 && averageTemp() >= targetTemp) { //Cycle count will only be 0 upon first turning on the system, this prevents a user from restarting the test by accidentally pressing select
    startupProcedure();
  }
  else {
    displayData(lcd_key);
  }

  //This section maintains the specified temperature and humidity (depending on cycle)
  if (cycleCounter() == true) { //Only enters on even number cycles ("wet cycles")
    humMaintenance(targetTemp);
  } else {
    digitalWrite(Humidifier_Relay, LOW);
    digitalWrite(Heat_Mist, LOW);
    digitalWrite(Humidifier_Fan_Relay, LOW);
    print2Serial(averageTemp(), averageHum());
    delay(1000);
    tempMaintenance(targetTemp);
  }
  //This section checks to see if the cycle has been running for the specified time and the number of completed cycles (ends the program if cycle count is reached)
  checkTime();
  //cyclesCompleted();

} //End of Loop


//This function allows the selection of different I2C addresses on the multiplexer
void tcaselect(uint8_t i) {
  if (i > 7) return;
  Wire.beginTransmission(TCAADDR);
  Wire.write(1 << i);
  Wire.endTransmission();
}

//This function averages the temperatures of all three sensors in a weighted manner
float averageTemp() {
  tcaselect(7);
  float sht3Temp1 = sht31_2.readTemperature();
  tcaselect(5);
  float sht3Temp2 = sht31_1.readTemperature();
  tcaselect(6);
  float sht3Temp3 = sht31_3.readTemperature();
  //tcaselect(5);
  //float sht3Temp4 = sht31_4.readTemperature();
  float tempAverage = ((sht3TempWeight1 * sht3Temp1 + sht3TempWeight2 * sht3Temp2 + sht3TempWeight3 * sht3Temp3)) / (sht3TempWeight1 + sht3TempWeight2 + sht3TempWeight3);
  return tempAverage;
}

//This function averages the humidity of all three sensors in a weighted manner
float averageHum() {
  tcaselect(7);
  float sht3Hum1 = sht31_2.readHumidity();
  tcaselect(5);
  float sht3Hum2 = sht31_1.readHumidity();
  tcaselect(6);
  float sht3Hum3 = sht31_3.readHumidity();
  float humAverage = ((sht3HumWeight1 * sht3Hum1) + (sht3HumWeight2 * sht3Hum2) + (sht3HumWeight3 * sht3Hum3)) / (sht3HumWeight1 + sht3HumWeight2 + sht3HumWeight3);
  return humAverage;
}

//This function reads the value of the button on the LCD Display
/*int read_LCD_buttons() {
  adc_key_in = analogRead(0);
  if (adc_key_in < 50) return btnRIGHT; //3
  if (adc_key_in < 250) return btnUP; //1
  if (adc_key_in < 450) return btnDOWN; //0
  if (adc_key_in < 650) return btnLEFT; //2
  if (adc_key_in < 850) return btnSELECT; //4
  if (adc_key_in > 1000) return btnNONE; //5

  return btnNONE;
  }*/

//This function maintains the temperature of the system (for dry-cycles)
void tempMaintenance(float temperature) {
  float maintenanceTargetTemp = temperature - sensorTempVariance;
  if (averageTemp() <= maintenanceTargetTemp) {
    //digitalWrite(Chamber_Fan_Relay1, HIGH);
    digitalWrite(Chamber_Fan_Relay2, HIGH);
    if (averageTemp() < maintenanceTargetTemp) {
      digitalWrite(Heater_Relay, HIGH);
      delay(2000);
      digitalWrite(Heater_Relay, LOW);
      print2Serial(averageTemp(), averageHum());
    }
    delay(1000); //Delay is required so that residual heat in the inline heater will be blown into the chamber
    if (averageTemp() < temperature && cycleCount == 0) {
      digitalWrite(Heater_Relay, HIGH);
      delay(3500);
      digitalWrite(Heater_Relay, LOW);
      print2Serial(averageTemp(), averageHum());
    }
    delay(1000);
  }
  else {
    digitalWrite(Chamber_Fan_Relay1, LOW);
    digitalWrite(Chamber_Fan_Relay2, LOW);
  }
}

//This function maintains the temperature of the system (for wet-cycles)
void tempRH_Maintenance(float temperature) {
  float maintenance_TargetTemp = temperature - sensorTempVariance;
  digitalWrite(Chamber_Fan_Relay1, LOW);
  if (averageTemp() <= maintenance_TargetTemp) {
    digitalWrite(Chamber_Fan_Relay2, HIGH);
    digitalWrite(Heater_Relay, HIGH);
    delay(mistLoading);
    while (averageTemp() <= maintenance_TargetTemp && idealValues == false) {
      print2Serial(averageTemp(), averageHum());
      displayData(lcd_key);
      if (averageHum() < targetHum - sensorHumVariance ) {
        digitalWrite(Humidifier_Fan_Relay, HIGH);
        delay(mistLoading);
      }
      else {
        digitalWrite(Humidifier_Fan_Relay, LOW);
        delay(mistLoading);
        idealValues = true;
      }
    }
    digitalWrite(Heater_Relay, LOW);
    delay(800); //Delay is required so that residual heat in the inline heater will be blown into the chamber
    digitalWrite(Chamber_Fan_Relay2, LOW);
    //digitalWrite(Humidifier_Fan_Relay, LOW);
  }
  else {
    idealValues = false;
    return;
  }
}

//This function prints the data to the serial monitor and lcd display
void displayData(int sensor2Display) { //Value of 1 = top sensor, value of 2 = left sensor, value of 3 = right sensor, and value of 0 or 5 = average
  float temp2Print = 0;
  float hum2Print = 0;
  if (sensor2Display == btnUP) {
    /* //  tcaselect(2); //value in parenthesis corresponds to the physical sensor at the highest location in the chamber
      //  temp2Print = sht31_1.readTemperature();
      //   hum2Print = sht31_1.readHumidity();
      } else if (sensor2Display == btnLEFT) {
      //   tcaselect(3); //value in parenthesis corresponds to the physical sensor at the left most location in the chamber
      //  temp2Print = sht31_2.readTemperature();
      //  hum2Print = sht31_2.readHumidity();
      } else if (sensor2Display == btnRIGHT) {
      //   tcaselect(4); //value in parenthesis corresponds to the physical sensor at the right most location in the chamber
      //   temp2Print = sht31_3.readTemperature();
      //   hum2Print = sht31_3.readHumidity();*/
  } else {
    temp2Print = averageTemp();
    hum2Print = averageHum();
  }
  lcd.home();
  lcd.print("T:");
  lcd.print(round(temp2Print));
  lcd.print("C");
  lcd.print(" H:");
  if (hum2Print < 10) {
    lcd.print("0");
  }
  lcd.print(round(hum2Print));
  lcd.print("%");
  lcd.setCursor(0, 1);
  unsigned long int timeMilliseconds = timeVar;
  unsigned long int timeHours = timeMilliseconds / hours;
  unsigned long int timeMins = (timeMilliseconds - (timeHours * hours)) / minutes;
  lcd.print("t:");
  lcd.print(timeHours);
  lcd.print("h");
  if (timeMins < 10) {
    lcd.print("0");
  }
  lcd.print(timeMins);
  lcd.setCursor(6, 1);
  lcd.print("m");
  lcd.print(" Cycle:");
  lcd.print(cycleCount);
}

//This function is for starting the initial test
void startupProcedure() {
  lcd.clear();
  lcd.print("Starting...");
  delay(1000); //Delay is added just for user experience
  digitalWrite(UV_Light_Relay, HIGH);
  delay(500);
  //unsigned int dummyVar = uvCheck(); //Added to confirm via the serial monitor that the UV is operational
  startTime = millis(); //Officially begins the start of the first cycle
  cycleCount = 1; //Initialize the cycle counting and ensures that the requirements to trigger the startup procedure can no longer be met
}

//This function keeps count of which cycle the system is on
bool cycleCounter() {
  if (cycleCount % 2 == 0) { //Even numbered cycles (wet cycles) will return true
    return true;
  }
  else {
    return false;
  }
}

//This function removes the excess moisture if the target RH is passed. Also, by momentarily turning on the humidifier fan it tries to keep all sensors in the same RH range.
void excess_Humidity() {
  float adjustedHumTarget = targetHum - (2 * sensorHumVariance);
  if (averageHum() > adjustedHumTarget) {
    digitalWrite(Heat_Mist, LOW);
  }
  if (averageHum() >= targetHum) {         // If RH is gone too much high, play with chamber fans to remove the excessive mist
    digitalWrite(Humidifier_Fan_Relay, LOW);
    digitalWrite(Chamber_Fan_Relay1, HIGH);
    delay(800);
    digitalWrite(Chamber_Fan_Relay1, LOW);
    delay(mistLoading);
  }
  else {
    return;
  /*  tcaselect(6);
    float T_Last = sht31_3.readTemperature();
    float RH_Last = sht31_3.readHumidity();
    tcaselect(7);
    float T_First = sht31_2.readTemperature();
    float RH_First = sht31_2.readHumidity();
    if (T_First != T_Last || RH_First != RH_Last) {
      digitalWrite(Chamber_Fan_Relay2, HIGH);
      delay(250);
      digitalWrite(Chamber_Fan_Relay2, LOW);
      print2Serial(averageTemp(), averageHum());
      delay(2000);
    }*/
    }
}

//This function maintains the humidity of the system
void humMaintenance(float temperature) {
  float adjustedHumTarget = targetHum - sensorHumVariance;
  if (averageHum() > targetHum + mistLoading * sensorHumVariance) {
    digitalWrite(Humidifier_Relay, LOW);
    digitalWrite(Heat_Mist, LOW);
  }
  else {
    digitalWrite(Humidifier_Relay, HIGH);
  }
  if (digitalRead(Humidifier_Fan_Relay) == HIGH) {     // If target RH is reached, turn the fogger OFF.
    if (averageHum() >= adjustedHumTarget) {           // First see if RH is in the desired range
      digitalWrite(Humidifier_Fan_Relay, LOW);
      delay(mistLoading);
      if (averageHum() < targetHum) {  //Going a little bit higher than the RH setpoint
        digitalWrite(Humidifier_Fan_Relay, HIGH);
        print2Serial(averageTemp(), averageHum());
        delay(mistLoading / 2);
        digitalWrite(Humidifier_Fan_Relay, LOW);
      }
      tempRH_Maintenance(temperature);
    }
    excess_Humidity();
  }
  if (averageHum() < targetHum) {
    digitalWrite(Humidifier_Fan_Relay, HIGH);
    if (averageHum() > targetHum / 2 && averageHum() < (adjustedHumTarget - 2 * sensorHumVariance)) {
      digitalWrite(Heat_Mist, HIGH);
    }
    print2Serial(averageTemp(), averageHum());
    delay(mistLoading);
    tempRH_Maintenance(temperature);
  }
  else {
    excess_Humidity();
  }
}

//This function checks to see if the current cycle has been running for more than the specified cycle time and increases the cycle count
void checkTime() {
  //int convertedTime = (int) cycleDuration * hours; //convert cycle duration to milliseconds (casting to int drops the fractions of the millisecond if any and makes it possible to convert to long)
  unsigned long cycleDurationMills = cycleDuration * hours;
  //long timeCheckVar = timeVar;
  if (timeVar >= cycleDurationMills) {
    //lcd.clear();
    cycleCount = 2;
    toggleUV();
    toggleTargetTemp();
  }
  else {
    cycleCount = 1;
  }
}

//This functions turns the UV light on/off depending on the cycle
void toggleUV() {
  if (cycleCounter() == true) {
    digitalWrite(UV_Light_Relay, LOW);
    delay(500); //Delay is required so that the sensors have adequate time to determine if the UV light is off
    //unsigned int dummyVar = uvCheck();
  }
  else if (cycleCounter() == false && cycleCount > 0) {
    digitalWrite(UV_Light_Relay, HIGH);
    delay(500); //Delay is required so that the sensors have adequate time to determine if the UV light is on
    //unsigned int dummyVar = uvCheck();
    //startTime = millis(); //Starts the timer for the current cycle as soon as the UV light is on
  }
}

//This function sets the target temperature depending on the cycle
void toggleTargetTemp() {
  if (cycleCounter() == true) {
    targetTemp = targetTemp2;
    //print2Serial(averageTemp(), averageHum());
    humMaintenance(targetTemp); //Brings system to the specified operating conditions for wet cycle
    //startTime = millis(); //Timer for the wet cycle begins when target humidity is reached
  }
  else {
    targetTemp = targetTemp1;
    //print2Serial(averageTemp(), averageHum());
  }
}

//This function prints the necessary data to the serial monitor
void print2Serial(float temperatureValue, float humidityValue) {
  float temp2Print = 0;
  float hum2Print = 0;

  Serial.println(F("THE ORDER OF SENSORS IS ACCORDING TO THE AIR FLOW DIRECTION"));
  Serial.println(F(""));
  Serial.print(F("Target Temperature: "));
  Serial.println(targetTemp);
  Serial.print(F("Current Avg. Temperature: "));
  Serial.print(temperatureValue);
  Serial.println(F(" °C"));
  Serial.println(F(""));
  Serial.print(F("RIGHT (1st sensor): "));
  tcaselect(7);
  temp2Print = sht31_2.readTemperature();
  Serial.print(temp2Print);
  Serial.println(F(" °C"));

  Serial.print(F("MIDDLE (2nd sensor): "));
  tcaselect(5);
  temp2Print = sht31_1.readTemperature();
  Serial.print(temp2Print);
  Serial.println(F(" °C"));

  Serial.print(F("LEFT (3rd sensor): "));
  tcaselect(6);
  temp2Print = sht31_3.readTemperature();
  Serial.print(temp2Print);
  Serial.println(F(" °C"));

  Serial.println(F(""));
  Serial.print(F("Current Avg. RH: "));
  Serial.print(humidityValue);
  Serial.println(F(" %"));
  Serial.println(F(""));
  Serial.print(F("RIGHT Humidity: "));
  tcaselect(7);
  hum2Print = sht31_2.readHumidity();
  Serial.print(hum2Print);
  Serial.println(F(" %"));

  Serial.print(F("MIDDLE Humidity: "));
  tcaselect(5);
  hum2Print = sht31_1.readHumidity();
  Serial.print(hum2Print);
  Serial.println(F(" %"));

  Serial.print(F("LEFT Humidity: "));
  tcaselect(6);
  hum2Print = sht31_3.readHumidity();
  Serial.print(hum2Print);
  Serial.println(F(" %"));

  Serial.println(F(""));
  Serial.print(F("Cycle Count: "));
  Serial.println(cycleCount);
  Serial.print(F("Current Time Elapsed Since Start of the Batch: "));
  unsigned long int timeVarHrs = timeVar / hours;
  unsigned long int timeVar2 = (timeVar - (timeVarHrs * hours));
  unsigned long int timeVarMins = timeVar2 / minutes;
  unsigned long int timeVarSecs = (timeVar2 - (timeVarMins * minutes)) / seconds;
  Serial.print(timeVarHrs);
  Serial.print(F(" Hrs "));
  Serial.print(timeVarMins);
  Serial.print(F(" Mins "));
  Serial.print(timeVarSecs);
  Serial.println(F(" Secs"));
  Serial.println(F("*****************************************************************"));
  Serial.println(F(""));

Except for deep sleep modes, the Arduino is always active (there is no HALT instruction), so your question is unclear.

You should avoid using delay(). Use millis() instead for timing events.

What do you mean by "freezing"? If the Arduino hangs up and needs to be rebooted, you have a fatal program error somewhere (violation of array bounds and memory corruption are common errors).

So I replace millis() wherever I need the code to wait a bit? Can you give me an example in the code?

I stops working with controlling relays and temperature and RH drop. When I reset the arduino I see the actual T and RH are decreasing or less than the setpoints for the desired cycle.

How do I know which one is the issue?

Not quite that simple. Follow this excellent tutorial to learn how to time events and computing on an Arduino, without using delay().

How do I know which one is the issue?

The usual approach is to put Serial.print() statements throughout the code, in places where you expect the error to appear, and print out the values of suspect variables. Check that the values make sense.

The code is a terrible mess, I'll be surprised if it works without freezing for at least a couple of hours
If you're worried about making your code run stable, you need to clean it up of all the junk it contains.

Are you run a I2c scanner in each start of the code? Why? As I see - you don't use the results, so the code is completely useless:

what;s this? What for?

And what is the point to setup a watchdog with a timeout of 250ms if you have dozens of delays in your code that are a second or two long?

OK, I'll be happy to correct it if you can give better examples. Items you're addressing have reasons to be there.

Yes, the T/RH sensors work with I2C bus connections and I have three of them. These were the most accurate sensor for this application.

Then what is my main input for temperature and Humidity?

This is there to avoid the freezing issue (I've been told to use this command to make sure all unused pins are secure).

The watchdog is there to reset the whole code after 8 hours. The delays are in the code to work with controlling relays to adjust the test conditions.

Bad idea. Get rid of the watchdog and fix the program errors.

Keep in mind that program malfunctions can also result from noise in an improperly designed power supply, and is especially likely with heating systems, relays, etc.

Your input of temperature has nothing to do with I2c scan code. As I said - you even do not use the results of scanning. So you can simple remove it from the code - nothing will change.

Such using of watchdog is absolutely senseless. It will fire ONLY if the program do not freeze during eight hours - that is, just when it is not needed But if you program freeze before this 8 hour point - the watchdog will not be able to prevent this.
A watchdog is used in a completely different way - it must be launched immediately after the start of the program and work all this time. The program should restart it before the timeout expires - i.e. roughly every second or so. If the program does not restart it, then the program freezed. Then the watchdog will do its job.
In order to use a watchdog, the program should not have a delay() longer than its timeout.
You do not have a watchdog at all.

This is exactly the previous trouble shooting I worked on and I made sure to minimize all the sources of noise by using proper hardware. The fact that the issue is still there and the freezing point is similar (at least after all hardware modifications) in all different runs, makes me sure that it might be a small mistake in the code. The conditions I end up having now is ideal temperature and RH in the second 4 hour window. Isn't this showing this is a problem with the code?

Maybe, but you haven't posted any information regarding the hardware, so there is no reason to believe your claim.

As already pointed out, your code does have serious problems.

I'm trying to monitor if I can find the problem with array bounds as you said.

For example, using twisted pair wires with RFI shielding for the high current parts... also separating AC/DC and grounding the items that might generate high voltage (such as UV lamps) and using RFI shielding for their wiring. I'm have an Optocoupler between the arduino and the controlling transistor for relays. All of these plus small modifications here and there to remove any other kinds of glitching. But since this freezing issue has only one result now (finishing at ideal values), I think it is a code problem.

I'm trying to improve it and solve these issues but all I got so far is there are problems.

Are my explanations in posts #5 and #8 not informative enough?
Can you tell me how much you understand this code? Did you write it yourself or copied it somewhere on the net?

Try it with the relays disconnected.

1 Like

I removed the for loop you addressed in post #5. For the watchdog items, I need to find why it makes such a glitch before completely changing the code to something new. This code was quite functional for a while... I had to make a few changes in the hardware (location of sensors and flow) to satisfy some parameters and now because the T&RH are changing in a different fashion, the previous code might not be functional.

Seriously? of course I understand it. Although I accept this is not anywhere close to a standard code for such a job. It is all because of constant changes in the items and removing different sources of noise. So some initial mistakes might still be there.

Some parts (like the for loop you found) are copied form net, but the whole thing is pretty much mine.

None of these minor fixes address the problem of an inadequate power supply. If the voltage droops due to a temporary overload (heater or motor startup current), brownout will cause the Arduino to malfunction.

OK, I forgot to add that the Arduino is always connected to an iMac (for constant serial monitoring) with a USB cable (with ferrite chokes). Also, I have it connected to a 5V power supply from the other input source. I thought it will be better to have this one too in case iMac shows any fluctuations in its ports. Arduino power supplies (including iMac) are using a different outlet plug and are totally separated from the chamber.

Sigh.


  for (i = 30; i < 53; i++) {
    pinMode(i, INPUT_PULLUP);
  }

  for (i = 8; i < 15; i++) {
    pinMode("A" + i, INPUT_PULLUP);
  }

  for (i = 14; i < 18; i++) {
    pinMode(i, INPUT_PULLUP);
  }

Sure! Thanks, but do you mean these part which are only in the initialization or the setup might be the cause of this glitching after 5-6 hours?

???
I thought you inserted these lines to prevent glitches
No, they are unlikely to be a source of glitches.
But I doubt is whether they are needed at all in the code.

This was one of the items I was told to do that might help. Apparently, right now this is not the issue and it keeps happening.
Today I'm only keeping the wet cycle active to track down the part in the code that fails to repeat the process in the middle of the cycle.