To stop the AC from switching on and
off while having a jumping value in the temperature reading or a non
corresponding timer adjustment in the ac - setup, we are adding a
timer to lock the AC for 8 minutes after it last switched off. Before
we start implementing that timer, we build a little timer function,
since we have quite a few statements like:
currentTime = millis()/1000; endTime = currentTime – presetTime; if(endTime >= timeLimit){ doSomething; }
To cut this scenario short, I packed it
into a little function which we can place right after all the
check_Light() and ac_read() functions:
boolean allTimer(unsigned long timeSet, unsigned int timeLimit){ currentTime = millis()/1000; //set the reference time endTime = currentTime – timeSet; //calculate the reference time against a set time if(endTime >= timeLimit){ //check if we are passed the limit return true; //return true if yes } else{ return false; } }
This makes it easy for our function
call.
if(allTimer(roomTimer[room], delayTime[room])) Do something;
That if – statement is only processed
if the function returns true.
Now, did you place the function
already? Good, than we have to change a few timer statements.
We jump right into the check_Light_P
function:
unsigned long check_light_P(byte pir, byte prio, byte room, unsigned long light){ if(switchState[prio] == 0 && sensorValue <= photoCellCutOff) { //checking if S2 priority off was //set bed 1 if(switchState[pir] == 1 && priorityStatus[room] == 0) { //check if the PIR in bed 1 was //activated and no priority was set //Serial.println("We switch in the lights in bedroom 1"); //Debug only lightOutput[room] = light; //switching on the lights – binary //000000000000000000000001 lightStatus[room] = 1; //setting the light status for bed 1 lightOutput[14] = 16384; //make sure the master relay //stays on lightStatus[14] = 1; //setting the master delay status roomTimer[room] = millis()/1000; //setting the timer } else if(switchState[pir] == 0 && lightStatus[room] == 1) { //the PIR not activated but the //lights are on //>>>>>>>>>>>>>NOTE the change below<<<<<<<<<<<<< if(allTimer(roomTimer[room], delayTime[room])){ // check allowed delay time //Serial.println("Time is up switching off the lights"); //Debug only lightOutput[room] = 0; //switching off the lights lightStatus[room] = 0; //resetting the light status roomTimer[room] = 0; //resetting the room timer } } } else if(switchState[prio] == 1 && lightStatus[room] == 1 && switchState1Old != 1) { //if priority is activated and the //lights are on //Serial.println("Priority switch activated switching off the lights"); //Debug only lightOutput[room] = 0; //switching off the lights lightStatus[room] = 0; //resetting the light status roomTimer[room] = 0; //resetting the room timer priorityStatus[room] = 1; //setting the priority status bed 1 } else if(switchState[prio] == 1 && lightStatus[room] == 0 && switchState1Old != 1) { //if priority was activated and the //lights are off //Serial.println("Priority switch deactivated switching on the lights"); //Debug only lightOutput[room] = light; //switching on the lights lightStatus[room] = 1; //setting the light status roomTimer[room] = millis()/1000; //setting the room timer priorityStatus[room] = 0; //setting the priority for bed 1 back //to 0 } switchState1Old = switchState[prio]; //passing on the switch state return lightOutput[room]; }
Found the changes? Good, but don't
worry to much, before I start storing some of the variables in the
EEPROM memory, I post a full working code again. Now we move down to
the next function, check_light_N and do the same there:
unsigned long check_light_N(byte pir, byte room, unsigned long light){ if(switchState[pir] == 1) { //checking S9 PIR of bathroom 1 //(room 5) //Serial.println("We switch on the lights"); //Debug only lightOutput[room] = light; //switching on the lights lightStatus[room] = 1; //setting the light status lightOutput[14] = 16384; //make sure the master relay //stays on lightStatus[14] = 1; //setting the master delay status roomTimer[room] = millis()/1000; //setting the room timer } else if(switchState[pir] == 0 && lightStatus[room] == 1) { //if no PIR was activated and //the lights are on //>>>>>>>>>>>>>NOTE changes below<<<<<<<<<<<<< if(allTimer(roomTimer[room], delayTime[room])){ //check if the time limit is reached //Serial.println("We are switching off the lights"); //debug only lightOutput[room] = 0; //switching off the lights lightStatus[room] = 0; //resetting the light status roomTimer[room] = 0; //resetting the room timer } } return lightOutput[room]; }
Before we take care of the ac_read()
function, we make a small d-tour and add a variable for the 8 minutes
lock timer for the AC-units. There fore we go to the declaration
part in to the “all the other variables section:
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////all the other variables///////////////////////////// /////////////////////////////////////////////////////////////////////////////// ////Sensor and timer variables int delayTime[16] = {dBed1, dBed2, dBed3, dLiving, dBath1, dBath2, dBath3, dBath4, dKitchen, dCorridor, dAC1, dAC2, dAC3, dAC4, dMaster, 0}; byte temperatur1 = 0; //holding temperature for room 1 //>>>>>>>>>>>>Add the line below<<<<<<<<<<<<<< unsigned int lastRun[4] = {0}; //var to hold var when ac was last stopped
from here we go down to the ac_read()
function. We add the 8 minute lock timer and change the the general
timers in to function calls in one go.
We are going to break it up a bit and
start with AC operating mode 1:
unsigned long ac_read(byte readSw, byte room){ byte periode = get_ac_periode(); //function call to check time periode (season) //check if a forced switch on is defined and the set temperature if(ac_forced_on[room-10][0] != 99 && checkOnTime(room_timers[room][periode][0], room_timers[room][periode][1], room_timers[room][periode][2], room_timers[room][periode][3]) == 1 && temperatur1 >= ac_set_temp){ priorityStatus[room] = 1; //set priority status to 1 if yes } else{ priorityStatus[room] = 0; //set priority status to 0 if no } if(ac_op_mode == 1){ if(switchState[readSw] == 1 && lightStatus[14] == 1){ //Checking if readswitches are activated //and the master relay is on AC room //>>>>>>>>>>>>NOTE the Changes<<<<<<<<<<<<< //we are packing the light (AC) output statements in a if -statement checking if the 8 minute lock //time are passed if(allTimer(lastRun[room - 10], 480)){ //check if 8 minute lock is passed since last run lightOutput[room] = outputValues[room]; //providing the ability to //switch on the AC lightStatus[room] = 1; //setting the light (AC) status roomTimer[room] = millis()/1000; //setting the timer //>>>>>>>>>>>>ADD the line below<<<<<<<<<<<<< lastRun[room - 10] = 0; //setting the lock timer to 0 } //We need to add the else statement to keep everything off if the lock time is not up yet else{ lightOutput[room] = 0; //cancelling ability to switch on the //AC lightStatus[room] = 0; //resetting the light (AC) status roomTimer[room] = 0; } } else if(switchState[readSw] == 0 && lightStatus[14] == 1){ //if a door is opened and the master //relay is on if(allTimer(roomTimer[room], delayTime[room])){ //checking the time limit lightOutput[room] = 0; //cancelling ability to switch on the //AC lightStatus[room] = 0; //resetting the light (AC) status roomTimer[room] = 0; //resetting the timer //And while we are switching off the units, we need to set the timer //>>>>>>>>>>>>>Add the line below<<<<<<<<<<<<< lastRun[room - 10] = millis()/1000; } } return lightOutput[room]; } else if(ac_op_mode == 2){
Please note, that operating mode 1 is
not meant to switch on the AC. The room management systems relay is
only replacing variable read switches and is meant to be connected
according to your AC's installation instructions instead of the read
switches on doors and windows. The read switches are connected to the
corresponding input channel of the room management system. Sure, you
can connect it to a contactor, cut the power supply and use the AC's
auto restart ability to start your AC but this would put extra strain
on the compressor and the AC's control system.
Lets move on to operating mode 2:
It is actually pretty simple, all
statements where we switch on some lights, we need to a statement
checking the 8 minute lock timer.
Everything looking like that:
if(checkOnTime(room_timers[room][periode][0], room_timers[room][periode][1], //checking if AC is allowed to run room_timers[room][periode][2], room_timers[room][periode][3]) == 1){ lightOutput[room] = outputValues[room]; //switch on the AC lightStatus[room] = 1; //setting the light (AC) status roomTimer[room] = millis()/1000; //setting the timer }
has to change to:
room_timers[room][periode][2], room_timers[room][periode][3]) == 1){ if(allTimer(lastRun[room - 10], 480)){ //check if 8 minute lock is passed since last run lightOutput[room] = outputValues[room]; //switch on the AC lightStatus[room] = 1; //setting the light (AC) status roomTimer[room] = millis()/1000; //setting the timer lastRun[room - 10] = 0; } else{ lightOutput[room] = 0; //keep it off lightStatus[room] = 0; }
The same goes for operating mode 3. To
cut a long story short, here is the revised ac_read function with all
the changes.
unsigned long ac_read(byte readSw, byte room){ byte periode = get_ac_periode(); //function call to check time periode (season) //check if a forced switch on is defined and the set temperature if(ac_forced_on[room-10][0] != 99 && checkOnTime(room_timers[room][periode][0], room_timers[room][periode][1], room_timers[room][periode][2], room_timers[room][periode][3]) == 1 && temperatur1 >= ac_set_temp){ priorityStatus[room] = 1; //set priority status to 1 if yes } else{ priorityStatus[room] = 0; //set priority status to 0 if no } if(ac_op_mode == 1){ if(switchState[readSw] == 1 && lightStatus[14] == 1){ //Checking if readswitches are activated //and the master relay is on AC room 1 (bed1) if(allTimer(lastRun[room - 10], 480)){ //check if 8 minute lock is passed since last run lightOutput[room] = outputValues[room]; //providing the ability to //switch on the AC lightStatus[room] = 1; //setting the light (AC) status roomTimer[room] = millis()/1000; //setting the timer lastRun[room - 10] = 0; } else{ lightOutput[room] = 0; //cancelling ability to switch on the //AC lightStatus[room] = 0; //resetting the light (AC) status roomTimer[room] = 0; } } else if(switchState[readSw] == 0 && lightStatus[14] == 1){ //if a door is opened and the master //relay is on if(allTimer(roomTimer[room], delayTime[room])){ //checking the time limit lightOutput[room] = 0; //cancelling ability to switch on the //AC lightStatus[room] = 0; //resetting the light (AC) status roomTimer[room] = 0; //resetting the timer lastRun[room - 10] = millis()/1000; } } return lightOutput[room]; } else if(ac_op_mode == 2){ if(ac_master_bypass[room - 10] == 0){ //check if the master bypass is set if(switchState[readSw] == 1 && lightStatus[14] == 1){ //Checking if readswitches are activated if(checkOnTime(room_timers[room][periode][0], room_timers[room][periode][1], //checking if AC is allowed to run room_timers[room][periode][2], room_timers[room][periode][3]) == 1){ if(allTimer(lastRun[room - 10], 480)){ //check if 8 minute lock is passed since last run lightOutput[room] = outputValues[room]; //switch on the AC lightStatus[room] = 1; //setting the light (AC) status roomTimer[room] = millis()/1000; //setting the timer lastRun[room - 10] = 0; } else{ lightOutput[room] = 0; //keep it off lightStatus[room] = 0; } } } else if(switchState[readSw] == 1 && priorityStatus[room] == 1){ //if doors and windows are closed and priority is set if(currentHour >= ac_forced_on[room-10][0] && currentMinute >= ac_forced_on[room-10][1]){ //check if it's time to start if(allTimer(lastRun[room - 10], 480)){ //check if 8 minute lock is passed since last run lightOutput[room] = outputValues[room]; //switch on the AC lightStatus[room] = 1; //setting the light (AC) status roomTimer[room] = millis()/1000; //setting the timer lastRun[room - 10] = 0; } else{ lightOutput[room] = 0; //keep it off lightStatus[room] = 0; } } else{ lightOutput[room] = 0; //keep it off lightStatus[room] = 0; //setting the light (AC) status roomTimer[room] = 0; //resetting the room timer } } else if(switchState[readSw] == 0 && lightStatus[14] == 1){ //if a door is opened and the master //relay is on //delay time if(allTimer(roomTimer[room], delayTime[room])){ //checking the time limit lightOutput[room] = 0; //cancelling ability to switch on the //AC lightStatus[room] = 0; //resetting the light (AC) status roomTimer[room] = 0; //resetting the timer lastRun[room - 10] = millis()/1000; } } } else if(ac_master_bypass[room - 10] == 1){ //if master relay bypass is on if(switchState[readSw] == 1){ //Checking if readswitches are activated if(checkOnTime(room_timers[room][periode][0], room_timers[room][periode][1], room_timers[room][periode][2], room_timers[room][periode][3]) == 1 && temperatur1 >= ac_set_temp){ if(allTimer(lastRun[room - 10], 480)){ //check if 8 minute lock is passed since last run lightOutput[room] = outputValues[room]; //switch on the AC lightStatus[room] = 1; //setting the light (AC) status roomTimer[room] = millis()/1000; //setting the timer lastRun[room - 10] = 0; } else{ lightOutput[room] = 0; //keep it off lightStatus[room] = 0; } } } else if(switchState[readSw] == 0){ //if a door is opened and the master //relay is on //delay time if(allTimer(roomTimer[room], delayTime[room])){ //checking the time limit lightOutput[room] = 0; //cancelling ability to switch on the //AC lightStatus[room] = 0; //resetting the light (AC) status roomTimer[room] = 0; //resetting the timer lastRun[room - 10] = millis() / 1000; } } } return lightOutput[room]; } else if(ac_op_mode == 3){ //AC operating mode 3 lightOutput[room] = 0; //Setting the lightOutput to 0 if(roomLight[room] == 1 && lastRun[room - 10] == 0){ //if a "on" command was given and the time since last run is more than 8 minutes if(allTimer(roomTimer[room], acSwitchDelay)){ lightStatus[room] = 1; //set AC status to on roomLight[room] = 0; //cancel "on" command return 0; //return 0 } else{ return outputValues[room]; //pulse the switch while "on" command active } } if(roomLight[room] == 1 && lastRun[room - 10] != 0){ //if a "on" command was given and the time since last run is less than 8 minutes /*currentTime = millis()/1000; //setting time for reference endTime = currentTime - lastRun[room - 10]; //compare time with last switch off time if(endTime >= 480) lastRun[room - 10] = 0; */ //if last switch off is 8 minutes ore longer if(allTimer(lastRun[room - 10], 480)) lastRun[room - 10] = 0; return 0; //return 0 } if(roomLight[room] == 2){ //if an "off" command was given check delay timer /*currentTime = millis()/1000; //set time for reference endTime = currentTime - roomTimer[room]; //compare reference with set off delay if(endTime >= delayTime[room]){ */ //check if it matches allowed difference if(allTimer(roomTimer[room], delayTime[room])){ roomLight[room] = 3; //final command to switch off return 0; //return 0 } else{ roomLight[room] = 2; //keep the status return 0; //return 0 } } if(roomLight[room] == 3){ //final off command given if(allTimer(roomTimer[room], acSwitchDelay)){ lightStatus[room] = 0; //reset command status roomLight[room] = 0; //reset AC status lastRun[room - 10] = millis()/1000; //set switch off time return 0; //return 0 } else{ return outputValues[room]; //pulse the switch } } if(ac_master_bypass[room-10] == 0){ if(lightStatus[room] == 0 && roomLight[room] == 0){ if(switchState[readSw] == 1 && lightStatus[14] == 1 && temperatur1 >= ac_set_temp && priorityStatus[room] == 0){ if(checkOnTime(room_timers[room][periode][0], room_timers[room][periode][1], //checking if AC is allowed to run room_timers[room][periode][2], room_timers[room][periode][3]) == 1){ roomLight[room] = 1; roomTimer[room] = millis()/1000; return 0; } else { return 0; } } if(switchState[readSw] == 1 && priorityStatus[room] == 1 && temperatur1 >= ac_set_temp){ if(currentHour >= ac_forced_on[room-10][0] && currentMinute >= ac_forced_on[room-10][1]){ //check if it's time to start roomLight[room] = 1; roomTimer[room] = millis()/1000; return 0; } else { return 0; } } } if(lightStatus[room] == 1 && roomLight[room] == 0){ if(currentHour == room_timers[room][periode][2] && //if the allowed running limit is reached currentMinute >= room_timers[room][periode][3]){ roomLight[room] = 2; roomTimer[room] = millis()/1000; return 0; } else{ return 0; } if(priorityStatus[room] == 1 && switchState[readSw] == 0){ roomLight[room] = 2; roomTimer[room] = millis()/1000; return 0; } else{ return 0; } if(priorityStatus[room] == 0){ if(switchState[readSw] == 0 | lightStatus[14] == 0){ roomLight[room] = 2; roomTimer[room] = millis()/1000; return 0; } else{ return 0; } } } } } return 0; }
Since we got this straight, we need to
do a few adjustments. Tu update the settings for the AC's, we are
using most of the functions, we are also using for updating the light
settings. Which is great, it saves us a lot of typing and memory
space in the program. However, we need to do at least one ajustment.
If we look at our arrays holding the variables for operating the
light, they are nearly all proportional to the rooms array[0]
corresponds with room 1, array[1] corresponds with room 2 and so on.
Since we are using the same variables and arrays to control the AC
units, we need to account for it in the functions. Let's have a quick
look at the lightOutput[] array. As just explained, if we are
referring to room 5, in the lightOutput[] array we need to look at
place no 4 (lightOutput[4] to find the right value. Just remember,
array counts start with 0 and not with 1 like we number the rooms. If
I need to print a room number, since everything is linear, I can pass
the corresponding array place to a function to find all needed
variables and to print the room number on the screen, I just add 1 to
the value and I have the actual room number and not the place holder
in the array. But this works only until we come up to the AC's. The
first AC unit in the first room is now placeholder 10 in the arrays
and carrying on with the just mentioned system, that would make room
11 for the first AC unit...
Therefore, we need to change the part
where we print the room number in the adjustment functions a little.
We currently are showing the assigned
room no with lcd.print(room + 1). We need to change this to a little
if-statement:
if(room >= 10 && room <= 13){ //calculating room for AC units lcd.print(room - 9]; //AC room } else{ lcd.print(room + 1); //light room
The assigned place holders in the
arrays for the AC-units are 10, 11, 12 and 13. We need to make sure,
if 1 of this numbers is passed into the variable room, giving the
right place holder in the arrays but we need to subtract 9 to get the
right room no. Placeholder 10 stands for AC 1 in room 1 and so on.
Here the effected, updated functions:
- int get_delay(byte info, byte room, int reading){
//function to adjust the pir delay time and AC off - delay int get_delay(byte info, byte room, int reading){ byte subButton = 0; //resetting the button value byte value = reading / 60; //converting to Minutes lcd.clear(); //clear screen lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(msg_table[info])))); //print passed message if(room >= 10 && room <= 13){ //calculating room for AC units lcd.print(room - 9]; //AC room } else{ lcd.print(room + 1); //light room } lcd.setCursor(0, 1); //set cursor to second row, first column if(value < 10) lcd.write(pgm_read_byte(&char_table[2])); //print 0 lcd.print(value); //print the passed value in minutes lcd.setCursor(4, 1); //set cursor to second row, column 6 lcd.print("Min"); //just print Min. while(subButton != btnSelect){ //wait for select btn subButton = read_act_buttons(); //check if a button was pressed if(subButton == btnSearch){ //if btnSearch was pressed if(value > 0 && value < 30){ //we are within allowed range value++; //add 1 to value while btnSearch is pressed } if(value >= 30) value = 1; //if reaches upper limit set to lower limit lcd.setCursor(0, 1); //setting the cursor if(value < 10) lcd.write(pgm_read_byte(&char_table[2])); //print 0 lcd.print(value); //printing the updated value } } return value*60; }
- byte get_offon(byte info, byte room, byte reading){
//function to set a timer active / inactive byte get_offon(byte info, byte room, byte reading){ byte subButton = 0; //resetting button value lcd.clear(); //clear screen lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(msg_table[info])))); //print passed info text if(room >= 10 && room <= 13){ //calculating room for AC units lcd.print(room - 9]; //AC room } else{ lcd.print(room + 1); //light room } lcd.setCursor(0, 1); //set cursor to second row column 1 if(reading != 1) lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(msg_table[7])))); //if value is not 1 timer is off //print off if(reading == 1) lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(msg_table[8])))); //if timer is 1, timer is active //print active while(subButton != btnSelect){ //waiting for btnSelect to be pressed subButton = read_act_buttons(); //checking for pressed buttons if(subButton == btnSearch){ //if btnSearch is pressed if(reading == 1) reading = 0; //set to 0 if 1 else if(reading == 0) reading = 1; //set to 1 if 0 } lcd.setCursor(0, 1); //set cursor to first column, second row if(reading != 1) lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(msg_table[7])))); //print off if not set to 1 if(reading == 1) lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(msg_table[8])))); //print Active if set to 1 } return reading; }
The last thing we take care of today is
preparing the timers for the outside lighting to go also into the
menu so we are able to adjust them to individual liking. I am sorry
for making you jump around in the code but we need to start again at
the top in the declaration part, “Timer and Sensitivity Settings”
section. There we find the following two entries and delete them.
//>>>>>>>>>>>>>DELETE the following two variables<<<<<<<<<<<<<< byte hourOutsideOff = 23; //var holding the time (full hours) in which the lights have //to switch off byte minuteOutsideOff = 30; //var holding the time (minutes) in which the lights //have to switch off
Now e move down to the “/holiday and
AC timer settings/” section:
byte timer_active[15][4] = { //<<<<<<<<<<<<< CHANGE timer_active[14][4] to timer_active[15][4] {1, 1, 1, 0}, //room 0 timers 0 to 3 {1, 1, 0, 0}, //room 1 timers 0 to 3 {1, 1, 1, 1}, //room 2 timers 0 to 3 {0, 1, 0, 0}, //room 3 timers 0 to 3 {1, 1, 2, 2}, //room 4 timers 0 to 3 {1, 1, 2, 2}, //room 5 timers 0 to 3 {1, 1, 2, 2}, //room 6 timers 0 to 3 {1, 0, 2, 2}, //room 7 timers 0 to 3 {1, 1, 2, 2}, //room 8 timers 0 to 3 {0, 0, 2, 2}, //room 9 timers 0 to 3 {1, 1, 1, 0}, //room 0 AC timers 0 to 3 {1, 1, 1, 0}, //room 1 AC timers 0 to 3 {1, 1, 1, 0}, //room 2 AC timers 0 to 3 {1, 1, 2, 0}, //room 3 AC timers 0 to 3 //>>>>>>>>>>>>ADD the line below<<<<<<<<<<<<<< {0, 1, 2, 2} //outside lighting }; //Timer Settings room, timer, hour on, minute on, hour off, minute off byte room_timers[15][4][4] = { //<<<<<<<<<<<<< CHANGE room_timers[14][4][4] to room_timers[15][4][4] { {5, 35, 6, 5}, //room 0 timer 0 {19, 35, 20, 15}, //room 0 timer 1 {21, 5, 21, 15}, //room 0 timer 2 {0, 0, 0, 0} //room 0 timer 3 }, { {6, 30, 6, 50}, //room 2 timer 1 {19, 30, 20, 10}, //room 2 timer 2 {0, 0, 0, 0}, //room 2 timer 3 {0, 0, 0, 0} //room 2 timer 4 }, { {5, 50, 6, 20}, //room 3 timer 1 {18, 10, 18, 25}, //room 3 timer 2 {19, 15, 19, 40}, //room 3 timer 3 {23, 20, 23, 35} //room 3 timer 4 }, { {0, 0, 0, 0}, //room 4 timer 1 {17, 30, 23, 30}, //room 4 timer 2 {0, 0, 0, 0}, //room 4 timer 3 {0, 0, 0, 0} //room 4 timer 4 }, { {5, 40, 5, 45}, //room 5 timer 1 {19, 55, 20, 10}, //room 5 timer 2 {0, 0, 0, 0}, //not used {0, 0, 0, 0} //not used }, { {6, 35, 6, 45}, //room 6 timer 1 {19, 50, 20, 5}, //room 6 timer 2 {0, 0, 0, 0}, //not used {0, 0, 0, 0} //not used }, { {6, 5, 6, 25}, //room 7 timer 1 {22, 50, 23, 15}, //room 7 timer 2 {0, 0, 0, 0}, //not used {0, 0, 0, 0} //not used }, { {0, 0, 0, 0}, //room 8 timer 1 {22, 5, 22, 20}, //room 8 timer 2 {0, 0, 0, 0}, //not used {0, 0, 0, 0} //not used }, { {5, 50, 6, 45}, //room 9 timer 1 {17, 45, 18, 30}, //room 9 timer 2 {0, 0, 0, 0}, //room 9 timer 3 {0, 0, 0, 0} //not used }, { {0, 0, 0, 0}, //room 10 timer 1 {0, 0, 0, 0}, //room 10 timer 2 {0, 0, 0, 0}, //not used {0, 0, 0, 0} //not used }, { {19, 30, 22, 0}, //room 0 AC timer 1 {19, 30, 5, 30}, //room 0 AC timer 2 {19, 30, 22, 0}, //room 0 AC timer 3 {0, 0, 0, 0} //room 0 AC timer 4 }, { {19, 30, 22, 0}, //room 1 AC timer 1 {19, 30, 5, 30}, //room 1 AC timer 2 {19, 30, 22, 0}, //room 1 AC timer 3 {0, 0, 0, 0} //room 1 AC timer 4 }, { {21, 30, 1, 0}, //room 2 AC timer 1 {21, 30, 6, 0}, //room 2 AC timer 2 {21, 30, 1, 0}, //room 2 AC timer 3 {0, 0, 0, 0} //room 2 AC timer 4 }, { {13, 0, 20, 0}, //room 3 AC timer 1 {5, 0, 23, 59}, //room 3 AC timer 2 {6, 0, 20, 0}, //room 3 AC timer 3 {0, 0, 0, 0} //room 3 AC timer 4 }, //>>>>>>>>>>>>>ADD from here<<<<<<<<<<<<<< { {0, 0, 0, 0}, //outside lights timer 1 {17, 0, 23, 59}, //outside lights timer 2 {0, 0, 0, 0}, //outside lights timer 3 {0, 0, 0, 0} //outside lights timer 4 } //>>>>>>>>>>>>>>Addition ends here<<<<<<<<<<<<<< };
We move down a little further into the
“all the other variables” section and find:
unsigned int outputValues[14] = {1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192}
and change it to
unsigned int outputValues[15] = {1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,32768};
in the same section, just a little
further down we delete:
//>>>>>>>>>>>>>>DELETE the line below<<<<<<<<<<<<<<< unsigned int outsideOnTime = 0; //checking result if the time is within //on or off time limits
Now we go down into the main loop into
the “holiday lighting” section:
//////////////Holiday lighting///////////////////////// if(switchState[20] == 1) { //check if the holiday switch //is activated lightOutput[14] = 0; //make sure the master relay is off ///////////////loop through all the lights/////////////// for(int x=0; x<16; x++){ //>>>>>>>>>>>>>CHANGE x<10; to x<16; //>>>>>>>>>>>>ADD the line below<<<<<<<<<<<<< if(x >= 0 && x < 10 | x == 15){ for(int i=0; i<4; i++){ if(timer_active[x][i] == 1 && currentHour >= room_timers[x][i][0] && currentHour <= (room_timers[x][i][2] + 1)){ //checking if we came passed //the hour where the lights //to be switched on //checking the times roomLight[x] = checkOnTime(room_timers[x][i][0], room_timers[x][i][1], room_timers[x][i][2], room_timers[x][i][3]); } } if(roomLight[x] == 1 && lightLevel[x] == 1){ //if with in the on time lightOutput[x] = outputValues[x]; //switch on the lights } else { lightOutput[x] = 0; //other keep them off lightLevel[x] = 0; } } //>>>>>>>>>>>>>>ADD the closing braces for the new if – statement }
We extend the loop to go through 16
“rooms” by changing x<10 to x<16 which we need cause the
variables for the outside lighting are on place 15 in our arrays.
Since the whole system was never planned to reach this dimensions
when I started, there are a few thing which should be on a different
place like the outside lights. They should be on place 10 to save a
couple of lines of code. However, now it is as it is and maybe in the
next complete revision I change it as it should be. For time being,
we need to add the if – statement (if(x >= 0 && x <
10 | x == 15){) to exclude the places 10, 11, 12 and 13 (AC units)
and place 14 (master relay) from the loop.
Since we have done this, we can delete
the outside lighting part in the 'holiday lighting” section.
//>>>>>>>>>>>>>DELETE from here<<<<<<<<<<<<<< ////////Outside lights//////////////////// for(i=0; i<4; i++){ outsideOnTime = checkOnTime(17, 02, hourOutsideOff, minuteOutsideOff); //function call to check time if(outsideOnTime == 1 && lightLevel[15] == 1){ lightOutput[15] = 32768; } else { lightOutput[15] = 0; lightLevel[15] = 0; } //>>>>>>>>>>>>>Delete ends here<<<<<<<<<<<<<< #ifdef DA_DEBUG_holtimers for(int x=0; x<16; x++){ for(int y=0; y<4; y++){ Serial.print("Room "); Serial.print(x); Serial.print(": "); Serial.println(timer_active[x][y]); Serial.print("Room "); Serial.print(x); Serial.print(" Lights: "); Serial.println(room1Light[x]); } } #endif } else {
Right connecting to the holiday
lighting part is the part where we check the lights in normal
operational mode and the first part of it is again the outside
lighting:
outsideOnTime = checkOnTime(17, 02, hourOutsideOff, minuteOutsideOff); //function call to check time if(outsideOnTime == 1 && lightLevel[15] == 1){ lightOutput[15] = 32768; } else { lightOutput[15] = 0; lightLevel[15] = 0; } //////////////////room lights//////////////////////////////
changes to:
////////Outside lights//////////////////// for(int i=0; i<4; i++){ roomLight[15] = checkOnTime(room_timers[15][i][0], room_timers[15][i][1], room_timers[15][i][2], room_timers[15][i][3]); if(roomLight[15] == 1 && lightLevel[15] == 1){ lightOutput[15] = outputValues[15]; } else { lightOutput[15] = 0; lightLevel[15] = 0; } } //////////////////room lights//////////////////////////////
In the next post we implement the
outside lights into the menu and we will have a look at saving around
100 lines of code in the selectMenu() function as suggested from
Reuben.
No comments:
Post a Comment