Translate

Monday 19 May 2014

The full sketch of room management system including the menu to control the lights

As promised a full sketch again with all the changes, alterations and updates including the menu to control, timers, delays and photo cell settings for the lights. I am still working on a extended AC control and the EEPROM usage to make changes more permanent, so they don't get lost on power cuts or a system reset. Further improvement in code and functionality are also coming in the next couple of posts.

/////////////////////Includes/////////////////////////////
#include <DS1307RTC.h>
#include <Time.h>
#include <Wire.h>
#include <ShiftLCD.h>
#include <avr/pgmspace.h>

#define DS1307_ADDRESS 0x68
byte zero = 0x00;
/////////////////////Declaring the Variables/////////////////

///////////Timer and Sensitivity Settings to be changed to individual needs////////////////
unsigned int sensitivity = 400;    //should be between 200 and 1000 as
                                   //lower the number as more responsive 
                                   //the system will be
unsigned int photoCellCutOn = 320;  //var holding the switching limit for the photocell
unsigned int photoCellCutOff = 280; //var holding the value where the photocell cuts off
unsigned int photoOutsideOn = 220; //var holding the value which the photocell reading 
unsigned int photoOutsideOff = 260;
byte hourOutsideOff = 23;          //var holding the time (full hours) in which the lights have 
                                   //to switch off
byte minuteOutsideOff = 30;        //var holding the time (minutes) in which the lights 
                                   //have to switch off

int dBed1 = 60;            //delay time in seconds for bedroom 1
int dBed2 = 60;            //delay time in seconds for bedroom 2
int dBed3 = 60;            //delay time in seconds for bedroom 3
int dLiving = 300;         //delay time in seconds for living area
int dBath1 = 180;          //delay time in seconds for bathroom 1
int dBath2 = 180;          //delay time in seconds for bathroom 2
int dBath3 = 180;          //delay time in seconds for bathroom 3
int dBath4 = 180;          //delay time in seconds for bathroom 4
int dKitchen = 120;        //delay time in seconds for kitchen
int dCorridor = 60;        //delay time in seconds for corridor
int dAC1 = 120;            //delay time in seconds for AC 1 (bed1)
int dAC2 = 120;            //delay time in seconds for AC 2 (bed2)
int dAC3 = 120;            //delay time in seconds for AC 3 (bed3)
int dAC4 = 120;            //delay time in seconds for AC 4 (living)
int dMaster = 240;         //delay time in seconds for Master Off

byte hourAc1On = 18;
byte minuteAc1On = 0;
byte hourAc1Off = 24;
byte minuteAc1Off = 0;

//////////////////////holliday timer settings//////////////////////

byte timer_active[10][4] = {
                    {1, 1, 1, 0},    //room 0 timers 0 to 3
                    {1, 1, 0, 0},    //room 1 timers 0 to 3
                    {1, 1, 1, 1},    //room 2 timers 0 to 3
                    {0, 1, 0, 0},    //room 3 timers 0 to 3
                    {1, 1, 2, 2},    //room 4 timers 0 to 3
                    {1, 1, 2, 2},    //room 5 timers 0 to 3
                    {1, 1, 2, 2},    //room 6 timers 0 to 3
                    {1, 0, 2, 2},    //room 7 timers 0 to 3
                    {1, 1, 2, 2},    //room 8 timers 0 to 3
                    {0, 0, 2, 2}     //room 9 timers 0 to 3
};

//Timer Settings room, timer, hour on, minute on, hour off, minute off
byte room_timers[10][4][4] = {
                               {
                                 {5, 35, 6, 5},        //room 1 timer 1
                                 {19, 35, 20, 15},     //room 1 timer 2
                                 {21, 5, 21, 15},      //room 1 timer 3
                                 {0, 0, 0, 0}          //room 1 timer 4
                               },
                               {
                                 {6, 30, 6, 50},       //room 2 timer 1
                                 {19, 30, 20, 10},     //room 2 timer 2
                                 {0, 0, 0, 0},         //room 2 timer 3
                                 {0, 0, 0, 0}          //room 2 timer 4
                               },
                               {
                                 {5, 50, 6, 20},       //room 3 timer 1
                                 {18, 10, 18, 25},     //room 3 timer 2
                                 {19, 15, 19, 40},     //room 3 timer 3
                                 {23, 20, 23, 35}      //room 3 timer 4
                               },
                               {
                                 {0, 0, 0, 0},         //room 4 timer 1
                                 {17, 30, 23, 30},     //room 4 timer 2
                                 {0, 0, 0, 0},         //room 4 timer 3
                                 {0, 0, 0, 0}          //room 4 timer 4
                               },
                               {
                                 {5, 40, 5, 45},       //room 5 timer 1
                                 {19, 55, 20, 10},     //room 5 timer 2
                                 {0, 0, 0, 0},         //not used
                                 {0, 0, 0, 0}          //not used
                               },
                               {
                                 {6, 35, 6, 45},       //room 6 timer 1
                                 {19, 50, 20, 5},      //room 6 timer 2
                                 {0, 0, 0, 0},         //not used
                                 {0, 0, 0, 0}          //not used
                               },
                               {
                                 {6, 5, 6, 25},        //room 7 timer 1
                                 {22, 50, 23, 15},     //room 7 timer 2
                                 {0, 0, 0, 0},         //not used
                                 {0, 0, 0, 0}          //not used
                               },
                               {
                                 {0, 0, 0, 0},         //room 8 timer 1
                                 {22, 5, 22, 20},      //room 8 timer 2
                                 {0, 0, 0, 0},         //not used
                                 {0, 0, 0, 0}          //not used
                               },
                               {
                                 {5, 50, 6, 45},       //room 9 timer 1
                                 {17, 45, 18, 30},     //room 9 timer 2
                                 {0, 0, 0, 0},         //room 9 timer 3
                                 {0, 0, 0, 0}          //not used
                               },
                               {
                                 {0, 0, 0, 0},         //room 10 timer 1
                                 {0, 0, 0, 0},         //room 10 timer 2
                                 {0, 0, 0, 0},         //not used
                                 {0, 0, 0, 0}          //not used
                               }
};
 
///////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////DO NOT MODIVY BELOW HERE///////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////
////////////////////////////defining Arduino Pins/////////////////////////////
//////////////////////////////////////////////////////////////////////////////
ShiftLCD lcd(9, 11, 10);       //initializing the LCD adaptor pins

const byte latchPin = 2;        //5latch pin input connected to
                               //Arduino digital pin 2
const byte clockPin = 3;        //6clock pin input connected to
                               //Arduino digital pin 3
const byte dataPin = 4;         //7data pin input connected to 
                               //Arduino digital pin 4
                               
const byte latchPinOut = 5;     //2latch pin output shift register
                               //74HC595 connected to Arduino
                               //digital pin 5
const byte clockPinOut = 6;     //3clock pin output shift register
                               //74HC595 connected to Arduino
                               //digital pin 6
const byte dataPinOut = 7;      //4data pin output shift register
                               //74HC595 connected to Arduino
                               //digital pin 7

const byte lightSensor = 0;          //defining the input for the photocell

const byte doorMonitor = 8;           //Arduino pin for a monitor LED
const byte setupMode = 12;            //Arduino pin for switching to setup mode

/////////////////////////////////////////////////////////////////////////////
///////Variables to hold the data for each input shift register//////////////
/////////////////////////////////////////////////////////////////////////////

byte switchVar1 = 0;           //data for input shift register 1
byte switchVar2 = 0;           //data for input shift register 2
byte switchVar3 = 0;           //data for input shift register 3

///////////////////////////////////////////////////////////////////////////////
///////////////////////////all the other variables/////////////////////////////
///////////////////////////////////////////////////////////////////////////////

////Sensor and timer variables
int delayTime[16] = {dBed1, dBed2, dBed3, dLiving, dBath1, dBath2, dBath3,
                     dBath4, dKitchen, dCorridor, dAC1, dAC2, dAC3, dAC4,
                     dMaster, 0};
                               
int sensorValue = 0;                          //holding the indicated sensor value of the photocell
byte photocellSwitch = 0;                    //holding the switch command after 
                                             //checking sensor readings (0, 1)
byte photocellSwitchOld = 0;                 //switch command from the previous pass
byte lightLevel[17] ={0};                    //array holding the switch state
                                             //checking timer and photocell (0, 1)


unsigned int roomTimer[17] = {0};            //array holding the time when the PIR was last activated
unsigned int currentTime = 0;                //var to hold a reference time to calculate the up time 
                                              //against the preprogrammed delay time
unsigned int endTime = 0;                    //var to hold a temp result to calculate the up time 
                                              //against the preprogrammed delay time 
unsigned int outsideOnTime = 0;              //checking result if the time is within 
                                             //on or off time limits  
                                             
////////////////////////////////////////////////////////////////////////////////////////
//////////////////////PIR and Room switch related Var's/////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////                                            

byte mainOff = 1;                             //variable for master relay control
unsigned int offTime = 0;                    //var needed to calculate delay for master off
byte masterSwitchStateOld = 0;                //var holding the previous door switch state
byte switchState[25] = {0};                   //array holding the state of each switch 
unsigned long lightOutput[17] = {0};         //array holding a integer which converted to binary 
                                              //will trigger the relay to switch in our output code
byte lightStatus[17] = {0};                   //array holding the switch status of each room on/off
byte priorityStatus[17] = {0};                 //array holding the priority status of each room on/off
byte switchState1Old = 0;                     //var to check if the priority switch state has changed
byte switchState3Old = 0;                     //var to check if the priority switch state has changed
byte switchState5Old = 0;                     //var to check if the priority switch state has changed
byte switchState7Old = 0;                     //var to check if the priority switch state has changed

//////////////////////////////////////////////////////////////////////////////
///////////////////////////Output/////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////

unsigned long outputL = 0;                    //variable holding the output data

//////////////////////////////////////////////////////////////////////////////////////
///////////////////////////Service Switches///////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////

byte maintenancePin = 0;                       //defining the var for the maintenance switch
byte maintenanceActive = 0;                    //holding the switch state

/////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////RTC and Holiday switch timers///////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
tmElements_t tm;               //initializing RTC

byte room1Lights = 0;                 //var to hold the on command for room light
byte room2Lights = 0;                 //var to hold the on command for room light
byte room3Lights = 0;                 //var to hold the on command for room light
byte room4Lights = 0;                 //var to hold the on command for room light
byte room5Lights = 0;                 //var to hold the on command for room light
byte room6Lights = 0;                 //var to hold the on command for room light
byte room7Lights = 0;                 //var to hold the on command for room light
byte room8Lights = 0;                 //var to hold the on command for room light
byte room9Lights = 0;                 //var to hold the on command for room light
byte room10Lights = 0;

byte currentHour = 0;                 //var holding the time (hour 0-23)
byte currentMinute = 0;               //var holding the time (minute 0-59)
byte currentDay = 0;                  //var holding the date (day 1-31)
byte currentDoM = 0;                  //var holding the weekday (Sun - Sa, 1-7)
byte currentMonth = 0;                //var holding the date (month 1-12)
int currentYear = 0;                  //var holding the year (based on unix time)

//Array holding the day names to replace the weekday index

prog_char weekday_0[] PROGMEM = "Sun";
prog_char weekday_1[] PROGMEM = "Mon";
prog_char weekday_2[] PROGMEM = "Tue";
prog_char weekday_3[] PROGMEM = "Wed";
prog_char weekday_4[] PROGMEM = "Thu";
prog_char weekday_5[] PROGMEM = "Fri";
prog_char weekday_6[] PROGMEM = "Sat";

PROGMEM const char *weekday_table[] = {
  weekday_0,
  weekday_1,
  weekday_2,
  weekday_3,
  weekday_4,
  weekday_5,
  weekday_6
};

char buffer[20];
///////////////////////////////////////////////////////////////////////////
///////////////////Menu and user interface/////////////////////////////////
///////////////////////////////////////////////////////////////////////////

const byte btnMenu = 1;          //defining the menu button – moves through the menu
const byte btnSearch = 2;        //defining the search button – moves through values 
const byte btnSelect = 3;        //defining the select button – selects a menu or a value
const byte btnNone = 0;          //defining the non button pressed var
int act_key_in = 0;              //var holding the key related sensor reading

byte menuOption = 0;             //var to count current menu option
const byte menuOptions = 20;     //available menu options
byte submenu = 0;                //var to count current submenu option
const byte submenus = 9;         //available submenu options

char buffer_M[20];               //var holding the menu strings retrieved from
                                 //the program memory

//Storing some menu messages in the program memory
prog_char msg_0[] PROGMEM = "Not Used";      
prog_char msg_1[] PROGMEM = "Saving....";
prog_char msg_2[] PROGMEM = "Setup mode";
prog_char msg_3[] PROGMEM = "Starting....";
prog_char msg_4[] PROGMEM = "RMU 1.3.1";
prog_char msg_5[] PROGMEM = "Weekday";
prog_char msg_6[] PROGMEM = "On  TIMER  Off";
prog_char msg_7[] PROGMEM = "Off   ";
prog_char msg_8[] PROGMEM = "Active";
prog_char msg_9[] PROGMEM = "PIR Delay R";
prog_char msg_10[] PROGMEM = "T1 On/Off R";
prog_char msg_11[] PROGMEM = "T2 On/Off R";
prog_char msg_12[] PROGMEM = "T3 On/Off R";
prog_char msg_13[] PROGMEM = "ADJ Hour On";
prog_char msg_14[] PROGMEM = "ADJ Minute On";
prog_char msg_15[] PROGMEM = "ADJ Hour Off";
prog_char msg_16[] PROGMEM = "ADJ Minute Off";
prog_char msg_17[] PROGMEM = "Set Sensitivity";
prog_char msg_18[] PROGMEM = "Set photocell R";
prog_char msg_19[] PROGMEM = "Set photocell O";
prog_char msg_20[] PROGMEM = "ADJ Time Minute";
prog_char msg_21[] PROGMEM = "ADJ Time Hour";
prog_char msg_22[] PROGMEM = "ADJ Date Day";
prog_char msg_23[] PROGMEM = "ADJ Date Month";
prog_char msg_24[] PROGMEM = "ADJ Date Year";
prog_char msg_25[] PROGMEM = "T4 On/Off R";


//Creating the table for the stored menu messages
PROGMEM const char *msg_table[] = {
  msg_0,
  msg_1,
  msg_2,
  msg_3,
  msg_4,
  msg_5,
  msg_6,
  msg_7,
  msg_8,
  msg_9,
  msg_10,
  msg_11,
  msg_12,
  msg_13,
  msg_14,
  msg_15,
  msg_16,
  msg_17,
  msg_18,
  msg_19,
  msg_20,
  msg_21,
  msg_22,
  msg_23,
  msg_24,
  msg_25
};

//storing some special char's in the program memory
const byte char_table[] PROGMEM = {
  B01111110,                          //Arrow right
  B01111111,                          //Arrow left
  B00110000,                          //0
  B00111010,                          //seperator
  B00101110,                          //dott
  B00110001,                          //1
  B00110010,                          //2
  B00110011,                          //3
  B00110100,                          //4
  B00110101,                          //5
  B00110110,                          //6
  B00110111,                          //7
  B00111000,                          //8
  B00111001                           //9
};

//storing the main menu points in the program memory
prog_char menu_0[] PROGMEM = "Date/Time";
prog_char menu_1[] PROGMEM = "Sensitivity";
prog_char menu_2[] PROGMEM = "Room photo cut";
prog_char menu_3[] PROGMEM = "Room photo limit";
prog_char menu_4[] PROGMEM = "OS photo cut";
prog_char menu_5[] PROGMEM = "OS photo limit";
prog_char menu_6[] PROGMEM = "Room 1";
prog_char menu_7[] PROGMEM = "Room 2";
prog_char menu_8[] PROGMEM = "Room 3";
prog_char menu_9[] PROGMEM = "Room 4";
prog_char menu_10[] PROGMEM = "Room 5";
prog_char menu_11[] PROGMEM = "Room 6";
prog_char menu_12[] PROGMEM = "Room 7";
prog_char menu_13[] PROGMEM = "Room 8";
prog_char menu_14[] PROGMEM = "Room 9";
prog_char menu_15[] PROGMEM = "Room 10";
prog_char menu_16[] PROGMEM = "AC 1";
prog_char menu_17[] PROGMEM = "AC 2";
prog_char menu_18[] PROGMEM = "AC 3";
prog_char menu_19[] PROGMEM = "AC 4";

PROGMEM const char *menu_table[] = {
  menu_0,
  menu_1,
  menu_2,
  menu_3,
  menu_4,
  menu_5,
  menu_6,
  menu_7,
  menu_8,
  menu_9,
  menu_10,
  menu_11,
  menu_12,
  menu_13,
  menu_14,
  menu_15,
  menu_16,
  menu_17,
  menu_18,
  menu_19
};

//storing the sub menu points in the program memory
prog_char submenu_0[] PROGMEM = "PIR delay R";
prog_char submenu_1[] PROGMEM = "HT1 Active R";
prog_char submenu_2[] PROGMEM = "Timer 1 R";
prog_char submenu_3[] PROGMEM = "HT2 Active R";
prog_char submenu_4[] PROGMEM = "Timer 2 R";
prog_char submenu_5[] PROGMEM = "HT3 Active R";
prog_char submenu_6[] PROGMEM = "Timer 3 R";
prog_char submenu_7[] PROGMEM = "HT4 Active R";
prog_char submenu_8[] PROGMEM = "Timer 4 R";

PROGMEM const char *submenu_table[] = {
  submenu_0,
  submenu_1,
  submenu_2,
  submenu_3,
  submenu_4,
  submenu_5,
  submenu_6,
  submenu_7,
  submenu_8
};
  

void setup() {
   //////////////Start Serial for Debugging/////////////////////

   //Serial.begin(9600);
   
   //printing initialisation message
   lcd.begin(16, 2);
   lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(msg_table[4]))));
   delay(1000);
   lcd.setCursor(0, 1);
   lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(msg_table[3]))));
   delay(2000);

     
     //////////////////defining pin modes////////////////////
   
   pinMode(doorMonitor, OUTPUT);        //setting the LED pin to output
   
   pinMode(setupMode, INPUT);           //setup switch to activate menu
   
   pinMode(latchPin, OUTPUT);  //setting the latch pin to output
   pinMode(clockPin, OUTPUT);  //setting the clock pin to output
   pinMode(dataPin, INPUT);  //setting the data pin to input
   
   pinMode(latchPinOut, OUTPUT);
   pinMode(clockPinOut, OUTPUT);
   pinMode(dataPinOut, OUTPUT);
   
}  

void loop() {
 
  ///////////////////checking the setup switch/////////////////////////
  while(digitalRead(setupMode) != 0){        //stay in here if activated
    lcd.clear();                             //clear display
    lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(msg_table[2]))));                 //print Setup mode
    delay(500);                              //small delay
    
    button_loop();                           //function call to monitore menu buttons
  }
   //////////////////////////////////////getting the input//////////////////////////////////////////////////
   
  
   //Serial.print("switchVar1 first: ");
   //Serial.println(switchVar1, BIN);
   //Serial.print("switchVar2 first: ");
   //Serial.println(switchVar2, BIN);
   //Serial.print("switchVar3 first: ");
   //Serial.println(switchVar3, BIN);
   
   //pulse the latch pin, set to high to collect serial data
   digitalWrite(latchPin, HIGH);
   //give it chance to collect the data
   delayMicroseconds(25);
   //set latch pin to low to transmit data serially
   digitalWrite(latchPin, LOW);

   //while in serial mode, collect data into a byte
   switchVar1 = shiftIn(dataPin, clockPin);
   switchVar2 = shiftIn(dataPin, clockPin);
   switchVar3 = shiftIn(dataPin, clockPin);
   
   /////////////do something with the collected Data/////////////////////
   //checks for debugging
   //Serial.println();                       //debug only
   //Serial.print("Switch variable 1: ");    //debug only
   //Serial.println(switchVar1, BIN);        //debug only
   //Serial.println("-------------------");  //debug only
   //Serial.println();                       //debug only
   //Serial.print("Switch variable 2: ");    //debug only
   //Serial.println(switchVar2, BIN);        //debug only
   //Serial.println("-------------------");  //debug only
   //Serial.println();                       //debug only
   //Serial.print("Switch variable 3: ");    //debug only
   //Serial.println(switchVar3, BIN);        //debug only
   //Serial.println("-------------------");  //debug only
   
   ////////////loop through the 8 input pins to check their status////////////
   for(int n=0; n<=7; n++){

      //shift register 1
      if(switchVar1 & (1 << 0)) {                     //checking S1
         //Serial.println("Switch 1 was activated.");   //debug only
         switchState[0] = 1;
      }
      else {
         switchState[0] = 0;
      }

      if(switchVar1 & (1 << 1)) {                     //checking S2
         //Serial.println("Switch 2 was activated.");   //debug only
         switchState[1] = 1;
      }
      else {
         switchState[1] = 0;
      }
   
      if(switchVar1 & (1 << 2)) {                     //checking S3
         //Serial.println("Switch 3 was activated.");   //debug only
         switchState[2] = 1;
      }
      else {
         switchState[2] = 0;
      }

      if(switchVar1 & (1 << 3)) {                     //checking S4
         //Serial.println("Switch 4 was activated.");   //debug only
         switchState[3] = 1;
      }
      else {
         switchState[3] = 0;
      }

      if(switchVar1 & (1 << 4)) {                     //checking S8
         //Serial.println("Switch 8 was activated.");   //debug only
         switchState[7] = 1;
      }
      else {
         switchState[7] = 0;
      }

      if(switchVar1 & (1 << 5)) {                     //checking S7
         //Serial.println("Switch 7 was activated.");   //debug only
         switchState[6] = 1;
      }
      else {
         switchState[6] = 0;
      }

      if(switchVar1 & (1 << 6)) {                     //checking S6
         //Serial.println("Switch 6 was activated.");   //debug only
         switchState[5] = 1;
      }
      else {
         switchState[5] = 0;
      }

      if(switchVar1 & (1 << 7)) {                     //checking S5
         //Serial.println("Switch 5 was activated.");   //debug only
         switchState[4] = 1;
      }
      else {
         switchState[4] = 0;
      }

      //shift register 2

      if(switchVar2 & (1)) {                          //checking S9
         //Serial.println("Switch 9 was activated.");   //debug only
         switchState[8] = 1;
      }
      else {
         switchState[8] = 0;
      }

      if(switchVar2 & (1 << 1)) {                      //checking S10
         //Serial.println("Switch 10 was activated.");   //debug only
         switchState[9] = 1;
      }
      else {
         switchState[9] = 0;
      }

      if(switchVar2 & (1 << 2)) {                    //checking S11
         //Serial.println("Switch 11 was activated.");   //debug only
         switchState[10] = 1;
      }
      else {
         switchState[10] = 0;
      }

      if(switchVar2 & (1 << 3)) {                   //checking S12
         //Serial.println("Switch 12 was activated.");   //debug only
         switchState[11] = 1;
      }
      else {
         switchState[11] = 0;
      }

      if(switchVar2 & (1 << 4)) {                      //checking S16
         //Serial.println("Switch 16 was activated.");   //debug only
         switchState[15] = 1;
      }
      else {
         switchState[15] = 0;
      }

      if(switchVar2 & (1 << 5)) {                      //checking S15
         //Serial.println("Switch 15 was activated.");   //debug only
         switchState[14] = 1;
      }
      else {
         switchState[14] = 0;
      }

      if(switchVar2 & (1 << 6)) {                      //checking S14
         //Serial.println("Switch 14 was activated.");   //debug only
         switchState[13] = 1;
      }
      else {
         switchState[13] = 0;
      }

      if(switchVar2 & (1 << 7)) {                      //checking S13
         //Serial.println("Switch 13 was activated.");   //debug only
         switchState[12] = 1;
      }
      else {
         switchState[12] = 0;
      }

      //shift register 3

       if(switchVar3 & (1)) {                          //checking S17
         //Serial.println("Switch 17 was activated.");   //debug only
         switchState[16] = 1;
      }
      else {
         switchState[16] = 0;
      }

       if(switchVar3 & (1 << 1)) {                     //checking S18
         //Serial.println("Switch 18 was activated.");   //debug only
         switchState[17] = 1;
      }
      else {
         switchState[17] = 0;
      }
      if(switchVar3 & (1 << 2)) {                     //checking S19
         //Serial.println("Switch 19 was activated.");   //debug only
         switchState[18] = 1;
      }
      else {
         switchState[18] = 0;
      }
      
      if(switchVar3 & (1 << 3)) {                     //checking S20
         //Serial.println("Switch 20 was activated.");   //debug only
         maintenancePin = 1;
      }
      else {
         maintenancePin = 0;
      }
      
      if(switchVar3 & (1 << 4)) {                     //checking S21
         //Serial.println("Switch 20 was activated.");   //debug only
         switchState[20] = 1;
      }
      else {
         switchState[20] = 0;
      }
      
      if(switchVar3 & (1 << 5)) {                     //checking S22
         //Serial.println("Switch 21 was activated.");   //debug only
         switchState[21] = 1;
      }
      else {
         switchState[21] = 0;
      }
      
      if(switchVar3 & (1 << 6)) {                     //checking S23
         //Serial.println("Switch 22 was activated.");   //debug only
         switchState[22] = 1;
      }
      else {
         switchState[22] = 0;
      }
   }
   
  //////////////Debug Statements//////////////////////////////////
  /*for(int c=0; c<21; c++){
   Serial.print("Switch state: ");
   Serial.print(c);
   Serial.print(" / ");
   Serial.println(switchState[c]);
   delay(100);
  }*/
   //////////////////checking the light status//////////////////////
  
    sensorValue = 0; 
    int reading = 0;                                  //the readings
     for(int i=0; i<15; i++){                         //take 15 readings
      reading += analogRead(lightSensor);
    }
    //average the readings
    sensorValue = reading / 15;
   //Serial.print("Sensor value: ");
   //Serial.println(sensorValue);
  
   //////////////////processing the input/////////////////////
  if(RTC.read(tm)) {             //Reading the clock
    currentHour = tm.Hour;       //passing the time into a var
    currentMinute = tm.Minute;   //passing the time into a var
    currentDay = tm.Wday - 1;        //passing Weekday 
                                 //(Mon - Sun eg 1-7) into var
    currentDoM = tm.Day;         //passing day in to var (1-31)
    currentMonth = tm.Month;     //passing month into var (1-12)
    currentYear = tmYearToCalendar(tm.Year); //passing year to var
  }
  
  lcd.setCursor(0, 0);             //set the corsor to line 1 pos 1
  lcd.print("               ");    //print 15 blanks to delete all
                                   //prior statements
  lcd.setCursor(0, 1);             //set cursor to row 2 pos 1
  lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(weekday_table[currentDay]))));
  lcd.print(" ");
  if(currentDoM < 10) lcd.write(pgm_read_byte(&char_table[2]));  //print 0
  lcd.print(currentDoM);
  lcd.write(pgm_read_byte(&char_table[4]));   //print dott
  if(currentMonth < 10) lcd.write(pgm_read_byte(&char_table[2]));  //print 0
  lcd.print(currentMonth);
  lcd.print(" ");
  if(currentHour < 10) lcd.write(pgm_read_byte(&char_table[2]));  
                                   //if the hour is less than 10
                                   //we print a 0 to keep 2 digits
  lcd.print(currentHour);          //print current time (hour)
  lcd.write(pgm_read_byte(&char_table[3]));   //print seperator
  if(currentMinute < 10) lcd.write(pgm_read_byte(&char_table[2]));  
                                   //if the minute is less than
                                   //10 print 0 to keep 2 digits
  lcd.print(currentMinute);        //print current time (minutes)
  //Serial.print("Light level room 1: ");
  //Serial.println(lightLevel[0]);
  //Serial.print("Light level room 4: ");
  //Serial.println(lightLevel[3]); 
  photocellSwitch = getSensorValue(sensorValue, photoCellCutOff, 
                                   photoCellCutOn, photocellSwitchOld);
  photocellSwitchOld = photocellSwitch;
  if(photocellSwitch == 1 && currentHour >= 17 && currentHour <= 23) {
    //Serial.println("Entered first loop!");
    for(int i=0; i<9; i++){
      lightLevel[i] = 1;
    }
    lightLevel[15] = 1;
  }
  else if(photocellSwitch == 1 && currentHour >= 0 && currentHour <= 8){
    //Serial.println("Entered second loop!");
    for(int i=0; i<9; i++){
      lightLevel[i] = 1;
    }
    lightLevel[15] = 1;
  }
  else if(photocellSwitch == 0 && currentHour >= 5 && currentHour <= 8){
    //Serial.println("Entered third loop!");
    for(int c=0; c<17; c++){
      lightLevel[c] = 0;
    }
  }
  //////////////Holiday lighting/////////////////////////
    
  if(switchState[20] == 1) {       //check if the holliday switch
                                   //is activated
    lightOutput[14] = 0;           //make sure the master  relay is off
    
    //Serial.print("Current date: ");
    //Serial.print(days[currentDay - 1]);
    //Serial.print(", ");
    //Serial.print(currentDoM);
    //Serial.print("/");
    //Serial.print(currentMonth);
    //Serial.print("/");
    //Serial.println(currentYear);
    //Serial.print("Current Time: ");
    //Serial.print(currentHour);
    //Serial.print(" : ");
    //Serial.println(currentMinute);
    //Serial.print("Photo cell switch: ");
    //Serial.println(photocellSwitch);  
    //Serial.print("Light level room 1 after: ");
    //Serial.println(lightLevel[0]);
    //Serial.print("photocell switch: ");
    //Serial.println(photocellSwitch);
    //Serial.print("Light level room 3 after: ");
    //Serial.println(lightLevel[2]);
    //Serial.print("Light level room 4 after: ");
    //Serial.println(lightLevel[3]);
    ///////Room 1 (Bed 1) ///////////// 
    if(timer_active[0][0] == 1 && currentHour >= room_timers[0][0][0] && 
       currentHour <= (room_timers[0][0][2] + 1)){ //checking if we came passed
                                           //the hour where the lights
                                           //to be switched on
                                    
      //checking the times                              
      room1Lights = checkOnTime(room_timers[0][0][0], room_timers[0][0][1], 
                                room_timers[0][0][2], room_timers[0][0][3]);
    }
    
    
    if(timer_active[0][1] == 1 && currentHour >= room_timers[0][1][0] &&
       currentHour <= (room_timers[0][1][2] + 1)){ //checking if we came passed
                                          //the hour where the lights
                                          //to be switched on
                                    
      //checking the times                              
      room1Lights = checkOnTime(room_timers[0][1][0], room_timers[0][1][1], 
                                room_timers[0][1][2], room_timers[0][1][3]);
    }
        
 
    if(timer_active[0][2] == 1 && currentHour >= room_timers[0][2][0] &&
       currentHour <= (room_timers[0][2][2] + 1)){ //checking if we came passed
                                           //the hour where the lights
                                           //to be switched on
    //checking the times                                 
      room1Lights = checkOnTime(room_timers[0][2][0], room_timers[0][2][1], 
                                room_timers[0][2][2], room_timers[0][2][3]);
    }
    
    if(timer_active[0][3] == 1 && currentHour >= room_timers[0][3][0] &&
       currentHour <= (room_timers[0][3][2] + 1)){ //checking if we came passed
                                           //the hour where the lights
                                           //to be switched on
    //checking the times                                 
      room1Lights = checkOnTime(room_timers[0][3][0], room_timers[0][3][1], 
                                room_timers[0][3][2], room_timers[0][3][3]);
    }
    
    if(room1Lights == 1 && lightLevel[0] == 1){   //if with in the on time
      lightOutput[0] =1;            //switch on the lights
    }
    else {
      lightOutput[0] = 0;           //other keep them off
      lightLevel[0] = 0;
    }
    
    ////////Room 2 (Bed 2)//////////////
    if(timer_active[1][0] ==1 && currentHour >= room_timers[1][0][0]
       && currentHour <= (room_timers[1][0][2] + 1)){
      room2Lights = checkOnTime(room_timers[1][0][0], room_timers[1][0][1], 
                                room_timers[1][0][2], room_timers[1][0][3]);
    }
    
    if(timer_active[1][1] == 1 && currentHour >= room_timers[1][1][0] && 
       currentHour <= (room_timers[1][1][2] + 1)){
      room2Lights = checkOnTime(room_timers[1][1][0], room_timers[1][1][1], 
                                room_timers[1][1][2], room_timers[1][1][3]);
    }
    
    if(timer_active[1][2] == 1 && currentHour >= room_timers[1][2][0] && 
       currentHour <= (room_timers[1][2][2] + 1)){
      room2Lights = checkOnTime(room_timers[1][2][0], room_timers[1][2][1], 
                                room_timers[1][2][2], room_timers[1][2][3]);
    }
    
    if(timer_active[1][3] == 1 && currentHour >= room_timers[1][3][0] && 
       currentHour <= (room_timers[1][3][2] + 1)){
      room2Lights = checkOnTime(room_timers[1][3][0], room_timers[1][3][1], 
                                room_timers[1][3][2], room_timers[1][3][3]);
    }
    
    if(room2Lights == 1 && lightLevel[1] == 1){
      lightOutput[1] = 2;
    }
    else {
      lightOutput[1] = 0;
      lightLevel[1] =0;
    }
    
    ////////Room 3 (Bed 3) ////////////
    if(timer_active[2][0] == 1 && currentHour >= room_timers[2][0][0] && 
    currentHour <= (room_timers[2][0][2] + 1)){
      room3Lights = checkOnTime(room_timers[2][0][0], room_timers[2][0][1], 
                                room_timers[2][0][2], room_timers[2][0][3]);
    }
    
    if(timer_active[2][1] == 1 && currentHour >= room_timers[2][1][0] && 
       currentHour <= (room_timers[2][1][2] + 1)){
      room3Lights = checkOnTime(room_timers[2][1][0], room_timers[2][1][1], 
                                room_timers[2][1][2], room_timers[2][1][3]);
    }
    
    if(timer_active[2][2] == 1 && currentHour >= room_timers[2][2][0] && 
    currentHour <= (room_timers[2][2][2] + 1)){
      room3Lights = checkOnTime(room_timers[2][2][0], room_timers[2][2][1], 
                                room_timers[2][2][2], room_timers[2][2][3]);
    }
    
    if(timer_active[2][3] == 1 && currentHour >= room_timers[2][3][0] && 
    currentHour <= (room_timers[2][3][2] + 1)){
      room3Lights = checkOnTime(room_timers[2][3][0], room_timers[2][3][1], 
                                room_timers[2][3][2], room_timers[2][3][3]);
    }
    
    if(room3Lights == 1 && lightLevel[2] == 1){
      lightOutput[2] = 4;
    }
    else {
      lightOutput[2] = 0;
      lightLevel[2] = 0;
    }
    
    ////////Room 4 (living)/////////////////////
    if(timer_active[3][0] == 1 && currentHour >= room_timers[3][0][0] && 
       currentHour <= (room_timers[3][0][2] + 1)){
      room4Lights = checkOnTime(room_timers[3][0][0], room_timers[3][0][1], 
                                room_timers[3][0][2], room_timers[3][0][3]);
    }
    if(timer_active[3][1] == 1 && currentHour >= room_timers[3][1][0] && 
       currentHour <= (room_timers[3][1][2] + 1)){
      room4Lights = checkOnTime(room_timers[3][1][0], room_timers[3][1][1], 
                                room_timers[3][1][2], room_timers[3][1][3]);
    }
    
    if(timer_active[3][2] == 1 && currentHour >= room_timers[3][2][0] && 
       currentHour <= (room_timers[3][2][2] + 1)){
      room4Lights = checkOnTime(room_timers[3][2][0], room_timers[3][2][1], 
                                room_timers[3][2][2], room_timers[3][2][3]);
    }
    
    if(timer_active[3][3] == 1 && currentHour >= room_timers[3][3][0] && 
       currentHour <= (room_timers[3][3][2] + 1)){
      room4Lights = checkOnTime(room_timers[3][3][0], room_timers[3][3][1], 
                                room_timers[3][3][2], room_timers[3][3][3]);
    }
        
    if(room4Lights == 1 && lightLevel[3] == 1){
      lightOutput[3] = 8;
    }
    else {
      lightOutput[3] = 0;
      lightLevel[3] = 0;
    }
    
    ////////Room 5 (Bath 1)/////////////////////
    if(timer_active[4][0] == 1 && currentHour >= room_timers[4][0][0] && 
       currentHour <= (room_timers[4][0][2] + 1)){
      room5Lights = checkOnTime(room_timers[4][0][0], room_timers[4][0][1], 
                                room_timers[4][0][2], room_timers[4][0][3]);
    }
        
    if(timer_active[4][1] == 1 && currentHour >= room_timers[4][1][0] && 
       currentHour <= (room_timers[4][1][2] + 1)){
      room5Lights = checkOnTime(room_timers[4][1][0], room_timers[4][1][1], 
                                room_timers[4][1][2], room_timers[4][1][3]);
    }
    
    if(room5Lights == 1 && lightLevel[4] == 1){
      lightOutput[4] = 16;
    }
    else {
      lightOutput[4] = 0;
      lightLevel[4] =0;
    }
    
    ////////Room 6 (Bath 2)/////////////////////
    if(timer_active[5][0] == 1 && currentHour >= room_timers[5][0][0] && 
       currentHour <= (room_timers[5][0][2] + 1)){
      room6Lights = checkOnTime(room_timers[5][0][0], room_timers[5][0][1], 
                                room_timers[5][0][2], room_timers[5][0][3]);
    }
    
    if(timer_active[5][1] == 1 && currentHour >= room_timers[5][1][0] && 
       currentHour <= (room_timers[5][1][2] + 1)){
      room6Lights = checkOnTime(room_timers[5][1][0], room_timers[5][1][1], 
                                room_timers[5][1][2], room_timers[5][1][3]);
    }
    
    if(room6Lights == 1 && lightLevel[5] == 1){
      lightOutput[5] = 32;
    }
    else {
      lightOutput[5] = 0;
      lightLevel[5] = 0;
    }
    
    ////////Room 7 (Bath 3)/////////////////////
    if(timer_active[6][0] == 1 && currentHour >= room_timers[6][0][0] && 
       currentHour <= (room_timers[6][0][2])){
      room7Lights = checkOnTime(room_timers[6][0][0], room_timers[6][0][1], 
                                room_timers[6][0][2], room_timers[6][0][3]);
    }
    
    if(timer_active[6][1] == 1 && currentHour >= room_timers[6][1][0] && 
       currentHour <= (room_timers[6][1][2] + 1)){
      room7Lights = checkOnTime(room_timers[6][1][0], room_timers[6][1][1], 
                                room_timers[6][1][2], room_timers[6][1][3]);
    }
    
    if(room7Lights == 1 && lightLevel[6] == 1){
      lightOutput[6] = 64;
    }
    else {
      lightOutput[6] = 0;
      lightLevel[6] = 0;
    }
    
    ////////Room 8 (Bath 4)/////////////////////
    if(timer_active[7][0] == 1 && currentHour >= room_timers[7][0][0] && 
       currentHour <= (room_timers[7][0][2] + 1)){
      room8Lights = checkOnTime(room_timers[7][0][0], room_timers[7][0][1], 
                                room_timers[7][0][2], room_timers[7][0][3]);
    }
    
    if(timer_active[7][1] == 1 && currentHour >= room_timers[7][1][0] && 
       currentHour <= (room_timers[7][1][2] + 1)){
      room8Lights = checkOnTime(room_timers[7][1][0], room_timers[7][1][1], 
                                room_timers[7][1][2], room_timers[7][1][3]);
    }
    
    if(room8Lights == 1 && lightLevel[7] == 1){
      lightOutput[7] = 128;
    }
    else {
      lightOutput[7] = 0;
      lightLevel[7] = 0;
    }
    
    ////////Room 9 (kitchen)/////////////////////
    if(timer_active[8][0] == 1 && currentHour >= room_timers[8][0][0] && 
       currentHour <= (room_timers[8][0][2] + 1)){
      room9Lights = checkOnTime(room_timers[8][0][0], room_timers[8][0][1], 
                                room_timers[8][0][2], room_timers[8][0][3]);
    }
    if(timer_active[8][1] == 1 && currentHour >= room_timers[8][1][0] && 
       currentHour <= (room_timers[8][1][2] + 1)){
      room9Lights = checkOnTime(room_timers[8][1][0], room_timers[8][1][1], 
                                room_timers[8][1][2], room_timers[8][1][3]);
    }
    
    if(room9Lights == 1 && lightLevel[8] == 1){
      lightOutput[8] = 256;
    }
    else {
      lightOutput[8] = 0;
      lightLevel[8] = 0;
    }
     
        ////////Room 10 (corridor)/////////////////////
    if(timer_active[9][0] == 1 && currentHour >= room_timers[9][0][0] && 
       currentHour <= (room_timers[9][0][2] + 1)){
      room10Lights = checkOnTime(room_timers[9][0][0], room_timers[9][0][1], 
                                room_timers[9][0][2], room_timers[9][0][3]);
    }
    if(timer_active[9][1] == 1 && currentHour >= room_timers[9][1][0] && 
       currentHour <= (room_timers[9][1][2] + 1)){
      room9Lights = checkOnTime(room_timers[9][1][0], room_timers[9][1][1], 
                                room_timers[9][1][2], room_timers[9][1][3]);
    }
    
    if(room10Lights == 1 && lightLevel[9] == 1){
      lightOutput[9] = 512;
    }
    else {
      lightOutput[9] = 0;
      lightLevel[9] = 0;
    }
 
      ////////Outside lights////////////////////
     outsideOnTime = checkOnTime(17, 02, hourOutsideOff, 
                                  minuteOutsideOff);    //function call to check time
     
     //Serial.print("Timer: ");                          //debug only
     //Serial.println(outsideOnTime);                    //debug only
     /*if(sensorValue <= photoOutsideOn | 
        sensorValue < (photoOutsideOn + 50)            //checking if light is
                                                       //within photocell readings
        && outsideOnTime == 1){
       lightOutput[15] = 32768;                        //switching on the lights
     }
     else {
       lightOutput[15] = 0;                            //no matches, they switch off
     }*/
     
     if(outsideOnTime == 1 && lightLevel[15] == 1){
       lightOutput[15] = 32768;
     }
     else {
       lightOutput[15] = 0;
       lightLevel[15] = 0;
     }
 
  }  
  else {
      
     ////////Outside lights////////////////////
     outsideOnTime = checkOnTime(17, 02, hourOutsideOff, 
                                 minuteOutsideOff);    //function call to check time
     //Serial.print("Timer: ");                          //debug only
     //Serial.println(outsideOnTime);                    //debug only
     /*if(sensorValue <= photoOutsideOn | 
        sensorValue < (photoOutsideOn + 50)            //checking if light is
                                                       //within photocell readings
        && outsideOnTime == 1){
       lightOutput[15] = 32768;                        //switching on the lights
     }
     else {
       lightOutput[15] = 0;                            //no matches, they switch off
     }*/
     if(outsideOnTime == 1 && lightLevel[15] == 1){
       lightOutput[15] = 32768;
     }
     else {
       lightOutput[15] = 0;
       lightLevel[15] = 0;
     }  
     //////////////////room lights//////////////////////////////
         
      lightStatus[16] = check_master(0);                 //check if doorswitch was activated room 1 (bed1)
     
      lightOutput[0] = check_light_P(0, 1, 0, 1);        //check status room 1 (bed 1)
      delay(5);
      lightStatus[16] = check_master(2);                 //check if doorswitch was activated room 2 (bed 2)
     
      lightOutput[1] = check_light_P(2, 3, 1, 2);       //check status room 2 (bed 2)
      delay(5);
      lightStatus[16] = check_master(4);                 //check if doorswitch was activated room 3 (bed 3)
      
      lightOutput[2] = check_light_P(4, 5, 2, 4);       //check status room 3 (bed 3)
      delay(5);
      lightStatus[16] = check_master(6);                 //check if doorswitch was activated room 4 (living)
     
      lightOutput[3] = check_light_P(6, 7, 3, 8);       //check status room 4 (living)
      delay(5);
      lightStatus[16] = check_master(8);                 //check if doorswitch was activated room 5 (bath 1)
      
      lightOutput[4] = check_light_N(8, 4, 16);         //check status room 5 (bath 1)
      delay(5);
      lightStatus[16] = check_master(9);                 //check if door switch was activated room 6 (bath 2)
      
      lightOutput[5] = check_light_N(9, 5, 32);
      delay(5);
      lightStatus[16] = check_master(10);
    
      lightOutput[6] = check_light_N(10, 6, 64);
      delay(5);
      lightStatus[16] = check_master(11);  
      
      lightOutput[7] = check_light_N(11, 7, 128);
      delay(5);
      lightStatus[16] = check_master(12); 
      
      lightOutput[8] = check_light_N(12, 8, 256);
      delay(5);
      lightStatus[16] = check_master(13);
    
      lightOutput[9] = check_light_N(13, 9, 512);
  
  /////////////////////Ac Read Switches////////////////////////
  
    if(switchState[14] == 1 && lightStatus[14] == 1){              //Checking if readswitches are activated
                                                                 //and the master relay is on AC room 1 (bed1)
      lightOutput[10] = 1024;                                    //providing the ability to
                                                                 //switch on the AC
      lightStatus[10] = 1;                                       //setting the light (AC) status
      roomTimer[10] = millis()/1000;                                  //setting the timer
    }
    else if(switchState[14] == 0 && lightStatus[14] == 1){       //if a door is opened and the master
                                                                 //relay is on
      currentTime = millis()/1000;                                    //setting time reference
      endTime = currentTime - roomTimer[10];                     //calculating the inactive time
      if(endTime >= delayTime[10]){                              //comparing inactive time with
                                                                 //delay time
        lightOutput[10] = 0;                                     //canceling ability to switch on the 
                                                                 //AC
        lightStatus[10] = 0;                                     //resetting the light (AC) status
        roomTimer[10] = 0;                                       //resetting the timer
      }
    }
    
  if(switchState[15] == 1 && lightStatus[14] == 1){              //Checking if readswitches are activated
                                                                 //and the master relay is on AC room 2 (bed2)
      lightOutput[11] = 2048;                                    //providing the ability to
                                                                 //switch on the AC
      lightStatus[11] = 1;                                       //setting the light (AC) status
      roomTimer[11] = millis()/1000;                                  //setting the timer
    }
    else if(switchState[15] == 0 && lightStatus[14] == 1){       //if a door is opened and the master
                                                                 //relay is on
      currentTime = millis()/1000;                                    //setting time reference
      endTime = currentTime - roomTimer[11];                     //calculating the inactive time
      if(endTime >= delayTime[11]){                              //comparing inactive time with
                                                                 //delay time
        lightOutput[11] = 0;                                     //canceling ability to switch on the 
                                                                 //AC
        lightStatus[11] = 0;                                     //resetting the light (AC) status
        roomTimer[11] = 0;                                       //resetting the timer
      }
    }  
  
  if(switchState[16] == 1 && lightStatus[14] == 1){              //Checking if readswitches are activated
                                                                 //and the master relay is on AC room 3 (bed3)
      lightOutput[12] = 4096;                                    //providing the ability to
                                                                 //switch on the AC
      lightStatus[12] = 1;                                       //setting the light (AC) status
      roomTimer[12] = millis()/1000;                                  //setting the timer
    }
    else if(switchState[16] == 0 && lightStatus[14] == 1){       //if a door is opened and the master
                                                                 //relay is on
      currentTime = millis()/1000;                                    //setting time reference
      endTime = currentTime - roomTimer[12];                     //calculating the inactive time
      if(endTime >= delayTime[12]){                              //comparing inactive time with
                                                                 //delay time
        lightOutput[12] = 0;                                     //canceling ability to switch on the 
                                                                 //AC
        lightStatus[12] = 0;                                     //resetting the light (AC) status
        roomTimer[12] = 0;                                       //resetting the timer
      }
    }  
  
  if(switchState[17] == 1 && lightStatus[14] == 1){              //Checking if readswitches are activated
                                                                 //and the master relay is on AC room 4 living
      lightOutput[13] = 8192;                                    //providing the ability to
                                                                 //switch on the AC
      lightStatus[13] = 1;                                       //setting the light (AC) status
      roomTimer[13] = millis()/1000;                                  //setting the timer
    }
    else if(switchState[17] == 0 && lightStatus[14] == 1){       //if a door is opened and the master
                                                                 //relay is on
      currentTime = millis()/1000;                                    //setting time reference
      endTime = currentTime - roomTimer[13];                     //calculating the inactive time
      if(endTime >= delayTime[13]){                              //comparing inactive time with
                                                                 //delay time
        lightOutput[13] = 0;                                     //canceling ability to switch on the 
                                                                 //AC
        lightStatus[13] = 0;                                     //resetting the light (AC) status
        roomTimer[13] = 0;                                       //resetting the timer
      }
    }
    
      /////////////Door switch control ////////////////////
    //Serial.print("switchState 18 :");
    //Serial.println(switchState[18]);
    //Serial.print("Switch state old: ");
    //Serial.println(masterSwitchStateOld);
    //Serial.print("Light status 16: ");
    //Serial.println(lightStatus[16]);
      
    if(switchState[18] != masterSwitchStateOld) {               //door switch check if the switch state
                                                                //has changed
      //Serial.println("Door switch was activated");              //debug only
      currentTime = millis()/1000;                                   //setting time reference
      lightStatus[16] = 1;                                      //setting light status
      digitalWrite(doorMonitor, HIGH);                          //setting the control LED
      for(int i=0; i<17; i++){                                  //looping through the timers
        roomTimer[i] = currentTime;                             //setting the timers
      }
    }
    else if(switchState[18] == masterSwitchStateOld && lightStatus[16] == 1){ //if the switch state
                                                                //has not changed and the lights are on
      //Serial.println("Checking off status");                    //debug only
      currentTime = millis()/1000;                                   //setting the time reference
      offTime = roomTimer[16] + delayTime[14];                  //setting the allowed delay time
      //Serial.print("off Time: ");
      //Serial.println(offTime);
      //Serial.print("current Time: ");
      //Serial.println(currentTime);
      if(currentTime >= offTime) {                              //comparing the times
        for(int c=0; c<17; c++) {                               //looping through the circuits
          if(roomTimer[c] != roomTimer[16]) {                   //comparing timers
            mainOff = 1;                                        //setting the switch off all command
            lightStatus[16] = 0;                                //switching off the master relay
          }
          else {
            mainOff = 0;                                        //if the timers match we set the 
                                                                //switch off all command to 0
            break;                                              //leaving the loop
          }
        }
      }
      //Serial.print("Main off: ");
      //Serial.println(mainOff);
      if(mainOff == 0) {                                        //master off command is 0
        //Serial.println("switching off everything and reset all"); //debug only
        for(int i=0; i<17; i++) {                               //looping through the circuits
          lightStatus[i] = 0;                                   //resetting all light status
          lightOutput[i] = 0;                                   //switching off all lights
          priorityStatus[i] = 0;                                //resetting all set priorities
          roomTimer[i] = 0;                                     //resetting all room timers
        }
        digitalWrite(doorMonitor, LOW);                         //resetting the control LED
        mainOff = 1;                                            //resetting master off command
      }
    }
    masterSwitchStateOld = switchState[18];                     //setting the switchState to old
  }  
  ///////////////////////////Output/////////////////////////////////////////////////
  
  for(int i=0; i<17; i++) {                                //loop through the light output array
    /*Serial.print("Light Output ");                        //debug only
    Serial.print(i);                                      //debug only
    Serial.print(": ");                                   //debug only
    Serial.println(lightOutput[i]);                       //debug only
    Serial.print("Light status: ");                       //debug only
    Serial.println(lightStatus[i]);                       //debug only
    Serial.print("Room Timer: ");                         //debug only
    Serial.println(roomTimer[i]);                         //debug only
    delay(500);*/
    outputL += lightOutput[i];                            //adding up the numbers
  }
  
  if(maintenancePin == 1) {              //if maintenance switch is active
    for(int i=1; i>17; i++){             //loop through all circuits
      lightStatus[i] = 1;                //setting the light status of everything
      roomTimer[i] = millis()/1000;           //setting all the room timers
    }
    outputL = 32767;                     //setting the output 
                                         //binary 0111111111111111
  }  
  
  lcd.setCursor(0,0);
  lcd.print(outputL, BIN);
  //Serial.print("Output value: ");
  //Serial.print(outputL);
  //Serial.print("   ");
  //Serial.println(outputL, BIN);
  digitalWrite(latchPinOut, LOW);                   //setting the latch pin to low to
                                                    //be able to send the data
  shiftOut(dataPinOut, clockPinOut, MSBFIRST, (outputL >> 8)); //sending the date for the 
                                                               //second shift register
  shiftOut(dataPinOut, clockPinOut, MSBFIRST, outputL);        //sending the data for the
                                                               //first shift register
  digitalWrite(latchPinOut, HIGH);                  //setting the latch pin back to
                                                    //high to finish the data transmission
  
  outputL = 0;                                      //setting the var holding the output 
                                                    //number back to 0 
  delay(sensitivity);                               //delay to adjust how responsive the
                                                    //system will react
  
}



////////////////Shift In Function for Input processing ////////////

byte shiftIn(int myDataPin, int myClockPin) {
  int i;
  int temp = 0;
  int pinState;
  byte myDataIn = 0;
  
  pinMode(myClockPin, OUTPUT);
  pinMode(myDataPin, INPUT);
  
  for(i=7; i>=0; i--) {
    digitalWrite(myClockPin, LOW);
    delayMicroseconds(2);
    temp = digitalRead(myDataPin);
    if(temp) {
      pinState = 1;
      myDataIn = myDataIn | (1 << i);
    }
    else {
      pinState = 0;
    }
    //Serial.print("PinState: ");    //debug only
    //Serial.print(pinState);        //debug only
    //Serial.print("        ");      //debug only
    //Serial.println(myDataIn, BIN); //debug only
    
    digitalWrite(myClockPin, HIGH);
  }
  //Serial.println();                //debug only
  //Serial.println(myDataIn, BIN);   //debug only
  return myDataIn;
}


////////////function to check timer/////////
byte checkOnTime(byte hourOn, byte minuteOn, byte hourOff, byte minuteOff){
  tmElements_t tm;
  byte onTime = 0;
  long timeNow = 0;
  long onTrigger = 0;
  long offTrigger = 0;
  
  if(RTC.read(tm)){ 
    
    timeNow = tmConvert_t(tmYearToCalendar(tm.Year), tm.Month, tm.Day, tm.Hour, tm.Minute, tm.Second);
    
    onTrigger = tmConvert_t(tmYearToCalendar(tm.Year), tm.Month, tm.Day, hourOn, minuteOn, 0);
    
    if(hourOff < hourOn) {
      offTrigger = tmConvert_t(tmYearToCalendar(tm.Year), tm.Month, tm.Day+1, hourOff, minuteOff, 0);
    }
    else {
      offTrigger = tmConvert_t(tmYearToCalendar(tm.Year), tm.Month, tm.Day, hourOff, minuteOff, 0);
    }
    if(timeNow >= onTrigger && timeNow < offTrigger) {
      onTime = 1;
    }
    else {
      onTime = 0;
    }
  }
  //Serial.print("   Time now: ");
  //Serial.println(timeNow);
  //Serial.print(" On trigger: ");
  //Serial.println(onTrigger);
  //Serial.print("Off Trigger: ");
  //Serial.println(offTrigger);
  return onTime;
}

/////function to convert real time to unix timne////////
time_t tmConvert_t(int YYYY, byte MM, byte DD, byte hh, byte mm, byte ss){
  tmElements_t tmSet;
  tmSet.Year = YYYY - 1970;
  tmSet.Month = MM;
  tmSet.Day = DD;
  tmSet.Hour = hh;
  tmSet.Minute = mm;
  tmSet.Second = ss;
  return makeTime(tmSet);         //convert to time_t
}

byte getSensorValue(int sensorReading, int switchValue, 
                    int switchLimit, byte switchStatus){
  byte onStatus = 0;
  
  if(switchStatus == 0){
    if(sensorReading <= switchValue){
      onStatus = 1;
    }
    else if(sensorReading > switchLimit){
      onStatus = 0;
    }
    else if(sensorReading > switchValue &&
            sensorReading <= switchLimit){
      onStatus = 0;
    }
  }
  else if(switchStatus == 1){
    if(sensorReading <= switchValue){
      onStatus = 1;
    }
    else if(sensorReading > switchValue &&
            sensorReading <= switchLimit){
      onStatus = 1;
    }
    else if(sensorReading > switchLimit){
      onStatus = 0;
    }
  }
  return onStatus;
} 

byte check_master(byte swNo){
  if(switchState[swNo] == 1 && lightStatus[16] == 1) {            //checking if PIR with switch Number  was
                                                                   //activated (bed 1)
     lightStatus[16] = 0;                                      //resetting master off
     digitalWrite(doorMonitor, LOW);                           //resetting the door Monitor LED
  }
  //else {
    //lightStatus[16] = 1;
 // }
  return lightStatus[16];
}

unsigned long check_light_P(byte pir, byte prio, byte room, unsigned long light){
  if(switchState[prio] == 0 && sensorValue <= photoCellCutOff) {  //checking if S2 priority off was
                                                                   //set bed 1
      if(switchState[pir] == 1 && priorityStatus[room] == 0) {        //check if the PIR in bed 1 was
                                                                 //activated and no priority was set
         //Serial.println("We switch in the lights in bedroom 1");  //Debug only
         lightOutput[room] = light;                                     //switching on the lights – binary
                                                                 //000000000000000000000001
         lightStatus[room] = 1;                                     //setting the light status for bed 1
         lightOutput[14] = 16384;                                //make sure the master relay
                                                                 //stays on
         lightStatus[14] = 1;                                    //setting the master yelay status
         roomTimer[room] = millis()/1000;                                //setting the timer
      }
      else if(switchState[pir]  == 0 && lightStatus[room] == 1) {     //the PIR not activated but the
                                                                 //lights are on
         //Serial.println("We are checking the timer");            //Debug only
         currentTime = millis()/1000;                                 //setting time reference
         endTime = currentTime - roomTimer[room];                   //calculating the inactive time
         if(endTime >= delayTime[room]) {                           //comparing inactive time with
                                                                 //allowed delay time
            //Serial.println("Time is up switching off the lights");  //Debug only
            lightOutput[room] = 0;                                  //switching off the lights
            lightStatus[room] = 0;                                  //resetting the light status
            roomTimer[room] = 0;                                    //resetting the room timer
         }
      }
   }
   else if(switchState[prio] == 1 && lightStatus[room] == 1
           && switchState1Old != 1) {                            //if priority is activated and the
                                                                 //lights are on
      //Serial.println("Priority switch activated switching off the lights");  //Debug only
      lightOutput[room] = 0;                                        //switching off the lights
      lightStatus[room] = 0;                                        //resetting the light status
      roomTimer[room] = 0;                                          //resetting the room timer
      priorityStatus[room] = 1;                                     //setting the priority status bed 1
   }
   else if(switchState[prio] == 1 && lightStatus[room] == 0
           && switchState1Old != 1) {                               //if priority was activated and the 
                                                                 //lights are off
      //Serial.println("Priority switch deactivated switching on the lights");    //Debug only
      lightOutput[room] = light;                                         //switching on the lights
      lightStatus[room] = 1;                                        //setting the light status
      roomTimer[room] = millis()/1000;                                   //setting the room timer
      priorityStatus[room] = 0;                                     //setting the priority for bed 1 back                                                                  //to 0
   }
   switchState1Old = switchState[prio];        //passing on the switch state
   return lightOutput[room];
}

unsigned long check_light_N(byte pir, byte room, unsigned long light){
  if(switchState[pir] == 1) {                                     //checking S9 PIR of bathroom 1 
                                                                 //(room 5)
    //Serial.println("We switch on the lights");                 //Debug only
    lightOutput[room] = light;                                       //switching on the lights
    lightStatus[room] = 1;                                    //setting the light status
    lightOutput[14] = 16384;                                   //make sure the master relay
                                                               //stays on
    lightStatus[14] = 1;                                       //setting the master yelay status
    roomTimer[room] = millis()/1000;                                   //setting the room timer
  }
  else if(switchState[pir] == 0 && lightStatus[room] == 1) {       //if no PIR was activated and 
                                                              //the lights are on
    //Serial.println("We are checking the timer");              //Debug only
    currentTime = millis()/1000;                                   //setting time reference
    endTime = currentTime - roomTimer[room];                     //calculating the inactive time
    if(endTime >= delayTime[room]) {                             //comparing inactive time with 
                                                              //delay time
      //Serial.println("We are switching off the lights");      //debug only 
      lightOutput[room] = 0;                                     //switching off the lights
      lightStatus[room] = 0;                                    //resetting the light status
      roomTimer[room] = 0;                                       //resetting the room timer
    }
  }
  return lightOutput[room];
}

int read_act_buttons(){
  act_key_in = analogRead(1);      //reading the sensor
  delay(250);                      //button debounce delay
  //Readings centered at 170 for menu
  //203 for search and 252 for select
  //Serial.print("Reading: ");
  //Serial.println(act_key_in);
  if(act_key_in < 160) return btnNone; //most likely result first
  //adding a range of +/- 10 to compensate for bouncing
  //readings
  if(act_key_in > 160 && act_key_in < 180) return btnMenu;  
  if(act_key_in > 193 && act_key_in < 213) return btnSearch;
  if(act_key_in > 242 && act_key_in < 262) return btnSelect;
  return btnNone;
}

//Checking for a pressed menu button
void button_loop(){
  //Serial.println("in button loop");
  byte button = read_act_buttons();   //function call to read the buttons
  if(button == btnMenu){              //if button menu was pressed
    selectMenu();                   //delay for readability
  }
}

void selectMenu(){
  //Serial.println("SelectMenu");
  byte button = 0;                    //var holding the button value
  byte subButton = 0;                 //var holding the subButton value
  menuOption = 1;                     //current menu option
  lcd.clear();                        //clear screen
  //print the retrieved string on lcd
  lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(menu_table[0]))));
  
  while(menuOption <= menuOptions){   //loop through menu options
    button = read_act_buttons();      //check if button was pressed
    if(button == btnMenu){            //if it was btn menu
      menuOption++;                   //add 1 to menu option
      if(menuOption == 2){             //if it's menu option 2
        lcd.clear();                   //clear display
        //print retrieved string on lcd
        lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(menu_table[1]))));
      }
      if(menuOption == 3){             //if it's menu option 3
        lcd.clear();                   //clear display
        //print retrieved string on lcd
        lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(menu_table[2]))));
      }
      if(menuOption == 4){            //if it's menu option 4
        lcd.clear();                  //clear lcd
        //print retrieved string on lcd
        lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(menu_table[3]))));
        lcd.setCursor(0, 1);          //set cursor to row 2 column 1
        //print tetrieved message sdting
        lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(msg_table[0]))));
      }
      if(menuOption == 5){            //if it's menu option 5
        lcd.clear();                  //clear display
        //print retrieved string on lcd
        lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(menu_table[4]))));
      }
      if(menuOption == 6){            //if it's menu option 6
        lcd.clear();                  //clear lcd
        //print retrieved string on lcd
        lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(menu_table[5]))));
        lcd.setCursor(0, 1);          //set cursor to row 2 column 1
        //print retrieved message string
        lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(msg_table[0]))));
      }
      if(menuOption == 7){            //if it's menu option 7
        lcd.clear();                  //clear lcd
        //print retrieved string on lcd
        lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(menu_table[6]))));
        lcd.setCursor(15, 0);          //set cursor to row 2 column 1
        //print tetrieved message string
        lcd.write(pgm_read_byte(&char_table[0]));
      }
      if(menuOption == 8){            //if it's menu option 8
        lcd.clear();                  //clear lcd
        //print retrieved string on lcd
        lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(menu_table[7]))));
        lcd.setCursor(15, 0);          //set cursor to row 2 column 1
        //print tetrieved message string
        lcd.write(pgm_read_byte(&char_table[0]));
      }
      if(menuOption == 9){            //if it's menu option 9
        lcd.clear();                  //clear lcd
        //print retrieved string on lcd
        lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(menu_table[8]))));
        lcd.setCursor(15, 0);          //set cursor to row 2 column 1
        //print tetrieved message string
        lcd.write(pgm_read_byte(&char_table[0]));
      }
      if(menuOption == 10){            //if it's menu option 10
        lcd.clear();                  //clear lcd
        //print retrieved string on lcd
        lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(menu_table[9]))));
        lcd.setCursor(15, 0);          //set cursor to row 2 column 1
        //print tetrieved message string
        lcd.write(pgm_read_byte(&char_table[0]));
      }
      if(menuOption == 11){            //if it's menu option 12
        lcd.clear();                  //clear lcd
        //print retrieved string on lcd
        lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(menu_table[10]))));
        lcd.setCursor(15, 0);          //set cursor to row 2 column 1
        //print tetrieved message string
        lcd.write(pgm_read_byte(&char_table[0]));
      }
      if(menuOption == 12){            //if it's menu option 13
        lcd.clear();                  //clear lcd
        //print retrieved string on lcd
        lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(menu_table[11]))));
        lcd.setCursor(15, 0);          //set cursor to row 2 column 1
        //print tetrieved message sdting
        lcd.write(pgm_read_byte(&char_table[0]));
      }
      if(menuOption == 13){            //if it's menu option 14
        lcd.clear();                  //clear lcd
        //print retrieved string on lcd
        lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(menu_table[12]))));
        lcd.setCursor(15, 0);          //set cursor to row 2 column 1
        //print tetrieved message string
        lcd.write(pgm_read_byte(&char_table[0]));
      }
      if(menuOption == 14){            //if it's menu option 15
        lcd.clear();                  //clear lcd
        //print retrieved string on lcd
        lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(menu_table[13]))));
        lcd.setCursor(15, 0);          //set cursor to row 2 column 1
        //print tetrieved message string
        lcd.write(pgm_read_byte(&char_table[0]));
      }
      if(menuOption == 15){            //if it's menu option 16
        lcd.clear();                  //clear lcd
        //print retrieved string on lcd
        lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(menu_table[14]))));
        lcd.setCursor(15, 0);          //set cursor to row 2 column 1
        //print retrieved message string
        lcd.write(pgm_read_byte(&char_table[0]));
      }
      if(menuOption == 16){            //if it's menu option 17
        lcd.clear();                  //clear lcd
        //print retrieved string on lcd
        lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(menu_table[15]))));
        lcd.setCursor(15, 0);          //set cursor to row 2 column 1
        //print tetrieved message string
        lcd.write(pgm_read_byte(&char_table[0]));
      }
      if(menuOption == 17){            //if it's menu option 18
        lcd.clear();                  //clear lcd
        //print retrieved string on lcd
        lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(menu_table[16]))));
        lcd.setCursor(15, 0);          //set cursor to row 2 column 1
        //print retrieved message string
        lcd.write(pgm_read_byte(&char_table[0]));
      }
      if(menuOption == 18){            //if it's menu option 19
        lcd.clear();                  //clear lcd
        //print retrieved string on lcd
        lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(menu_table[17]))));
        lcd.setCursor(15, 0);          //set cursor to row 2 column 1
        //print tetrieved message sdting
        lcd.write(pgm_read_byte(&char_table[0]));
      }
      if(menuOption == 19){            //if it's menu option 20
        lcd.clear();                  //clear lcd
        //print retrieved string on lcd
        lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(menu_table[18]))));
        lcd.setCursor(15, 0);          //set cursor to row 2 column 1
        //print tetrieved message sdting
        lcd.write(pgm_read_byte(&char_table[0]));
      }
      if(menuOption == 20){            //if it's menu option 21
        lcd.clear();                  //clear lcd
        //print retrieved string on lcd
        lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(menu_table[19]))));
        lcd.setCursor(15, 0);          //set cursor to row 2 column 1
        //print retrieved message string
        lcd.write(pgm_read_byte(&char_table[0]));
      }
    }
    
    if(button == btnSelect){ //if the select button is pressed
      if(menuOption == 1){   //amd menu option is 1
        adjust_date_time();  //go to adust date and time
        return;
      }
      if(menuOption == 2){   //and menu option is 2
        sensitivity = get_Timer(17, sensitivity, 0, 1000); //go to function 
        return;
      }
      if(menuOption == 3){   //and menu option is 3
        photoCellCutOff = get_Timer(18, photoCellCutOff, 0, 1024); //go to function
        return;
      }
      if(menuOption == 4) return; //and menu option is 4 return (not used)
      if(menuOption == 5){   //and menu option is 5     
        photoOutsideOff = get_Timer(19, photoOutsideOff, 0, 1024); //go to function
        return;
      }
      if(menuOption == 6) return; //and menu option is 6 return (not used)
      if(menuOption == 7){ //and menu option is 7 (room 1)
        get_submenu(0);
      }
      if(menuOption == 8){ //and menu option is 8 (room 2)
        get_submenu(1);
      } //submenu end
      if(menuOption == 9){ //and menu option is 9 (room 3)
        get_submenu(2);
      } //submenu end
      if(menuOption == 10){ //and menu option is 9 (room 4)
        get_submenu(3);
      }
      if(menuOption == 11){ //and menu option is 11 (room 5)
        get_submenu(4);
      }
      if(menuOption == 12){ //and menu option is 12 (room 6)
        get_submenu(5);
      } //submenu end
      if(menuOption == 13){ //and menu option is 13 (room 7)
        get_submenu(6);
      } //submenu end
      if(menuOption == 14){ //and menu option is 14 (room 8)
        get_submenu(7);
      } //submenu end
      if(menuOption == 15){ //and menu option is 15 (room 9)
        get_submenu(8);
      } //submenu end
      if(menuOption == 16){ //and menu option is 16 (room 10)
        get_submenu(9);
      } //submenu end
    }   
  }
}

void get_submenu(byte room){
  byte subButton = 0;        //resetting the button var
  submenu = 1;       //submenu counter
  lcd.clear();       //clear screen
  //retrieving and printing first sub menu point
  lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(submenu_table[0]))));
  lcd.print(room + 1);    //printing assigned room number
  while(submenu < submenus){ //loop through the sub menu points
    subButton = read_act_buttons();  //checking for pressed buttons
    if(subButton == btnMenu){   //if button Menu was pressed
      submenu++;               //add 1 - move to the next sub menu point
      if(submenu == 2){      //if we are at sub menu 2
        lcd.clear(); 
        //retrieve and print second sub menu point
        lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(submenu_table[1]))));
        lcd.print(room + 1);    //printing assigned room number
      }
      if(submenu == 3){      //if we are at sub menu 3
        lcd.clear(); 
        //retrieve and print second sub menu point
        lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(submenu_table[2]))));
        lcd.print(room + 1);    //printing assigned room number
      }
      if(submenu == 4){      //if we are at sub menu 4
        lcd.clear(); 
        //retrieve and print second sub menu point
        lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(submenu_table[3]))));
        lcd.print(room + 1);    //printing assigned room number 1
      }
      if(submenu == 5){      //if we are at sub menu 5
        lcd.clear(); 
        //retrieve and print second sub menu point
        lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(submenu_table[4]))));
        lcd.write(pgm_read_byte(&char_table[5]));    //printing assigned room number 1
      }
      if(submenu == 6){      //if we are at sub menu 6
        lcd.clear(); 
        //retrieve and print second sub menu point
        lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(submenu_table[5]))));
        lcd.print(room + 1);    //printing assigned room number
        if(timer_active[room][2] == 2){
          lcd.setCursor(0, 1);
          lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(msg_table[0])))); //print not used
        }
      }
      if(submenu == 7){      //if we are at sub menu 7
        lcd.clear(); 
        //retrieve and print second sub menu point
        lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(submenu_table[6]))));
        lcd.print(room + 1);    //printing assigned room number
        if(timer_active[room][2] == 2){
          lcd.setCursor(0, 1);
          lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(msg_table[0])))); //print not used
        } 
      }
      if(submenu == 8){      //if we are at sub menu 6
        lcd.clear(); 
        //retrieve and print second sub menu point
        lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(submenu_table[7]))));
        lcd.print(room + 1);    //printing assigned room number 
        if(timer_active[room][3] == 2){
          lcd.setCursor(0, 1);
          lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(msg_table[0])))); //print not used
        }
      }
      if(submenu == 9){      //if we are at sub menu 7
        lcd.clear(); 
        //retrieve and print second sub menu point
        lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(submenu_table[8]))));
        lcd.print(room + 1);    //printing assigned room number
        if(timer_active[room][3] == 2){
          lcd.setCursor(0, 1);
          lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(msg_table[0])))); //print not used
        } 
      }
    }
    if(subButton == btnSelect){   //if we pressed btnSelect
      if(submenu == 1){           //and submenu is 1
        //call the function get_delay() to change the setting
        delayTime[room] = get_delay(9, room, delayTime[room]);
        return;
      }
      if(submenu == 2){           //and sub menu is 2
        //call the function get_offon to change the setting
        timer_active[room][0] = get_offon(10, room, timer_active[room][0]);
        return;
      }
      if(submenu == 3){           //and submenu is 3
        //call the function get_setTime() to change timer 1
        get_setTime(room_timers[room][0][0], room_timers[room][0][1],
                    room_timers[room][0][2], room_timers[room][0][3], 
                    room, 0);
        return;
      }
      if(submenu == 4){           //and submenu is 4
        //call the function get_offon() to change the setting
        timer_active[room][1] = get_offon(11, room, timer_active[room][1]);
        return;
      }
      if(submenu == 5){           //and submenu is 5
        //call the function get_setTime() to change timer 2
        get_setTime(room_timers[room][1][0], room_timers[room][1][1],
                    room_timers[room][1][2], room_timers[room][1][3], 
                    room, 1);
        return;
      }
      if(submenu == 6 && timer_active[room][2] != 2){   //and submenu is 6
        //call the function get_offon() to change the setting
        timer_active[room][2] = get_offon(12, room, timer_active[room][2]);
        return;
      }
      if(submenu == 7 && timer_active[room][2] != 2){          //and submenu == 7
        //call function get_setTime() to change timer 3
        get_setTime(room_timers[room][2][0], room_timers[room][2][1],
                    room_timers[room][2][2], room_timers[room][2][3], 
                    room, 2);
        return;
      }
      if(submenu == 8 && timer_active[room][3] != 2){           //and submenu is 6
        //call the function get_offon() to change the setting
        timer_active[room][3] = get_offon(25, room, timer_active[room][3]);
        return;
      }
      if(submenu == 9 && timer_active[room][3] != 2){          //and submenu == 7
        //call function get_setTime() to change timer 3
        get_setTime(room_timers[room][3][0], room_timers[room][3][1],
                    room_timers[room][3][2], room_timers[room][3][3], 
                    room, 3);
        return;
      }
    }
  }
} 

byte get_setTime( byte onTimeH, byte onTimeM, byte offTimeH,
                  byte offTimeM, byte room, byte timer){
  byte subButton = 0;
  onTimeH = get_Timer(13, onTimeH, 0, 23);
  if(onTimeH >= 0 && onTimeH < 24){
    onTimeM = get_Timer(14, onTimeM, 0, 59);
    if(onTimeM < 60){
      offTimeH = get_Timer(15, offTimeH, 0, 23);
      if(offTimeH >= 0 && offTimeH < 24){
        offTimeM = get_Timer(16, offTimeM, 0, 59);
        if(offTimeM < 60){
          lcd.clear();
          lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(msg_table[6]))));
          lcd.setCursor(0, 1);
          if(onTimeH < 10) lcd.write(pgm_read_byte(&char_table[2]));  //print 0
          lcd.print(onTimeH);
          lcd.write(pgm_read_byte(&char_table[3]));   //print seperator
          if(onTimeM < 10) lcd.write(pgm_read_byte(&char_table[2]));  //print 0
          lcd.print(onTimeM);
          lcd.setCursor(11, 1);
          if(offTimeH < 10) lcd.write(pgm_read_byte(&char_table[2]));  //print 0
          lcd.print(offTimeH);
          lcd.write(pgm_read_byte(&char_table[3]));   //print seperator
          if(offTimeM < 10) lcd.write(pgm_read_byte(&char_table[2]));  //print 0
          lcd.print(offTimeM);
          while(subButton != btnSelect){
            subButton = read_act_buttons();
            if(subButton == btnMenu) return 0;
            if(subButton == btnSelect){
              lcd.clear();
              lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(msg_table[1]))));
              delay(1000);
              room_timers[room][timer][0] = onTimeH;
              room_timers[room][timer][1] = onTimeM;
              room_timers[room][timer][2] = offTimeH;
              room_timers[room][timer][3] = offTimeM;
              return 0;
            }
          }
        }
      }
    }
  }
}
          

//function to set a timer active / inactive
byte get_offon(byte info, byte room, byte reading){
  byte subButton = 0;        //resetting button value
  lcd.clear();          //clear screen
  lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(msg_table[info]))));  //print passed info text
  lcd.print(room + 1);
  lcd.setCursor(0, 1);  //set cursor to second row column 1
  if(reading != 1) lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(msg_table[7]))));  //if value is not 1 timer is off
                                           //print off
  if(reading == 1) lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(msg_table[8]))));    //if timer is 1, timer is active
                                           //print active
  while(subButton != btnSelect){           //waiting for btnSelect to be pressed
    subButton = read_act_buttons();        //checking for pressed buttons
    if(subButton == btnSearch){            //if btnSearch is pressed
      if(reading == 1) reading = 0;       //set to 0 if 1
      else
      if(reading == 0) reading = 1;        //set to 1 if 0
    }
    lcd.setCursor(0, 1);                   //set cursor to first column, second row
    if(reading != 1) lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(msg_table[7])))); //print off if not set to 1
    if(reading == 1) lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(msg_table[8]))));  //print Active if set to 1
  }
  return reading;
}
  

//function to adjust the pir delay time
int get_delay(byte info, byte room, int reading){
  byte subButton = 0;      //resetting the button value
  byte value = reading / 60; //converting to Minutes
  lcd.clear();             //clear screen
  lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(msg_table[info]))));  //print passed message
  lcd.print(room + 1);
  lcd.setCursor(0, 1);     //set cursor to second row, first column
  if(value < 10) lcd.write(pgm_read_byte(&char_table[2]));  //print 0
  lcd.print(value);        //print the passed value in minutes
  lcd.setCursor(4, 1);     //set cursor to second row, column 6
  lcd.print("Min");        //just print Min.
  while(subButton != btnSelect){    //wait for select btn
    subButton = read_act_buttons(); //check if a button was pressed
    if(subButton == btnSearch){      //if btnSearch was pressed
      if(value > 0 && value < 30){  //we are within allowed range
        value++;                    //add 1 to value while btnSearch is pressed
      }
      if(value >= 30) value = 1;    //if reaches upper limit set to lower limit
      lcd.setCursor(0, 1);         //setting the cursor
      if(value < 10) lcd.write(pgm_read_byte(&char_table[2]));  //print 0
      lcd.print(value);             //printing the updated value
    }
  }
  return value*60;
}

void adjust_date_time(){
  byte button = 0; //set button var to 0
  //function call to adjust the minute part of the system time
  byte minuteT = get_Timer(20, tm.Minute, 0, 59); 
  if(minuteT >= 0 && minuteT < 60){ //check the returned result
    //function call to adjust the hour part of the system time
    byte hourT = get_Timer(21, tm.Hour, 0, 23);
    if(hourT >= 0 && hourT < 24){ //check the returned result
      //function call to adjust the day of the week
      byte weekDay = get_weekday();  
      if(weekDay > 0 && weekDay <= 7){ //check the returned result
        //function call to adjust the day of the month
        byte monthDay = get_Timer(22, tm.Day, 1, 31);
        if(monthDay >= 1 && monthDay <=31){  //check the returned result
          //function call to adjust the month
          byte monthT = get_Timer(23, tm.Month, 1, 12);
          if(monthT >= 1 && monthT <= 12){ //check returned result
            //function call to adjust the year
            byte yearT = get_Timer(24, tmYearToCalendar(tm.Year)-2000, 0, 99);
            if(yearT >= 0 && yearT <= 99){ //check the returned results
              byte value = weekDay;   //passing on the variable for calculations
              //the following lcd statements print the adjusted results 
              //on the LCD
              lcd.clear();
              if(hourT < 10) lcd.write(pgm_read_byte(&char_table[2]));    //print 0
              lcd.print(hourT);
              lcd.write(pgm_read_byte(&char_table[3]));   //print seperator
              if(minuteT < 10) lcd.write(pgm_read_byte(&char_table[2]));  //print 0
              lcd.print(minuteT);
              lcd.setCursor(0, 1);
              lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(weekday_table[value-1]))));
              lcd.print(" ");
              if(monthDay < 10) lcd.write(pgm_read_byte(&char_table[2]));  //print 0
              lcd.print(monthDay);
              lcd.write(pgm_read_byte(&char_table[4]));   //print dott
              if(monthT < 10) lcd.write(pgm_read_byte(&char_table[2]));    //print 0
              lcd.print(monthT);
              lcd.write(pgm_read_byte(&char_table[4]));   //print dott
              lcd.print(yearT);
              while(button != btnSelect){   //loop until button select is pressed
                button = read_act_buttons();
                if(button == btnMenu) return; //if button Menu is pressed return without saving
                if(button == btnSelect){ //if button select is pressed
                  lcd.clear();
                  lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(msg_table[1])))); //print saving
                  delay(1000);
                  //function call to save the adjusted values to RTC
                  save_time(minuteT, hourT, weekDay, monthDay, monthT, yearT);
                }
              }
              return;
            }
          }
        }
      }
    }
  }
}

void save_time(byte mi, byte hr, byte wkDay, byte da, byte mo, byte yr){
  Wire.beginTransmission(DS1307_ADDRESS);  //starting transmission to DS 1307 RTC
  Wire.write(zero);                        //needed leading zero byte
  
  Wire.write(decToBcd(0));       //set seconds to 0
  Wire.write(decToBcd(mi));      //set minutes to updated value
  Wire.write(decToBcd(hr));      //set hour to updated value
  Wire.write(decToBcd(wkDay));   //set weekday to updated value
  Wire.write(decToBcd(da));      //set month day to updated value
  Wire.write(decToBcd(mo));      //set month to updated value
  Wire.write(decToBcd(yr));      //set year to updated value
  
  Wire.write(zero);              //send finishing zero byte
  
  Wire.endTransmission();        //close transmission
}

byte decToBcd(byte val){
  return ((val/10*16) + (val%10));
}

int get_Timer(byte info, int reading, int startVal, int maxCount){
  byte button = 0;                 //reseting the button var
  lcd.clear();                     //clear the screen
  lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(msg_table[info]))));  //print the passed on info text
  lcd.setCursor(0, 1);             //set the cursor to second row first column
  lcd.print(reading);              //print the passed on value to be changed
  while(button != btnSelect){      //wait for a button to be pressed
    button = read_act_buttons();   //check if a button is pressed
    if(button == btnSearch){       //if btnSearch is pressed
      //if the reading is somewhere between the limit we add 1
      //to the value with every loop through while the btnSearch
      //is pressed
      if(reading >= startVal && reading < maxCount) reading++;
      if(reading >= maxCount)reading = startVal;   //reset the value to be changed to
                                                   //the lower limit
      lcd.setCursor(0, 1);      //setting the cursor to first column, second row
      lcd.print(reading);       //print the updating value
      lcd.print("    ");        //print 4 empty spaces to delete left overs
                                //if we the value changes from high to
                                //low limit
    }
  }
  return reading;               //return the value
}

byte get_weekday(){
  byte button = 0;              //reseting the button var
  byte value = currentDay;      //passing the global weekday variable to a
                                //local one for calculations
  //Serial.println(currentDay); //debug only
  lcd.clear();                  //clear the screen
  //print what we are updating (weekday)
  lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(msg_table[5])))); 
  lcd.setCursor(0, 1);          //set the cursor to second row, first column
  //print the current value for weekday
  lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(weekday_table[value]))));
  while(button != btnSelect){   //waite for a button to be pressed
    button = read_act_buttons(); //checking for a button pressed 
    if(button == btnSearch){     //if it was btnSearch
      if(value >= 0 && value < 7) value++; //checking between 0 and 6
      if(value >= 7) value = 0;    //setting the value back to 0 
      //Serial.print("Value: "); //debug only
      //Serial.println(value);   //debug only
      lcd.setCursor(0, 1);       //set cursor to second row, first column
      //printing the ubdating value
      lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(weekday_table[value]))));
    }
  }
  return value + 1; //return the value and add 1 to be stored in RTC memory 
}

No comments:

Post a Comment