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