Translate

Tuesday 29 April 2014

Room Management System – Cleaning up the sketch for Menu

Since I had a few days now calculating and playing around with the program memory I found out, that it will be close to squeeze everything on the Atmega 328. The first step to get it done is to do a little “house keeping”. Since I started the project with just a simple task, making lights go on and off using PIR's and time delays it was growing quite a bit, adding the RTC, the automatic switch mode while the house is vacant and now we try to build a menu on top. Before we start, with the final task, we need to free up some memory, both, program memory and RAM.

First we have a closer look at our sketch where we check the various PIR's and priority switches to determine if a light is to be on or off and we find, that we repeat the same code for every room. That's a call for packing it into a function.

There for we go into the main loop of the sketch and find the part where it says
 “ //////////////////room lights//////////////////////////////” In my sketch it's currently line 885 but that may vary depending on your commenting and the amount of Serial.print statements for debugging.

Here we find the following code:

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
}

and replace it with:

check_master(0);

Resetting the master timer which we do for every set of PIR's no goes into the function called check_master(switch Number) from switchState[switch Number].

Now we go down to the far end of the sketch and write the function:

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

We find the same peace of code for the next room :

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
}

and replace it with:

check_master(2);

We do the same thing with all the rooms. Please make sure, that the numbers switchState[switch Number] and the function call check_master[switch Number] match and you use the “switch Number” from the switchState[] you are replacing and not the one from the following code. The following statement in the first 4 rooms is checking the priority switch and not the PIR's.
That wasn't so hard I guess. Now since we got into changing things again, we come to the more difficult part. We put the whole statement where we determine if a light has to be switched on or not into a function.

There for we need to find the part in our sketch where it says:

&& outsideOnTime == 1){
lightOutput[15] = 32768;                 //switching on the lights
}
else {
lightOutput[15] = 0;                        //no matches, they switch off
}
//////////////////room lights//////////////////////////////
check_master(0);                           //check if door switch was activated room 1 (bed1)

//Starting from here, the whole part until “switchState1Old = switchState[1]; “ has to go – but stop, //don't delete it right away cause we use it again to build our function.

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 relay 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

The whole mentioned part we replace with:

check_light_P(0, 1, 0, 1);                                                 //check status room 1 (bed 1)


check_light_P() is our function call. Don't worry about yet, we will build the function in a minute. The first number we are passing to the function is the place in the switchState[] - array holding the variable assigned to the pir switch state for that room. (0 for room bed 1, 2 for bed 2, 4 for bed 3, 6 for living, 8 for bath 1, 9 for bath 2, 10 for bath 3 and so on. The second number is the place in the switchState[] - array holding the variable assigned to the priority switch for that room (1 for priority bed 1, 3 for priority bed 2, 5 for priority bed 3 and 5 for priority living. The third number is the place in various arrays holding variables direct assigned to the room like light status, room timer etc. (0 = room 1, 1 = room 2, 2 = room 3, …) and the last number is the light output command for the particular room representing the integer of a binary controlling the output shift register.

Now we take the part we just cut and go all the way down again, right to the end of our sketch and build the function. First thing we paste the replaced part at the very end of the sketch.
First we add:

void check_light_P(byte pir, byte prio, byte room, unsigned long light){ //adding the function entry

//before we do anything else, we go to the bottom of the sketch and close the function with a “}”.
//The variable pir is the place holder of the space in the switchState array for the room we want
// to process. Now careful because the first 4 rooms have to switchState variables, one for the
// PIR's and one for the priority switch. The first is the one for the PIR the second for the priority
//switch. The first one is “0”. Where ever it reads switchState[0] in the function, we replace the 0
//with pir so it reads switchState[pir]. The second switchState variable we are using is
//switchState[1]. Where ever in the function we find switchState[1] we replace the “1” with prio so
//it reads switchState[prio]. The next variable addresses everything in arrays related direct to the
//room like lightOutput[0], lightStatus[0], roomTimer[0] etc. There we replace the “0” with room so
//it reads lightOutput[room], lightStatus[room], roomTimer[room]...
//The last thing we need to change is the lightOutput. After you made all the other changes, you will //find two statements lightOutput[room] = 1;. This two statements have to change to //lightOutput[room] = light;


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 relay 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];
}                                                                          //closing the function


You found everything, - great, to confirm, below you have the complete function with all the changes.

void 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 relay status
roomTimer[room] = millis();                                                    //setting the timer
}
else if(switchState[pir] == 0 && lightStatus[room] == 1) {         //the PIR not activated but the
                                                                                             //lights are on
//Serial.println("We are checking the timer");                             //Debug only
currentTime = millis();                                                           //setting time reference
endTime = currentTime - roomTimer[room];                           //calculating the inactive time
if(endTime >= delayTime[room]) {                                         //comparing inactive time with
                                                                                          //allowed delay time
//Serial.println("Time is up switching off the lights");               //Debug only
lightOutput[room] = 0;                                                         //switching off the lights
lightStatus[room] = 0;                                                          //resetting the light status
roomTimer[room] = 0;                                                         //resetting the room timer
}
}
}
else if(switchState[prio] == 1 && lightStatus[room] == 1
&& switchState1Old != 1) {                                               //if priority is activated and the
//lights are on
//Serial.println("Priority switch activated switching off the lights"); //Debug only
lightOutput[room] = 0;                                                       //switching off the lights
lightStatus[room] = 0;                                                        //resetting the light status
roomTimer[room] = 0;                                                       //resetting the room timer
priorityStatus[room] = 1;                                                    //setting the priority status bed 1
}
else if(switchState[prio] == 1 && lightStatus[room] == 0
&& switchState1Old != 1) {                                              //if priority was activated and the
//lights are off
//Serial.println("Priority switch deactivated switching on the lights"); //Debug only
lightOutput[room] = light;                                                 //switching on the lights
lightStatus[room] = 1;                                                      //setting the light status
roomTimer[room] = millis();                                             //setting the room timer
priorityStatus[room] = 0;                                                  //setting the priority for bed 1 back 
                                                                                      //to 0
}
switchState1Old = switchState[prio];                                 //passing on the switch state
}

And we are back up in the main loop where it says:

//////////////////room lights//////////////////////////////
check_master(0);                      //check if door switch was activated room 1 (bed1)
check_light_P(0, 1, 0, 1);          //check status room 1 (bed 1)
check_master(2);                      //check if door switch was activated room 2 (bed 2)

//Next we replace the following part including switchState3Old = switchState[3]; with

//check_light_P(2, 3, 1, 2); //check status room 2 (bed 2)


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 relay 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];

The same we do with the next two rooms including the living room, so the part below reads like:

//////////////////room lights//////////////////////////////
check_master(0);                 //check if door switch was activated room 1 (bed1)
check_light_P(0, 1, 0, 1);     //check status room 1 (bed 1)
check_master(2);                 //check if door switch was activated room 2 (bed 2)
check_light_P(2, 3, 1, 2);     //check status room 2 (bed 2)
check_master(4);                 //check if door switch was activated room 3 (bed 3)
check_light_P(4, 5, 2, 4);     //check status room 3 (bed 3)
check_master(6);                //check if door switch was activated room 4 (living)
check_light_P(6, 7, 3, 8);      //check status room 4 (living)
check_master(8);                //check if door switch was activated room 5 (bath 1)
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 relay status
roomTimer[4] = millis();      //setting the room timer
}

If you didn't catch up with everything don't worry to much. There will be quite a few changes now and before we start building the menu, I prepare and post a full code again with all valid changes.

No comments:

Post a Comment