Environment controller.

For the 8 way relays I tied into a powerstrip following a instructable from google.
20x4lcd, 5 buttons, Arduino Mega, 1 dht11 3 dht22, ds1307. Running liquidmenu to manage the menu system.

#include <EEPROM.h>
#include <RTClib.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <LiquidMenu.h>
#include <DHT.h>
#include "Button.h"

#define dht_apin A0 //Analog sensor pin is connected to.
#define DHTTYPE DHT11
#define Light1Pin 7
#define Light2Pin 6

DHT dht(dht_apin,DHTTYPE);
LiquidCrystal_I2C lcd(0x27, 20, 4);
RTC_DS1307 rtc;

// Button objects instantiation
const bool pullup = true;
Button left(8, pullup);
Button right(9, pullup);
Button up(10, pullup);
Button down(11, pullup);
Button enter(12, pullup);

// Pin definitions and variables for their state.
const byte pin6 = 6;
byte pin6_level = 0;

const byte pinA4 = A4;
byte pinA4_value = 0;

const byte pinA5 = A5;
byte pinA5_value = 0;

// The analog reading sample period in seconds.
// It is later overwritten by it's EEPROM value.
unsigned short sample_period = 2;

// Text used for indication for the save lines.
char* input_saved;
char* output_saved;
int printTime();
const char* light1State();
const char* light2State();
int lightOn;
int lightOff;
int lightRelayPins[] = { 6,7 };

enum FunctionTypes {
	increase = 1,
	decrease = 2,
};

//temp/hum variables
int t1;
int h1;

// A LiquidLine object can be used more that once.
LiquidLine back_line(11, 1, "/BACK");


LiquidLine welcome_line1(1, 1, " Arduino ", LIQUIDMENU_VERSION);
LiquidLine welcome_line2(1, 2, "Garden Automater");
LiquidScreen welcome_screen(welcome_line1, welcome_line2);

// These lines direct to other menus.
LiquidLine timeC(0, 0, printTime);
//LiquidLine offON(9, 1, onOFF);
LiquidLine Lights(0, 1, "Lights>");
LiquidLine TempHum(0, 2, "Temp/Hum>");
LiquidScreen io_screen(Lights, TempHum, timeC);

// This is the first menu.
LiquidMenu main_menu(lcd, welcome_screen, io_screen, 1);

LiquidLine Light1(0, 1, "Light1: ", light1State);
LiquidLine Light2(0, 2, "Light2: ", light2State);
LiquidScreen light_screen(Light1,Light2,timeC);

LiquidLine lightOn_line(0, 1, "Time ON: ", lightOn);
LiquidLine lightOff_line(0, 2, "Time OFF: ", lightOff);
LiquidScreen oSecondary_screen(timeC, lightOn_line, lightOff_line, back_line);

// This is the second menu.
LiquidMenu Lights_menu(lcd, light_screen, oSecondary_screen);


LiquidLine temp1_line(0, 0, "Temp1: ", t1);
LiquidLine temp2_line(0, 1, "Temp2: ", pinA5_value);
LiquidLine temp3_line(0, 2, "Temp3: ", pinA5_value);
LiquidLine temp4_line(0, 3, "Temp4: ", pinA5_value);
LiquidScreen temp_screen(temp1_line, temp2_line, temp3_line, temp4_line);

LiquidLine hum1_line(0, 0, "Hum1: ", h1);
LiquidLine hum2_line(0, 1, "Hum2: ", pinA5_value);
LiquidLine hum3_line(0, 2, "Hum3: ", pinA5_value);
LiquidLine hum4_line(0, 3, "Hum4: ", pinA5_value);
LiquidScreen hum_screen(hum1_line, hum2_line, hum3_line, hum4_line);

LiquidLine iSample_line(0, 1, "Sample: ", sample_period, "s");
LiquidLine iSave_line(0, 2, "Save", input_saved);
LiquidScreen iSecondary_screen(iSample_line, iSave_line, back_line);

// And this is the final third menu.
LiquidMenu TempHum_menu(lcd, temp_screen,hum_screen, iSecondary_screen);

/*
 * LiquidSystem object combines the LiquidMenu objects to form
 * a menu system. It provides the same functions as LiquidMenu
 * with the addition of add_menu() and change_menu().
 */
LiquidSystem menu_system(main_menu, Lights_menu, TempHum_menu);


// Checks all the buttons.
void buttonsCheck() {
	if (right.check() == LOW) {
		menu_system.next_screen();
	}
	if (left.check() == LOW) {
		menu_system.previous_screen();
	}
	if (up.check() == LOW) {
		menu_system.call_function(increase);
	}
	if (down.check() == LOW) {
		menu_system.call_function(decrease);
	}
	if (enter.check() == LOW) {
		menu_system.switch_focus();
	}
}

// Callback function that will be attached to back_line.
void go_back() {
	// This function takes reference to the wanted menu.
	menu_system.change_menu(main_menu);
}

void goto_Lights_menu() {
	menu_system.change_menu(Lights_menu);
}

void goto_TempHum_menu() {
	menu_system.change_menu(TempHum_menu);
}

void on_light1() {
	if (digitalRead(Light1Pin)) {
		digitalWrite(Light1Pin, HIGH);
	}
	else {
		digitalWrite(Light1Pin, LOW);
	}
	analogWrite(pin6, pin6_level);
	output_saved = (char*)"  ";
}

void on_light2() {
	if (digitalRead(Light2Pin)) {
		digitalWrite(Light2Pin, HIGH);
	}
	else {
		digitalWrite(Light2Pin, LOW);
	}
	analogWrite(pin6, pin6_level);
	output_saved = (char*)"  ";
}

void decrease_pin6() {
	if (pin6_level > 25) {
		pin6_level -= 25;
	}
	else {
		pin6_level = 0;
	}
	analogWrite(pin6, pin6_level);
	output_saved = (char*)"  ";
}

void save_input() {
	EEPROM.put(11, sample_period);
	input_saved = (char*)" *";
}

void increase_lights() {
	if (lightOn <= 24) {
		lightOn = lightOn + 1;
	}
	else {
		lightOn = 24;
	}
}

void decrease_lights() {
	if (lightOff <= 24) {
		lightOff = -1;
	}
	else {
		lightOff = 0;
	}
}

void increase_samplePeriod() {
	if (sample_period < 10) {
		sample_period++;
		input_saved = (char*)"  ";
	}
}

void decrease_samplePeriod() {
	if (sample_period > 0) {
		sample_period--;
		input_saved = (char*)"  ";
	}
}

void setup() {
	Serial.begin(112000);

	pinMode(pin6, OUTPUT);

	// Reads the values recorded in the EEPROM
	EEPROM.get(9, pin6_level);
	EEPROM.get(11, sample_period);
	analogWrite(pin6, pin6_level);
	lcd.begin(20, 4);
	lcd.init();
	lcd.backlight();

	back_line.set_focusPosition(Position::LEFT);

	back_line.attach_function(1, go_back);
	back_line.attach_function(2, go_back);

	Lights.attach_function(1, goto_Lights_menu);
	Lights.attach_function(2, goto_Lights_menu);
	TempHum.attach_function(1, goto_TempHum_menu);
	TempHum.attach_function(2, goto_TempHum_menu);

	Light1.attach_function(increase, on_light1);
	Light1.attach_function(decrease, on_light1);
	Light2.attach_function(increase, on_light2);
	Light2.attach_function(decrease, on_light2);

	lightOn_line.attach_function(increase, increase_lights);
	lightOn_line.attach_function(decrease, decrease_lights);
	iSave_line.attach_function(1, save_input);
	iSave_line.attach_function(2, save_input);
	iSample_line.attach_function(increase, increase_samplePeriod);
	iSample_line.attach_function(decrease, decrease_samplePeriod);

	input_saved = (char*)" *";
	output_saved = (char*)" *";
	//onOFF = (char *)"ON";

	if (!rtc.begin()) {
		Serial.println("Couldn't find RTC");
		while (1);
	}

	if (!rtc.isrunning()) {
		Serial.println("RTC lost power, lets set the time!");

		// Comment out below lines once you set the date & time.
		// Following line sets the RTC to the date & time this sketch was compiled
		rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));

		// Following line sets the RTC with an explicit date & time
		// for example to set January 27 2017 at 12:56 you would call:
		// rtc.adjust(DateTime(2017, 1, 27, 12, 56, 0));
	}
	
	menu_system.update();
}

void loop() {
	buttonsCheck();

	h1 = dht.readHumidity();
	t1 = dht.readTemperature(true);

	// check if returns are valid, if they are NaN (not a number) then something went wrong!
	if (isnan(t1) || isnan(h1)) {
		Serial.println("Failed to read from DHT #1");
	}
	else {
		Serial.print("Humidity 1: ");
		Serial.print(h1);
		Serial.print(" %\t");
		Serial.print("Temperature 1: ");
		Serial.print(t1);
		Serial.println(" *C");
	}
	
	static unsigned long lastMillis_sample = 0;
	if (millis() - lastMillis_sample > (sample_period * 1000)) {
		lastMillis_sample = millis();
		menu_system.update();
	}

}

int printTime() {
	DateTime now = rtc.now();
	lcd.setCursor(0, 0);
	lcd.print(now.month(), DEC);
	lcd.print('/');
	lcd.print(now.day(), DEC);
	lcd.print('/');
	lcd.print(now.year(), DEC);
	lcd.print(' ');
	lcd.print(now.hour(), DEC);
	lcd.print(':');
	lcd.print(now.minute(), DEC);
	lcd.print(':');
	lcd.print(now.second(), DEC);
}

const char* light1State() {
	if (digitalRead(Light1Pin) == HIGH) {
		return "ON";
	}
	else
	{
		return "OFF";
	}

}

const char* light2State() {
	if (digitalRead(Light2Pin) == HIGH) {
		return "ON";
	}
	else
	{
		return "OFF";
	}

}

I still have to write in the extra dht22 sensors along with the functions for the menu, function to turn on/off humidifier, and a function to turn on/off lights.
I have been writing for about 6hrs now trying to make sure things are right and need a short break. Just a short bit left to do. It’s easy to tell what everything does I think, but the idea is to have the lights on in between a set time and humidifier on if humidity is below a set point. Many people should be able to make use of this.

Well done but what is Your question and what facts do You give us to help You?

Railroader:
Well done but what is Your question and what facts do You give us to help You?

Thank you very much, this is this biggest project I have completed so far.
If someone or anyone see’s a part that could be condensed or if see something that isn’t needed, I would like input on that. I am a beginner, never really stuck to working with this every day till now so there is much to learn for this and future reference.
Only place I feel should have the back button is the last screen since the screens can be navigated through. I have a SD CARD yet to connect, I need to write a function for that, would like to print date time, when a sensor comes on or off, and any changes in what a sensor sense’s(Temp/Humidity).
I already have the dht11 connected, and have 3 more dht22’s to connect so I also have to choose which pins to connect for those 3 and each relay, so that’s 11 more pins to use.
Had the idea of a array of pins for the relay, have it’s own menu, and the ability to go through which pin and or pins should be connected to lights and water. Kind of feel’s like a extra at the moment that’s not needed since writing this program, and can just write which relay pins should be tied to lights and water system.
However it would be nice to only have to rely on the system to manage what pins go to what and if not connected when set, print’s “pin not connected”, but that can be done in a future update as I just want to get this functioning right now. Spent about 6 month’s dealing with programming errors, what type of menu/library would like, and what and how should everything be displayed. I have and will continue to put a lot of work into this to make it as universal and beginner friendly as possible.

Sounds like the hard way to control stuff. (But the OP did say it was an Instructable).

You are more likely to get responses here if you break your project into workable chunks. The best place to start would be a system diagram.

#include <EEPROM.h>
#include <RTClib.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <LiquidMenu.h>
#include <DHT.h>
#include "Button.h"

#define dht_apin A0 //Analog sensor pin is connected to.
#define DHTTYPE DHT11
#define Light1Pin 7
#define Light2Pin 6

DHT dht(dht_apin, DHTTYPE);
LiquidCrystal_I2C lcd(0x27, 20, 4);
RTC_DS1307 rtc;

// Button objects instantiation
const bool pullup = true;
Button left(8, pullup);
Button right(9, pullup);
Button up(10, pullup);
Button down(11, pullup);
Button enter(12, pullup);

// Pin definitions and variables for their state.
const byte pin6 = 6;
byte pin6_level = 0;

const byte pinA4 = A4;
byte pinA4_value = 0;

const byte pinA5 = A5;
byte pinA5_value = 0;

// The analog reading sample period in seconds.
// It is later overwritten by it's EEPROM value.
unsigned short sample_period = 2;

// Text used for indication for the save lines.
char* input_saved;
char* output_saved;
int printTime();
const char* light1State();
const char* light2State();
int lightOn;
int lightOff;
int relayPins[] = { 6,7 };

enum FunctionTypes {
 increase = 1,
 decrease = 2,
};

//temp/hum variables
int t1;
int h1;

// A LiquidLine object can be used more that once.
LiquidLine back_line(11, 1, "/BACK");
LiquidLine timeC(0, 0, printTime);

LiquidLine welcome_line1(1, 1, " Arduino ", LIQUIDMENU_VERSION);
LiquidLine welcome_line2(1, 2, "Garden Automater");
LiquidScreen welcome_screen(welcome_line1, welcome_line2);

// These lines direct to other menus.
LiquidLine Lights(0, 1, "Lights>");
LiquidLine TempHum(0, 2, "Temp/Hum>");
LiquidScreen io_screen(Lights, TempHum, timeC);

// This is the first menu.
LiquidMenu main_menu(lcd, welcome_screen, io_screen, 1);

LiquidLine Light1(0, 1, "Light1: ", light1State);
LiquidLine Light2(0, 2, "Light2: ", light2State);
LiquidScreen light_screen(Light1, Light2, timeC);

LiquidLine lightOn_line(0, 1, "Time ON: ", lightOn);
LiquidLine lightOff_line(0, 2, "Time OFF: ", lightOff);
LiquidScreen oSecondary_screen(timeC, lightOn_line, lightOff_line, back_line);

// This is the second menu.
LiquidMenu Lights_menu(lcd, light_screen, oSecondary_screen);


LiquidLine temp1_line(0, 0, "Temp1: ", t1);
LiquidLine temp2_line(0, 1, "Temp2: ", pinA5_value);
LiquidLine temp3_line(0, 2, "Temp3: ", pinA5_value);
LiquidLine temp4_line(0, 3, "Temp4: ", pinA5_value);
LiquidScreen temp_screen(temp1_line, temp2_line, temp3_line, temp4_line);

LiquidLine hum1_line(0, 0, "Hum1: ", h1);
LiquidLine hum2_line(0, 1, "Hum2: ", pinA5_value);
LiquidLine hum3_line(0, 2, "Hum3: ", pinA5_value);
LiquidLine hum4_line(0, 3, "Hum4: ", pinA5_value);
LiquidScreen hum_screen(hum1_line, hum2_line, hum3_line, hum4_line);

LiquidLine iSample_line(0, 1, "Sample: ", sample_period, "s");
LiquidLine iSave_line(0, 2, "Save", input_saved);
LiquidScreen iSecondary_screen(iSample_line, iSave_line, back_line);

// And this is the final third menu.
LiquidMenu TempHum_menu(lcd, temp_screen, hum_screen, iSecondary_screen);

/*
 * LiquidSystem object combines the LiquidMenu objects to form
 * a menu system. It provides the same functions as LiquidMenu
 * with the addition of add_menu() and change_menu().
 */
LiquidSystem menu_system(main_menu, Lights_menu, TempHum_menu);


// Checks all the buttons.
void buttonsCheck() {
 if (right.check() == LOW) {
 menu_system.next_screen();
 }
 if (left.check() == LOW) {
 menu_system.previous_screen();
 }
 if (up.check() == LOW) {
 menu_system.call_function(increase);
 }
 if (down.check() == LOW) {
 menu_system.call_function(decrease);
 }
 if (enter.check() == LOW) {
 menu_system.switch_focus();
 }
}

// Callback function that will be attached to back_line.
void go_back() {
 // This function takes reference to the wanted menu.
 menu_system.change_menu(main_menu);
}

void goto_Lights_menu() {
 menu_system.change_menu(Lights_menu);
}

void goto_TempHum_menu() {
 menu_system.change_menu(TempHum_menu);
}

void on_light1() {
 if (digitalRead(Light1Pin)) {
 digitalWrite(Light1Pin, HIGH);
 }
 else {
 digitalWrite(Light1Pin, LOW);
 }
 output_saved = (char*)"  ";
}

void on_light2() {
 if (digitalRead(Light2Pin)) {
 digitalWrite(Light2Pin, HIGH);
 }
 else {
 digitalWrite(Light2Pin, LOW);
 }
 output_saved = (char*)"  ";
}

void off_light1() {
 if (digitalRead(Light1Pin)) {
 digitalWrite(Light1Pin, LOW);
 }
 else {
 digitalWrite(Light1Pin, HIGH);
 }
 output_saved = (char*)"  ";
}

void off_light2() {
 if (digitalRead(Light2Pin)) {
 digitalWrite(Light2Pin, LOW);
 }
 else {
 digitalWrite(Light2Pin, HIGH);
 }
 output_saved = (char*)"  ";
}

void save_input() {
 EEPROM.put(11, sample_period);
 input_saved = (char*)" *";
}

void increase_lightsOn() {
 if (lightOn <= 24) {
 lightOn = lightOn + 1;
 }
 else {
 lightOn = 24;
 }
}

void decrease_lightsOn() {
 if (lightOn <= 24) {
 lightOn =- 1;
 }
 else {
 lightOn = 0;
 }
}

void increase_lightsOff() {
 if (lightOff <= 24) {
 lightOff = lightOn + 1;
 }
 else {
 lightOff = 24;
 }
}

void decrease_lightsOff() {
 if (lightOff <= 24) {
 lightOff = -1;
 }
 else {
 lightOff = 0;
 }
}

void increase_samplePeriod() {
 if (sample_period < 10) {
 sample_period++;
 input_saved = (char*)"  ";
 }
}

void decrease_samplePeriod() {
 if (sample_period > 0) {
 sample_period--;
 input_saved = (char*)"  ";
 }
}

void setup() {
 Serial.begin(112000);

 pinMode(pin6, OUTPUT);
 for (int r = 0; r < 2; r++) {
 pinMode(relayPins[r], OUTPUT);
 digitalWrite(relayPins[r],LOW);
 }
 // Reads the values recorded in the EEPROM
 EEPROM.get(9, pin6_level);
 EEPROM.get(11, sample_period);
 analogWrite(pin6, pin6_level);
 lcd.begin(20, 4);
 lcd.init();
 lcd.backlight();

 back_line.set_focusPosition(Position::LEFT);

 back_line.attach_function(1, go_back);
 back_line.attach_function(2, go_back);

 Lights.attach_function(1, goto_Lights_menu);
 Lights.attach_function(2, goto_Lights_menu);
 TempHum.attach_function(1, goto_TempHum_menu);
 TempHum.attach_function(2, goto_TempHum_menu);

 Light1.attach_function(increase, on_light1);
 Light1.attach_function(decrease, off_light1);
 Light2.attach_function(increase, on_light2);
 Light2.attach_function(decrease, off_light2);

 lightOn_line.attach_function(increase, increase_lightsOn);
 lightOn_line.attach_function(decrease, decrease_lightsOn);
 lightOff_line.attach_function(increase, increase_lightsOff);
 lightOff_line.attach_function(decrease, decrease_lightsOff);
 iSave_line.attach_function(1, save_input);
 iSave_line.attach_function(2, save_input);
 iSample_line.attach_function(increase, increase_samplePeriod);
 iSample_line.attach_function(decrease, decrease_samplePeriod);

 input_saved = (char*)" *";
 output_saved = (char*)" *";

 if (!rtc.begin()) {
 Serial.println("Couldn't find RTC");
 while (1);
 }
 if (!rtc.isrunning()) {
 Serial.println("RTC lost power, lets set the time!");

 // Comment out below lines once you set the date & time.
 // Following line sets the RTC to the date & time this sketch was compiled
 rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));

 // Following line sets the RTC with an explicit date & time
 // for example to set January 27 2017 at 12:56 you would call:
 // rtc.adjust(DateTime(2017, 1, 27, 12, 56, 0));
 }
 menu_system.update();
}
void loop() {
 buttonsCheck();
 h1 = dht.readHumidity();
 t1 = dht.readTemperature(true);

 // check if returns are valid, if they are NaN (not a number) then something went wrong!
 if (isnan(t1) || isnan(h1)) {
 Serial.println("Failed to read from DHT #1");
 }
 else {
 Serial.print("Humidity 1: ");
 Serial.print(h1);
 Serial.print(" %\t");
 Serial.print("Temperature 1: ");
 Serial.print(t1);
 Serial.println(" *C");
 }
 static unsigned long lastMillis_sample = 0;
 if (millis() - lastMillis_sample > (sample_period * 1000)) {
 lastMillis_sample = millis();
 menu_system.update();
 }

}
int printTime() {
 DateTime now = rtc.now();
 lcd.setCursor(0, 0);
 lcd.print(now.month(), DEC);
 lcd.print('/');
 lcd.print(now.day(), DEC);
 lcd.print('/');
 lcd.print(now.year(), DEC);
 lcd.print(' ');
 lcd.print(now.hour(), DEC);
 lcd.print(':');
 lcd.print(now.minute(), DEC);
 lcd.print(':');
 lcd.print(now.second(), DEC);
}
const char* light1State() {
 if (digitalRead(Light1Pin) == HIGH) {
 return "ON";
 }
 else
 {
 return "OFF";
 }
}
const char* light2State() {
 if (digitalRead(Light2Pin) == HIGH) {
 return "ON";
 }
 else
 {
 return "OFF";
 }
}
void lightProgram() {
 DateTime now = rtc.now();
 int hour = now.hour();
 for (int a = 0; a < 2; a++) {
 if (lightOn == hour) {
 Serial.print("Lights on!");
 digitalWrite(relayPins[a], HIGH);
 }
 if (lightOff == hour) {
 Serial.print("Lights on!");
 digitalWrite(relayPins[a], LOW);
 }
 }
}

This works and is a updated version from previously, the humidity control function still needs to be written but that is easy and will only take a few minutes to write, so I wrote the light program, or the program to be run setting the relays to high or low depending on a condition that is connected to the set relay pins.
The relay/powerstrip system can be found by searching “arduinrelay” or something similar, not into hacking up good cords and thought would be best to tie the relays into power receptacles so can plug and turn on w/o hacking up any wires.
The program says what’s connected to what so I don’t see the point at fritzing since I am horrible at it, and it’s time consuming when could just understand the connections through the code.
If you check my post history you can see the progress of this project and my search for a easily managable menu system that could support additional code. Built the menu slowly starting with a example, used previous sketches to recycle workable code for the sensors being used, adding a small bit each time, dealing with one issue at a time until getting to this workable version.
There is still more to write for the additional dht sensors and relay pins, along with hum/water control, datalogging date time when a sensor is on or off and values when changed to a sd card, and possibly expand to wifi to manage through a webpage and view the data.