Commercial Lighting Controller

I'm making a controller to control a grow light that uses a 0-10v line to control intensity and spectrum.
Currently the code and hardware is designed for use on a 328P, or one of the newer ICs from Microchip like the ATTINY3224.

The user uses one of 5 buttons to scroll through a 4x16 lcd display to select, view and change on/off times and a main screen displaying time of day and settings, which are stored in EEPROM. Pushing the buttons and changing values is controlled in software using state control, see code below.
The hardware uses an RTC for time keeping, MCP23008 to break out the buttons, an MCP4725 DAC to convert digital 0 - 5v to analog with an OP Amp to take things to 0 - 10v (or MCP4726 DAC without the OP Amp as it has 2x out gain option), and theres an LDR to dim the LCD backlight in the dark.

Code:


/*********************
Draft code (v4) for timer interface via buttons and LCD display using a DS3231 RTC for
time and UNO as MCU
The user pushes the SELECT and RIGHT button to see on and off times, these times are
adjustable with the UP, DOWN, LEFT, and RIGHT buttons.
**********************/

// Include the following libraries:
#include "HystFilter.h"
#include <RTClib.h>
#include <DST_RTC.h>         // Supplemental library for DST.
#include <Wire.h>
#include <LiquidCrystal.h>
#include <StateMachine.h>
#include <EEPROM.h>
#include <pu2clr_mcp23008.h> // Library for MCP23008 I2C GPIO port expander
#include <Adafruit_MCP4725.h> 

Adafruit_MCP4725 dac;        // Create structure for DAC
  
const int LDRPIN = 5;       // Pin for LDR to control LCD backlight
int ldrValue;
const int LCDBACKLIGHT = 9;  // LCD backlight
const int LDRCUTOFFVALUE = 550;
HystFilter potA( 1024, 2, 20 ) ;  // 10 bit ADC = 1024, 64 discrete output values required, margin = 3 units (of 1024)

int channelNum;              // Number of channel.

int increment = 1;           // Amount to increment up or down the time on/off variables.

int timeOnHour[4];           // Turn on light at hour.
int timeOnMinute[4];         // Turn on light at minute.
int timeOffHour[4];          // Turn off light at hour.
int timeOffMinute[4];        // Turn off light at minute.

int settingDST;

int chanStat[4];             // Variable for channel on/off status.

int timer = millis();        // Timer for while loops, to be set and reset to 10 seconds at each button push.  
unsigned long lastmillis = 0;

const int BUTTONLEFT   = 3;  // Physical second left button
const int BUTTONUP     = 4;  // Physical left button
const int BUTTONSELECT = 5;  // Physical center button
const int BUTTONDOWN   = 6;  // Physical right button
const int BUTTONRIGHT  = 7;  // Physical second right button

int ButtonLeftState    = 0;  // State variable for left button
int ButtonUpState      = 0;  // State variable for up button
int buttonSelectState  = 0;  // State variable for select button
int ButtonDownState    = 0;  // State variable for down button
int ButtonRightState   = 0;  // State variable for right button

RTC_DS3231 rtc;              // Create structure for DS3231 RTC.
DST_RTC dst_rtc;             // DST object
const char rulesDST[] = "US"; // US DST rules

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

MCP mcp;                     // Create object for MCP23008

enum APP_STATE {
  STATE_NORMAL_SCREEN,       // Normal state is the default state that displays time of day.
  STATE_TO_ON_HOUR_SCREEN,   // Transition state between normal screen and 'on hour' screen.
  STATE_ON_HOUR_SCREEN,      // This state allows the user to change the time on hour.  
  STATE_ON_MINUTE_SCREEN,    // This state allows the user to change the time on minute.
  STATE_OFF_HOUR_SCREEN,     // This state allows the user to change the off hour.
  STATE_OFF_MINUTE_SCREEN,   // This state allows the user to change the off minute.
  STATE_TO_NORMAL_SCREEN,     // Transition state to normal screen.
  TO_DST_OPTION_SCREEN,
  DST_OPTION_SCREEN
  } state;
  
/////////////////////////////////////////SETUP/////////////////////////////////////////

void setup() {
   
 pinMode(LCDBACKLIGHT, OUTPUT);
 lcd.begin(16, 4);
 //Serial.begin(9600);
 dac.begin(0x60);                      // Start DAC
 mcp.setup(0x20, 0B11111000);          // Use address 0X20, and GPIO 0 to 4 are set to input (buttons) and 5 to 7 are output.
 mcp.setRegister(REG_GPPU, 0B1111000); // sets GPIO 0 to 4 with internal pull up resistors
 
timeOnHour[0] =    EEPROMReadInt(0);   // Read variables stored in EEPROM.
timeOnHour[1] =    EEPROMReadInt(2);   // Read variables stored in EEPROM.
timeOnHour[2] =    EEPROMReadInt(4);   // Read variables stored in EEPROM.
timeOnHour[3] =    EEPROMReadInt(6);   // Read variables stored in EEPROM.

timeOnMinute[0] =  EEPROMReadInt(8);   // Read variables stored in EEPROM.
timeOnMinute[1] =  EEPROMReadInt(10);  // Read variables stored in EEPROM.
timeOnMinute[2] =  EEPROMReadInt(12);  // Read variables stored in EEPROM.
timeOnMinute[3] =  EEPROMReadInt(14);  // Read variables stored in EEPROM.

timeOffHour[0] =   EEPROMReadInt(16);  // Read variables stored in EEPROM.
timeOffHour[1] =   EEPROMReadInt(18);  // Read variables stored in EEPROM.
timeOffHour[2] =   EEPROMReadInt(20);  // Read variables stored in EEPROM.
timeOffHour[3] =   EEPROMReadInt(22);  // Read variables stored in EEPROM.

timeOffMinute[0] = EEPROMReadInt(24);  // Read variables stored in EEPROM.
timeOffMinute[1] = EEPROMReadInt(26);  // Read variables stored in EEPROM.
timeOffMinute[2] = EEPROMReadInt(28);  // Read variables stored in EEPROM.
timeOffMinute[3] = EEPROMReadInt(30);  // Read variables stored in EEPROM. 

settingDST       = EEPROMReadInt(32);  // Read variables stored in EEPROM.

channelNum = 0;
   
   if (! rtc.begin()) {                // Confirms that the RTC is connected and working.    
  lcd.print("RTC not responding");  
  }  
}

/////////////////////////////////////////LOOP/////////////////////////////////////////

void loop() {

// ldrValue = analogRead(LDRPIN);
 
 if (potA.getOutputLevel(analogRead(LDRPIN)) == 1) {
  digitalWrite(LCDBACKLIGHT, LOW);  
  }
  else {
   digitalWrite(LCDBACKLIGHT, HIGH); 
  }
 
 ButtonUpState     = mcp.gpioRead(BUTTONUP);
 buttonSelectState = mcp.gpioRead(BUTTONSELECT);
 ButtonDownState   = mcp.gpioRead(BUTTONDOWN); 
 ButtonLeftState   = mcp.gpioRead(BUTTONLEFT);
 ButtonRightState  = mcp.gpioRead(BUTTONRIGHT);
 
  DateTime now = rtc.now();
  DateTime dstTime = dst_rtc.calculateTime(now); // takes into account DST
  
  int hour_Now;
  int minute_Now;
   
 if(settingDST == 1){
    hour_Now = dstTime.hour();
    minute_Now = dstTime.minute();
  }
 if(settingDST == 0){
    hour_Now = now.hour();
    minute_Now = now.minute();  
  }

 long milli_Time_Now   = Time_To_Millis(hour_Now, minute_Now);  // Convert time from RTC to millis          
 long milli_Time_On_0  = Time_To_Millis(timeOnHour[0], timeOnMinute[0]); 
 long milli_Time_Off_0 = Time_To_Millis(timeOffHour[0], timeOffMinute[0]);
 long milli_Time_On_1  = Time_To_Millis(timeOnHour[1], timeOnMinute[1]); 
 long milli_Time_Off_1 = Time_To_Millis(timeOffHour[1], timeOffMinute[1]); 
 long milli_Time_On_2  = Time_To_Millis(timeOnHour[2], timeOnMinute[2]); 
 long milli_Time_Off_2 = Time_To_Millis(timeOffHour[2], timeOffMinute[2]);
 long milli_Time_On_3  = Time_To_Millis(timeOnHour[3], timeOnMinute[3]); 
 long milli_Time_Off_3 = Time_To_Millis(timeOffHour[3], timeOffMinute[3]);

 if ((milli_Time_Now >= milli_Time_On_0) && (milli_Time_Now < milli_Time_Off_0)) { // Channel 0 daytime actions
    dac.setVoltage(4006, false); 
    chanStat[0] = 1; 
    } 
 if (milli_Time_Now < milli_Time_On_0 || milli_Time_Now >= milli_Time_Off_0)  {    // Channel 0 nightime actions
    dac.setVoltage(0, false);
    chanStat[0] = 0; 
    }
 if ((milli_Time_Now >= milli_Time_On_1) && (milli_Time_Now < milli_Time_Off_1)) { // Channel 0 daytime actions
    //dac.setVoltage(4006, false); 
    chanStat[1] = 1; 
    } 
 if (milli_Time_Now < milli_Time_On_1 || milli_Time_Now >= milli_Time_Off_1)  {    // Channel 0 nightime actions
    //dac.setVoltage(0, false);
    chanStat[1] = 0; 
    }
 if ((milli_Time_Now >= milli_Time_On_2) && (milli_Time_Now < milli_Time_Off_2)) { // Channel 0 daytime actions
    //dac.setVoltage(4006, false); 
    chanStat[2] = 1; 
    } 
 if (milli_Time_Now < milli_Time_On_2 || milli_Time_Now >= milli_Time_Off_2)  {    // Channel 0 nightime actions
    //dac.setVoltage(0, false);
    chanStat[2] = 0; 
    }
 if ((milli_Time_Now >= milli_Time_On_3) && (milli_Time_Now < milli_Time_Off_3)) { // Channel 0 daytime actions
    //dac.setVoltage(4006, false); 
    chanStat[3] = 1; 
    } 
 if (milli_Time_Now < milli_Time_On_3 || milli_Time_Now >= milli_Time_Off_3)  {   // Channel 0 nightime actions
    //dac.setVoltage(0, false);
    chanStat[3] = 0; 
    }

switch(state) {
    case STATE_NORMAL_SCREEN:
      if(millis() - lastmillis > 500) {   // Update normal screen every second.
        lastmillis = millis(); 
        LCD_Normal_Screen();              // While normal screen is displayed show time.
        LCD_Channel_Status();             // Display channel status 
      }      
      if(buttonSelectState == HIGH) {     // Check if any buttons pressed and if so go to select screen.
        Debounce();                       // Debounce
        state = TO_DST_OPTION_SCREEN;
        lastmillis = millis();            // Take note of the time when we switch to the select screen.
      }
      break;
      
    case STATE_TO_ON_HOUR_SCREEN:
      Transition_Screen();     
      state = STATE_ON_HOUR_SCREEN;
      break;

    case STATE_TO_NORMAL_SCREEN:
      lastmillis = millis();              // Reset millis    
      lcd.clear();
      channelNum = 0;
      state = STATE_NORMAL_SCREEN;
      break;  


    case TO_DST_OPTION_SCREEN:
      lastmillis = millis();              // Reset millis    
      lcd.clear();
      LCD_Normal_Screen();
      Display_DST_Options();

      state = DST_OPTION_SCREEN; 
      break;
    
    case DST_OPTION_SCREEN:
      if(millis() - lastmillis > 10000) { // If more than 10 seconds elapse return to normal screen.
        state = STATE_TO_NORMAL_SCREEN;
        lcd.noBlink();
        break;                            // Exit the switch statement if 10 seconds have elapsed without buttons pushed.       
      }
      if(ButtonUpState == HIGH) {         // Actions to complete when up button pressed.                                        
        Debounce();                       // Debounce
        lastmillis = millis();            // Reset millis countdown
        settingDST += 1;
        if (settingDST > 1){
          settingDST = 0;
          }
        Display_DST_Options(); 
        EEPROMWriteDST();                  // Write DST setting to EEPROM. 
      }      
      if(ButtonDownState == HIGH) {       // Actions to complete when down button pressed.
        Debounce();                       // Debounce
        lastmillis = millis();            // Reset millis countdown
        settingDST -= 1;
        if (settingDST < 0){
          settingDST = 1;        
        }
        Display_DST_Options();
        EEPROMWriteDST();                  // Write DST setting to EEPROM.        
      }
      if(buttonSelectState == HIGH){
       Debounce();                        // Debounce 
       lastmillis = millis();             // Reset millis countdown                 
       Display_DST_Options();
       state = STATE_TO_ON_HOUR_SCREEN;     
       }       
       break;
       
    case STATE_ON_HOUR_SCREEN:
      if(millis() - lastmillis > 10000) { // If more than 10 seconds elapse return to normal screen.
        state = STATE_TO_NORMAL_SCREEN;
        lcd.noBlink();
        break;                            // Exit the switch statement if 10 seconds have elapsed without buttons pushed.
      }
      lcd.setCursor(8, 2);                // Move cursor to timeOnHour.
      lcd.blink();                        // Set cursor to blink over timeOnHour1.   
      if(ButtonUpState == HIGH) {         // Actions to complete when up button pressed.                                        
        Debounce();                       // Debounce
        lastmillis = millis();            // Reset millis countdown
        timeOnHour[channelNum] = Increment_Up_24(timeOnHour[channelNum]); // Increment time up one hour
        EEPROMWriteTimeOnHour();            
        lcd.clear();
        display_On_Off_Times();           // Update the display  
      }
           
      if(ButtonDownState == HIGH) {       // Actions to complete when down button pressed.
        Debounce();                       // Debounce
        lastmillis = millis();            // Reset millis countdown
        timeOnHour[channelNum] = Increment_Down_24(timeOnHour[channelNum]);        
        EEPROMWriteTimeOnHour();  
        lcd.clear();
        display_On_Off_Times();           // Update the display
      }
      if(ButtonRightState == HIGH) {
        Debounce();                       // Debounce
        lastmillis = millis();            // Reset millis countdown            
        state = STATE_ON_MINUTE_SCREEN;
      }      
      if(buttonSelectState == HIGH){
       Debounce();                        // Debounce 
       lastmillis = millis();             // Reset millis countdown                 
       channelNum += 1;
       if (channelNum >3){
        channelNum = 0;
        } 
       Transition_Screen();     
       state = STATE_TO_ON_HOUR_SCREEN;     
       }       
       break;

    case STATE_ON_MINUTE_SCREEN:
      if(millis() - lastmillis > 10000) { // If more than 10 seconds elapse return to normal screen.
        state = STATE_TO_NORMAL_SCREEN;
        lcd.noBlink();
        break;                            // Exit the switch statement if 10 seconds have elapsed without buttons pushed.
      }
       if(timeOnHour[channelNum] > 9) {   // Moves cursor over if timeOffHour 2 digits wide, then move flashing cursor over one.
       lcd.setCursor(11, 2);        
       }
       else {lcd.setCursor(10, 2);        // Move cursor to timeOnMinute1.
       }
      lcd.blink();                        // Set cursor to blink over timeOnMinute1.      
      if(ButtonUpState == HIGH) {         // Actions to complete when up button pressed.                                        
        Debounce();                       // Debounce
        lastmillis = millis();            // Reset millis countdown
        timeOnMinute[channelNum] = Increment_Up_60(timeOnMinute[channelNum]);
        EEPROMWriteTimeOnMinute();  
        lcd.clear();
        display_On_Off_Times();           // Update the display  
      }      
      if(ButtonDownState == HIGH) {       // Actions to complete when down button pressed.
        Debounce();                       // Debounce
        lastmillis = millis();            // Reset millis countdown
        timeOnMinute[channelNum] = Increment_Down_60(timeOnMinute[channelNum]);
        EEPROMWriteTimeOnMinute() ; 
        lcd.clear();
        display_On_Off_Times();           // Update the display
      }  
      if(ButtonRightState == HIGH) {
        Debounce();                       // Debounce
        lastmillis = millis();            // Reset millis countdown       
        state = STATE_OFF_HOUR_SCREEN;
        }
      if(buttonSelectState == HIGH){
        Debounce();                        // Debounce
        lastmillis = millis();             // Reset millis countdown               
        channelNum += 1;
       if (channelNum >3){
         channelNum = 0;
         } 
       Transition_Screen();     
       state = STATE_TO_ON_HOUR_SCREEN;        
       }       
       break;            
             
     case STATE_OFF_HOUR_SCREEN:
      if(millis() - lastmillis > 10000) { // If more than 10 seconds elapse return to normal screen.
        state = STATE_TO_NORMAL_SCREEN;
        lcd.noBlink();
        break;                            // Exit the switch statement if 10 seconds have elapsed without buttons pushed.
      }

      lcd.setCursor(9, 3);       
      lcd.blink();                        // Set cursor to blink over timeOffHour1.
      
      if(ButtonUpState == HIGH) {         // Actions to complete when up button pressed.                                        
        Debounce();                       // Debounce
        lastmillis = millis();            // Reset millis countdown
        timeOffHour[channelNum] = Increment_Up_24(timeOffHour[channelNum]); // Increment time up one hour
        EEPROMWriteTimeOffHour();
        lcd.clear();
        display_On_Off_Times();           // Update the display  
      }
      
      if(ButtonDownState == HIGH) {       // Actions to complete when down button pressed.
        Debounce();                       // Debounce
        lastmillis = millis();            // Reset millis countdown
        timeOffHour[channelNum] = Increment_Down_24(timeOffHour[channelNum]);
        EEPROMWriteTimeOffHour();              
        lcd.clear();
        display_On_Off_Times();           // Update the display
      }
        
      if(ButtonRightState == HIGH) {
        Debounce();                       // Debounce
        lastmillis = millis();            // Reset millis countdown               
        state = STATE_OFF_MINUTE_SCREEN;
        }           
      if(buttonSelectState == HIGH){
       Debounce();                        // Debounce
       lastmillis = millis();             // Reset millis countdown                 
       channelNum += 1;
       if (channelNum >3){
        channelNum = 0;
        } 
       Transition_Screen();     
       state = STATE_TO_ON_HOUR_SCREEN;      
       }              
       break;      
        
     case STATE_OFF_MINUTE_SCREEN:
      if(millis() - lastmillis > 10000) { // If more than 10 seconds elapse return to normal screen.
        state = STATE_TO_NORMAL_SCREEN;
        lcd.noBlink();
        break;                            // Exit the switch statement if 10 seconds have elapsed without buttons pushed.
      }

       if(timeOffHour[channelNum] > 9) {  // moves cursor over if timeOffHour 2 digits wide, then move flashing cursor over one.
       lcd.setCursor(12, 3);        
       }
       else {lcd.setCursor(11, 3);        // Move cursor to timeOffMinute1.
       }
      lcd.blink();                        // Set cursor to blink over timeOffMinute1. 
  
      if(ButtonUpState == HIGH) {         // Actions to complete when up button pressed.                                        
        Debounce();                       // Debounce
        lastmillis = millis();            // Reset millis countdown
        timeOffMinute[channelNum] = Increment_Up_60(timeOffMinute[channelNum]);
        EEPROMWriteTimeOffMinute();
        lcd.clear();
        display_On_Off_Times();           // Update the display  
      }
      
      if(ButtonDownState == HIGH) {       // Actions to complete when down button pressed.
        Debounce();                       // Debounce
        lastmillis = millis();            // Reset millis countdown
        timeOffMinute[channelNum] = Increment_Down_60(timeOffMinute[channelNum]);
        EEPROMWriteTimeOffMinute();
        lcd.clear();
        display_On_Off_Times();           // Update the display
      }  
      if(ButtonRightState == HIGH) {
        Debounce();                       // Debounce
        lastmillis = millis();            // Reset millis countdown               
        state = STATE_TO_ON_HOUR_SCREEN;
        }           
      if(buttonSelectState == HIGH){
       Debounce();                        // Debounce
       lastmillis = millis();             // Reset millis countdown        
       channelNum += 1;
       if (channelNum >3){
        channelNum = 0;
        } 
       Transition_Screen();     
       state = STATE_TO_ON_HOUR_SCREEN;       
       }       
       break;     
   }  
}

/////////////////////////////////////////FUNCTIONS/////////////////////////////////////////

int Increment_Up_24(int var_To_Increment)// Increments a 0-24 hour variable up.
{
   var_To_Increment += increment;        // Increase the hour
  if(var_To_Increment > 24){             // Restrict hour values to 0-24 
    var_To_Increment = 0;
    }
  if(var_To_Increment < 0){
    var_To_Increment = 24;
    }  
  return var_To_Increment;
  }

int Increment_Down_24(int var_To_Increment)// Increments a 0-24 hour variable down.
{
    var_To_Increment -= increment;         // Decrease the hour
  if(var_To_Increment > 24){               // Restrict hour values to 0-24 
    var_To_Increment = 0;
    }
  if(var_To_Increment < 0){
    var_To_Increment = 24;
    }
  return var_To_Increment;  
  }

int Increment_Up_60(int var_To_Increment)// Increments a 0-60 hour variable up.
{
  var_To_Increment += increment;         // Increase the minute
  if(var_To_Increment > 59){             // Restrict minute values to 0-59 
    var_To_Increment = 0;
    }
  if(var_To_Increment < 0){
    var_To_Increment = 59;
      }  
  return var_To_Increment;  
  }

int Increment_Down_60(int var_To_Increment)// Increments a 0-60 hour variable down.
{
  var_To_Increment -= increment;           // Increase the minute
  if(var_To_Increment > 59){               // Restrict minute values to 0-59 
    var_To_Increment = 0;
    }
  if(var_To_Increment < 0){
    var_To_Increment = 59;
      }  
  return var_To_Increment;   
  }

long Time_To_Millis(int hours_, int minutes_) // Converts time from 00:00 to millis.
{      // Converts time to millis.

  long hourToConvert = long(hours_);
  long minuteToConvert = long(minutes_);
  long millis_Time = ((hourToConvert * 3600000) + (minuteToConvert * 60000));
  return millis_Time;  
  }

void Debounce()            // Debounce value to stop button entries skipping.
{
  delay(250);
  }
  
void Display_DST_Options()
{
  lcd.clear();  
  LCD_Normal_Screen();
  lcd.setCursor(0, 1);               // Move cursor to timeOnHour. 
  lcd.print("DST Set To:");  
  lcd.setCursor(6,2);
 if(settingDST == 1)
  {
  lcd.print("Auto"); 
  }
 if(settingDST == 0) 
  {
    lcd.setCursor(2,2);
  lcd.print("Auto DST Off");  
  }
}

void Transition_Screen()   // Clears and redraws the LCD during transitions.
{
  lastmillis = millis();   // Reset millis
  lcd.clear();
  display_On_Off_Times();  // The select on/off time screen is displayed.
  delay(100);
  } 

void LCD_Normal_Screen()   // Prints the current time on the LCD screen
{
   lcd.clear();
   
   int second_Now;
   int minute_Now;
   int hour_Now; 
   int day_Now;
   int month_Now; 
   int year_Now;
    
    DateTime now = rtc.now();
    DateTime dstTime = dst_rtc.calculateTime(now); // takes into account DST
 if(settingDST == 1){   
    second_Now = dstTime.second();
    minute_Now = dstTime.minute();
    hour_Now = dstTime.hour();
    day_Now = dstTime.day();
    month_Now = dstTime.month();
    year_Now =  dstTime.year();
  }
 if(settingDST == 0){
    second_Now = now.second();
    minute_Now = now.minute();
    hour_Now = now.hour();
    day_Now = now.day();
    month_Now = now.month();
    year_Now =  now.year(); 
  } 
 if(hour_Now == 0 && minute_Now == 0 && second_Now == 1){ // Remove trailing digit after roll-over from 23:59.
   lcd.clear();    
  }
      lcd.setCursor(0, 0);
      lcd.print(year_Now);
      lcd.print("/");
      lcd.print(month_Now);
      lcd.print("/");
      lcd.print(day_Now);
      lcd.print(" ");
      lcd.print(hour_Now);
      lcd.print(":");
      if(minute_Now < 10){
        lcd.print("0");
        }
      lcd.print(minute_Now);
  }

void LCD_Channel_Status()   // Print channels status to LCD
{
  lcd.setCursor(3, 1);
  lcd.print("Channels:");
  lcd.setCursor(0, 2);
  lcd.print("1:");
  if (chanStat[0] == 0) {
    lcd.print("Off");
    }
  if (chanStat[0] == 1) {
    lcd.print("On");
    } 
  lcd.setCursor(10, 2);
  lcd.print("2:");
  if (chanStat[1] == 0) {
    lcd.print("Off");
    }
  if (chanStat[1] == 1) {
    lcd.print("On");
    }  
  lcd.setCursor(0, 3);
  lcd.print("3:");
  if (chanStat[2] == 0) {
    lcd.print("Off");
    }
  if (chanStat[2] == 1) {
    lcd.print("On");
    }
  lcd.setCursor(10, 3);
  lcd.print("4:");
  if (chanStat[3] == 0) {
    lcd.print("Off");
    }
  if (chanStat[3] == 1) {
    lcd.print("On");
    }      
  }

void display_On_Off_Times() // Displays the current on and off times on the timer.
  {
  lcd.setCursor(0, 0);
  LCD_Normal_Screen();
  lcd.setCursor(0, 1);
  lcd.print("Channel: ");
  if(channelNum == 0){
    lcd.print("1");
    }
  if(channelNum == 1){
    lcd.print("2");
    }
  if(channelNum == 2){
    lcd.print("3");
    }  
  if(channelNum == 3){
    lcd.print("4");  
    }
  lcd.setCursor(0, 2);
  lcd.print("Time On:");
  lcd.print(timeOnHour[channelNum]);
  lcd.print(":");
  if (timeOnMinute[channelNum] < 10){
    lcd.print("0");
    } 
  lcd.print(timeOnMinute[channelNum]);
  lcd.setCursor(0, 3);
  lcd.print("Time Off:");
  lcd.print(timeOffHour[channelNum]);
  lcd.print(":");
  if (timeOffMinute[channelNum] < 10) {
    lcd.print("0");
    }
  lcd.print(timeOffMinute[channelNum]);   
    }

void EEPROMWriteInt(int p_address, int p_value) // This function will write a 2 byte integer to the eeprom at the specified.
      {
      byte lowByte = ((p_value >> 0) & 0xFF);
      byte highByte = ((p_value >> 8) & 0xFF);
      EEPROM.write(p_address, lowByte);
      EEPROM.write(p_address + 1, highByte);
      }

unsigned int EEPROMReadInt(int p_address) // This function will read a 2 byte integer from the eeprom at the specified address.
      {
      byte lowByte = EEPROM.read(p_address);
      byte highByte = EEPROM.read(p_address + 1);
      return ((lowByte << 0) & 0xFF) + ((highByte << 8) & 0xFF00);
      }

void EEPROMWriteDST()
    {
     EEPROMWriteInt(32, settingDST);       
     }

void EEPROMWriteTimeOnHour()
    {
    if(channelNum == 0){
      EEPROMWriteInt(0, timeOnHour[0]);
      }
    if(channelNum == 1){
      EEPROMWriteInt(2, timeOnHour[1]);
      }
    if(channelNum == 2){
      EEPROMWriteInt(4, timeOnHour[2]);
      }
    if(channelNum == 3){
      EEPROMWriteInt(6, timeOnHour[3]);
      }  
    }  

void EEPROMWriteTimeOnMinute()
    {
    if(channelNum == 0){
      EEPROMWriteInt(8, timeOnMinute[0]);
      }
    if(channelNum == 1){
      EEPROMWriteInt(10, timeOnMinute[1]);
      }
    if(channelNum == 2){
      EEPROMWriteInt(12, timeOnMinute[2]);
      }
    if(channelNum == 3){
      EEPROMWriteInt(14, timeOnMinute[3]);
      } 
    } 

void EEPROMWriteTimeOffHour()
    {
    if(channelNum == 0){
      EEPROMWriteInt(16, timeOffHour[0]);
      }
    if(channelNum == 1){
      EEPROMWriteInt(18, timeOffHour[1]);
      }
    if(channelNum == 2){
      EEPROMWriteInt(20, timeOffHour[2]);
      }
    if(channelNum == 3){
      EEPROMWriteInt(22, timeOffHour[3]);
      }
    }

void EEPROMWriteTimeOffMinute()
    {
    if(channelNum == 0){
      EEPROMWriteInt(24, timeOffMinute[0]);
      }
    if(channelNum == 1){
      EEPROMWriteInt(26, timeOffMinute[1]);
      }
    if(channelNum == 2){
      EEPROMWriteInt(28, timeOffMinute[2]);
      }
    if(channelNum == 3){
      EEPROMWriteInt(30, timeOffMinute[3]);
      }
    }             

Now, after all the coding above and testing on a breadboard I came across the new GIGA and GIGA display, the issue with the above version of the project was always the display, the 328P just doesn't have enough memory to control a larger screen than 16x4.
I would have bought the GIGA anyway, but my question is how much of a leap is it from a 16x4 display to the touch screen and higher complexity of the GIGA display?
There seems to be three recomended libraries for the display, the GFX looks good, but how much more complicated are the others?

Have I left anything out?

Thanks in advance for any help, even google term recomendations, I don't mind doing my own reading if you are not in the mood for writing a disertation.

It is a big difference, but as always eat the elephant in small pieces. I would start with just getting the Giga Display to show the same four lines as now, then go from there.