Translate

Sunday 13 April 2014

Room Management System - Switching some lights while on vacation - Photocell update


I had to do some changes in the “Holiday switching” part of the room management system due to stability problems. Since I have implemented the the analogue smoothing algorithm in my last post, which was working perfect on the experimental unit on my desk, in a real life test the system became unstable after 2 days. So I got back to the thinking and experimenting state.
However, after removing the analogue smoothing and making a few changes in the photocell processing it works perfectly
If you do encounter the same problems, here are the changes I made:


First, I added a variable to program a switching limit to the photocell processing part.

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

///////////Timer and Sensitivity Settings to be changed to individual needs////////////////
unsigned int sensitivity = 500;              //should be between 200 and 1000 as
                                                        //lower the number as more responsive
                                                        //the system will be
//>>>>>Added a switching limiter to the photo cell controls<<<<<<<<<<<<<<<<<<<<<<<<
unsigned int photoCellCutOn = 320;     //var holding the switching limit for the photocell
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
unsigned int photoCellCutOff = 280;    //var holding the value where the photocell cuts off
unsigned int photoOutsideOn = 220;    //var holding the value which the photocell reading
unsigned int photoOutsideOff = 260;
unsigned int hourOutsideOff = 23;       //var holding the time (full hours) in which the lights have
                                                        //to switch off
unsigned int minuteOutsideOff = 30;    //var holding the time (minutes) in which the lights
                                                        //have to switch off

Second, I added some more variables for time and date for further development, a variable to check the previous switch command from the photocell and a array holding the names of the weekday to replace the weekday index. The variables used for smoothing can be removed since we are not using them any more.


byte room4Lights = 0;
byte room5Lights = 0;
byte room6Lights = 0;
byte room7Lights = 0;
byte room8Lights = 0;
byte room9Lights = 0;

byte currentHour = 0;             //var holding the time (hour 0-23)
byte currentMinute = 0;          //var holding the time (minute 0-59)
byte currentDay = 0;              //var holding the date (day 1-31)
//>>>>>>>>>>>>>>>>>Added time variables<<<<<<<<<<<<<<<<<<<<<<
byte currentDoM = 0;            //var holding the weekday (Sun - Sat, 1-7)
byte currentMonth = 0;          //var holding the date (month 1-12)
int currentYear = 0;                //var holding the year (based on Unix time)
//>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

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

//>>>>>>>>following 3 var's can be removed<<<<<<<<<<<<<<<<<<<
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
//>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<

//>>>>>>>>>>>>>>>>Added var to check previous switch command<<<<<<<<<<
byte photocellSwitchOld = 0;   //switch command from the previous pass
//>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<

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

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


Third, we move down, into the main loop, to where it says “//checking the light status//”. There we need to remove the following statements:

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

//>>>>>>>>>>>>>>to be removed<<<<<<<<<<<<<<<<<<<<<<<<<<
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
//>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

This statement is to be replaced by the following:


//////////////////checking the light status//////////////////////
//>>>>>>>>>>>>>replacement starts here<<<<<<<<<<<<<<<<<
if(analogRead(lightSensor) > 0 &&
analogRead(lightSensor) < 1024){          //checking if the reading
                                                          //is within the sensor limits
int reading[10] = {0};                           //declaring a local var to hold
                                                          //the readings
for(int i=0; i<10; i++){                          //take 10 readings
reading[i] += analogRead(lightSensor);
}
                                                          //average the readings
sensorValue = (reading[0] + reading[1] + reading[2] + reading[3] +
reading[4] + reading[5] + reading[6] + reading[7] +
reading[8] + reading[9]) / 10;
}
else {
sensorValue = 0;                        //if something goes wrong switch on the lights anyway
}
//>>>>>>>>>>>>>>>replacement ends here<<<<<<<<<<<<<<<<<<<<<<<<<<

Serial.print("Sensor value: ");
Serial.println(sensorValue);

From here we move down just a bit to where it says “//processing the input//”. There we also need to make a couple of modifications:

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

//>>>>>>>remove the following two lines<<<<<<<<<<<<<<<<<<<<<<<<<<<
photocellSwitch = getSensorValue(sensorValue,  //function call to check
photoCellCutOff);                                            //if light level is within
                                                                     //switching limits
//>>>>>>>>>>>>and replace with<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
photocellSwitch = getSensorValue(sensorValue, photoCellCutOff, //function call to check
photoCellCutOn, photocellSwitchOld);                                       //if light level is within
                                                                                             //switching limits
photocellSwitchOld = photocellSwitch;                                      //remember the switch state
//>>>>>>>>>>>>>replacement ends here<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

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

if(switchState[20] == 1) {           //check if the holiday switch


From here we move down to the end of our sketch where we have been writing all the functions and there we remove the following completely:
//>>>>>>>>>>>>to be removed<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//function to smooth analogue readings
//the analogue smoothing algorithm 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;
}
//>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

If this is done, we go back to the function “byte getSensorValue()”. Please replace the function with the following. The name of the function stays the same, just the content changed a bit:

//>>>>>>>>>>>>>>>>replacement getSensorValue() function<<<<<<<<<<<<<<<<
byte getSensorValue(int sensorReading, int switchValue,
int switchLimit, byte switchStatus){
byte onStatus = 0;
if(switchStatus == 0){                   //checking if the last state was off
if(sensorReading <= switchValue){  //checking if the reading is going 
                                                   //past the switch value
onStatus = 1;                                //set to 1 if it does
}
else if(sensorReading > switchLimit){ //check if the reading is above the set limit
onStatus = 0;                                    //set to 0 if it does
}
else if(sensorReading > switchValue &&  //covering the reading between switch
sensorReading <= switchLimit){            //value and limit
onStatus = 0;                                        //set to 0 if within
}
}
else if(switchStatus = 1){                   //if the last state was on
if(sensorReading <= switchValue){      //if the reading is below the switch value
onStatus = 1;                                    //set to 1
}
else if(sensorReading > switchValue &&  //if the reading is between switch
sensorReading <= switchLimit){             //value and limit
onStatus = 1;                                        //set to 1
}
else if(sensorReading > switchLimit){     //if the reading goes above the limit
onStatus = 0;                                       //set to 0
}
}
return onStatus;
}
//>>>>>>>>>>>>>>>>>>End of replacement<<<<<<<<<<<<<<<<<<<<<<


I know, that little issue delays the post of the complete sketch a bit but I am nearly there. However, if you are not experiencing any problems like a unstable system or the lights start switching kind of randomly, you do not have to do this changes. The smoothing function still gives a more stable reading than the averaging over 10 sensor readings. It might also be possible to leave the smoothing function and just change the getSensorValue() function. Than you can leave everything as is except you have to add variable for the switching limit and the one remembering the previous photocellSwitch state and of course the replacement for the getSensorValue() function.

No comments:

Post a Comment