/*
* Schedule turns ON-OFF
* Author: MyEngineeringStuffs
* https://myengineeringstuffs.com
*
* Published December 25, 2022 © GPL3+
* https://www.hackster.io/my_engineeringStuffs/schedule-turn-on-and-off-of-devices-using-rtc-and-arduino-d5b4e3
*
* https://myengineeringstuffs.com/2023/02/schedule-turns-on-off-of-devices-using-rtc-and-arduino/
* https://www.youtube.com/watch?v=5_UV0Lymi18
*/

#include "Wire.h"
#include "EEPROM.h"
#include "RTClib.h"
#include "LiquidCrystal.h"

#define relay 7
#define btn1 6
#define btn2 5
#define btn3 4
#define btn4 3

LiquidCrystal lcd(13, 12, 11, 10, 9, 8);
RTC_DS1307 RTC;
int starthr=0,startmin=0,offhr=0,offmin=0;
int HOUR,MINUT,SECOND,DAY,MONTH,YEAR;

byte Aalpha[8] ={  0b01110,
                   0b10001,
                   0b11111,
                   0b10001,
                   0b10001,
                   0b00000,
                   0b00000,
                   0b00000
                   };
 byte Malpha[8] ={ 0b10001,
                   0b11011,
                   0b10101,
                   0b10001,
                   0b10001,
                   0b00000,
                   0b00000,
                   0b00000};                                      
 byte Palpha[8]={  0b11100,
                   0b10010,
                   0b11100,
                   0b10000,
                   0b10000,
                   0b00000,
                   0b00000,
                   0b00000};

void setup() {
  // put your btn3up code here, to run once:
   Wire.begin();
   RTC.begin();
   lcd.begin(16,2);
   pinMode(btn1, INPUT);
   pinMode(btn2, INPUT);
   pinMode(btn3, INPUT);
   pinMode(btn4, INPUT);
   pinMode(relay, OUTPUT);
   digitalWrite(relay,LOW); 
   lcd.setCursor(0,0);
   lcd.print("YT CHANNEL *MES*"); 
   lcd.setCursor(0,1);
   lcd.print("  DEVICE ON/OFF "); 
   delay(3000);
 if(!RTC.isrunning())
 {
 RTC.adjust(DateTime(__DATE__,__TIME__));
 }
}

void loop() {
  // put your main code here, to run repeatedly:
DateTime now = RTC.now();
if(digitalRead(btn4)==LOW){
  deviceontime();
  deviceofftime();
}
 
 lcd.clear();
 lcd.setCursor(0,0);
 lcd.print("TIME:");
 lcd.setCursor(6,0);
 printDigits(HOUR=now.hour()); 
 lcd.print(":");
 printDigits(MINUT=now.minute());
 lcd.print(":");
 printDigits(SECOND=now.second());
 if(HOUR < 12){                  // Adding the AM/PM sufffix
          lcd.createChar(5,Aalpha);
          lcd.createChar(6,Malpha);
          lcd.setCursor(14,0);
          lcd.write(5);
          lcd.setCursor(15,0);
          lcd.write(6);
          
    }
   else{
          lcd.createChar(5,Palpha);
          lcd.createChar(6,Malpha);
          lcd.setCursor(14,0);
          lcd.write(5);
          lcd.setCursor(15,0);
          lcd.write(6);
   } 
 lcd.setCursor(0,1);
 lcd.print("DATE: ");
 printDigits(DAY=now.day());
 lcd.print("/");
 printDigits(MONTH=now.month());
 lcd.print("/");
 lcd.print(YEAR=now.year());
 digitalWrite(relay,LOW);
 delay(1000);
 if(HOUR== EEPROM.read(0) && MINUT == EEPROM.read(1)){
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(" Device Turn ON ");
  digitalWrite(relay,HIGH);
  CheckTime();
 }
}

void printDigits(int digits)//this void function is really useful; it adds a "0" to the
//beginning of the number, so that 5 minutes is displayed as "00:05:00", rather than "00:5 :00"
{
  if(digits < 10) 
  {
    lcd.print("0");
    lcd.print(digits);
  }
  else
  {
    lcd.print(digits);
  }
}
/* Function to check matching time */
void CheckTime()
{
  int checkhrOFF=0,checkminOFF=0;
  while(1)
  { 
  DateTime now = RTC.now();
  lcd.setCursor(0,1);
  lcd.print("TIME: ");
  printDigits(HOUR=now.hour()); 
  lcd.print(":");
  printDigits(MINUT=now.minute());
  lcd.print(":");
  printDigits(SECOND=now.second());
  checkhrOFF=EEPROM.read(2);
  checkminOFF=EEPROM.read(3);
  if(HOUR == checkhrOFF && MINUT == checkminOFF){
   lcd.clear();
  lcd.setCursor(0,1);
  lcd.print(" Device Turn OFF");
  digitalWrite(relay,LOW);
  delay(2000);
  break;   
  }
 }
}
void deviceontime(){
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("ENTER ON TIME");
        lcd.setCursor(8,1);
        lcd.print("00:00:00");
       while(1){
             if(digitalRead(btn1)==LOW){
              starthr++;
              lcd.setCursor(8,1);
              printDigits(starthr);
              //EEPROM.write(0,starthr);
              delay(200);
              if(starthr==24)
              starthr=0;
             }
             if(digitalRead(btn2)==LOW){
              startmin++;
              lcd.setCursor(11,1);
              printDigits(startmin);
             // EEPROM.write(0,startmin);
              delay(200);
              if(startmin==60)
              startmin=0;
             }
              if(digitalRead(btn3)==LOW){
                 
                 EEPROM.write(0,starthr);
                 EEPROM.write(1,startmin);
                 lcd.setCursor(0,0);
                 lcd.print(" START TIME SET ");
                 lcd.setCursor(0,1);
                 lcd.print("AT: ");
                 printDigits(EEPROM.read(0));
                 lcd.print(":");
                 printDigits(EEPROM.read(1));
                 lcd.print(":00");
                 lcd.print("     ");
                 delay(5000);
                 starthr=0;
                 startmin=0;
                 break;
              }
       }
}


void deviceofftime(){
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("ENTER OFF TIME");
        lcd.setCursor(8,1);
        lcd.print("00:00:00");
       while(1){
             if(digitalRead(btn1)==LOW){
              offhr++;
              lcd.setCursor(8,1);
              printDigits(offhr);
              //EEPROM.write(0,starthr);
              delay(200);
              if(offhr==24)
              offhr=0;
             }
             if(digitalRead(btn2)==LOW){
              offmin++;
              lcd.setCursor(11,1);
              printDigits(offmin);
             // EEPROM.write(0,startmin);
              delay(200);
              if(offmin==60)
              offmin=0;
             }
              if(digitalRead(btn3)==LOW){
                 EEPROM.write(2,offhr);
                 EEPROM.write(3,offmin);
                 lcd.setCursor(0,0);
                 lcd.print("  OFF TIME SET  ");
                 lcd.setCursor(0,1);
                 lcd.print("AT: ");
                 printDigits(EEPROM.read(2));
                 lcd.print(":");
                 printDigits(EEPROM.read(3));
                 lcd.print(":00");
                 lcd.print("     ");
                 delay(5000);
                 offhr=0;
                 offmin=0;
                 break;
              }
             
       }
}
GND5VSDASCLSQWRTCDS1307+
NOCOMNCVCCGNDINLED1PWRRelay Module