Translate

Friday, 23 May 2014

Room Management System – Adding a little more control to the AC's


Before we start adding the code, a quick word to restrictions in this scope. Since we are working with a relay controlling the power supply to the AC-unit or plug in to a power-switch of the unit, we are only able to start the unit at predefined settings form the AC's own control. In some cases, specially with some new models, which switch only through remote control or being switched through a pulse generated by a electronic circuit it might not be possible at all to plug this unit in, being able to switch your AC on.
One feature of the current AC models work to our advantage, auto restart. Some Mitsubishi and LG Air-conditioners are equipet with a auto restart function, restarting the AC-unit automaticly after a power cut with the same settings as before. We can start up the AC unit and control a contactor with the Arduino relay to cut the power. If we want the AC unit to come back on, we let the Arduino switch the power back on, the auto restart function kicks in and the AC is running again
Mode 1 is serving as a read switch, switching the AC off, when a door or window is opened for more than a predefined time.

Mode 2 is controlling the Unit plugged in parallel to a switch.

Mode 3 is controlling the Unit plugged in parallel to momentary switch (push button)

Mode 1 is switching the unit off if a window or door is opened for more than a predefined delay time

Mode 2 and 3 can be set to switch on during a predefined time period using 4 independent timers.
All rooms can also be set to switch only on when a specified temperature is reached measured from 1 or 2 centralized temperature sensors It also switches off like in Mode 1 when a window or door is opened for more than a predefined time.
Optional in all modes is to bypass the switching off of AC units when the Master relay switches off.

General Idea:
Set a time in which the AC is allowed to run. Switch everything off when the last one leaves the house, Switch predefined units back on for example 1 hour before the first one comes home and or when the temperature goes above a predefined setting.

Lets start and add again a few variables. There fore we go to our declaration part in to the “Timer and Sensitivity settings” section. There we add a array holding start and end month for 4 different time periods (seasons) to allow different AC settings for different seasonal requirements. Please modify the entries to your requirements since this will be your default settings. Soon as we go back into the menu, this settings can be adjusted.

byte ac_period[4][2] = {

{1, 5}, //time period between January and May

{6, 9}, //time period between June and September

{10, 10}, //October

{11, 12} //time period between November and December

};

Next we add an array holding values to bypass the master relay to avoid the switching off of the units while the master relay is switching off while no more motion is detected in the house.

byte ac_master_bypass[4] = {0}; //array holding values to bypass master relay

Now we move down a bit in to the “AC and holiday timer settings”, where we add 4 lines to the timer_active[][] array:

byte timer_active[14][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

//>>>>>>>>>>>>>Addition start here<<<<<<<<<<<<<

{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

//>>>>>>>>>>>>>Addition ends here<<<<<<<<<<<<<

};

We also need to add the respective timers to the room_timers[] array:

byte room_timers[14][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

},

//>>>>>>>>>>>>>Addition starts here<<<<<<<<<<<<<

{

{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

}

//>>>>>>>>>>>>>Addition ends here<<<<<<<<<<<<<

};

If we want to switch on the AC units at a specified time, we need another variable. We add another array holding the times we want the AC units to switch on even if the master relay is still off.

byte ac_forced_on[4][2] = {

{19, 30}, //Switch on AC room 1

{19, 30}, //Switch on AC room 2

{22, 0}, //Switch on AC room 3

{16, 0} //Switch on AC room 4

};

Now we jump down to the ac_read() function and modify as followed:


unsigned long ac_read(byte readSw, byte room, unsigned long light){

byte period = get_ac_period(); //function call to check time period (season)

//check if a forced switch on is defined

if(ac_forced_on[room-10][0] != 99 && checkOnTime(room_timers[room][period][0], room_timers[room][period][1],

room_timers[room][period][2], room_timers[room][period][3]) == 1){

priorityStatus[room] = 1; //set priority status to 1 if yes

}

else{

priorityStatus[room] = 0; //set priority status to 0 if no

}

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][period][0], room_timers[room][period][1], //checking if AC is allowed to run

room_timers[room][period][2], room_timers[room][period][3]) == 1){

lightOutput[room] = light; //switch on the AC

lightStatus[room] = 1; //setting the light (AC) status

roomTimer[room] = millis()/1000; //setting the timer

}

}

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

lightOutput[room] = light; //switch on the AC

lightStatus[room] = 1; //setting the light (AC) status

roomTimer[room] = millis()/1000; //setting the timer

}

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

currentTime = millis()/1000; //setting time reference

endTime = currentTime - roomTimer[room]; //calculating the inactive time

if(endTime >= delayTime[room]){ //comparing inactive time with

//delay time

lightOutput[room] = 0; //cancelling ability to switch on the

//AC

lightStatus[room] = 0; //resetting the light (AC) status

roomTimer[room] = 0; //resetting the timer

}

}

}

else if(ac_master_bypass[room - 10] == 1){

if(switchState[readSw] == 1){ //Checking if readswitches are activated

if(checkOnTime(room_timers[room][period][0], room_timers[room][period][1],

room_timers[room][period][2], room_timers[room][period][3]) == 1){

lightOutput[room] = light; //providing the ability to

//switch on the AC

lightStatus[room] = 1; //setting the light (AC) status

roomTimer[room] = millis()/1000; //setting the timer

}

}

else if(switchState[readSw] == 0){ //if a door is opened and the master

//relay is on

currentTime = millis()/1000; //setting time reference

endTime = currentTime - roomTimer[room]; //calculating the inactive time

if(endTime >= delayTime[room]){ //comparing inactive time with

//delay time

lightOutput[room] = 0; //cancelling ability to switch on the

//AC

lightStatus[room] = 0; //resetting the light (AC) status

roomTimer[room] = 0; //resetting the timer

}

}

}

return lightOutput[room];

}

If you had a closer look to the code already you might have noticed, that again, I sneaked another function in, get_ac_period(). This function goes right under the ac_read() function.


//function to return the current time period of the year

byte get_ac_period(){

int i = 0; //declare the counter

for(i=0; i<4; i++){ //loop through the array

//and compare the settings with the current month

//if the current month is found with in a defined

//limit break the loop and return the counter at the moment of breaking

if(currentMonth >= ac_period[i][0] && currentMonth <= ac_period[i][1]) break;

}

return i; //return the counter

}

Lets see, what's going on in the ac_read() function:
First thing we do is to check in which season we are with the following function call.
byte period = get_ac_period();
get_ac_period returns a place holder for the room timers to determine the time settings for the current season.
Next we check if a switch on time was set (overrides the master relay) with
if(ac_forced_on[room-10][0] != 99 && checkOnTime(room_timers[room][period][0], room_timers[room][period][1],
room_timers[room][period][2], room_timers[room][period][3]) == 1)
and set a priority status accordingly.
From here we go through a few if-statements to check if the AC is allowed to run and or if it has to be switched on

with the master relay active and the “forced switch on” set to off:
The AC unit will be able to run (depending on AC internal settings) within the time limits defined in the seasonal timer. Soon as the door switch activates the master off, all running AC units will switch off with the master relay and depending on the AC internal settings, come back on, if within the seasonal time limits soon as the master relay comes back on.

With the master relay active and the “forced switch on” set to on:
The AC unit will be able to run (depending on AC internal settings) within the time limits defined in the seasonal timer. Soon as the door switch activates the master off, all running AC units will switch off with the master relay. Depending on the AC internal settings, the AC comes back on at the in “forced switch on” defined time, overriding the master relay.

With the master relay bypassed and the “forced switch on” set to on of off:
The AC unit run (depending on AC internal settings) within the time limits defined in the seasonal timer, no matter the state of the master relay or the “forced switch on” settings.

The current code for the AC will be the default mode 2, controlling the AC unit using the units switch (not momentary switch) or the AC-units AUTO restart ability.

In the next post we will implement a simple temperature control and take care of the code for mode 1, using the read switches only for AC control.

No comments:

Post a Comment