Arduino Vivarium Controller - Freezing after random elapsed time.

I have sleuthed through this forum a bit to learn how to code my first arduino projects. This is my first post. I am at my wits end. I don't know what is wrong and need your help. I have been helping my cousin with creating a vivarium with full climate control for his snake enclosure. So far I have been unable to get my code to actually work for more than 3 days at a time. The arduino will periodically freeze and I am not sure if it is a memory problem or a potential hardware problem

Hardware: Arduino Mega 2560 DS1307 RTC - powered by arduino 16x2 LCD - Powered by arduino (3) DHT21 Temperature/Humidity Sensors - powered by arduino 8 Channel Relay - Power for the equipment comes from an external source ---(2) under tank heaters ---(1) Humidifier ---(6) Led Lights ---(1) Ventilation Fan

Code Overview:

The code is supposed to initialize and use the time generated from the RTC to make determinations about whether it should be in Daytime operation or Nighttime operation.

Daytime Operation - At 8:00am it initializes and switches from night mode to day mode - Night lights turn off - Day lights turn on - Maxtemp/Mintemp and Maxtemp2/Mintemp2 change to the values defined in their respective functions

-The tank is constantly monitoring humidity except when it is either watering the tank or venting the tank. -It should be updating the sensor values frequently and displaying them as well as time on the LCD screen. -It should not crash.

Nighttime Operation -At 9pm night time initializes -Night lights turn on -Day lights turn off -Maxtemp/Mintemp and Maxtemp2/Mintemp2 change to the values defined in the night time functions

The code will run and operates as it should for indeterminate amounts of time. I have tested individual functions and have not had a problem with the operation of those either. I was wondering if anyone would be able to look over my code and give me an idea of what I am doing wrong. Whether it is a simple coding error or possibly a problem with power consumption. I am not extremely well versed in arduino coding. This was actually my first project. I have since then completed other more simple projects but am still struggling to get this working correctly. Any help will be MUCH appreciated.

#include <Time.h>
#include <DS1307RTC.h>
#include "DHT.h"
#include <SPI.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

#define DS1307_ADDRESS 0x68 //RTC ADDRESS
#define DHTPIN 2     //PROBE # 1   HOT SIDE PROBE
#define DHTPIN_A 3   //COLD SIDE PROBE
#define DHTPIN_D 6   //PROBE # 4   AMBIENT PROBE 2


#define I2C_ADDR    0x27 // <<----- Add your address here.  Find it from I2C Scanner
#define BACKLIGHT_PIN     3
#define En_pin  2
#define Rw_pin  1
#define Rs_pin  0
#define D4_pin  4
#define D5_pin  5
#define D6_pin  6
#define D7_pin  7


LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);

byte zero = 0x00; //workaround for issue #527

#define DHTTYPE DHT21   // DHT 21  

// Initialize DHT sensor for normal 16mhz Arduino
DHT dht(DHTPIN, DHTTYPE);
DHT dht_A(DHTPIN_A,DHTTYPE);
DHT dht_D(DHTPIN_D,DHTTYPE);

const  int humidityPin = 22; //HUMIDIFIER
const int  digitalPin = 24;  //HEATER 1
const  int digitalPin2 = 26; //HEATER 2

const  int digitalPin4 = 30; //DAY LIGHTS
const  int digitalPin5 = 32; //NIGHT LIGHTS
const  int digitalPin6 = 34; //FAN

int maxtemp; //Max temp for hot side
int mintemp; //Min temp for hot side
int maxtemp2;//Max temp for cold side
int mintemp2;//Min temp for cold side
tmElements_t tm;

const int minhumidity = 75; //Minimum Humidity Level as read by ambient sensor
const int maxhumidity = 97; //Maximum humidity level as read by ambient sensor

float f1; // Hot side temperature in farenheit
float f2; // Cold Side temperature in farenheit
float f5; // Ambient Temperature in farenheit
float h1; // Hot side humidity sensor value
float h2; // Cold side humidity sensor value
float h5; // Ambient humidity sensor value

void setup(){
  
  delay(5000);
  
  Serial.begin(9600);
  while (!Serial) ; // wait for serial
  delay(200);
 
  
  
  lcd.begin (16,2); //  <<----- My LCD was 16x2
  
  pinMode(humidityPin,OUTPUT);
  pinMode(digitalPin, OUTPUT);
  pinMode(digitalPin2,OUTPUT);

  pinMode(digitalPin4,OUTPUT);
  pinMode(digitalPin5,OUTPUT);
  pinMode(digitalPin6,OUTPUT);

   
  Wire.begin();
  dht.begin(); //Hot Side sensor
  dht_A.begin(); // Cold Side sensor
  dht_D.begin(); // Ambient Sensor
  
  dayLights(); 
  DayheaterOne();
  DayheaterTwo();
    
lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
lcd.setBacklight(HIGH);
lcd.clear();
lcd.setCursor(0,0);
delay(1500);
}



void  loop(){ 
  
  const int morntime = 8; //Time in hour(s) at which morning begins
  const int nighttime = 20; //Time in hour(s) at which night time begins
  const int HR1 = 8;//HOUR for function call watering
  const int HR2 = 15;//HOUR for function call venting
  const int HR3 = 23;//HOUR for function call N/A
  const int VT1 = 15;//MINUTE at which venting will shut off
  const int VT2 = 30;//MINUTE at which watering will shut off
 

 Update(); 
 delay(3000);
 Coldheater(); // Cold side heater control
 Warmheater(); // Warm side heater control
 showLCD(); // Display the values on the LCD
 
//DAYTIME IS FROM 8:00am to 9:00pm -- 13 hours  
    if(tm.Hour == HR1 && tm.Minute <= 1){
     dayLights(); 
     DayheaterOne();
     DayheaterTwo();
     delay(1000);
    }

    //VENTS FROM 3:00 to 3:15 - 
    else if (tm.Hour == HR2 && tm.Minute <= 15){ 
         Venting(); 
         delay(1000);
    }
      //NIGHT TIME LIGHT/HEAT SETUP
           else if(tm.Hour == 21 && tm.Minute <= 1){
             nightLights();
             NightheaterOne();
             NightheaterTwo();
             delay(1000);
           }
           //WATERS from 11:00 to 11:30   
           else if (tm.Hour == HR3 && tm.Minute <= 30){
                Watering();
                delay(1000);
              } 
           //Humidity Control
            else{
                humidity();
                delay(1000);
              }
}//END VOID LOOP


//HUMIDITY CONTROL
void humidity(){

  if (h5 <= minhumidity){
            digitalWrite(humidityPin,HIGH); 
            delay(1000);   
  }

  else if (h5 >= maxhumidity){
       digitalWrite(humidityPin,LOW);
       delay(1000); 
  }
  else {
       delay(1000); 
      } 
}


void showLCD(){
  
  lcd.clear();
  lcd.setCursor(0,0);           
  lcd.print("Warm Side Temp:");
  lcd.setCursor(0, 1);           
  lcd.print(f1);       
  lcd.print((char)223);          
  lcd.print("F");
  delay(1500);
  
  lcd.clear();
  lcd.setCursor(0,0);           
  lcd.print("Cold Side Temp:");
  lcd.setCursor(0,1);           
  lcd.print(f2);       
  lcd.print((char)223);          
  lcd.print("F");
  delay(1500);
  
  lcd.clear();
  lcd.setCursor(0,0);           
  lcd.print("Ambient Temp:");
  lcd.setCursor(0,1);           
  lcd.print(f5);       
  lcd.print((char)223);          
  lcd.print("F");
  delay(1500);
  
  lcd.clear();
  lcd.setCursor(0, 0);           
  lcd.print("Humidity:");
  lcd.setCursor(0, 1);          
  lcd.print(h5);            //HUMIDITY SENSOR
  lcd.print("%");
  delay(1500);
  
  lcd.clear();
  lcd.setCursor(0, 0);           
  lcd.print("Time:");
  lcd.setCursor(0, 1);          
  lcd.print(tm.Hour);
  lcd.print(":");
  lcd.print(tm.Minute); 
}//END LCD DISPLAY
 


//DAYLIGHTS SETTINGS
void dayLights(){
  digitalWrite(digitalPin4,HIGH);   //DAYLIGHTS
  digitalWrite(digitalPin5,LOW);  //NIGHTLIGHTS
  delay(1000);

}

//NIGHT LIGHTS SETTINGS
void nightLights(){
  digitalWrite(digitalPin4,LOW); //DAYLIGHTS
  digitalWrite(digitalPin5,HIGH);  //NIGHTLIGHTS
  delay(1000);  
}
  
  
//Warm Side Heater Control
void Warmheater(){
    if (f1 <= mintemp) {
              digitalWrite(digitalPin,HIGH);
              delay(1000); 
    }  
    else if(f1 >= maxtemp){
        digitalWrite(digitalPin,LOW);
        delay(1000); 
    }    
    else {
      delay(1000); 
        
  }
}

//Cold Side Heater Control
void Coldheater(){
    if (f2 <= mintemp2){
             digitalWrite(digitalPin2,HIGH); 
             delay(1000);   
          }
    else if(f2 >= maxtemp2){
            digitalWrite(digitalPin2,LOW);
            delay(1000); 
          }   
          
    else {
        delay(1000);  
  }
}



//HEATER TEMPERATURES/////////////////
//DAY HEATER 1  
void DayheaterOne(){
  maxtemp = 85;    
  mintemp = 82;
}

//DAYHEATER 2
void DayheaterTwo(){
 maxtemp2 = 77;
 mintemp2 = 75;
}  

//NIGHT HEATER 1
void NightheaterOne(){
 maxtemp = 79;    
 mintemp = 77;
}

//NIGHT HEATER 2
void NightheaterTwo(){ 
 maxtemp2 = 75;
 mintemp2 = 73;
}



void Watering(){
     digitalWrite(digitalPin6,LOW); //FAN
     digitalWrite(humidityPin,HIGH);  
     delay(1000);   
}

void Venting(){
   digitalWrite(digitalPin6,HIGH); // FAN
   delay(1000); 
}

void Update(){
  f5 = dht_D.readTemperature(true);
  f2 = dht_A.readTemperature(true);
  f1 = dht.readTemperature(true);
  h5 = dht_D.readHumidity();
  RTC.read(tm);
  delay(1000);
}

I guess a more general question would be: Does it look like I have properly coded the system in question? I really could use either affirmation of tips or pointers to get this thing working. If not.. I fear for the snake that has to live in this vivarium.

bump

I can't see anything obvious wrong. How much Available Memory do you have?

If it's low, can you use the F macro to move some of your strings into progmem? e.g.:

  lcd.print(F("Humidity:"));

I will run that program to find how much memory I have available. When I was uploading the code it said it only used around 7% of the memory.

Could you expand on what you mean by if its low, moving the string into the lcd print? Like I said, I do not have much experience with arduino coding. I am always open to learning more!

RAM and program space are separate on the arduino. You can have a small sketch that nonetheless uses up all of the (tiny amount of) RAM available. Call the freememory function in your existing sketch to see what's going on in this regard.

The F macro (see example above) helps in a low RAM situation by keeping literal character strings from consuming that memory unnecessarily.

So by changing my LCD prints to the F macro example you gave, it does not store those values in the RAM? Could it be possible that the program is freezing then because of excessive RAM use? Do you know if the tm.time strings are also using up a lot of RAM? Or would it write over the previous string? Same goes for the temperature readings. Would those be taking up RAM or would they be overwriting the value with each Update()?

Thanks for the help! It is greatly appreciated!

Any other possible problems?