Translate

Friday, 2 May 2014

Room Management System – Cleaning up the sketch for Menu implementation - part 2


Let's do a little more housekeeping before we start to free up some RAM using the program memory. First thing to do today is putting the code taking care of rooms without priority switch into a function. There fore we find again the part where it says”/////room lights////////” and keep on going down to the function call “check_master(8)” and cut the marked part below:

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

delay(5);

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)

delay(5);

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)

delay(5);

check_master(6); //check if door switch was activated room 4 (living)

check_light_P(6, 7, 3, 8); //check status room 4 (living)

delay(5);

check_master(8); //check if door switch was activated room 5 (bath 1)

//>>>>>>>>>>>>>>>>>cut from here<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

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

}

else if(switchState[8] == 0 && lightStatus[4] == 1) { //if no PIR was activated and

//the lights are on

//Serial.println("We are checking the timer"); //Debug only

currentTime = millis(); //setting time reference

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

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

//delay time

//Serial.println("We are switching off the lights"); //debug only

lightOutput[4] = 0; //switching off the lights

lightStatus[4] = 0; //resetting the light status

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

}

}

//>>>>>>>>>>>>>>>>>>>cut ends here<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

We replace the cut out part with the function call:

check_light_N(8, 4, 16);

The first number represents again the space in the switchState[] - array corresponding with the pir in that room. The second number is the space in all directly to the room related arrays and the last number is representing the integer of a binary value controlling the output shift register.
From here we move all the way down to the end of the sketch where we build the next function. You can past the part with you just cut again at the far end of the sketch and add initialisation for the function.
Void check_light_N(byte pir, byte room, unsigned long light){

}

Next we have to replace the space identifiers of the arrays with the imported variables.
Everything switchState[8] becomes switchState[pir],
lightStatus[4], lightOutput[4] and roomTimer[4]
become
lightStatus[room], lightOutput[room] and roomTimer[room],
lightOutput[room] = 16 becomes lightOutput[room] = light;

Below is the function with all the changes made:

void 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 yelay status

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

}

else if(switchState[pir] == 0 && lightStatus[room] == 1) { //if no PIR was activated and

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

//delay time

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

}

}

}

If you upload the revised sketch to your processor, you will notice about a 20 % degrees in program memory use which is very good, since we need some of this space to store the messages being printed on our LCD display.

Let's start packing some of our constants into the program memory. Tu get used to the procedure, we want to extend the standard display a little. Currently the display shows nicely the current time. But we want to display the weekday, day, month and time. The numeric variables from the RTC are in the system anyway since we use them to switch the outside lights and to control the automatic light switching while on vacation. Memory consuming is displaying the weekdays and that's what we pack into the program memory first.

To use the program memory we need a library, which is part of the Arduino IDE. Right on top of the sketch where all our other includes are we add:

#include <avr/pgmspace.h>

From here we move down to the end of our declaration part just before the setup loop and there we add:

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)

byte photocellSwitchOld = 0; //switch command from the previous pass

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

//in the section below we store every single string into the program memory

//prog_char is telling the system that it's receiving a character string

//weekday_0[] is giving it a meaningful name, PROGMEM is the

//command to store it in the program memory and within “” is what we

//need to store

prog_char weekday_0[] PROGMEM = "Sun";

prog_char weekday_1[] PROGMEM = "Mon";

prog_char weekday_2[] PROGMEM = "Tue";

prog_char weekday_3[] PROGMEM = "Wed";

prog_char weekday_4[] PROGMEM = "Thu";

prog_char weekday_5[] PROGMEM = "Fri";

prog_char weekday_6[] PROGMEM = "Sat";

//The next step is, packing everything in a table. Writing it in a column

//is just for readabilety

//PROGMEM again is revering to program storage space.

//const char is the data type weekday_table[] again is a meaningful name

//for the table and in the table the place holders of the initialisation above

PROGMEM const char *weekday_table[] = {

weekday_0,

weekday_1,

weekday_2,

weekday_3,

weekday_4,

weekday_5,

weekday_6

};

//Last thing in our declaration part is to declare a buffer

//large enough to hold the biggest string we stored in the

//program memory.

char buffer[20]; //buffer needed to retrieve data from the

//program memory

//>>>>>>>>>>> addition ends here<<<<<<<<<<<<<<<

void setup() {

//////////////Start Serial for Debugging/////////////////////

//Serial.begin(9600);

lcd.begin(16, 2);

From here we jump down to the part where it reads “//processing the input//” and there we change the code for printing the date and time to the display:

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

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

currentDay = tm.Wday - 1; //passing Weekday

//(Mon - Sun eg 1-7) into var

currentDoM = tm.Day; //passing day in to var (1-31)

currentMonth = tm.Month; //passing month into var (1-12)

currentYear = tmYearToCalendar(tm.Year); //passing year to var

}

//>>>>>>>changes and additions start here<<<<<<<<<<<<<<<<

lcd.setCursor(0, 0); //set the corsor to line 1 pos 1

lcd.print(" "); //print 15 blanks to delete all

//prior statements

lcd.setCursor(0, 1); //set cursor to row 2 pos 1

lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(weekday_table[currentDay])))); //printing

//the weekday

lcd.print(" "); //print an empty space

if(currentDoM < 10) lcd.print("0"); //print a 0 if day of the month is less than 10 to keep

//a two digit output

lcd.print(currentDoM); //print day of the month

lcd.print("."); //print an empty space

if(currentMonth < 10) lcd.print("0"); //print 0 if the month is less than 10 to keep a

//two digit output

lcd.print(currentMonth); //print the month

lcd.print(" "); //print an empty space

if(currentHour < 10) lcd.print("0"); //if the hour is less than 10

//we print a 0 to keep 2 digits

lcd.print(currentHour); //print current time (hour)

lcd.print(":"); //print seperator

if(currentMinute < 10) lcd.print("0"); //if the minute is less than

//10 print 0 to keep 2 digits

lcd.print(currentMinute); //print current time (minutes)

//>>>>>>>>>additions and changes end here<<<<<<<<<<<<<<<<<

//Serial.print("Light level room 1: ");

That's all not real magic. The only thing we have a little bit a closer look is the statement we retrieve the weekdays from the program memory:

lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(weekday_table[currentDay]))));

strcpy_P is telling the system to copy a string from program memory into RAM, (char*) is specifing the data type to copy. pgm_read_word is revering to a 16 bit data type in the program memory, weekday_table is the name of the table we want to retrieve the data from. The time library is giving us the weekday as number from 1 to 7 where 1 is Sunday. Remember when we pass the variable currentDay = tm.Wday – 1? We need the minus 1 to account for arrays are being numbered starting from 0 and not from 1. Doing this little conversion and we can use the digit contained in currentDay direct as identifier for the weekday_table[] array.

Before we upload everything, we need to do a couple of more changes, finding a problem with the program flow since we packed the pir controls into a function. Being honest, I was guessing a bit, getting away with replacing a junk of code with just a function call which I have done plenty of times in php. But it looks like C# doesn't like it this way.

Let's have a quick look at the main loop where it says “//////room lights////////”. There we do the following changes:
the function call check_master(n) becomes light_Status[16] = check_master(n)
and
the function call check_light_P(n, n, n, n) becomes lightOutput(x) = check_light_P(n, n, x, n);
please note, that the number “x” in lightOutput[x] has to match with third variable we pass to the function(check_light_P(n, n, x, n)),
the same goes for the function call
check_light_N(n, x, n) it changes to lightOutput[x] = check_light_N(n, x, n);
again, please not that the number x in lightOutput[x] matches the number x in check_light_N(n, x, n);


//////////////////room lights//////////////////////////////

lightStatus[16] = check_master(0); //check if door switch was activated room 1 (bed1)

lightOutput[0] = check_light_P(0, 1, 0, 1); //check status room 1 (bed 1)

delay(5);

lightStatus[16] = check_master(2); //check if doorswitch was activated room 2 (bed 2)

lightOutput[1] = check_light_P(2, 3, 1, 2); //check status room 2 (bed 2)

delay(5);

lightStatus[16] = check_master(4); //check if doorswitch was activated room 3 (bed 3)

lightOutput[2] = check_light_P(4, 5, 2, 4); //check status room 3 (bed 3)

delay(5);

lightStatus[16] = check_master(6); //check if doorswitch was activated room 4 (living)

lightOutput[3] = check_light_P(6, 7, 3, 8); //check status room 4 (living)

delay(5);

lightStatus[16] = check_master(8); //check if doorswitch was activated room 5 (bath 1)

lightOutput[4] = check_light_N(8, 4, 16); //check status room 5 (bath 1)

delay(5);

lightStatus[16] = check_master(9); //check if door switch was activated room 6 (bath 2)

lightOutput[5] = check_light_N(9, 5, 32);

delay(5);

lightStatus[16] = check_master(10);

lightOutput[6] = check_light_N(10, 6, 64);

delay(5);

lightStatus[16] = check_master(11);

lightOutput[7] = check_light_N(11, 7, 128);

delay(5);

lightStatus[16] = check_master(12);

lightOutput[8] = check_light_N(12, 8, 256);

delay(5);

lightStatus[16] = check_master(13);

lightOutput[9] = check_light_N(13, 9, 512);

Since I have been doing al this changes, I am running in one issue after the other and currently I am reading in how the Atmega is handling its memory.
For now lets carry on with some changes to get a working sketch again. We jump all the way up to the declaration part again.

long int dAC4 = 120000; //delay time in milliseconds for AC 4 (living)

long int dMaster = 240000; //delay time in milliseconds for Master Off

unsigned int hourAc1On = 18; >>>>>>>change to byte hourAc1On = 18;

unsigned int minuteAc1On = 0; >>>>>>>change to byte minuteAc1On = 0;

unsigned int hourAc1Off = 24; >>>>>>>change to byte hourAc1Off = 24;

unsigned int minuteAc1Off = 0; >>>>>>>change to byte minuteAc1Off = 0;

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

all the following timer settings we change from unsigned int to byte

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

byte room1MActive = 1; //Set to 1 if you want to process

//Timer will be ignored when set to 0

byte room1OnM[2] = {5, 35}; //Time to switch on the lights 5

byte room1OffM[2] = {6, 5}; //Time to switch off the lights 6

byte room1O1Active = 1; //Set to 1 if you want to process

//Timer will be ignored when set to 0

byte room1On1[2] = {19, 35}; //Time to switch on the lights

byte room1Off1[2] = {20, 15}; //Time to switch off the lights

byte room102Active = 1; //Set to 1 if you want to process

//Timer will be ignored when set to 0

byte room1On2[2] = {21, 5}; //Time to switch on the ;ights

byte room1Off2[2] = {21, 15}; //Time to switch off the lights

////////////Room 2 (Bed 2) ///////////

byte room2MActive = 1; //Set to 1 if you want to process

//Timer will be ignored when set to 0

byte room2OnM[2] = {6, 30}; //Time to switch on the lights

byte room2OffM[2] = {6, 50}; //Time to switch off the lights

byte room201Active = 1; //Set to 1 if you want to process

//Timer will be ignored when set to 0

byte room2On1[2] = {19, 30}; //Time to switch on the lights

byte room2Off1[2] = {20, 10}; //Time to switch off the lights

////////////Room 3 (Bed 3) ///////////

byte room3MActive = 1; //Set to 1 if you want to process

//Timer will be ignored when set to 0

byte room3OnM[2] = {5, 50}; //time to switch on the lights

byte room3OffM[2] = {6, 20}; //time to switch off the lights

byte room301Active = 1; //Set to 1 if you want to process

//Timer will be ignored when set to 0

byte room3On1[2] = {18, 10}; //time to switch on the lights

byte room3Off1[2] = {18, 25}; //time to switch off the lights

byte room302Active = 1; //Set to 1 if you want to process

//Timer will be ignored when set to 0

byte room3On2[2] = {19, 15}; //Time to switch on the lights

byte room3Off2[2] = {19, 40}; //Time to switch off the lights

byte room303Active = 1; //Set to 1 if you want to process

//Timer will be ignored when set to 0

byte room3On3[2] = {23, 20}; //Time to switch on the lights

byte room3Off3[2] = {23, 35}; //Time to switch off the lights

///////////Room 4 {Living)

byte room401Active = 1; //Set to 1 if you want to process

//Timer will be ignored when set to 0

byte room4On[2] = {17, 30}; //Time to switch on the lights

byte room4Off[2] = {23, 30}; //Time to switch off the lights

//////////Room 5 (bath 1)//////////

byte room5MActive = 1; //Set to 1 if you want to process

//Timer will be ignored when set to 0

byte room5OnM[2] = {5, 40}; //Time to switch on the lights

byte room5OffM[2] = {5, 45}; //Time to switch off the lights

byte room501Active = 1; //Set to 1 if you want to process

//Timer will be ignored when set to 0

byte room5On[2] = {19, 55}; //Time to switch on the lights

byte room5Off[2] = {20, 10}; //Time to switch off the lights

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

byte room6MActive = 1; //Set to 1 if you want to process

//Timer will be ignored when set to 0

byte room6OnM[2] = {6, 35}; //Time to switch on the lights

byte room6OffM[2] = {6, 45}; //Time to switch off the lights

byte room601Active = 1; //Set to 1 if you want to process

//Timer will be ignored when set to 0

byte room6On[2] = {19, 50}; //Time to switch on the lights

byte room6Off[2] = {20, 05}; //Time to switch off the lights

//////////Room 7 (bath 3)//////////

byte room7MActive = 1; //Set to 1 if you want to process

//Timer will be ignored when set to 0

byte room7OnM[2] = {6, 5}; //Time to switch on the lights

byte room7OffM[2] = {6, 25}; //Time to switch off the lights

byte room701Active = 1; //Set to 1 if you want to process

//Timer will be ignored when set to 0

byte room7On[2] = {22, 50}; //Time to switch on the lights

byte room7Off[2] = {23, 15}; //Time to switch off the lights

//////////Room 8 (bath 4)//////////

byte room8MActive = 1; //Set to 1 if you want to process

//Timer will be ignored when set to 0

byte room8On[2] = {22, 5}; //Time to switch on the lights

byte room8Off[2] = {22, 20}; //Time to switch off the lights

//////////Room 9 (Kitchen)//////////

byte room9MActive = 1; //Set to 1 if you want to process

//Timer will be ignored when set to 0

byte room9OnM[2] = {5, 50}; //Time to switch on the lights

byte room9OffM[2] = {6, 45}; //Time to switch off the lights

byte room901Active = 1; //Set to 1 if you want to process

//Timer will be ignored when set to 0

byte room9On[2] = {17, 45}; //Time to switch on the lights

byte room9Off[2] = {18, 30}; //Time to switch off the lights

////////////////////////////DO NOT MODIVY BELOW HERE///////////////////////////////////////

Now we move down to where it says “/////all the other variables///////”
please check all the underlined statements and change the data type to byte. All statements in Italic, please change the data type to unsigned int.

unsigned long delayTime[16] = {dBed1, dBed2, dBed3, dLiving, dBath1, dBath2, dBath3,

dBath4, dKitchen, dCorridor, dAC1, dAC2, dAC3, dAC4,

dMaster, 0};

int sensorValue = 0; //holding the indicated sensor value of the photocell

unsigned long outputL = 0; //variable holding the output data

byte mainOff = 1; //variable for master relay control

unsigned int offTime = 0; //var needed to calculate delay for master off

byte masterSwitchStateOld = 0; //var holding the previous door switch state

byte switchState[25] = {0}; //array holding the state of each switch

unsigned long lightOutput[17] = {0}; //array holding a integer which converted to binary

//will trigger the relay to switch in our output code

byte lightStatus[17] = {0}; //array holding the switch status of each room on/off

unsigned int roomTimer[17] = {0}; //array holding the time when the PIR was last activated

byte priorityStatus[17] = {0}; //array holding the priority status of each room on/off

unsigned int currentTime = 0; //var to hold a reference time to calculate the up time

//against the preprogrammed delay time

unsigned int endTime = 0; //var to hold a temp result to calculate the up time

//against the preprogrammed delay time

byte maintenancePin = 0; //defining the var for the maintenance switch

byte maintenanceActive = 0; //holding the switch state

byte switchState1Old = 0; //var to check if the switch state has changed

byte switchState3Old = 0; //var to check if the switch state has changed

byte switchState5Old = 0; //var to check if the switch state has changed

byte switchState7Old = 0; //var to check if the switch state has changed

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

byte currentDoM = 0; //var holding the weekday (Sun - Sa, 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)

byte photocellSwitchOld = 0; //switch command from the previous pas

Next we move down to the part where it says “//checking the light status//” where we replace a junk of code:

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

//>>>>>>>>>>>>>>>>>>>>>>>>Delete from here<<<<<<<<<<<<<<

if(analogRead(lightSensor) > 0 &&

analogRead(lightSensor) < 1024){ //checking if the reading

//is within the sensor limits

int reading[15] = {0}; //declaring a local var to hold

//the readings

for(int i=0; i<15; 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] + reading[10] + reading[11] +

reading[12] + reading[13] + reading[14]) / 15;

}

else {

sensorValue = 0; //if something goes wrong switch on the lights anyway

}

//>>>>>>>>>>>>>>>to here<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

//Serial.print("Sensor value: ");

//Serial.println(sensorValue);

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


and replace the part we just deleted with:



sensorValue = 0;

int reading = 0; //the readings

for(int i=0; i<15; i++){ //take 15 readings

reading += analogRead(lightSensor);

}

//average the readings

sensorValue = reading / 15;


from here we move down to “/////////////////////Ac Read Switches////////////////////////”

from here down, where ever we find a statement like
roomTimer(n) = millis();
or
currentTime = millis();
we change it to
roomTimer(n) = millis()/1000;
and
currentTime = millis()/1000;

I underlined again all parts of code effected


/////////////////////Ac Read Switches////////////////////////

if(switchState[14] == 1 && lightStatus[14] == 1){ //Checking if readswitches are activated

//and the master relay is on AC room 1 (bed1)

lightOutput[10] = 1024; //providing the ability to

//switch on the AC

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

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

}

else if(switchState[14] == 0 && lightStatus[14] == 1){ //if a door is opened and the master

//relay is on

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

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

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

//delay time

lightOutput[10] = 0; //canceling ability to switch on the

//AC

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

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

}

}

if(switchState[15] == 1 && lightStatus[14] == 1){ //Checking if readswitches are activated

//and the master relay is on AC room 2 (bed2)

lightOutput[11] = 2048; //providing the ability to

//switch on the AC

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

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

}

else if(switchState[15] == 0 && lightStatus[14] == 1){ //if a door is opened and the master

//relay is on

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

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

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

//delay time

lightOutput[11] = 0; //canceling ability to switch on the

//AC

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

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

}

}

if(switchState[16] == 1 && lightStatus[14] == 1){ //Checking if readswitches are activated

//and the master relay is on AC room 3 (bed3)

lightOutput[12] = 4096; //providing the ability to

//switch on the AC

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

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

}

else if(switchState[16] == 0 && lightStatus[14] == 1){ //if a door is opened and the master

//relay is on

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

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

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

//delay time

lightOutput[12] = 0; //canceling ability to switch on the

//AC

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

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

}

}

if(switchState[17] == 1 && lightStatus[14] == 1){ //Checking if readswitches are activated

//and the master relay is on AC room 4 living

lightOutput[13] = 8192; //providing the ability to

//switch on the AC

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

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

}

else if(switchState[17] == 0 && lightStatus[14] == 1){ //if a door is opened and the master

//relay is on

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

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

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

//delay time

lightOutput[13] = 0; //canceling ability to switch on the

//AC

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

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

}

}

/////////////Door switch control ////////////////////

if(switchState[18] != masterSwitchStateOld) { //door switch check if the switch state

//has changed

//Serial.println("Door switch was activated"); //debug only

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

lightStatus[16] = 1; //setting light status

digitalWrite(doorMonitor, HIGH); //setting the control LED

for(int i=0; i<17; i++){ //looping through the timers

roomTimer[i] = currentTime; //setting the timers

}

}

else if(switchState[18] == masterSwitchStateOld && lightStatus[16] == 1){ //if the switch state

//has not changed and the lights are on

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

offTime = roomTimer[16] + delayTime[14]; //setting the allowed delay time

if(currentTime >= offTime) { //comparing the times

for(int c=0; c<17; c++) { //looping through the circuits

if(roomTimer[c] != roomTimer[16]) { //comparing timers

mainOff = 1; //setting the switch off all command

lightStatus[16] = 0; //switching off the master relay

}

else {

mainOff = 0; //if the timers match we set the

//switch off all command to 0

break; //leaving the loop

}

}

}

//Serial.print("Main off: ");

//Serial.println(mainOff);

if(mainOff == 0) { //master off command is 0

//Serial.println("switching off everything and reset all"); //debug only

for(int i=0; i<17; i++) { //looping through the circuits

lightStatus[i] = 0; //resetting all light status

lightOutput[i] = 0; //switching off all lights

priorityStatus[i] = 0; //resetting all set priorities

roomTimer[i] = 0; //resetting all room timers

}

digitalWrite(doorMonitor, LOW); //resetting the control LED

mainOff = 1; //resetting master off command

}

}

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

}

///////////////////////////Output/////////////////////////////////////////////////

for(int i=0; i<17; i++) { //loop through the light output array

outputL += lightOutput[i]; //adding up the numbers

}

if(maintenancePin == 1) { //if maintenance switch is active

for(int i=1; i>17; i++){ //loop through all circuits

lightStatus[i] = 1; //setting the light status of everything

roomTimer[i] = millis()/1000; //setting all the room timers

}

outputL = 32767; //setting the output

//binary 0111111111111111

} 

From here we jump down straight to our new implemented functions check_light_P() and check_light_N and do the same thing. I underlined again all effected code:


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

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

//Serial.println("We are checking the timer"); //Debug only

currentTime = millis()/1000; //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()/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];

}

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

//Serial.println("We are checking the timer"); //Debug only

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

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

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

//delay time

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

}

Since we have changed our delay timers from milliseconds to seconds, we have to jump again across the sketch to the declarations where we change all the delay times from long to int and cut 3 0's from the value so the value reads seconds and not milliseconds as originally declared.


///////////Timer and Sensitivity Settings to be changed to individual needs////////////////

unsigned int sensitivity = 400; //should be between 200 and 1000 as

//lower the number as more responsive

//the system will be

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

//>>>>>>>>>>>>revised timer settings<<<<<<<<<<<<<<<<<<<<<<<<<<<

int dBed1 = 60; //delay time in milliseconds for bedroom 1

int dBed2 = 60; //delay time in milliseconds for bedroom 2

int dBed3 = 60; //delay time in milliseconds for bedroom 3

int dLiving = 300; //delay time in milliseconds for living area

int dBath1 = 180; //delay time in milliseconds for bathroom 1

int dBath2 = 180; //delay time in milliseconds for bathroom 2

int dBath3 = 180; //delay time in milliseconds for bathroom 3

int dBath4 = 180; //delay time in milliseconds for bathroom 4

int dKitchen = 120; //delay time in milliseconds for kitchen

int dCorridor = 60; //delay time in milliseconds for corridor

int dAC1 = 120; //delay time in milliseconds for AC 1 (bed1)

int dAC2 = 120; //delay time in milliseconds for AC 2 (bed2)

int dAC3 = 120; //delay time in milliseconds for AC 3 (bed3)

int dAC4 = 120; //delay time in milliseconds for AC 4 (living)

int dMaster = 240; //delay time in milliseconds for Master Off

//>>>>>>>>>>>revised timer settings above<<<<<<<<<<<<<<<<<

Finally for today a small bug fix. There for we go down to the function getSensorValue()


byte getSensorValue(int sensorReading, int switchValue, 
                    int switchLimit, byte switchStatus){
  byte onStatus = 0;
  
  if(switchStatus == 0){
    if(sensorReading <= switchValue){
      onStatus = 1;
    }
    else if(sensorReading > switchLimit){
      onStatus = 0;
    }
    else if(sensorReading > switchValue &&
            sensorReading <= switchLimit){
      onStatus = 0;
    }
  }
  //>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<
  //The below statement need to be changed to
  //else if(switchStatus == 1){
  //>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<
  else if(switchStatus = 1){
    if(sensorReading <= switchValue){
      onStatus = 1;
    }
    else if(sensorReading > switchValue &&
            sensorReading <= switchLimit){
      onStatus = 1;
    }
    else if(sensorReading > switchLimit){
      onStatus = 0;
    }
  }
  return onStatus;
} 

No comments:

Post a Comment