/*
** This example uses F Malpartida's NewLiquidCrystal library. Obtain from:
** https://bitbucket.org/fmalpartida/new-liquidcrystal 
* 
* Also - RTClib based on https://github.com/adafruit/RTClib
* 
* Written by DIYtronics: http://www.instructables.com/member/diytronics/
*/
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Library inclusions:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
#include "RTClib.h"
RTC_DS3231 rtc;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
//LCD Initilization
///////////////////////////////////////////////////////////////////////////////////////////////////////////////

#define I2C_ADDR    0x27 
#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);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Variable Declerations
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
int seconds;
int minutes;
int hours;
int menu;
int upminutesa = 0;
int uphoursa = 0;
int dwnminutesa = 0;
int dwnhoursa = 0;
int setupminutesa = 0;
int setuphoursa = 0;
int setdwnminutesa = 0;
int setdwnhoursa = 0;
int upminutesb = 0;
int uphoursb = 0;
int dwnminutesb = 0;
int dwnhoursb = 0;
int setupminutesb = 0;
int setuphoursb = 0;
int setdwnminutesb = 0;
int setdwnhoursb = 0;
int active = 1;
int selcounter;
int senseLED = 3;
int rval;
int gval;
int bval;
int minup;
int hourup;
int mindwn;
int hourdwn;
int blindposition = 0;
int redreading;
int greenreading;
int bluereading;
int up;
int dwn;
int sel;
int esc;
int prevUp = HIGH;
int prevDwn = HIGH;
int prevSel = HIGH;
int disprelay = 7;
int timec;
int setcounter; 
int setcountera;
int countera;
int greenstate;
int redstate;
int state = 1;
int trigcounter;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Button pins
///////////////////////////////////////////////////////////////////////////////////////////////////////////////

int buttonUP = 12;
int buttonDWN = 11;
int buttonSEL = 10;
int buttonESC = 9;
int counter = 0;
int dwncounter = 0;
int esccounter = 0;

///////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Other defintions
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
int power = 6; //Coverter relay power
int fwd = 5; //Forward relay
int bwd = 4; //Backward relay
int greenpin = 2; //Green detection from other Arduino
int redpin = 3; //Red detection from other Arduino

///////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Setup
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setup()
{
rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); //Sync RTC and Computer time
Serial.begin(9600); 

pinMode(buttonUP, INPUT_PULLUP); //Use internal pullups for control panel switches
pinMode(buttonDWN, INPUT_PULLUP);//^
pinMode(buttonSEL, INPUT_PULLUP);//^
pinMode(buttonESC, INPUT_PULLUP);//^

pinMode(disprelay, OUTPUT); //Configure relay output pins
pinMode(power, OUTPUT); //^
pinMode(fwd, OUTPUT);//^
pinMode(bwd, OUTPUT);//^


digitalWrite(disprelay, LOW); //Set default to turn backlight on

digitalWrite(power, HIGH); //Have everything else off
digitalWrite(fwd, HIGH);//^
digitalWrite(bwd, HIGH);//^
     
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
//LCD Setup
///////////////////////////////////////////////////////////////////////////////////////////////////////////////

lcd.begin (20,4); //Configure LCD
lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE); //^
lcd.setBacklight(HIGH);//^
mainmenu();//^

pinMode(senseLED, OUTPUT); //Configure LED
digitalWrite(senseLED,LOW); //Configure LED
pinMode(redpin, INPUT); //Configure sensor input
pinMode(greenpin, INPUT); //Configure sensor input

digitalRead(greenpin); //Read sensor from Arduino
digitalRead(redpin); //Read sensor from Arduino
blindposition = 1; //Retact blind
}


void loop()
{

 getbutton(); //Get menu button presses
 printtime(); //Update time
 checktime(); //Check if blind needs to move
 
 redstate = digitalRead(redpin); //Get sensor
 greenstate = digitalRead(greenpin); //Get sensor
 
 checkblind(); //Check position
 
}


///////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Get Time From I2C RTC
///////////////////////////////////////////////////////////////////////////////////////////////////////////////

 void gettime(){
  if (! rtc.begin()) { //Reports if RTC not found
    Serial.println("Couldn't find RTC");
    while (1);
  }
  if (rtc.lostPower()) {
    Serial.println("RTC lost power, lets set the time!"); //Sets time if power lost.
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }
  DateTime now = rtc.now(); //Update time
  seconds = (now.second()); //Update seconds
  minutes = (now.minute()); //Update minutes
  hours = (now.hour()); //Update hours
    }

///////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Print Time to LCD
///////////////////////////////////////////////////////////////////////////////////////////////////////////////

void printtime(){ //Print the time on screen
    gettime(); //Get the time from RTC
    lcd.setCursor(10,0); 
    lcd.print("T:");
    lcd.setCursor(12,0);
    lcd.print(hours, DEC); //Use DEC to convert to numbers
    lcd.setCursor(14,0);
    lcd.print(':');
    lcd.setCursor(15,0);
    lcd.print(minutes, DEC); //Use DEC to convert to numbers
    lcd.setCursor(17,0);
    lcd.print(':');
    lcd.setCursor(18,0);
    lcd.print(seconds, DEC); //Use DEC to convert to numbers
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Displays Menu
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
 void mainmenu(){ //Reddraw static menu
  lcd.clear();
  lcd.setCursor(1,0);
  lcd.print("Disp PWR");
  lcd.setCursor(1,1);
  lcd.print("Set Open Time");
  lcd.setCursor(1,2);
  lcd.print("Set Down Time");
  lcd.setCursor(1,3);
  lcd.print("MANUAL TRIGGER");
 }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Shows cursor
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
void cursorpos(){ //Update/Move cursor
   if (active == 1){
   if (counter == 0){
    lcd.setCursor(0,0);
    lcd.print(">");
    lcd.setCursor(0,1);
    lcd.print(" ");
    lcd.setCursor(0,2);
    lcd.print(" ");
    lcd.setCursor(0,3);
    lcd.print(" ");
    menu = 1;
   }
    
  if (counter == 1){  //Update/Move cursor
    lcd.setCursor(0,1);
    lcd.print(">");
    lcd.setCursor(0,0);
    lcd.print(" ");
    lcd.setCursor(0,2);
    lcd.print(" ");
    lcd.setCursor(0,3);
    lcd.print(" ");
    menu = 2;
  }
  
  if (counter == 2){  //Update/Move cursor
    lcd.setCursor(0,2);
    lcd.print(">");
    lcd.setCursor(0,1);
    lcd.print(" ");
    lcd.setCursor(0,0);
    lcd.print(" ");
    lcd.setCursor(0,3);
    lcd.print(" ");
    menu = 3;
  }
  
  if (counter == 3){  //Update/Move cursor
    lcd.setCursor(0,3);
    lcd.print(">");
    lcd.setCursor(0,1);
    lcd.print(" ");
    lcd.setCursor(0,2);
    lcd.print(" ");
    lcd.setCursor(0,0);
    lcd.print(" ");
    menu = 4;
   }
 }
 if(active == 0){ //If set open time selected show this
   oTimedisplay();
 }
   if(active == 2){ //If set close time selected show this
    cTimedisplay();
   }
 }

///////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Open Time
///////////////////////////////////////////////////////////////////////////////////////////////////////////////

void opentime(){
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Menu");

  }
  
void getbutton(){ // Get button input and assign to correct variables
   up = digitalRead(buttonUP);
  dwn = digitalRead(buttonDWN);
  sel = digitalRead(buttonSEL);
  esc = digitalRead(buttonESC);
  if(esc == LOW){
    active = 1;
    mainmenu();
    Serial.print("ESC");  // Get button input and assign to correct variables
    upminutesa = setupminutesa;
    upminutesb = setupminutesb;
    uphoursa = setuphoursa;
    uphoursb = setuphoursb;

    dwnminutesa = setdwnminutesa;
    dwnminutesb = setdwnminutesb;
    dwnhoursa = setdwnhoursa;
    dwnhoursb = setdwnhoursb;
    digitalWrite(disprelay, LOW);
    motorstop(); //stop motor if selected
  }
  switch(counter){ //loop logic keepin numbers within the limit
  case 4:
    counter = 3;
    break;
  case -1:
    counter = 0;
    break;
  }

 if ((up != prevUp) //testing switch press
  &&(up == LOW)){
    counter --;
    if (active == 0){
      setcounter ++;
      
    }
     if (active == 2){
      setcountera ++;
     
    }
    digitalWrite(disprelay, LOW);
  }
  prevUp = up;
  
  if ((dwn != prevDwn)  //testing switch press
  &&(dwn == LOW)){
    counter ++;
    if (active == 0){
      setcounter --;
     
    }
    if (active == 2){
      setcountera --;
      
    }
    digitalWrite(disprelay, LOW);
  }
  prevDwn = dwn;

  
    cursorpos();
    
   if ((sel != prevSel)  //testing switch press
  &&(sel == LOW)){
    if (countera < 3){
    countera ++;
    setcounter = 0;
    }
    else{
      countera = 0;
    }
    
      if (menu == 1){
      disPWR();
       
    }
    if (menu == 2){
        oTime();
      }
      
    
      
    if (menu == 3){
      cTime();
      
    }
    if (menu == 4){
      trig();
    }
    }
 

prevSel = sel;

}
void disPWR(){
  Serial.println("disPWR");
  digitalWrite(disprelay, HIGH);
  lcd.clear();
}

void oTime(){ 
  active = 0;
  lcd.clear();
  lcd.setCursor(0 ,0);
  lcd.print("Set Open: ");
  lcd.setCursor(0,1);
  lcd.print("Prog Time> ");
  //
  lcd.setCursor(12,1);
  lcd.print(upminutesa);
  //
  lcd.setCursor(13,1);
  lcd.print(upminutesb);
  //
  lcd.setCursor(14,1);
  lcd.print(":");
  //
  lcd.setCursor(15,1);
  lcd.print(uphoursa);
  //
  lcd.setCursor(16,1);
  lcd.print(uphoursb);
  //
  lcd.setCursor(0,2);
  lcd.print("Edit Time> ");
  }
  
  void oTimedisplay(){
  lcd.setCursor(12,2);
  lcd.print(setupminutesa);
  //
  lcd.setCursor(13,2);
  lcd.print(setupminutesb);
  //
  lcd.setCursor(14,2);
  lcd.print(":");
  
  lcd.setCursor(15,2);
  lcd.print(setuphoursa);
  
  lcd.setCursor(16,2);
  lcd.print(setuphoursb);
  lcd.setCursor(0,3);
  lcd.print("Sel Digit>");

  if (countera == 0){  //First hour digit
    lcd.setCursor(12,3);
  lcd.print("^");
 switch (setcounter){
  case 3:
  setcounter = 2;

  case -1:
  setcounter = 0;
 }
  setupminutesa = setcounter;
  
 }
  
  if (countera == 1){ //Second hour digit
    lcd.setCursor(13,3);
  lcd.print("^");
  switch (setcounter){
  case 10:
  setcounter = 9;

  case -1:
  setcounter = 0;
 }
 switch (setupminutesa){
  case 2:
  
  switch (setcounter){
  case 5:
  setcounter = 0;
 }
  
 }
  setupminutesb = setcounter;
  }
  
  if (countera == 2){ //First Minute digit
    lcd.setCursor(15,3);
  lcd.print("^");
    switch (setcounter){
  case 6:
  setcounter = 5;

  case -1:
  setcounter = 0;
 }
  setuphoursa = setcounter;
  }
  
  if (countera == 3){ //Second minute digit
    lcd.setCursor(16,3);
  lcd.print("^");
  switch (setcounter){
  case 10:
  setcounter = 9;

  case -1:
  setcounter = 0;
 }
  setuphoursb = setcounter;
  }
  Serial.println("Done");
  }


/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void cTime(){  //Menu for setting close time
  active = 2;
  lcd.clear();
  lcd.setCursor(0 ,0);
  lcd.print("Set Close: ");
  lcd.setCursor(0,1);
  lcd.print("Prog Time> ");
  //
  lcd.setCursor(12,1);
  lcd.print(dwnminutesa);
  //
  lcd.setCursor(13,1);
  lcd.print(dwnminutesb);
  //
  lcd.setCursor(14,1);
  lcd.print(":");
  //
  lcd.setCursor(15,1);
  lcd.print(dwnhoursa);
  //
  lcd.setCursor(16,1);
  lcd.print(dwnhoursb);
  //
  lcd.setCursor(0,2);
  lcd.print("Edit Time> ");
  }
  
  void cTimedisplay(){
  lcd.setCursor(12,2);
  lcd.print(setdwnminutesa);
  //
  lcd.setCursor(13,2);
  lcd.print(setdwnminutesb);
  //
  lcd.setCursor(14,2);
  lcd.print(":");
  
  lcd.setCursor(15,2);
  lcd.print(setdwnhoursa);
  
  lcd.setCursor(16,2);
  lcd.print(setdwnhoursb);
  lcd.setCursor(0,3);
  lcd.print("Sel Digit>");

  if (countera == 0){  //First hour digit
    lcd.setCursor(12,3);
  lcd.print("^");
 switch (setcountera){
  case 3:
  setcountera = 2;

  case -1:
  setcountera = 0;
 }
  setdwnminutesa = setcountera;
  
 }
  
  if (countera == 1){ //Second hour digit
    lcd.setCursor(13,3);
  lcd.print("^");
  switch (setcountera){
  case 10:
  setcountera = 9;

  case -1:
  setcountera = 0;
 }
 switch (setdwnminutesa){
  case 2:
  
  switch (setcountera){
  case 5:
  setcountera = 0;
 }
  
 }
  setdwnminutesb = setcountera;
  }
  
  if (countera == 2){ //First Minute digit
    lcd.setCursor(15,3);
  lcd.print("^");
    switch (setcountera){
  case 6:
  setcountera = 5;

  case -1:
  setcountera = 0;
 }
  setdwnhoursa = setcountera;
  }
  
  if (countera == 3){ //Second minute digit
    lcd.setCursor(16,3);
  lcd.print("^");
  switch (setcountera){
  case 10:
  setcountera = 9;

  case -1:
  setcountera = 0;
 }
  setdwnhoursb = setcountera;
  }
  Serial.println("Done");
  
}

void trig(){ //Keep track of blind position
  trigcounter ++;
  switch(trigcounter){
    case 3:
    trigcounter = 1;
  }
  if(trigcounter == 1){
    blindposition =  1;
  }
  if(trigcounter == 2){
    blindposition =  2;
  }
  Serial.println("Trig");
}


void motorfwd(){ //Move motor forwards
  digitalWrite(power, LOW);
  digitalWrite(bwd,HIGH); 
  digitalWrite(fwd,LOW); 
}

void motorbwd(){ //Move motor backwards
  digitalWrite(power, LOW);
  digitalWrite(fwd,HIGH);
  digitalWrite(bwd,LOW);
}

void motorstop(){ //Stop the motor
  digitalWrite(power, HIGH);
  digitalWrite(fwd,HIGH);
  digitalWrite(bwd,HIGH);
}



void checktime(){ //Check the time form the RTC
  DateTime now = rtc.now();
  minup = upminutesa*10 + upminutesb;
  hourup = uphoursa*10 + uphoursb;

  mindwn = dwnminutesa*10 + dwnminutesb;
  hourdwn = dwnhoursa*10 + dwnhoursb; 
  
  if(minup == now.hour()){
  if(hourup == now.minute()){ 
  blindposition = 1;
  }
  }
  
  if(hourdwn == now.minute()){
  if(mindwn == now.hour()){
  blindposition = 2;
  }
}
}


void checkblind(){ //Check the blind state.
  if(blindposition == 1){
      if(greenstate == HIGH){
        motorstop();
        blindposition = 3;
      }
      if(greenstate == LOW){
        motorfwd();
      }
  }
  if(blindposition == 2){
      if(redstate == HIGH){
        motorstop();
        blindposition = 3;
      }
      if(redstate == LOW){
        motorbwd();
      }
  }
  if(blindposition == 3){
        motorstop();
  }
  
}
