Translate

Showing posts with label shiftIn. Show all posts
Showing posts with label shiftIn. Show all posts

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 
}