Translate

Tuesday, 8 April 2014

Room Management System – Part 4 of Switching some lights while on vacation


As promised, today we take care of the photocell readings. If you have experimented with the photocell before and you have done one of the basic Arduino tutorials reading the analogue pin connected to it you may have noticed that the reading are jumping quite a bit. In my case they are going up and down 50 units with a constant light source and that is not very helpful while we want to switch something on or off when the light reaches a specific level. Trying to get a clear switching point specially at dusk and dawn with variable cloud conditions make the lights switch on and off a few times until the reading doesn't go above ore below the switching point. Even programming a buffer didn't help much it just moved the “not knowing what to do effect” to the upper and lower limits of the buffer. Than I came across some very useful Analogue Smoothing Algorithm by Tom Igoe which I liked a lot and it nearly solved the problem but still there where a 2 to 3 kind of ghost switchings until the system was stable.
What I came up with next, was checking the photocell reading, make sure they are within a predefined limit and flag the effected rooms, meaning as long as they are set to 1 and are within the time frame, the lights will switch on no matter of change of light conditions or sensor readings. Soon as the time limit is reached the lights will switch off and the light sensor flag will reset to 0.
There where still some issues with time delays in lights switching specially when we have more than 2 timers for a room. Implementing the “Analogue Smoothing Algorithm” from Tom Igoe finally brought enough accuracy to stop lights from coming on and off a couple of times before everything got settled.
For normal operation where we also partly depend on a photocell to determine if it's dark enough to switch the lights ore not, implementing the smoothing algorithm gives already enough accuracy since we are also using a time delay. 10 to 15 minutes should be enough to stabilize the light level either way on or off, since we don't have to deal with a up to 50 points jumping values.

Let's have a look at the sketch.

As usual, we start with a few additional variables and there for we go to the declaration part at the end of “//////////////all the other variables/////////////////////”:

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;
byte currentMinute = 0;

//>>>>>>>>>>>>addition starts here<<<<<<<<<<<<<<<
byte lightLevel[17] ={0};                 //array holding the light
                                                       //level flag value for each room
byte photocellSwitch = 0;                //check if the reading
                                                       //within a switching limit
int smoothed = 0;                            //var for the smoothed analogue reading value
int alpha = 4;                                   //the number of past samples to average
int sensor = 0;                                 //the photocell reading
//>>>>>>>>>>>>>>addition ends here<<<<<<<<<<<<<<<<<<<<<

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


From here we move down in to the main loop and find “////checking the light status//////” where we add:


//////////////////checking the light status//////////////////////

//>>>>>>>>>>>>>>addition starts here<<<<<<<<<<<<<<<<<<<<<<<<<<
alpha = (analogRead(1) / 114) + 1;           //creating alpha by
                                                                //reading a trim pot 
                                                               //on Arduino pin A1
sensor = analogRead(lightSensor);           //reading the photocell
sensorValue = smoothValue(sensor);        //function call to smooth the actual reading 

//if you have some problems with adjusting the light sensor,
//or you just want to know what's going on,
//uncomment the following print statements

//Serial.print("alpha, sensor, Sensor value: ");     //debug only
//Serial.print(alpha);                                          //debug only
//Serial.print(" : ");                                             //debug only
//Serial.print(sensor);                                        //debug only
//Serial.print(" : ");                                             //debug only
//Serial.println(sensorValue);                             //debug only

//////////////////processing the input/////////////////////

//Serial.print("Light level room 1: ");                  //debug only
//Serial.println(lightLevel[0]);                            //debug only
//Serial.print("Light level room 4: ");                 //debug only
//Serial.println(lightLevel[3]);                           //debug only
photocellSwitch = getSensorValue(sensorValue, //function call to check
photoCellCutOff);                                          //if light level is within
                                                                     //switching limits
//>>>>>>>>>addition ends here<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

//////////////Holiday lighting/////////////////////////

if(switchState[20] == 1) {                       //check if the holiday switch
                                                              //is activated
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
}


//>>>>>>>>>>>>addition starts here again<<<<<<<<<<<<<<<<<

//Double check if we are within permitted switching limits
//and flag the areas where lights being switched,
//to prevent lights from switching on and off when the
//light level is at the switching limit
//covering the time from evening to midnight 

if(photocellSwitch == 1 && currentHour >= 17 && currentHour <= 23) {
for(int i=0; i<9; i++){
lightLevel[i] = 1;
}
lightLevel[15] = 1;
}
//covering the time from midnight until morning
else if(photocellSwitch == 1 && currentHour >= 0 && currentHour <= 8){
for(int i=0; i<9; i++){
lightLevel[i] = 1;
}
lightLevel[15] = 1;
}

//if it's morning and the light level comes above the limit
//we make sure, the lights switch off
else if(photocellSwitch == 0 && currentHour >= 5 && currentHour <= 8){
for(int c=0; c<17; c++){
lightLevel[c] = 0;
}
}

//Again, if you would like to see what's going on,
//just uncomment the following serial print statements

//Serial.print("Light level room 1 after: ");       //debug only
//Serial.println(lightLevel[0]);                         //debug only
//Serial.print("photocell switch: ");                  //debug only
//Serial.println(photocellSwitch);                    //debug only
//Serial.print("Light level room 3 after: ");       //debug only
//Serial.println(lightLevel[2]);                         //debug only
//Serial.print("Light level room 4 after: ");       //debug only
//Serial.println(lightLevel[3]);                         //debug only
//>>>>>>>>>>addition ends here<<<<<<<<<<<<<<<<<<<<

///////Room 1 (Bed 1) /////////////

Now we need to implement the lightLevel[n] value in the statements where we check if the lights are to be switched on or not. There for we just go down a little further to the single rooms. Let's have a look at room 1:
///////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]);
}
//>>>>>>>>>>>>>>>>>>>>>>>>>>here we have to add<<<<<<<<<<<<<<<<<<<<
//in the if-statement below we currently check only
//if one of the timers is activated now we need to check
//if we hit the defined light level to switch on or off the lights.
//So we have to put that little addition in the if-statement
//“ && lightLevel[0] == 1”

if(room1Lights == 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;
}

//The above statement reads like that after the addition:
if(room1Lights == 1 && lightLevel[0] == 1){       //if within the on time
lightOutput[0] =1;                                                 //switch on the lights
}
else {
lightOutput[0] = 0;                  //other keep them off
lightLevel[0] = 0;                    //resetting the light level
}
////////Room 2 (Bed 2)//////////////

The same thing we have to do now for every single room where we want to check for light levels. In that process, I also modified the code for the outside lights a bit. Lets just go down to the point “ ////////Outside lights////////////////////” and there we need to change the following statement

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
}
to this:
if(outsideOnTime == 1 && lightLevel[15] == 1){
lightOutput[15] = 32768;
}
else {
lightOutput[15] = 0;
lightLevel[15] = 0;
}

You are still with me? Good, we are nearly done for today. We just need to add a couple of functions to make it work. Now we go all the way down to the bottom of our sketch:


//function to give the photo cell reading a switching range
//and compare it with the preset switch value
//returns 1 if within and 0 if not

byte getSensorValue(int sensorReading, int switchValue) {
byte onStatus = 0;
if(sensorReading <= (switchValue + 25)){
onStatus = 1;
}
else if(sensorReading < (switchValue + 50)){
onStatus = 0;
}
else {
onStatus = 0;
}
return onStatus;
}

The entry is the smoothed sensor reading (sensorReading) and the preset switch value (switchValue). The variable onStatus holds the final return value. In the first if-statement we check if the reading hits the switch value and switch on anyway even if the reading is 25 points higher. The next if-statement covers the jumping around the limits and keeps the lights off and finally if nothing else matches it is assumed that the lights should be off.

Finally we look at the smoothing function:

//function to smooth analog readings
//the analog smoothing algorythm was original
//written by Tom Igoe

int smoothValue(int rawValue){
  if(rawValue > smoothed) {
    smoothed = smoothed + (rawValue - smoothed) / alpha;
  }
  else {
    smoothed = smoothed - (smoothed - rawValue) / alpha;
  }
  return smoothed;
}

I know, it's a lot to update and I am still working on the complete code with all the current updates to make it a little easier to follow all the changes. 
 
One thing is left to do. We need to add a trim potentiometer to our breadboard to get a reference point for smoothing of analogue readings. I used a 100K potentiometer with one pin connected to 5V and the centre pin to pin 24 (A1) of the Atmega chip. I adjusted the reading to approximately to the switching value of the lights to get the best results.


Sunday, 6 April 2014

Room Management System – Part 3 of Switching some lights while on vacation


Today we will be taking care of a simple way to activate or deactivate time settings in the variable declaration part. And add photocell checking to our switch commands so we don't need to reprogram the timers every time the season changes. We just leave the time frame set for the days with the least day light time and run the switching command through a photocell reading so in summer the lights don't switch on before it is getting dark. Now it has to be dark and within the time frame to switch the lights.

Lets start with activating and deactivating single time settings. Again we start at the declaration part of our sketch and find the following lines where we add:

//////////////////////holiday timer settings//////////////////////

////////////Room 1 (Bed 1) ///////////

//>>>>>>>>>>addition starts here<<<<<<<<<<<<<<<<<<<<<<<<<
byte room1MActive = 1;                       //Set to 1 if you want to process
                                                             //Timer will be ignored when set to 0
//>>>>>>>>>>addition ends here<<<<<<<<<<<<<<<<<<<<<<<<<<<

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

//>>>>>>>>>>addition starts here<<<<<<<<<<<<<<<<<<<<<<<<<<
byte room1O1Active = 1;                      //Set to 1 if you want to process
                                                             //Timer will be ignored when set to 0
//>>>>>>>>>>addition ends here<<<<<<<<<<<<<<<<<<<<<<<<<<<

unsigned int room1On1[2] = {19, 35};  //Time to switch on the lights
unsigned int room1Off1[2] = {20, 15};  //Time to switch off the lights

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

////////////Room 2 (Bed 2) ///////////
unsigned int room2OnM[2] = {6, 30};    //Time to switch on the lights
unsigned int room2OffM[2] = {6, 50};    //Time to switch off the lights

We declare a variable for each timer setting like “room1MActive” for the morning switching time, “room1O1Active” for the first evening switching time of room 1, “ room1O2Active” for the second evening switching time of room 1 and set it to 1 if we want the time to be processed and to 0 if we want it to be ignored. This we do for every timer setting in each room and than we move down to the main loop again and find “////processing the input////” and “//////holiday switching/////”. There we add:

//////////////////processing the input/////////////////////
//////////////Holiday lighting/////////////////////////
if(switchState[20] == 1) {          //check if the holiday switch
                                                 //is activated
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
}

///////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){                                        //if with in the on time
lightOutput[0] =1;                                              //switch on the lights
}
else {
lightOutput[0] = 0;                                           //other keep them off
}
////////Room 2 (Bed 2)//////////////

Here we add to the if-statements where we check if we are within the time frame to activate the timer.
if(currentHour >= room1OnM[0] &&
currentHour <= (room1OffM[0] + 1)){                      //checking if we came passed
                                                                                 //the hour where the lights
                                                                                 //to be switched on

Right in the beginning of the if-statement we add “room1MActive == 1 &&”. Now the statement is also checking if the “active” variable is set to 1 and the complete statement looks like this:

if(room1MActive == 1 && currentHour >= room1OnM[0] &&
currentHour <= (room1OffM[0] + 1)){                           //checking if we came passed

We do the same thing with every timer all the way down to room 9.

I know, quite a bit a typing, but it makes the unit a little more flexible. If you want to use the same unit in a different house or flat where you don't have windows in the bathroom or in the kitchen for example, than there is no point in switching on the lights when nobody can see it. Instead of going through the whole sketch and start commenting things out or deleting parts, you just need to change the “active status” in the declaration part from 1 to 0 and you are done.

On this part I was planing to implement the photocell reading to limit the time where the lights are switched to times when they are needed to be on. Getting the readings of a photocell right on a desk with artificial light is quite easy but running the experiment in the garden with light levels constantly changing is a bit of a challenge I found. Got to say, I've learned quite a bit experimenting the last couple of days. Share all my experiments, findings and thoughts, I decided to do all this in the next post.

Saturday, 5 April 2014

Room Management System – Part 2 of Switching some lights while on vacation


In the last post we took care of the bedrooms and the living area. Our first task today is to add a few more statements, taking care of the bathrooms and the kitchen. There fore, we start at the declaration part of our sketch and where we have been defining the times when to switch on and off a light in a particular room, we add:

///////////Room 4 {Living)
unsigned int room4On[2] = {17, 30};           //Time to switch on the lights
unsigned int room4Off[2] = {23, 30};           //Time to switch off the lights

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

//////////Room 5 (bath 1)//////////
unsigned int room5On[2] = {19, 55};
unsigned int room5Off[2] = {20, 10};

//////////Room 6 (bath 2)//////////
unsigned int room6On[2] = {19, 50};
unsigned int room6Off[2] = {20, 05};

//////////Room 7 (bath 3)//////////
unsigned int room7On[2] = {22, 50};
unsigned int room7Off[2] = {23, 15};

//////////Room 8 (bath 4)//////////
unsigned int room8On[2] = {22, 5};
unsigned int room8Off[2] = {22, 20};

//////////Room 9(Kitchen)//////////
unsigned int room9On[2] = {17, 45};
unsigned int room9Off[2] = {18, 30};

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

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

I think it's pretty self explaining but still a few words what's going on.
The room(n)On[2] array holds to 2 numbers. For example {17, 45} would mean the lights would switch at 17:45 h. The first value in the array is always the hour in 24 hour time format from 0 to 23. The second value indicates the minutes from 0 to 59.
room9On[2] = {17, 45}; Setting the time to switch on the lights of room 9 to 17:45 h
room9Off[2] = {18, 30}; Setting the time to switch off the lights of room 9 to 18: 30h

From here we go further down, again to the end of our declaration part:


byte room1Lights = 0;        //light on – off command for room 1
byte room2Lights = 0;        //light on – off command for room 2
byte room3Lights = 0;        //light on – off command for room 3
byte room4Lights = 0;        //light on – off command for room 4

//>>>>>>addition starts here<<<<<<<<<<<<<<<<<<<<<<<<<<<
byte room5Lights = 0;        //light on – off command for room5
byte room6Lights = 0;       //light on – off command for room 6
byte room7Lights = 0;       //light on – off command for room 7
byte room8Lights = 0;       //light on – off command for room 8
byte room9Lights = 0;       //light on – off command for room 9
//>>>>>>>>addition ends here<<<<<<<<<<<<<<<<<<<<<<


byte currentHour = 0;
byte currentMinute = 0;
byte currentDay = 0;

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

Serial.begin(9600);

The variable room(n)Lights is holding only 0 for the lights have to stay off or 1 for “Yes we are with in the time limits”, the lights can be switched on.

From here we make our way down again in to the main loop in the part where it says “Holiday lighting”. There we carry on after “/////////room 4////////”.

////////Room 4 (living)/////////////////////
if(currentHour >= room4On[0]){
room4Lights = checkOnTime(room4On[0], room4On[1], room4Off[0], room4Off[1]);
}
if(room4Lights == 1){
lightOutput[3] = 8;
}
else {
lightOutput[3] = 0;
}
//>>>>>>>>>>>>>addition starts here<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
////////Room 5 (Bath 1)/////////////////////
if(currentHour >= room5On[0]){
room5Lights = checkOnTime(room5On[0], room5On[1], room5Off[0], room5Off[1]);
}
if(room5Lights == 1){
lightOutput[4] = 16;
}
else {
lightOutput[4] = 0;
}
////////Room 6 (Bath 2)/////////////////////
if(currentHour >= room6On[0]){
room6Lights = checkOnTime(room6On[0], room6On[1], room6Off[0], room6Off[1]);
}
if(room6Lights == 1){
lightOutput[5] = 32;
}
else {
lightOutput[5] = 0;
}
////////Room 7 (Bath 3)/////////////////////
if(currentHour >= room7On[0]){
room7Lights = checkOnTime(room7On[0], room7On[1], room7Off[0], room7Off[1]);
}
if(room7Lights == 1){
lightOutput[6] = 64;
}
else {
lightOutput[6] = 0;
}
////////Room 8 (Bath 4)/////////////////////
if(currentHour >= room8On[0]){
room8Lights = checkOnTime(room8On[0], room8On[1], room8Off[0], room8Off[1]);
}
if(room8Lights == 1){
lightOutput[7] = 128;
}
else {
lightOutput[7] = 0;
}
////////Room 9 (kitchen)/////////////////////
if(currentHour >= room9On[0]){
room8Lights = checkOnTime(room9On[0], room9On[1], room9Off[0], room9Off[1]);
}
if(room9Lights == 1){
lightOutput[8] = 256;
}
else {
lightOutput[8] = 0;
}
//>>>>>>>>>>>>>>>>>>>addition ends here<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
////////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
}
}
else {


For now we have been only looking into light switching in the evening. For everybody getting usually up early in the morning, there might be a need for doing a few lights also in the morning.

Lets start again with the bedrooms. Children have to catch the school bus in the morning and they leave usually quite early. We go back to the time declarations and add under Room 1:

//////////////////////holiday timer settings//////////////////////

////////////Room 1 (Bed 1) ///////////
//>>>>>>>>>addition starts here<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
unsigned int room1OnM[2] = {5, 35};                //Time to switch on the lights
unsigned int room1OffM[2] = {6, 15};                //Time to switch off the lights
//>>>>>>>>>addition ends here<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
unsigned int room1On1[2] = {19, 35};               //Time to switch on the lights
unsigned int room1Off1[2] = {20, 15};               //Time to switch off the lights

The bathroom to bedroom 1 is room 5. Let's switch on the lights in the bathroom as well for a few minutes. There fore we find the time declarations for room 5 and add:

///////////Room 4 {Living)
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)//////////
//>>>>>>>>>>>>>>>>>>>addition starts here<<<<<<<<<<<<<<<<<<<<<<<<
unsigned int room5OnM[2] = {5, 40};
unsigned int room5OffM[2] = {5, 45};
//>>>>>>>>>>>>>>>>>>addition ends here<<<<<<<<<<<<<<<<<<<<<<<<<
unsigned int room5On[2] = {19, 55};
unsigned int room5Off[2] = {20, 10};

//////////Room 6 (bath 2)//////////

While the lights go off in the bathroom, some action in the kitchen starts. So we add to room 9:

//////////Room 8 (bath 4)//////////
unsigned int room8On[2] = {22, 5};
unsigned int room8Off[2] = {22, 20};

//////////Room 9 (Kitchen)//////////
//>>>>>>>>>>>>>>>>>>>>>addition starts here<<<<<<<<<<<<<<<<<<<<<<<
unsigned int room9OnM[2] = {5, 50};
unsigned int room9OffM[2] = {6, 45};
//>>>>>>>>>>>>>>>>>>>>>addition ends here<<<<<<<<<<<<<<<<<<<<<<<
unsigned int room9On[2] = {17, 45};
unsigned int room9Off[2] = {18, 30};
////////////////////////////DO NOT MODIVY BELOW HERE///////////////////////////////////////

From here we move down again to the main loop in the part where we process the holiday lighting. We start off with room 1:

//////////////Holiday lighting/////////////////////////
if(switchState[20] == 1) { //check if the holiday switch
//is activated
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
}
///////Room 1 (Bed 1) /////////////

//>>>>>>>>>>>>>>>>>>>>>addition starts here <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
if(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(room1Lights == 1){                                      //if with in the on time
lightOutput[0] =1;                                            //switch on the lights
}
else {
lightOutput[0] = 0;                                            //other keep them off
}
//>>>>>>>>>>>>>>>>>>>addition ends here<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
if(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(room1Lights == 1){                             //if with in the on time
lightOutput[0] =1;                                   //switch on the lights
}
else {
lightOutput[0] = 0;                                 //other keep them off
}


You may have noticed a little change in the processing code. Up until now we where only checking if we passed the hour where the light have to be switched on to do the further processing which was OK as long as we where only switching the lights in the evening. Since we switch on lights in the morning as well, we restrict the time for further processing with in the switch on and off time. That means, we have to change the if-statement “if(currentHour >= room1OnM[0] ) {“. We just add “&& currentHour <= (room1OffM[0] + 1)”. We have to add 1 hour to the switch off hour since we have to account for anything from 0 to 59 minutes past the indicated switch on hour. Now the if-statement looks like “if(currentHour >= room1OnM[0] && currentHour <= (room1OffM[0] +1))”.
We do this change with all this statements in the holiday switch processing part. Please take care to get the numbers right. If the on hour is room1On1[0] the off hour has to be room1Off1[0].

OK, done?

Than we move down to room 5 and add:

////////Room 5 (Bath 1)/////////////////////
//>>>>>>>>>>>>>>addition starts here<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
if(currentHour >= room5OnM[0] && currentHour <= (room5OffM[0] + 1)){
room5Lights = checkOnTime(room5OnM[0], room5OnM[1], room5OffM[0], room5OffM[1]);
}
if(room5Lights == 1){
lightOutput[4] = 16;
}
else {
lightOutput[4] = 0;
}
//>>>>>>>>>>>>>>>>addition ends here<<<<<<<<<<<<<<<<<<<<<<<<<<<<
if(currentHour >= room5On[0] && currentHour <= (room5Off[0] + 1)){
room5Lights = checkOnTime(room5On[0], room5On[1], room5Off[0], room5Off[1]);

from here we move down to the kitchen (room 9) and to the same:

////////Room 9 (kitchen)/////////////////////
//>>>>>>>>>>>>>>>>>addition starts here<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
if(currentHour >= room9OnM[0] && currentHour <= room9OffM[0] + 1){
room9Lights = checkOnTime(room9On[0], room9On[1], room9Off[0], room9Off[1]);
}
//>>>>>>>>>>>>>>>>>>addition ends here<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
if(currentHour >= room9On[0] && currentHour <= (room9Off[0] + 1)){
room9Lights = checkOnTime(room9On[0], room9On[1], room9Off[0], room9Off[1]);
}
if(room9Lights == 1){
lightOutput[8] = 256;
}
else {
lightOutput[8] = 0;
}

It is pretty simple and I think it is not a big deal to carry on and individually put in the code for the other rooms as needed.

One more thing I have just noticed. Every time I check a timer if the lights have to be on or off, I also pass it on to the actual output command. If we have in 1 room for example the lights switching 5 times, we process the output command also 5 times. We need to do this only once after all the timers have been checked.
I am talking about this part:

if(room9Lights == 1){
lightOutput[8] = 256;
}
else {
lightOutput[8] = 0;
}

Please change your statements as on the following example of room 1.

///////Room 1 (Bed 1) /////////////
if(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]);
}
////>>>>>>>>>>>>>Delete from here<<<<<<<<<<<<<<<<<<<<<<<<
if(room1Lights == 1){                                   //if with in the on time
lightOutput[0] =1;                                         //switch on the lights
}
else {
lightOutput[0] = 0;                                        //other keep them off
}
/////>>>>>>>>>>>>...to here<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
if(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]);
}
//>>>>>>>>>>>>>>>>>Delete from Here<<<<<<<<<<<<<<<<<<<<<<<
if(room1Lights == 1){                               //if with in the on time
lightOutput[0] =1;                                      //switch on the lights
}
else {
lightOutput[0] = 0;                                   //other keep them off
}
//>>>>>>>>>>>>>>>>>to here<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
if(currentHour >= room1On2[0]){               //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]);
}
//>>>>>>IMPORTANT – DO NOT DELETE THE LAST ONE<<<<<<<<<<<
if(room1Lights == 1){                                 //if with in the on time
lightOutput[0] =1;                                       //switch on the lights
}
else {
lightOutput[0] = 0;                                        //other keep them off
}
///////Room 2 (Bed 2) /////////////

Since I have a very busy weekend, I have to delay my plans a little to post a complete updated sketch again. But hopefully some time next week I will manage, since we made quite a few changes and additions since the last full code.
Plans for the next post are a easy way to enable or disable rooms for holiday switching and checking the photocell since there is no need for lights to switch on or off while there is still bright day light, - not even while we are away for a cruise.

Friday, 4 April 2014

Room Management System – Switching on and off some lights while on vacation


I know, it's quite a few days since my last post but I am still working on the possibility of automated adjustment for day light saving time without implementing a huge library and I got the idea of adding a LCD and the ability to change some settings without taking the chip off or connecting the controller to the computer. My idea is still to keep this system independent from any network. While I was building a LCD shield to account for the possibility to run the LCD of a shift register since I am running out of Arduino pins, I found that I am missing a couple of parts, - they are already ordered but I still need to wait until they arrive.
To cut a long weekend story short, I started with the feature to switch on and off some lights while on a caribic cruise.
One way of doing it would have been to let the controller randomly decide which lights to switch on and off which might look nice but it doesn't really make sense to me since everybody has his ow habits of moving around in the house. We for example have an open plan living area. I come home, and soon as it gets dark the lights go on in there and in the kitchen. At latest 19:00h in the kitchen the lights go off and the lights in the living area are usually switched off between 23:00h and 23:30h. Our daughter is usually in her room from 19:00h onwards and she still goes to sleep at around 20:30. Well, the lights may go on in bedroom a couple of times before for a few minutes but that can be taken care of. The only room which is used a little more often and more randomly is the bathroom. The only thing needing to be taken care off is to make sure, that the bathroom lights come on just before bed time. The outside lights stay on the usual timing since the switch on when it gets dark and switch off at a preset time. Since we don't want worry about settings for winter spring, summer and autumn, I will give the program a time frame when to switch on the lights but still run it through a photocell to make sure that in summer the lights are not coming on at six in the afternoon while it's still bright daylight. But again in winter our lights are sometimes on at 5 in the evening.
I know it's a bit of a setting up to do we don't want just switch on and off some lights, we want to give somebody watching the impression that the house is used with all the usual habits while we are away.

First thing to do, we need another switch. That's the least of our worries since we still have 4 free input channels on our CD4021B shift register no 3. If you have a careful look at the following image, I added another switch on top of the long row of switches and buttons. The centre pin is connected to the 5 V supply and the left pin is going to PI5 (pin 13) of the just mentioned shift register.






Now we start with declaring all the variables and there for we go to the top of our sketch at the end of the part where it says “Time and sensitivity settings to be changed individually”.

There we add:

///////////Vacancy Timers/////////////////////
////Room 1 (Bed 1) ///////////
unsigned int room1On1[2] = {19, 35};              //Time to switch on the lights
unsigned int room1Off1[2] = {20, 15};              //Time to switch off the lights

unsigned int room1On2[2] = {21, 5};                //Time to switch on the ;lights
unsigned int room1Off2[2] = {21, 15};              //Time to switch off the lights

////////////Room 2 (Bed 2) ///////////
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) ///////////
unsigned int room3On1[2] = {18, 10};               //time to switch on the lights
unsigned int room3Off1[2] = {18, 25};              //time to switch off the lights

unsigned int room3On2[2] = {19, 15};              //Time to switch on the lights
unsigned int room3Off2[2] = {19, 40};              //Time to switch off the lights

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)
unsigned int room4On[2] = {17, 30};               //Time to switch on the lights
unsigned int room4Off[2] = {23, 30};               //Time to switch off the lights


From here we go down to “void setup()” and just above at the end of our variable declaration we add:

byte room1Lights = 0;                                      //light on – off command for room 1
byte room2Lights = 0;                                      //light on – off command for room 2
byte room3Lights = 0;                                      //light on – off command for room 3
byte room4Lights = 0;                                      //light on – off command for room 4

byte currentHour = 0;                                       //var holding the current time (hour)
byte currentMinute = 0;                                    //var holding the current time (minute)


Now we go way down into the main loop and just below “///////processing the input/////////” we add:

//////////////Holiday lighting/////////////////////////
if(switchState[20] == 1) {                              //check if the holiday switch
                                                                     //is activated
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
}
///////Room 1 (Bed 1) //////////////
if(currentHour >= room1On1[0]){                //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(room1Lights == 1){                                  //if with in the on time
lightOutput[0] =1;                                        //switch on the lights
}
else {
lightOutput[0] = 0;                                       //other keep them off
}
if(currentHour >= room1On2[0]){                //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){                                  //if with in the on time
lightOutput[0] =1;                                        //switch on the lights
}
else {
lightOutput[0] = 0;                                       //other keep them off
}
////////Room 2 (Bed 2)//////////////
if(currentHour >= room2On1[0]){
room2Lights = checkOnTime(room2On1[0], room2On1[1], room2Off1[0], room2Off1[1]);
}
if(room2Lights == 1){
lightOutput[1] = 2;
}
else {
lightOutput[1] = 0;
}
////////Room 3 (Bed 3) ////////////
if(currentHour >= room3On1[0]){
room3Lights = checkOnTime(room3On1[0], room3On1[1], room3Off1[0], room3Off1[1]);
}
if(room3Lights == 1){
lightOutput[2] = 4;
}
else {
lightOutput[2] = 0;
}
if(currentHour >= room3On2[0]){
room3Lights = checkOnTime(room3On2[0], room3On2[1], room3Off2[0], room3Off2[1]);
}
if(room3Lights == 1){
lightOutput[2] = 4;
}
else {
lightOutput[2] = 0;
}
////////Room 4 (living)/////////////////////
if(currentHour >= room4On[0]){
room4Lights = checkOnTime(room4On[0], room4On[1], room4Off[0], room4Off[1]);
}
if(room4Lights == 1){
lightOutput[3] =8;
}
else {
lightOutput[3] = 0;
}
Now we need to make a copy of the part below where we control the outside lights and paste it direct under the part we just added.

////////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
}

Here ends the holiday switch processing. Below HERE WE ADD!

else {
Please don't forget other wise it will only interfere with sensor switching. Another IMPORTANT step is to close our curly bracket. We go down until we find the line

masterSwitchStateOld = switchState[18]; //setting the switchState to old
///////////////////////////Output/////////////////////////////////////////////////

Right after the statement “masterSwitchStateOld = switchState[18]; “ we close the curly bracket so it looks like this:

masterSwitchStateOld = switchState[18];
}
///////////////////////////Output/////////////////////////////////////////////////

In the next article we will add the kitchen ant a couple of bathrooms.