Translate

Tuesday, 22 April 2014

Writing a menu for the Room Management System - Part 3


Today we add a few sub menus to make it a little more exiting. We jump right back into the variable declarations:

const int btnNone = 0;                                  //assignment for no button pressed
const byte arrowRight = B01111110;              //defining a special char to be printed
                                                                 //on the lcd (right arrow)
                                                                 //a list with special characters and it's
                                                                 //binary definitions can be found in the
                                                                 //Arduino Cookbook

int menuOption = 0;                                    //menuOption counter
int menuOptions = 19;                                 //available options

//>>>>>>>>>>addition starts here<<<<<<<<<<<<<<<<
int room1SubMenu = 0;                              //sub menu 1 option counter
int room1SubMenus = 7;                            //sub menu 1 available options
//>>>>>>>>>>addition ends here<<<<<<<<<<<<<<<<<

//The below variables are taken from the Room Management
//sketch and representing the default setup. This are also
//the values, the system will fall back to if something goes
//wrong like a power loss or even a system update.

/////////////////////////////////////////////////////////
//////////////var from RMU/////////////////////
int sensitivity = 500;                                 //var holding the over all responsiveness
                                                              //of the RMU representing a time delay
                                                              //between 0 and 1000 milliseconds at the
                                                              //of the main loop
int photoCellCutOff = 280;                        //The affected room lights switch on when
                                                              //the photocell reading goes below the set
                                                              //value
int photoOutsideOff = 260;                       //The outside light will switch on when
                                                             //the photocell reading goes below this
                                                             //value

//The following values representing delay times when lights switch
//off after the last detection off movement in a room in milliseconds
long dBed1 = 60000;

//>>>>>>>>>>addition starts here<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//this section is holding all variables related to automatic light switching
//while nobody is home.
byte room1MActive = 1;                      //variable to check if that timer is used
//>>>>>>>>>>addition ends here>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
////////////////////////////////////////////////////////
////////////////////////////////////////////////////////


From here, we move down to the end of the selectMenu() function. There we will be adding some sub menus:

if(menuOption == 4){                                //check the menu option
get_Timer("Set photo cut O", photoOutsideOff, 0, 1024); //function call
return;                                                      //return to main loop
}
if(menuOption == 5){                                //left empty cause not implemented yet
return;
}
//>>>>>>>>>>>>addition starts here<<<<<<<<<<<<<<<<<<<<
if(menuOption == 6){                                //Check the menu option
int subButton = 0;                                      //setting the button var to 0
room1SubMenu = 1;                                  //setting the sub menu to 1
lcd.clear();                                                //clear screen
lcd.print("R 1 PIR delay");                          //print the menu point
while(room1SubMenu < room1SubMenus){ //loop through the sub menus
subButton = read_buttons();                        //read button
if(subButton == btnMenu){                         //if Menu button was pressed
room1SubMenu++;                                    //add 1 to sub menu var
if(room1SubMenu == 2){                           //if sub menu = 2
lcd.clear();                                                //clear lcd screen
lcd.print("R1 HT 1 Active");                        //print menu point
}
if(room1SubMenu == 3){                            //if sub menu 3
lcd.clear();                                                 //clear screen
lcd.print("R1 Timer 1");                              //print menu point
}
if(room1SubMenu == 4){                            //if sub menu 4
lcd.clear();                                                 //clear screen
lcd.print("R1 HT 2 Active");                        //print menu point
}
if(room1SubMenu == 5){                           //if sub menu 5
lcd.clear();                                                //clear screen
lcd.print("R1 Timer 2");                             //print menu point
}
if(room1SubMenu == 6){                          //if sub menu 6
lcd.clear();                                               //clear lcd screen
lcd.print("R1 HT 3 Active");                      //print menu point
}
if(room1SubMenu == 7){                         //if sub menu 7
lcd.clear();                                              //clear screen
lcd.print("R1 Timer 3");                           //print menu point
}
}
if(subButton == btnSelect){                     //check if something was selected
if(room1SubMenu == 1){                       //if sub menu 1 was selected
get_delay("R1 PIR 1 Delay", dBed1);        //function call to set delay
return;                                                   //return to main loop
}
if(room1SubMenu == 2){                     //if sub menu 2 was selected
get_offon("R1 T1 On Off", room1MActive);    //function call to set timers active
return;                                                 //return to main loop
}
// to be continued
}
}
return;
}
}
//>>>>>>>>>>>>>>>>>addition ends here<<<<<<<<<<<<<<<<<<<<<<<<<<<
}
}


As you can see, we are walking through sub menus as we did with the main menu points. Lets have a quick look to a couple of more processing functions. We can add again right after the selectMenu() function:


//The entry variables into the function setting the time the light will stay on
//after the last detection of movement in a room during normal operation are
//again the text shown on lcd to describe what we are changing and the
//variable holding the current setting

int get_delay(char delayText[], long reading){
int subButton = 0;                   //resetting the button pressed
int value = reading / 60000;     //to show the value in minutes
                                            //we need to divide the value through
                                            //60000 since it is held in milliseconds
                                           // and 60000 milliseconds = 1 minute
lcd.clear();                           //clear lcd
lcd.print(delayText);              //print text var
lcd.setCursor(0, 1);               //set cursor to second row
lcd.print(value);                    //print current value in minutes
lcd.setCursor(6, 1);              //set cursor to pos 6 in second row
lcd.print("Min");                  //print Min for minutes
while(subButton != btnSelect){      //loop until we press select
subButton = read_buttons();          //read the button
if(subButton == btnSearch){         //if button search is pressed
if(value > 0 && value < 30){        //check if the value is within range
value++;                                     //add 1 with every loop
}
if(value >= 30){                          //if we reach max value
value = 0;                                   //start over at 0
value++;                                     //add 1 with each loop
}
lcd.setCursor(0, 1);                     //set cursor to beginning of second row
lcd.print(value);                           //print the updated results
lcd.print(" ");                               //clear the result part of the screen
}
}
if(room1SubMenu == 1){            //if select was pressed and sub menu 1 was selected
dBed1 = value * 60000;               //we convert the value back in to milliseconds
                                                 //and pass it back to the variable holding the value
                                                 //for further processing
}
}


The next function we have to have a look at is the one being responsible for changing the variable holding the on or off command for the timers activating lights on automated vacation switching.


//As in the other processing functions, we are entering with the describing text and the value we
//want to change

int get_offon(char offonText[], byte reading){
int subButton = 0;                                //setting the button var to 0
byte value = reading;                            //passing the incoming var for processing
lcd.clear();                                          //clear lcd
lcd.print(offonText);                            //print describing text
lcd.setCursor(0, 1);                             //set cursor to beginning of second row
if(value == 1){                                    //check the value of the variable
lcd.print("Active");                              //print active if 1
}
else if(value == 0){
lcd.print("Off");                                  //print off if 0
}
else {
value = 0;                                          //set to 0 if anything else is passed
lcd.print("Off");                                 //print off
}
while(subButton != btnSelect){            //loop until button select is pressed
subButton = read_buttons();                //read buttons
if(subButton == btnSearch){               //if button search is pressed
if(value == 1){                                  //and the value is 1
value = 0;                                         //change to 0
}
else if(value == 0){                            //if the value is 0
value = 1;                                         //change it to 1
}
}
lcd.setCursor(0, 1);                           //set cursor to beginning of row 2
if(value == 1){                                 //print updated values
lcd.print("Active");
}
if(value == 0){
lcd.print("Off");
}
lcd.print(" ");
}
if(room1SubMenu == 2){                   //if room1 sub menu 2 was selected
room1MActive = value;                      //pass the updated value back
}
}

The whole structure and the processing is not that difficult. The only problem with this approach is, that it is very memory consuming and only useful in small menus.
Over the next couple of days I try to add the missing function to update the timers and than I think everybody wanting to stay with this approach is able to carry on in the menu structure. I also got a delivery yesterday and I am pretty eager to get the LCD working using only 3 Atmega pins and a shift register. The next goal is to compact the menu and maybe it is still possible to squeeze it on the UNO board or the Atmega 328 without updating to a Mega...

Monday, 21 April 2014

Writing a Menu for the Room Management System Part 2


Since I started this menu project, even if I have to upgrade to a Arduino Mega to get it working, I find it a fascinating challenge. In the last post I defined the main menu structure. In this post I would like to change the first values using the menu.

Last night I got some very helpful comments on the last post and I will have a look at some different approaches to do this menu. I have already a third post prepared, for the current version to add some sub menu's which I will finish not to leave a gap in the structure. For small projects which can live with a small menu, the current version is a definite option. However, for larger projects requiring a large menu structure, this version uses up to much of the microprocessors memory. For now, lets have a look at part two of the current version:

We jump in at the top of the menu sketch and add some variables which I take direct from the Room Management System sketch to make implementation of the menu at a later point more easy.

const int btnNone = 0;                        //assignment for no button pressed
const byte arrowRight = B01111110;    //defining a special char to be printed
                                                       //on the lcd (right arrow)
                                                       //a list with special characters and it's
                                                       //binary definitions can be found in the
                                                       //Arduino Cookbook

int menuOption = 0;                          //menuOption counter
int menuOptions = 19;                       //available options


//The below variables are taken from the Room Management
//sketch and representing the default setup. This are also
//the values, the system will fall back to if something goes
//wrong like a power loss or even a system update.
//>>>>>>addition start<<<<<<<<<<<<
/////////////////////////////////////////////////////////
//////////////var from RMU/////////////////////
int sensitivity = 500;                        //var holding the over all responsiveness
                                                     //of the RMU representing a time delay
                                                     //between 0 and 1000 milliseconds at the
                                                     //of the main loop
int photoCellCutOff = 280;               //The affected room lights switch on when
                                                     //the photocell reading goes below the set
                                                     //value
int photoOutsideOff = 260;               //The outside light will switch on when
                                                     //the photocell reading goes below this
                                                     //value
//The following values representing delay times when lights switch
//off after the last detection off movement in a room in milliseconds
long dBed1 = 60000;
////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
//>>>>>>addition end<<<<<<<<<<<<

void setup() {
lcd.begin(16, 2);                           //start lcd with 16 col and 2 row


Now we are going down to the end of our selectMenu() function.


if(menuOption == 19){                 //if menuOption is 19
lcd.clear();                                  //clear lcd
lcd.print("AC 4:");                        //print menu point
lcd.setCursor(15, 0);                    //set cursor to the end of the row
lcd.write(arrowRight);                  //print right arrow to indicate
                                                  //existing sub menus
}
}
//>>>>>>>>>>>>addition start here<<<<<<<<<<<<<<<<<<<<<
if(button == btnSelect){               //if the button Select was pressed
if(menuOption == 1){                 //checking the menu option
get_Timer("Set Sens", sensitivity, 0, 1000);    //function to change and set the
                                                                 //system sensitivity
return;                                      //return to main loop
}
if(menuOption == 2){                //check the menu option
get_Timer("Set photo cut R", photoCellCutOff, 0, 1024);   //function call
return;                                     //return to main loop
}
if(menuOption == 3){               //left empty cause not implemented yet
return;
}
if(menuOption == 4){               //check the menu option
get_Timer("Set photo cut O", photoOutsideOff, 0, 1024);   //function call
return;                                    //return to main loop
}
if(menuOption == 5){              //left empty cause not implemented yet
return;
}
//>>>>>>>>>>>>addition ends here<<<<<<<<<<<<<<<<<<<<
}
}

That wasn't that hard to do. While we are still in the while-loop, we are checking if at any point the button “Select” was pressed. If yes, we check at which menu point (menuOption) and call a function which will update the value accordingly.
The function get_Timer needs a few values to be passed on to make it a bit more universal usable. The first value is the string we want to print as update message. Second, we add the variable holding the value we want to change. The next two values giving the range in which the function is allowed to change.
Lets have a closer look. We can start adding the function right at the end of selectMenu() function.

int get_Timer(char timerText[], int reading, int startVal, int maxCount){
int value = reading;                     //passing the var to change for processing
int button = 0;                            //reset the button value
lcd.clear();                                //clear the screen
lcd.print(timerText);                   //print the passed on text
lcd.setCursor(0, 1);                   //set cursor to bottom row
lcd.print(value);                        //print value to be changed
while(button != btnSelect){       //keep an eye on select button
button = read_buttons();           //check for buttons pressed
if(button == btnSearch){          //if button search is pressed
if(value > startVal && value < maxCount){       //check if the value is within
                                                                    //allowed range
value++;                                  //add 1 with every cycle
}
if(value >= maxCount){            //if value reaches the max
value = startVal;                       //we start over at minimum
value++;                                 //add 1 with every cycle
}
lcd.setCursor(0, 1);                 //set cursor to bottom row
lcd.print(value);                      //print updated value
lcd.print(" ");                          //prepare screen for next value
}
}

//The following statement check where the variable to process
//came from and give it back to it's origin

if(menuOption == 1 && value != reading){
sensitivity = value;
}
if(menuOption == 2 && value != reading){
photoCellCutOff = value;
}
if(menuOption == 4 && value != reading){
photoOutsideOff = value;
}
return value;
}

In the next post we start with sub menu's and a couple of more functions to process the changes.

Sunday, 20 April 2014

Writing a Menu for the Room Management System Part 1


While banging my head on how to keep the Room Management System a stand alone unit and while I am still waiting for some parts to arrive to connect the LCD to the Atmega 328 using only 3 digital pins, I started to write a menu system to implement.
Not even half way through the menu, I realised, that the menu will be again over a 1000 lines of code and even squeezing as much as any possible in functions uses already 450 byte of dynamic memory. Cleaning up the code from the room management system itself might help a bit but by all calculations I made, it will go above what the Atmega 328 can handle.

For everybody who would like to convert the whole system to a Arduino Mega, I share what I have done so far.
As said, I am still waiting for parts to connect the LCD to the room management system, so I used my Arduino board with standard connections for testing. Please check my last post LCD discovery.

While also running out of breadboard space, I soldered quickly a button shield with 3 buttons together and connected it to the Arduino digital pins 8, 9 and 10.



To save some more breadboard space and a few wires, I also built a simple shield for the LCD.



To clear up a little confusion, here a image with the LCD display attached.



Please make sure you solder the 10K potentiometer, the red marked jumper wire and the 8 pin female header for the jumpers connecting the Arduino board to the soldering side of the board, while the rest goes as usual on the parts side of the board. The connections DI 2 to DI 12 depending on your Arduino set up and demonstrating only to which pins I have connected them.
Finally a image showing everything connected together:



The set up:
If you have been looking around a little, you may notice that most of the examples and open source projects use a 1602 LCD Keypad shield which is very handy but it still needs more Atmega pins than we have left. Going back to the Room Management System project, we have 3 input pins on the third CD4021 input shift register left and we use one more of the Atmega's DI pins to implement a switch activating the setup mode. The goal was to do it with the least resource possible. That's why I went down to 3 separate buttons.

Lets start and declare some variables:


#include <LiquidCrystal.h> //include the liquid crystal library
#include <SPI.h> //not needed with the default lcd library

LiquidCrystal lcd(12, 11, 5, 4, 3, 2); //Create an instance of Liquid Crystal

const int btnMenu = 8;                //constant for Menu button
const int btnSearch = 9;              //constant for Search button
const int btnSelect = 10;              //constant for Select button
const int btnNone = 0;                 //assignment for no button pressed
const byte arrowRight = B01111110; //defining a special char to be printed
                                                     //on the lcd (right arrow)
                                                     //a list with special characters and it's
                                                     //binary definitions can be found in the
                                                     //Arduino Cookbook

int menuOption = 0;                        //menuOption counter
int menuOptions = 19;                     //available options

void setup() {
lcd.begin(16, 2);                             //start lcd with 16 col and 2 row
pinMode(btnMenu, INPUT);            //setting the pin modes
pinMode(btnSearch, INPUT);
pinMode(btnSelect, INPUT);
}

void loop(){
//The function button_Loop() is the menu entry point, checking if a
//menu related button was pressed
//in a real implementation the button_loop() function should be in a
//conditional statement only to be called when needed

button_loop();
}

//Function button_loop()
void button_loop(){
int button = read_buttons();          //function call to give back button pressed
if(button = btnMenu){                 //If btn Menu was pressed
selectMenu();                             //Function call to select from Menu
}
}

//The following function is the heart of the menu
//it goes through the main menu points where can be
//selected from

void selectMenu(){
int button = 0;                            //resetting the button var
menuOption = 1;                        //set menu option to 1
lcd.clear();                                //clear the lcd screen
lcd.print("Sensitivity:");              //print the first Menu point
while(menuOption <= menuOptions){ //loop through the available menu points
button = read_buttons();            //check if a button was pressed
if(button == btnMenu){             //check if the menu button was pressed
menuOption++;                         //if the menu button was pressed
                                               //add 1 to menuOption
if(menuOption == 2){                //if menuOption is 2
lcd.clear();                                //clear lcd screen
lcd.print("Room photo cut:");      //print second menu point
}
if(menuOption == 3){                //if menuOption is 3
lcd.clear();                                //clear lcd screen
lcd.print("Room photo limit:");      //print third menu point
lcd.setCursor(0, 1);                     //set cursor to second row
lcd.print("NOT USED");              //print note that this menu point is not used

//it carries on the same way up to menuOption 19
//check if menuOption is number n
//clear the display
//print the menu point
//if not in use set cursor to second row
//if not in use print message

}
if(menuOption == 4){
lcd.clear();
lcd.print("OS photo cut:");
}
if(menuOption == 5){
lcd.clear();
lcd.print("OS photo Limit:");
lcd.setCursor(0, 1);
lcd.print("NOT USED");
}
if(menuOption == 6){
lcd.clear();
lcd.print("Room 1:");
lcd.setCursor(15, 0);
lcd.write(arrowRight);
}
if(menuOption == 7){
lcd.clear();
lcd.print("Room 2:");
lcd.setCursor(15, 0);
lcd.write(arrowRight);
}
if(menuOption == 8){
lcd.clear();
lcd.print("Room 3:");
lcd.setCursor(15, 0);
lcd.write(arrowRight);
}
if(menuOption == 9){
lcd.clear();
lcd.print("Room 4:");
lcd.setCursor(15, 0);
lcd.write(arrowRight);
}
if(menuOption == 10){
lcd.clear();
lcd.print("Room 5:");
lcd.setCursor(15, 0);
lcd.write(arrowRight);
}
if(menuOption == 11){
lcd.clear();
lcd.print("Room 6:");
lcd.setCursor(15, 0);
lcd.write(arrowRight);
}
if(menuOption == 12){
lcd.clear();
lcd.print("Room 7:");
lcd.setCursor(15, 0);
lcd.write(arrowRight);
}
if(menuOption == 13){
lcd.clear();
lcd.print("Room 8:");
lcd.setCursor(15, 0);
lcd.write(arrowRight);
}
if(menuOption == 14){
lcd.clear();
lcd.print("Room 9:");
lcd.setCursor(15, 0);
lcd.write(arrowRight);
}
if(menuOption == 15){
lcd.clear();
lcd.print("Room 10:");
lcd.setCursor(15, 0);
lcd.write(arrowRight);
}
if(menuOption == 16){
lcd.clear();
lcd.print("AC 1:");
lcd.setCursor(15, 0);
lcd.write(arrowRight);
}
if(menuOption == 17){
lcd.clear();
lcd.print("AC 2:");
lcd.setCursor(15, 0);
lcd.write(arrowRight);
}
if(menuOption == 18){
lcd.clear();
lcd.print("AC 3:");
lcd.setCursor(15, 0);
lcd.write(arrowRight);
}
if(menuOption == 19){
lcd.clear();
lcd.print("AC 4:");
lcd.setCursor(15, 0);
lcd.write(arrowRight);
}
}
}
}


//function to give back the button which was pressed by it's assigned
//input pin number
int read_buttons(){
if(digitalRead(btnMenu) == HIGH){         //digital read the Menu button pin
delay(250);                                            //button denounce delay
return btnMenu;                                     //if activated return btnMenu
}

//the same conditions apply for the Search and Select button
//in the next two if-statements

else if(digitalRead(btnSearch) == HIGH){
delay(250);
return btnSearch;
}
else if(digitalRead(btnSelect) == HIGH){
delay(250);
return btnSelect;
}
else {
return btnNone;                                   //return 0 if no button was pressed
}
}


Friday, 18 April 2014

LCD Display Discovery using a 16 * 2 HD44780 LCD


While I am currently trying to find a way of interacting with my Room Management System without connecting it to a network or direct to a computer, I was playing a bit with LCD's. Reading through forum posts and tutorials, I was about to buy a new LCD since it was doing everything except printing anything to the screen.
If there are some more like me, experimenting the first time with a HD44780 LCD, don't through it out of the window while it doesn't work.
The following image is one found in plenty of tutorials. It might work with some other LCD shields but not with a HD44780.



The first and most important thing is that the LCD pin 5 (RW) has to go to ground. Second, without the back lighting (LCD pin 15 and 16) connected it is very difficult to adjust the contrast with the potentiometer only. There fore LCD pin 15 connects through a resistor to 5 volt supply. I used a 470 ohm resistor for it but you can play around a bit. Use a higher resistance if you need the back light darker an one with lower resistance if you need it brighter. A 1 to 5 k potentiometer will do the job if you need it adjustable. The LCD pin 16 goes to ground and the back light comes up.



To check it out, I rewrote a clock sketch a bit which I found in one of the Arduino books. Please be aware, that this sketch does not check with a real time clock. It uses the Arduino clock ant the time library.

#include <Time.h>
#include <LiquidCrystal.h>
#include <SPI.h> //not needed if you use the
//default library

LiquidCrystal lcd(12, 11, 5, 4, 3, 2); //create an instance of
//LiquidCrystal


void setup()
{
Serial.begin(9600);
lcd.begin(16, 2);
setTime(9,40,5,18,4,14); // set time to 9:40 Apr 18 2014
}

void loop()
{
digitalClockDisplay();
delay(1000);
}

void digitalClockDisplay(){
// digital clock display of the time
lcd.setCursor(4, 0);
lcd.print(hour());
printDigits(minute());
printDigits(second());
lcd.setCursor(3, 1);
lcd.print(day());
lcd.print(" ");
lcd.print(month());
lcd.print(" ");
lcd.print(year());
}

void printDigits(int digits){
// utility function for clock display: prints preceding colon and leading 0
lcd.print(":");
if(digits < 10)
lcd.print('0');
lcd.print(digits);
}


I am waiting for a couple of parts which I am missing in my circuit to hopefully be able to run the LCD through a shift register, using only 3 Arduino pins so I can carry on working on a small setup menu for the Room Management System.

Wednesday, 16 April 2014

Room Management System – 74HC595 shift register noise discovery

I have been banging my head on the wall for nearly a week now trying to sort out some instability problems. A couple of days ago, late in the evening I found a small mistake in my soldering. After making about 100 soldering point in a row I most have gotten a little tired and didn't solder the data pin properly to the board. Fixing it solved the problem for this evening. The next evening, - the problem was back. Reading through a lot of forum posts and rechecking the data sheet of the 74HC595 I found that this particular shift register in known for noise problems. Nothing to worry, we just need to add a few filter capacitors and the problem is solved. What I did is the following. The original 0.1 uF capacitor connected to the latch pin of the first shift register of our chain, going to ground has to go. This capacitor which is even used in the Arduino tutorial “Serial to parallel shift out” is preventing the latch pin to go HIGH fast enough before you bring it back down again.



The next step is to add a 0.1uF capacitor between VCC and ground on each shift register as close to it as any possible. Step number 3 is to add a 10 uF capacitor in the power line as close to the power source as any possible.



The last two images are only to show clearly what I have done. The following image shows it in the experimental setup with all the components as far as it is developed. 



That also brings me back to the analogue smoothing algorithm from Tom Igoe. If you didn't take it out yet and you want to go with it, please feel free to leave it as it is because there is nothing wrong with it. It was just co-instance that the stability problems where starting to occur after its implementation.

Monday, 14 April 2014

Room Management System - Full sketch including holiday switching

As promised,  here again a complete updated sketch with all the additions and changes included up to "Holiday switching of some lights". Please be aware of the fact the quotation marks change if you just copy and past, which will give you a warning from the compiler. Effected are all active Serial.print() statements and char or string arrays.

Again, you may use the sketch below as is or modify it to your needs. What ever you do with it, you do it at your own risk.

/////////////////////Includes/////////////////////////////
#include <DS1307RTC.h>
#include <Time.h>
#include <Wire.h>

/////////////////Declaring the Variables/////////////////

///////////Timer and Sensitivity Settings to be changed to individual needs////////////////
unsigned int sensitivity = 500;    //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;
unsigned int hourOutsideOff = 23;  //var holding the time (full hours) in which the lights have
                                   //to switch off
unsigned int minuteOutsideOff = 30;//var holding the time (minutes) in which the lights
                                   //have to switch off

long int dBed1 = 60000;            //delay time in milliseconds for bedroom 1
long int dBed2 = 60000;            //delay time in milliseconds for bedroom 2
long int dBed3 = 60000;            //delay time in milliseconds for bedroom 3
long int dLiving = 300000;         //delay time in milliseconds for living area
long int dBath1 = 180000;          //delay time in milliseconds for bathroom 1
long int dBath2 = 180000;          //delay time in milliseconds for bathroom 2
long int dBath3 = 180000;          //delay time in milliseconds for bathroom 3
long int dBath4 = 180000;          //delay time in milliseconds for bathroom 4
long int dKitchen = 120000;        //delay time in milliseconds for kitchen
long int dCorridor = 60000;        //delay time in milliseconds for corridor
long int dAC1 = 120000;            //delay time in milliseconds for AC 1 (bed1)
long int dAC2 = 120000;            //delay time in milliseconds for AC 2 (bed2)
long int dAC3 = 120000;            //delay time in milliseconds for AC 3 (bed3)
long int dAC4 = 120000;            //delay time in milliseconds for AC 4 (living)
long int dMaster = 240000;         //delay time in milliseconds for Master Off

unsigned int hourAc1On = 18;
unsigned int minuteAc1On = 0;
unsigned int hourAc1Off = 24;
unsigned int minuteAc1Off = 0;

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

////////////Room 1 (Bed 1) ///////////
byte room1MActive = 1;                     //Set to 1 if you want to process
                                           //Timer will be ignored when set to 0
unsigned int room1OnM[2] = {5, 35};        //Time to switch on the lights 5
unsigned int room1OffM[2] = {6, 5};       //Time to switch off the lights 6

byte room1O1Active = 1;                     //Set to 1 if you want to process
                                           //Timer will be ignored when set to 0
unsigned int room1On1[2] = {19, 35};        //Time to switch on the lights
unsigned int room1Off1[2] = {20, 15};       //Time to switch off the lights

byte room102Active = 1;                     //Set to 1 if you want to process
                                           //Timer will be ignored when set to 0
unsigned int room1On2[2] = {21, 5};        //Time to switch on the ;ights
unsigned int room1Off2[2] = {21, 15};       //Time to switch off the lights

////////////Room 2 (Bed 2) ///////////
byte room2MActive = 1;                     //Set to 1 if you want to process
                                           //Timer will be ignored when set to 0
unsigned int room2OnM[2] = {6, 30};         //Time to switch on the lights
unsigned int room2OffM[2] = {6, 50};        //Time to switch off the lights

byte room201Active = 1;                     //Set to 1 if you want to process
                                           //Timer will be ignored when set to 0
unsigned int room2On1[2] = {19, 30};        //Time to switch on the lights
unsigned int room2Off1[2] = {20, 10};       //Time to switch off the lights

////////////Room 3 (Bed 3) ///////////
byte room3MActive = 1;                     //Set to 1 if you want to process
                                           //Timer will be ignored when set to 0
unsigned int room3OnM[2] = {5, 50};        //time to switch on the lights
unsigned int room3OffM[2] = {6, 20};       //time to switch off the lights

byte room301Active = 1;                     //Set to 1 if you want to process
                                           //Timer will be ignored when set to 0
unsigned int room3On1[2] = {18, 10};        //time to switch on the lights
unsigned int room3Off1[2] = {18, 25};       //time to switch off the lights

byte room302Active = 1;                     //Set to 1 if you want to process
                                           //Timer will be ignored when set to 0
unsigned int room3On2[2] = {19, 15};        //Time to switch on the lights
unsigned int room3Off2[2] = {19, 40};       //Time to switch off the lights

byte room303Active = 1;                     //Set to 1 if you want to process
                                           //Timer will be ignored when set to 0
unsigned int room3On3[2] = {23, 20};        //Time to switch on the lights
unsigned int room3Off3[2] = {23, 35};       //Time to switch off the lights

///////////Room 4 {Living)
byte room401Active = 1;                     //Set to 1 if you want to process
                                           //Timer will be ignored when set to 0
unsigned int room4On[2] = {17, 30};         //Time to switch on the lights
unsigned int room4Off[2] = {23, 30};        //Time to switch off the lights

//////////Room 5 (bath 1)//////////
byte room5MActive = 1;                     //Set to 1 if you want to process
                                           //Timer will be ignored when set to 0
unsigned int room5OnM[2] = {5, 40};         //Time to switch on the lights
unsigned int room5OffM[2] = {5, 45};        //Time to switch off the lights

byte room501Active = 1;                     //Set to 1 if you want to process
                                           //Timer will be ignored when set to 0
unsigned int room5On[2] = {19, 55};         //Time to switch on the lights
unsigned int room5Off[2] = {20, 10};        //Time to switch off the lights

//////////Room 6 (bath 2)//////////
byte room6MActive = 1;                     //Set to 1 if you want to process
                                           //Timer will be ignored when set to 0
unsigned int room6OnM[2] = {6, 35};         //Time to switch on the lights
unsigned int room6OffM[2] = {6, 45};        //Time to switch off the lights

byte room601Active = 1;                     //Set to 1 if you want to process
                                           //Timer will be ignored when set to 0
unsigned int room6On[2] = {19, 50};         //Time to switch on the lights
unsigned int room6Off[2] = {20, 05};        //Time to switch off the lights

//////////Room 7 (bath 3)//////////
byte room7MActive = 1;                     //Set to 1 if you want to process
                                           //Timer will be ignored when set to 0
unsigned int room7OnM[2] = {6, 5};         //Time to switch on the lights
unsigned int room7OffM[2] = {6, 25};        //Time to switch off the lights

byte room701Active = 1;                     //Set to 1 if you want to process
                                           //Timer will be ignored when set to 0
unsigned int room7On[2] = {22, 50};         //Time to switch on the lights
unsigned int room7Off[2] = {23, 15};        //Time to switch off the lights

//////////Room 8 (bath 4)//////////
byte room8MActive = 1;                     //Set to 1 if you want to process
                                           //Timer will be ignored when set to 0
unsigned int room8On[2] = {22, 5};         //Time to switch on the lights
unsigned int room8Off[2] = {22, 20};       //Time to switch off the lights

//////////Room 9 (Kitchen)//////////
byte room9MActive = 1;                     //Set to 1 if you want to process
                                           //Timer will be ignored when set to 0
unsigned int room9OnM[2] = {5, 50};         //Time to switch on the lights
unsigned int room9OffM[2] = {6, 45};        //Time to switch off the lights

byte room901Active = 1;                     //Set to 1 if you want to process
                                            //Timer will be ignored when set to 0
unsigned int room9On[2] = {17, 45};         //Time to switch on the lights
unsigned int room9Off[2] = {18, 30};        //Time to switch off the lights
////////////////////////////DO NOT MODIVY BELOW HERE///////////////////////////////////////

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

//////////Variables to hold the data for each 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///////////////////////////
unsigned long delayTime[16] = {dBed1, dBed2, dBed3, dLiving, dBath1, dBath2, dBath3,
                               dBath4, dKitchen, dCorridor, dAC1, dAC2, dAC3, dAC4,
                               dMaster, 0};
                             
int lightSensor = A0;                         //defining the input for the photocell
int sensorValue = 0;                          //holding the indicated sensor value of the photocell
unsigned long outputL = 0;                    //variable holding the output data
byte mainOff = 1;                             //variable for master relay control
unsigned long offTime = 0;                    //var needed to calculate delay for master off
byte masterSwitchStateOld = 0;                //var holding the previous door switch state
int doorMonitor = 8;                         //Arduino pin for a monitor LED
unsigned int 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
unsigned int lightStatus[17] = {0};           //array holding the switch status of each room on/off
unsigned long roomTimer[17] = {0};            //array holding the time when the PIR was last activated
unsigned int priorityStatus[17] = {0};        //array holding the priority status of each room on/off
unsigned long currentTime = 0;                //var to hold a reference time to calculate the up time
                                              //against the preprogrammed delay time
unsigned long endTime = 0;                    //var to hold a temp result to calculate the up time
                                              //against the preprogrammed delay time
int maintenancePin = 0;                       //defining the var for the maintenance switch
int maintenanceActive = 0;                    //holding the switch state

unsigned int switchState1Old = 0;            //var to check if the switch state has changed
unsigned int switchState3Old = 0;            //var to check if the switch state has changed
unsigned int switchState5Old = 0;            //var to check if the switch state has changed
unsigned int switchState7Old = 0;            //var to check if the switch state has changed

unsigned int outsideOnTime = 0;              //checking result if the time is within
                                             //on or off time limits

byte room1Lights = 0;
byte room2Lights = 0;
byte room3Lights = 0;
byte room4Lights = 0;
byte room5Lights = 0;
byte room6Lights = 0;
byte room7Lights = 0;
byte room8Lights = 0;
byte room9Lights = 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)

byte lightLevel[17] ={0};  //array holding the switch state
                           //checking timer and photocell (0, 1)
byte photocellSwitch = 0;  //holding the switch command after
                           //checking sensor readings (0, 1)
byte photocellSwitchOld = 0; //switch command from the previous pass

//Array holding the day names to replace the weekday index
char* days[7] = {"Sunday", "Monday", "Tuesday", "Wednesday",
                 "Thursday", "Friday", "Saturday"};


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

   Serial.begin(9600);
   
     //////////////////defining pin modes////////////////////
 
   pinMode(doorMonitor, OUTPUT);        //setting the LED pin to output

   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() {

  ///////////////////reading the timer/////////////////////////
 
   //////////////////////////////////////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 S20
         //Serial.println("Switch 20 was activated.");   //debug only
         switchState[20] = 1;
      }
      else {
         switchState[20] = 0;
      }
   }
 
 
   //////////////////checking the light status//////////////////////
  if(analogRead(lightSensor) > 0 &&
     analogRead(lightSensor) < 1024){ //checking if the reading
                                      //is within the sensor limits
    int reading[10] = {0};            //declaring a local var to hold
                                      //the readings
     for(int i=0; i<10; i++){         //take 10 readings
      reading[i] += analogRead(lightSensor);
    }
    //average the readings
    sensorValue = (reading[0] + reading[1] + reading[2] + reading[3] +
                   reading[4] + reading[5] + reading[6] + reading[7] +
                   reading[8] + reading[9]) / 10;
  }
  else {
    sensorValue = 0; //if something goes wrong switch on the lights anyway
  }
 
  Serial.print("Sensor value: ");
  Serial.println(sensorValue);
 
   //////////////////processing the input/////////////////////
  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;
  //////////////Holliday lighting/////////////////////////
  
  if(switchState[20] == 1) {       //check if the holliday switch
                                   //is activated
    lightOutput[14] = 0;           //make sure the master  relay is off
    tmElements_t tm;               //initializing RTC
    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;        //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
    }
    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);
  
    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;
      }
    }
    //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(room1MActive == 1 && currentHour >= room1OnM[0] &&
       currentHour <= (room1OffM[0] + 1)){ //checking if we came passed
                                           //the hour where the lights
                                           //to be switched on
                                  
      //checking the times                            
      room1Lights = checkOnTime(room1OnM[0], room1OnM[1],
                                room1OffM[0], room1OffM[1]);
    }
  
  
    if(room1O1Active == 1 && currentHour >= room1On1[0] &&
       currentHour <= (room1Off1[0] +1)){ //checking if we came passed
                                          //the hour where the lights
                                          //to be switched on
                                  
      //checking the times                            
      room1Lights = checkOnTime(room1On1[0], room1On1[1],
                                room1Off1[0], room1Off1[1]);
    }
      

    if(room102Active == 1 && currentHour >= room1On2[0] &&
       currentHour <= (room1Off2[0] + 1)){ //checking if we came passed
                                           //the hour where the lights
                                           //to be switched on
    //checking the times                               
      room1Lights = checkOnTime(room1On2[0], room1On2[1],
                                room1Off2[0], room1Off2[1]);
    }
  
    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(room2MActive ==1 && currentHour >= room2OnM[0]
       && currentHour <= (room2OffM[0] + 1)){
      room2Lights = checkOnTime(room2OnM[0], room2OnM[1],
                    room2OffM[0], room2OffM[1]);
    }
  
    if(room201Active == 1 && currentHour >= room2On1[0] &&
       currentHour <= (room2Off1[0] + 1)){
      room2Lights = checkOnTime(room2On1[0], room2On1[1],
                    room2Off1[0], room2Off1[1]);
    }
  
    if(room2Lights == 1 && lightLevel[1] == 1){
      lightOutput[1] = 2;
    }
    else {
      lightOutput[1] = 0;
      lightLevel[1] =0;
    }
  
    ////////Room 3 (Bed 3) ////////////
    if(room3MActive == 1 && currentHour >= room3OnM[0] &&
    currentHour <= (room3OffM[0] + 1)){
      room3Lights = checkOnTime(room3OnM[0], room3OnM[1],
      room3OffM[0], room3OffM[1]);
    }
  
    if(room301Active == 1 && currentHour >= room3On1[0] &&
       currentHour <= (room3Off1[0] + 1)){
      room3Lights = checkOnTime(room3On1[0], room3On1[1],
      room3Off1[0], room3Off1[1]);
    }
  
    if(room302Active == 1 && currentHour >= room3On2[0] &&
    currentHour <= (room3Off2[0] + 1)){
      room3Lights = checkOnTime(room3On2[0], room3On2[1],
      room3Off2[0], room3Off2[1]);
    }
  
    if(room3Lights == 1 && lightLevel[2] == 1){
      lightOutput[2] = 4;
    }
    else {
      lightOutput[2] = 0;
      lightLevel[2] = 0;
    }
  
    ////////Room 4 (living)/////////////////////
    if(room401Active == 1 && currentHour >= room4On[0] &&
       currentHour <= (room4Off[0] + 1)){
      room4Lights = checkOnTime(room4On[0], room4On[1],
                    room4Off[0], room4Off[1]);
    }
  
    if(room4Lights == 1 && lightLevel[3] == 1){
      lightOutput[3] = 8;
    }
    else {
      lightOutput[3] = 0;
      lightLevel[3] = 0;
    }
  
    ////////Room 5 (Bath 1)/////////////////////
    if(room5MActive == 1 && currentHour >= room5OnM[0] &&
       currentHour <= (room5OffM[0] + 1)){
      room5Lights = checkOnTime(room5OnM[0], room5OnM[1], room5OffM[0], room5OffM[1]);
    }
      
    if(room501Active == 1 && currentHour >= room5On[0] &&
       currentHour <= (room5Off[0] + 1)){
      room5Lights = checkOnTime(room5On[0], room5On[1], room5Off[0], room5Off[1]);
    }
  
    if(room5Lights == 1 && lightLevel[4] == 1){
      lightOutput[4] = 16;
    }
    else {
      lightOutput[4] = 0;
      lightLevel[4] =0;
    }
  
    ////////Room 6 (Bath 2)/////////////////////
    if(room6MActive ==1 && currentHour >= room6OnM[0] &&
       currentHour <= (room6OffM[0] + 1)){
      room6Lights = checkOnTime(room6OnM[0], room6OnM[1],
                                room6OffM[0], room6OffM[1]);
    }
  
    if(room601Active == 1 && currentHour >= room6On[0] &&
       currentHour <= (room6Off[0] + 1)){
      room6Lights = checkOnTime(room6On[0], room6On[1],
                                room6Off[0], room6Off[1]);
    }
  
    if(room6Lights == 1 && lightLevel[5] == 1){
      lightOutput[5] = 32;
    }
    else {
      lightOutput[5] = 0;
      lightLevel[5] = 0;
    }
  
    ////////Room 7 (Bath 3)/////////////////////
    if(room7MActive == 1 && currentHour >= room7OnM[0] &&
       currentHour <= (room7OffM[0])){
      room7Lights = checkOnTime(room7OnM[0], room7OnM[1],
                                room7OffM[0], room7OffM[1]);
    }
  
    if(room701Active == 1 && currentHour >= room7On[0] &&
       currentHour <= (room7Off[0])){
      room7Lights = checkOnTime(room7On[0], room7On[1],
                                room7Off[0], room7Off[1]);
    }
  
    if(room7Lights == 1 && lightLevel[6] == 1){
      lightOutput[6] = 64;
    }
    else {
      lightOutput[6] = 0;
      lightLevel[6] = 0;
    }
  
    ////////Room 8 (Bath 4)/////////////////////
    if(room8MActive == 1 && currentHour >= room8On[0] &&
       currentHour <= (room8Off[0] + 1)){
      room8Lights = checkOnTime(room8On[0], room8On[1],
                                room8Off[0], room8Off[1]);
    }
  
    if(room8Lights == 1 && lightLevel[7] == 1){
      lightOutput[7] = 128;
    }
    else {
      lightOutput[7] = 0;
      lightLevel[7] = 0;
    }
  
    ////////Room 9 (kitchen)/////////////////////
    if(room9MActive == 1 && currentHour >= room9OnM[0] &&
       currentHour <= room9OffM[0] + 1){
      room9Lights = checkOnTime(room9OnM[0], room9OnM[1],
                                room9OffM[0], room9OffM[1]);
    }
    if(room901Active == 1 && currentHour >= room9On[0] && currentHour <= (room9Off[0] + 1)){
      room9Lights = checkOnTime(room9On[0], room9On[1],
                                room9Off[0], room9Off[1]);
    }
  
    if(room9Lights == 1 && lightLevel[8] == 1){
      lightOutput[8] = 256;
    }
    else {
      lightOutput[8] = 0;
      lightLevel[8] = 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
     }
     
     //////////////////room lights//////////////////////////////
   
      if(switchState[0] == 1 && lightStatus[16] == 1) {            //checking if PIR in Room 1 was
                                                                   //activated (bed 1)
         lightStatus[16] = 0;                                      //resetting master off
         digitalWrite(doorMonitor, LOW);                           //resetting the door Monitor LED
      }
   
      if(switchState[1] == 0 && sensorValue <= photoCellCutOff) {  //checking if S2 priority off was
                                                                   //set bed 1
        if(switchState[0] == 1 && priorityStatus[0] == 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[0] = 1;                                     //switching on the lights – binary
                                                                   //000000000000000000000001
           lightStatus[0] = 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[0] = millis();                                //setting the timer
        }
        else if(switchState[0]  == 0 && lightStatus[0] == 1) {     //the PIR not activated but the
                                                                   //lights are on
           //Serial.println("We are checking the timer");            //Debug only
           currentTime = millis();                                 //setting time reference
           endTime = currentTime - roomTimer[0];                   //calculating the inactive time
           if(endTime >= delayTime[0]) {                           //comparing inactive time with
                                                                   //allowed delay time
              //Serial.println("Time is up switching off the lights");  //Debug only
              lightOutput[0] = 0;                                  //switching off the lights
              lightStatus[0] = 0;                                  //resetting the light status
              roomTimer[0] = 0;                                    //resetting the room timer
           }
        }
     }
     else if(switchState[1] == 1 && lightStatus[0] == 1
             && switchState1Old != 1) {                            //if priority is activated and the
                                                                   //lights are on
        //Serial.println("Priority switch activated switching off the lights");  //Debug only
        lightOutput[0] = 0;                                        //switching off the lights
        lightStatus[0] = 0;                                        //resetting the light status
        roomTimer[0] = 0;                                          //resetting the room timer
        priorityStatus[0] = 1;                                     //setting the priority status bed 1
     }
     else if(switchState[1] == 1 && lightStatus[0] == 0
             && switchState1Old != 1) {                               //if priority was activated and the
                                                                   //lights are off
        //Serial.println("Priority switch deactivated switching on the lights");    //Debug only
        lightOutput[0] =1;                                         //switching on the lights
        lightStatus[0] = 1;                                        //setting the light status
        roomTimer[0] = millis();                                   //setting the room timer
        priorityStatus[0] = 0;                                     //setting the priority for bed 1 back                                                                  //to 0
     }
     switchState1Old = switchState[1];                             //passing on the switch state
   
   
     if(switchState[2] == 1 && lightStatus[16] == 1) {            //checking if PIR in Room 2 was
                                                                   //activated (bed 2)
        lightStatus[14] = 0;                                      //resetting master off
        digitalWrite(doorMonitor, LOW);                           //resetting the door Monitor LED
     }
   
     if(switchState[3] == 0 && sensorValue <= photoCellCutOff){    //checking if S4 priority off was
                                                                   //set bed 2
      if(switchState[2] == 1 && priorityStatus[1] == 0){           //check if the PIR in bed 2 was
                                                                   //activated (S3)
        //Serial.println("We switch on the lights");                 //debug only
        lightOutput[1] = 2;                                        //switch on the lights
                                                                   //Binary 0000000000000010
        lightStatus[1] = 1;                                        //setting the light status
        lightOutput[14] = 16384;                                   //make sure the master relay
                                                                   //stays on
        lightStatus[14] = 1;                                       //setting the master yelay status
        roomTimer[1] = millis();                                   //setting the timer
      }
      else if(switchState[2] == 0 && lightStatus[1] == 1) {       //the PIR not activated but the
                                                                  //the lights are on
        //Serial.println("We are checking the timer");              //debug only
        currentTime = millis();                                   //setting time reference
        endTime = currentTime - roomTimer[1];                     //calculating the inactive time
        if(endTime >= delayTime[1]) {                             //comparing inactive time with
          //Serial.println("Time is up we switch the lights off");  //debug only
          lightOutput[1] = 0;                                     //switching off the lights
          lightStatus[1] = 0;                                     //resetting the light status
          roomTimer[1] = 0;                                       //resetting the room timer
        }
      }
    }
    else if(switchState[3] == 1 && lightStatus[1] == 1
            && switchState3Old != 1) {                            //if priority is activated and the
                                                                  //lights are on
      //Serial.println("Priority switch activated, switching off the lights");  //debug only
      lightOutput[1] = 0;                                         //switching off the lights
      lightStatus[1] = 0;                                         //resetting the light status
      roomTimer[1] = 0;                                           //resetting the room timer
      priorityStatus[1] = 1;                                      //setting the priority status for
                                                                  //bed 2
    }
    else if(switchState[3] == 1 && lightStatus[1] == 0
            && switchState3Old != 1) {                            //if priority is activated and the
                                                                  //lights are off
      //Serial.println("Priority switch off, switching the light back to normal"); //debug only
      lightOutput[1] = 2;                                         //switching ion the lights
      lightStatus[1] = 1;                                         //setting the light status
      roomTimer[1] = millis();                                    //setting the room timer
      priorityStatus[1] = 0;                                      //resetting the priority status
    }
    switchState3Old = switchState[3];
  
  
    if(switchState[4] == 1 && lightStatus[16] == 1) {             //checking if PIR in Room 3 was
                                                                  //activated (bed 3)
        lightStatus[14] = 0;                                      //resetting master off
        digitalWrite(doorMonitor, LOW);                           //resetting the door Monitor LED
     }
  
     if(switchState[5] == 0  && sensorValue <= photoCellCutOff){   //checking if S6 priority off was
                                                                   //set bed 3
      if(switchState[4] == 1 && priorityStatus[2] == 0){           //check if the PIR in bed 3 was
                                                                   //activated (S5)
        //Serial.println("We switch on the lights");                 //debug only
        lightOutput[2] = 4;                                        //switch on the lights
                                                                   //Binary 0000000000000100
        lightStatus[2] = 1;                                        //setting the light status
        lightOutput[14] = 16384;                                   //make sure the master relay
                                                                   //stays on
        lightStatus[14] = 1;                                       //setting the master yelay status
        roomTimer[2] = millis();                                   //setting the timer
      }
      else if(switchState[4] == 0 && lightStatus[2] == 1) {       //the PIR not activated but the
                                                                  //the lights are on
        //Serial.println("We are checking the timer");              //debug only
        currentTime = millis();                                   //setting time reference
        endTime = currentTime - roomTimer[2];                     //calculating the inactive time
        if(endTime >= delayTime[2]) {                             //comparing inactive time with
          //Serial.println("Time is up we switch the lights off");  //debug only
          lightOutput[2] = 0;                                     //switching off the lights
          lightStatus[2] = 0;                                     //resetting the light status
          roomTimer[2] = 0;                                       //resetting the room timer
        }
      }
    }
    else if(switchState[5] == 1 && lightStatus[2] == 1
            && switchState5Old != 1) {                            //if priority is activated and the
                                                                  //lights are on
      //Serial.println("Priority switch activated, switching off the lights");  //debug only
      lightOutput[2] = 0;                                         //switching off the lights
      lightStatus[2] = 0;                                         //resetting the light status
      roomTimer[2] = 0;                                           //resetting the room timer
      priorityStatus[2] = 1;                                      //setting the priority status for
                                                                  //bed 3
    }
    else if(switchState[5] == 1 && lightStatus[2] == 0
            && switchState5Old != 1) {                            //if priority is activated and the
                                                                  //lights are off
      //Serial.println("Priority switch off, switching the light back to normal"); //debug only
      lightOutput[2] = 4;                                         //switching ion the lights
      lightStatus[2] = 1;                                         //setting the light status
      roomTimer[2] = millis();                                    //setting the room timer
      priorityStatus[2] = 0;                                      //resetting the priority status
    }
    switchState5Old = switchState[5];
  
  
    if(switchState[6] == 1 && lightStatus[16] == 1) {             //checking if PIR in Room 4 was
                                                                  //activated (living)
        lightStatus[16] = 0;                                      //resetting master off
        digitalWrite(doorMonitor, LOW);                           //resetting the door Monitor LED
     }
 
     if(switchState[7] == 0  && sensorValue <= photoCellCutOff){   //checking if S8 priority off was
                                                                   //set living
      if(switchState[6] == 1 && priorityStatus[3] == 0){           //check if the PIR in living was
                                                                   //activated (S7)
        //Serial.println("We switch on the lights");                 //debug only
        lightOutput[3] = 8;                                        //switch on the lights
                                                                   //Binary 0000000000001000
        lightStatus[3] = 1;                                        //setting the light status
        lightOutput[14] = 16384;                                   //make sure the master relay
                                                                   //stays on
        lightStatus[14] = 1;                                       //setting the master yelay status
        roomTimer[3] = millis();                                   //setting the timer
      }
      else if(switchState[6] == 0 && lightStatus[3] == 1) {       //the PIR not activated but the
                                                                  //the lights are on
        //Serial.println("We are checking the timer");              //debug only
        currentTime = millis();                                   //setting time reference
        endTime = currentTime - roomTimer[3];                     //calculating the inactive time
        if(endTime >= delayTime[3]) {                             //comparing inactive time with
                                                                  //delay time
          //Serial.println("Time is up we switch the lights off");  //debug only
          lightOutput[3] = 0;                                     //switching off the lights
          lightStatus[3] = 0;                                     //resetting the light status
          roomTimer[3] = 0;                                       //resetting the room timer
        }
      }
    }
    else if(switchState[7] == 1 && lightStatus[3] == 1
            && switchState7Old != 1) {                            //if priority is activated and the
                                                                  //lights are on
      //Serial.println("Priority switch activated, switching off the lights");  //debug only
      lightOutput[3] = 0;                                         //switching off the lights
      lightStatus[3] = 0;                                         //resetting the light status
      roomTimer[3] = 0;                                           //resetting the room timer
      priorityStatus[3] = 1;                                      //setting the priority status for
                                                                  //living
    }
    else if(switchState[7] == 1 && lightStatus[3] == 0
            && switchState7Old != 1) {                            //if priority is activated and the
                                                                  //lights are off
      //Serial.println("Priority switch off, switching the light back to normal"); //debug only
      lightOutput[3] = 8;                                         //switching on the lights
      lightStatus[3] = 1;                                         //setting the light status
      roomTimer[3] = millis();                                    //setting the room timer
      priorityStatus[3] = 0;                                      //resetting the priority status
    }
    switchState7Old = switchState[7];
  
  
    if(switchState[8] == 1 && lightStatus[16] == 1) {            //checking if PIR in Room 5 was
                                                                   //activated (bath 1)
        lightStatus[16] = 0;                                      //resetting master off
        digitalWrite(doorMonitor, LOW);                           //resetting the door Monitor LED
   }
 
   if(switchState[8] == 1) {                                     //checking S9 PIR of bathroom 1
                                                                 //(room 5)
      //Serial.println("We switch on the lights");                 //Debug only
      lightOutput[4] = 16;                                       //switching on the lights
      lightStatus[4] = 1;                                        //setting the light status
      lightOutput[14] = 16384;                                   //make sure the master relay
                                                                 //stays on
      lightStatus[14] = 1;                                       //setting the master yelay status
      roomTimer[4] = millis();                                   //setting the room timer
    }
    else if(switchState[8] == 0 && lightStatus[4] == 1) {       //if no PIR was activated and
                                                                //the lights are on
      //Serial.println("We are checking the timer");              //Debug only
      currentTime = millis();                                   //setting time reference
      endTime = currentTime - roomTimer[4];                     //calculating the inactive time
      if(endTime >= delayTime[4]) {                             //comparing inactive time with
                                                                //delay time
        //Serial.println("We are switching off the lights");      //debug only
        lightOutput[4] = 0;                                     //switching off the lights
        lightStatus[4] = 0;                                     //resetting the light status
        roomTimer[4] = 0;                                       //resetting the room timer
      }
    }
  
    if(switchState[9] == 1 && lightStatus[16] == 1) {            //checking if PIR in Room 6 was
                                                                   //activated (bath 2)
        lightStatus[16] = 0;                                      //resetting master off
        digitalWrite(doorMonitor, LOW);                           //resetting the door Monitor LED
     }
  
    if(switchState[9] == 1) {                                    //checking S10 PIR of bathroom 2
                                                                 //(room 6)
      //Serial.println("We switch on the lights");                 //Debug only
      lightOutput[5] = 32;                                       //switching on the lights
      lightStatus[5] = 1;                                        //setting the light status
      lightOutput[14] = 16384;                                   //make sure the master relay
                                                                 //stays on
      lightStatus[14] = 1;                                       //setting the master yelay status
      roomTimer[5] = millis();                                   //setting the room timer
    }
    else if(switchState[9] == 0 && lightStatus[5] == 1) {       //if no PIR was activated and
                                                                //the lights are on
      //Serial.println("We are checking the timer");              //Debug only
      currentTime = millis();                                   //setting time reference
      endTime = currentTime - roomTimer[5];                     //calculating the inactive time
      if(endTime >= delayTime[5]) {                             //comparing inactive time with
                                                                //delay time
        //Serial.println("We are switching off the lights");      //debug only
        lightOutput[5] = 0;                                     //switching off the lights
        lightStatus[5] = 0;                                     //resetting the light status
        roomTimer[5] = 0;                                       //resetting the room timer
      }
    }
  
    if(switchState[10] == 1 && lightStatus[16] == 1) {            //checking if PIR in Room 7 was
                                                                   //activated (bath 3)
        lightStatus[16] = 0;                                      //resetting master off
        digitalWrite(doorMonitor, LOW);                           //resetting the door Monitor LED
     }
  
    if(switchState[10] == 1) {                                    //checking S11 PIR of bathroom 3
                                                                 //(room 7)
      //Serial.println("We switch on the lights");                 //Debug only
      lightOutput[6] = 64;                                       //switching on the lights
      lightStatus[6] = 1;                                        //setting the light status
      lightOutput[14] = 16384;                                   //make sure the master relay
                                                                 //stays on
      lightStatus[14] = 1;                                       //setting the master yelay status
      roomTimer[6] = millis();                                   //setting the room timer
    }
    else if(switchState[10] == 0 && lightStatus[6] == 1) {       //if no PIR was activated and
                                                                //the lights are on
      //Serial.println("We are checking the timer");              //Debug only
      currentTime = millis();                                   //setting time reference
      endTime = currentTime - roomTimer[6];                     //calculating the inactive time
      if(endTime >= delayTime[6]) {                             //comparing inactive time with
                                                                //delay time
        //Serial.println("We are switching off the lights");      //debug only
        lightOutput[6] = 0;                                     //switching off the lights
        lightStatus[6] = 0;                                     //resetting the light status
        roomTimer[6] = 0;                                       //resetting the room timer
      }
    }
 
    if(switchState[11] == 1 && lightStatus[16] == 1) {            //checking if PIR in bath 4 was
                                                                   //activated (room 8)
        lightStatus[16] = 0;                                      //resetting master off
        digitalWrite(doorMonitor, LOW);                           //resetting the door Monitor LED
     }
  
    if(switchState[11] == 1) {                                    //checking S12 PIR of bathroom 4
                                                                 //(room 8)
      //Serial.println("We switch on the lights");                 //Debug only
      lightOutput[7] = 128;                                       //switching on the lights
      lightStatus[7] = 1;                                        //setting the light status
      lightOutput[14] = 16384;                                   //make sure the master relay
                                                                 //stays on
      lightStatus[14] = 1;                                       //setting the master yelay status
      roomTimer[7] = millis();                                   //setting the room timer
    }
    else if(switchState[11] == 0 && lightStatus[7] == 1) {      //if no PIR was activated and
                                                                //the lights are on
      //Serial.println("We are checking the timer");              //Debug only
      currentTime = millis();                                   //setting time reference
      endTime = currentTime - roomTimer[7];                     //calculating the inactive time
      if(endTime >= delayTime[7]) {                             //comparing inactive time with
                                                                //delay time
        //Serial.println("We are switching off the lights");      //debug only
        lightOutput[7] = 0;                                     //switching off the lights
        lightStatus[7] = 0;                                     //resetting the light status
        roomTimer[7] = 0;                                       //resetting the room timer
      }
    }
 
    if(switchState[12] == 1 && lightStatus[16] == 1) {            //checking if PIR in kitchen was
                                                                   //activated (room 9)
        lightStatus[16] = 0;                                      //resetting master off
        digitalWrite(doorMonitor, LOW);                           //resetting the door Monitor LED
     }
  
    if(switchState[12] == 1) {                                   //checking S13 PIR of kitchen
                                                                 //(room 9)
      //Serial.println("We switch on the lights");                 //Debug only
      lightOutput[8] = 256;                                       //switching on the lights
      lightStatus[8] = 1;                                        //setting the light status
      lightOutput[14] = 16384;                                   //make sure the master relay
                                                                 //stays on
      lightStatus[14] = 1;                                       //setting the master yelay status
      roomTimer[8] = millis();                                   //setting the room timer
    }
    else if(switchState[12] == 0 && lightStatus[8] == 1) {      //if no PIR was activated and
                                                                //the lights are on
      //Serial.println("We are checking the timer");              //Debug only
      currentTime = millis();                                   //setting time reference
      endTime = currentTime - roomTimer[8];                     //calculating the inactive time
      if(endTime >= delayTime[8]) {                             //comparing inactive time with
                                                                //delay time
        //Serial.println("We are switching off the lights");      //debug only
        lightOutput[8] = 0;                                     //switching off the lights
        lightStatus[8] = 0;                                     //resetting the light status
        roomTimer[8] = 0;                                       //resetting the room timer
      }
    }
  
    if(switchState[13] == 1 && lightStatus[16] == 1) {            //checking if PIR in corridor was
                                                                   //activated (room 10)
        lightStatus[16] = 0;                                      //resetting master off
        digitalWrite(doorMonitor, LOW);                           //resetting the door Monitor LED
     }
  
    if(switchState[13] == 1) {                                   //checking S14 PIR of Corridor
                                                                 //(room 10)
      //Serial.println("We switch on the lights");                 //Debug only
      lightOutput[9] = 512;                                       //switching on the lights
      lightStatus[9] = 1;                                        //setting the light status
      lightOutput[14] = 16384;                                   //make sure the master relay
                                                                 //stays on
      lightStatus[14] = 1;                                       //setting the master yelay status
      roomTimer[9] = millis();                                   //setting the room timer
    }
    else if(switchState[13] == 0 && lightStatus[9] == 1) {      //if no PIR was activated and
                                                                //the lights are on
      //Serial.println("We are checking the timer");              //Debug only
      currentTime = millis();                                   //setting time reference
      endTime = currentTime - roomTimer[9];                     //calculating the inactive time
      if(endTime >= delayTime[9]) {                             //comparing inactive time with
                                                                //delay time
        //Serial.println("We are switching off the lights");      //debug only
        lightOutput[9] = 0;                                     //switching off the lights
        lightStatus[9] = 0;                                     //resetting the light status
        roomTimer[9] = 0;                                       //resetting the room timer
      }
    }
    
  /////////////////////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();                                  //setting the timer
    }
    else if(switchState[14] == 0 && lightStatus[14] == 1){       //if a door is opened and the master
                                                                 //relay is on
      currentTime = millis();                                    //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();                                  //setting the timer
    }
    else if(switchState[15] == 0 && lightStatus[14] == 1){       //if a door is opened and the master
                                                                 //relay is on
      currentTime = millis();                                    //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();                                  //setting the timer
    }
    else if(switchState[16] == 0 && lightStatus[14] == 1){       //if a door is opened and the master
                                                                 //relay is on
      currentTime = millis();                                    //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();                                  //setting the timer
    }
    else if(switchState[17] == 0 && lightStatus[14] == 1){       //if a door is opened and the master
                                                                 //relay is on
      currentTime = millis();                                    //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();                                   //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();                                   //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
    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();           //setting all the room timers
    }
    outputL = 32767;                     //setting the output
                                         //binary 0111111111111111
  }
 
  //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;
}