//Nicolas Jarpa
//Multiple Timer  RTC3231+LCD+Single Relay+Everyday+eeprom

#include <EEPROM.h>
#include <RTClib.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2);//0x3F is my lcd address, maybe not yours!
RTC_DS1307 RTC;

//-----------------------//
//------Variables--------//
//-----------------------//

//------First Timer 
byte onhour1;
byte onmin1;
byte onsec1;

byte offhour1;
byte offmin1;
byte offsec1;
//------Pages or menus
int page_counter=1;
int subpage1_counter=0;
int subpage2_counter=0;

//-------To convert clock into single number
unsigned long Time;
unsigned long Hour;
unsigned long Min;
unsigned long Sec;
//------To convert first timer into Single number
unsigned long on_Time1;
unsigned long on_hour1;
unsigned long on_min1;
unsigned long on_sec1;

unsigned long off_Time1;
unsigned long off_hour1;
unsigned long off_min1;
unsigned long off_sec1;

//-------Push buttons current/last state 
boolean current_up = LOW;          
boolean last_up=LOW;            
boolean current_sel = LOW;
boolean last_sel = LOW;
boolean last_down = LOW;
boolean current_down = LOW;
//-------Pins
byte Relay =13;//Relay to pin 13
int up=2;      //Up button to pin 2
int sel=3;     //Select button to pin 3
int down=4;   //Down button to pin 4

//Custom return char
byte back[8] = {
  0b00100,
  0b01000,
  0b11111,
  0b01001,
  0b00101,
  0b00001,
  0b00001,
  0b11111
};

//Custom arrow char
byte arrow[8] = {
  0b01000,
  0b00100,
  0b00010,
  0b11111,
  0b00010,
  0b00100,
  0b01000,
  0b00000
};

void setup() { 
  pinMode(Relay, OUTPUT);
     
     Wire.begin();
     RTC.begin();
     lcd.init();
     lcd.backlight();
     lcd.clear();
  lcd.createChar(1, back);//Custom chars
  lcd.createChar(2, arrow);    
//--------eePROM  read values-------//
//------First Timer 
onhour1=EEPROM.read(0);
onmin1=EEPROM.read(1);
onsec1=EEPROM.read(2);

offhour1=EEPROM.read(3);
offmin1=EEPROM.read(4);
offsec1=EEPROM.read(5);

}

   //---- De-bouncing function for all buttons----//
boolean debounce(boolean last, int pin)
{
boolean current = digitalRead(pin);
if (last != current)
{
delay(10);
current = digitalRead(pin);
}
return current;
}

void loop() {
  
current_up = debounce(last_up, up);         //Debounce for Up button
current_sel = debounce(last_sel, sel);      //Debounce for Select  button
current_down = debounce(last_down, down);   //Debounce for Down button  
  
DateTime now = RTC.now();        // Clock call
now = RTC.now();

//-----Up/Down functions to move main pages------///   
 
if(subpage1_counter==0 && subpage2_counter==0){ //up/down buttons enabled if subpages counters are 0,Disabled if 1,2..etc to work on submenus
  
//Page Up
    if (last_up== LOW && current_up == HIGH){ //Up button pressed
      lcd.clear();                            //Clear lcd if page is changed to print new one
      if(page_counter <3){                   //Page counter never higher than 3(total of pages)
      page_counter ++;                       //Page up      
      }
      else{
      page_counter= 1;                       //If higher than 3 (last page)go to main page
      }
  
} 
last_up = current_up;                   //Save up button last state 

//Page Down
    if (last_down== LOW && current_down == HIGH){//Down button pressed
      lcd.clear();                               //Clear lcd if page is changed to print new one
      if(page_counter >1){                      //Page counter never lower than 1 
      page_counter --;                          //Page down
      
      }
      else{
      page_counter= 3;                 //If lower than 1(first page)go to last page
      }
  }    
    last_down = current_down;         //Save down button last state
}  
//------------Pages and submenus display and control----------//  
  switch (page_counter){
    case 1:                      //Content of main page
     last_sel=current_sel;  //Save last state of select button when we jump from the save screen
      lcd.setCursor(0,0);
      lcd.print("ULTRA MEGA TIMER");
      lcd.setCursor(0,1);
      lcd.print("TIME");
      
//--------Show  Time On LCD

lcd.setCursor(7,1);                 
if(now.hour() < 10)
{
lcd.print("0");
}
lcd.print(now.hour(), DEC); //Print hour
lcd.print(':');
if(now.minute() < 10)
{
lcd.print("0");
}
lcd.print(now.minute(), DEC); //Print min
lcd.print(':');
if(now.second() < 10)
{
lcd.print("0");
}
lcd.print(now.second(), DEC); //Print sec
    //case 1
    break;

    case 2:                   //Content and functions of page 2
      lcd.setCursor(0,0);
      lcd.print("T1");
      lcd.setCursor(3,0);
      lcd.print("ON");
      lcd.setCursor(1,1);
      lcd.write(byte(1));
      lcd.setCursor(3,1);
      lcd.print("OFF");

            lcd.setCursor(7,0);    //Printing on/off values
            if(onhour1<10){
              lcd.print("0");
            }
            lcd.print(onhour1);
            lcd.setCursor(10,0);
            if(onmin1<10){
              lcd.print("0");
            }
            lcd.print(onmin1);
            lcd.setCursor(13,0);
            if(onsec1<10){
              lcd.print("0");
            }
            lcd.print(onsec1);
            lcd.setCursor(7,1);
            if(offhour1<10){
              lcd.print("0"); 
            }
            lcd.print(offhour1);
            lcd.setCursor(10,1);
            if(offmin1<10){
              lcd.print("0");
            }
            lcd.print(offmin1);
            lcd.setCursor(13,1);
            if(offsec1<10){
              lcd.print("0");
            }
            lcd.print(offsec1);
                        
//--------------Modifying on/off values-------//
     // Sub counter control
     if (last_sel== LOW && current_sel == HIGH){ //select button pressed
      if(subpage1_counter <7){                    // subpage counter never higher than 7 (total of items)
     subpage1_counter ++;                         //subcounter to move beetwen submenu
     }
     else{                                       //If subpage higher than 7 (total of items) return to first item
      subpage1_counter=1;
     }
     }
     last_sel=current_sel;                      //Save last state of select button

     //First item control(subpage_counter =1) onhour1
     if(subpage1_counter==1){
     lcd.setCursor(0,1);         //Delete last arrow position (back)
     lcd.print(" ");                                         
     lcd.setCursor(6,0);          //Place arrow in front of selected item
     lcd.write(byte(2));         
     //Move item + or -
     if (last_up== LOW && current_up == HIGH){  //Up 
      if(onhour1 < 23){
     onhour1 ++;
      }
      else{
     onhour1 =0;
      }
     }
     last_up=current_up;
     
     if(last_down== LOW && current_down == HIGH){//Down
     if(onhour1 >0){
      onhour1 --; 
     }
     else{
      onhour1=23;
     }
     }
     last_down=current_down;
    }//subpage1_counter 1

     //Second item control(subpage_counter =2) onmin1
     if(subpage1_counter==2){
     lcd.setCursor(6,0);         //Delete last arrow position (onhour1)
     lcd.print(" ");                                         
     lcd.setCursor(9,0);          //Place arrow in front of selected item
     lcd.write(byte(2));         
     //Move item + or -
     if (last_up== LOW && current_up == HIGH){  //Up 
      if(onmin1 < 59){
     onmin1 ++;
      }
      else{
     onmin1 =0;
      }
     }
     last_up=current_up;
     
     if(last_down== LOW && current_down == HIGH){//Down
     if(onmin1 >0){
      onmin1 --; 
     }
     else{
      onmin1=59;
     }
     }
     last_down=current_down;
    }//subpage1_counter 2
    
     //Thirth item control(subpage_counter =3) onsec1
     if(subpage1_counter==3){
     lcd.setCursor(9,0);         //Delete last arrow position (onmin1)
     lcd.print(" ");                                        
     lcd.setCursor(12,0);          //Place arrow in front of selected item
     lcd.write(byte(2));         
     //Move item + or -
     if (last_up== LOW && current_up == HIGH){  //Up 
      if(onsec1 < 59){
     onsec1 ++;
      }
      else{
     onsec1 =0;
      }
     }
     last_up=current_up;
     
     if(last_down== LOW && current_down == HIGH){//Down
     if(onsec1 >0){
      onsec1 --; 
     }
     else{
      onsec1=59;
     }
     }
     last_down=current_down;
    }//subpage1_counter 3

     //fourth item control(subpage_counter =4) offhour1
     if(subpage1_counter==4){
     lcd.setCursor(12,0);         //Delete last arrow position (onsec1)
     lcd.print(" ");                                         
     lcd.setCursor(6,1);          //Place arrow in front of selected item
     lcd.write(byte(2));         
     //Move item + or -
     if (last_up== LOW && current_up == HIGH){  //Up 
      if(offhour1 < 23){
     offhour1 ++;
      }
      else{
     offhour1 =0;
      }
     }
     last_up=current_up;
     
     if(last_down== LOW && current_down == HIGH){//Down
     if(offhour1 >0){
      offhour1 --; 
     }
     else{
      offhour1=23;
     }
     }
     last_down=current_down;
    }//subpage1_counter 4

     //fifth item control(subpage_counter =5) offmin1
     if(subpage1_counter==5){
     lcd.setCursor(6,1);         //Delete last arrow position (offhour1)
     lcd.print(" ");                                         
     lcd.setCursor(9,1);          //Place arrow in front of selected item
     lcd.write(byte(2));         
     //Move item + or -
     if (last_up== LOW && current_up == HIGH){  //Up 
      if(offmin1 < 59){
     offmin1 ++;
      }
      else{
     offmin1 =0;
      }
     }
     last_up=current_up;
     
     if(last_down== LOW && current_down == HIGH){//Down
     if(offmin1 >0){
      offmin1 --; 
     }
     else{
      offmin1=59;
     }
     }
     last_down=current_down;
    }//subpage1_counter 5 

     //sixth item control(subpage_counter =6) offsec1
     if(subpage1_counter==6){
     lcd.setCursor(9,1);         //Delete last arrow position (offmin1)
     lcd.print(" ");                                         
     lcd.setCursor(12,1);          //Place arrow in front of selected item
     lcd.write(byte(2));         
     //Move item + or -
     if (last_up== LOW && current_up == HIGH){  //Up 
      if(offsec1 < 59){
     offsec1 ++;
      }
      else{
     offsec1 =0;
      }
     }
     last_up=current_up;
     
     if(last_down== LOW && current_down == HIGH){//Down
     if(offsec1 >0){
      offsec1 --; 
     }
     else{
      offsec1=59;
     }
     }
     last_down=current_down;
    }//subpage1_counter 6 
          

     //seventh item control(subpage_counter =7) back
     if(subpage1_counter==7){
     lcd.setCursor(12,1);         //Delete last arrow position (offsec1)
     lcd.print(" ");                                         
     lcd.setCursor(0,1);          //Place arrow in front of selected item
     lcd.write(byte(2));         
     //Move item + or -
     if (last_up== LOW && current_up == HIGH){  //Up
      lcd.setCursor(0,1);         //Delete last arrow position (back) to exit
      lcd.print(" "); 
     subpage1_counter=0;         //Exit submenu. Up/down butons enabled to move main pages     
     }
     last_up=current_up;
     
     if(last_down== LOW && current_down == HIGH){//Down
      lcd.setCursor(0,1);         //Delete last arrow position (back)
      lcd.print(" "); 
     subpage1_counter=1;         //Go to first item (onhour1)
     }
     last_down=current_down;
    }//subpage1_counter 7
    //case 2
    break;

    case 3:                //Page 3 display and functions
      lcd.setCursor(4,0);
      lcd.print("PRESS SEL");
      lcd.setCursor(5,1);
      lcd.print("TO SAVE");
     if (last_sel== LOW && current_sel == HIGH){  //select button pressed.Save settings to eeprom
  EEPROM.write(0, onhour1);
  EEPROM.write(1, onmin1);
  EEPROM.write(2, onsec1);
  EEPROM.write(3, offhour1);
  EEPROM.write(4, offmin1);
  EEPROM.write(5, offsec1);
  lcd.clear();                 //Print message "SAVED!"
  lcd.setCursor(5,1);
  lcd.print("SAVED!");
  delay(2000);
  lcd.clear();               //Clear lcd and go to main page
  page_counter=1;
     }
     last_sel=current_sel;  //Save last state of select button
      
    //Case 3
    break;
  }//switch


//-------------Conversion----------//

//---------Converting clock time into single number 
 
Hour = now.hour();
Min = now.minute();
Sec = now.second();
Time = (Hour*10000+ Min*100 +Sec*1);  

//--------Converting firt timer on/off into single number
on_hour1=onhour1;
on_min1=onmin1;
on_sec1=onsec1;
on_Time1=(on_hour1*10000 + on_min1*100 + on_sec1);

off_hour1=offhour1;
off_min1=offmin1;
off_sec1=offsec1;
off_Time1=(off_hour1*10000 + off_min1*100 + off_sec1);
   


//----Relay Function----//
if(onhour1 == offhour1 && onmin1==offmin1 && onsec1==offsec1){
   digitalWrite(Relay, LOW);
}

if(on_Time1 < off_Time1){
  
             if(Time >= on_Time1 && Time < off_Time1){  //Start
             digitalWrite(Relay, HIGH);
             }
             else if(Time >= off_Time1) {
             digitalWrite(Relay, LOW);
             }
             else{
             digitalWrite(Relay, LOW);
             }
}
if (on_Time1 > off_Time1){

            if(Time >= on_Time1 && Time <= 235959){     //Start
            digitalWrite(Relay, HIGH);  
            }
            else if(Time < off_Time1 ){
            digitalWrite(Relay, HIGH);
            }
            else if(Time >= off_Time1 && Time < on_Time1){
            digitalWrite(Relay, LOW);  
            }
}


}//void loop
GND5VSDASCLSQWRTCDS1307+