As promised a full sketch again with all the changes, alterations and updates including the menu to control, timers, delays and photo cell settings for the lights. I am still working on a extended AC control and the EEPROM usage to make changes more permanent, so they don't get lost on power cuts or a system reset. Further improvement in code and functionality are also coming in the next couple of posts.
/////////////////////Includes/////////////////////////////
#include <DS1307RTC.h>
#include <Time.h>
#include <Wire.h>
#include <ShiftLCD.h>
#include <avr/pgmspace.h>
#define DS1307_ADDRESS 0x68
byte zero = 0x00;
/////////////////////Declaring the Variables/////////////////
///////////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;
byte hourOutsideOff = 23; //var holding the time (full hours) in which the lights have
//to switch off
byte minuteOutsideOff = 30; //var holding the time (minutes) in which the lights
//have to switch off
int dBed1 = 60; //delay time in seconds for bedroom 1
int dBed2 = 60; //delay time in seconds for bedroom 2
int dBed3 = 60; //delay time in seconds for bedroom 3
int dLiving = 300; //delay time in seconds for living area
int dBath1 = 180; //delay time in seconds for bathroom 1
int dBath2 = 180; //delay time in seconds for bathroom 2
int dBath3 = 180; //delay time in seconds for bathroom 3
int dBath4 = 180; //delay time in seconds for bathroom 4
int dKitchen = 120; //delay time in seconds for kitchen
int dCorridor = 60; //delay time in seconds for corridor
int dAC1 = 120; //delay time in seconds for AC 1 (bed1)
int dAC2 = 120; //delay time in seconds for AC 2 (bed2)
int dAC3 = 120; //delay time in seconds for AC 3 (bed3)
int dAC4 = 120; //delay time in seconds for AC 4 (living)
int dMaster = 240; //delay time in seconds for Master Off
byte hourAc1On = 18;
byte minuteAc1On = 0;
byte hourAc1Off = 24;
byte minuteAc1Off = 0;
//////////////////////holliday timer settings//////////////////////
byte timer_active[10][4] = {
{1, 1, 1, 0}, //room 0 timers 0 to 3
{1, 1, 0, 0}, //room 1 timers 0 to 3
{1, 1, 1, 1}, //room 2 timers 0 to 3
{0, 1, 0, 0}, //room 3 timers 0 to 3
{1, 1, 2, 2}, //room 4 timers 0 to 3
{1, 1, 2, 2}, //room 5 timers 0 to 3
{1, 1, 2, 2}, //room 6 timers 0 to 3
{1, 0, 2, 2}, //room 7 timers 0 to 3
{1, 1, 2, 2}, //room 8 timers 0 to 3
{0, 0, 2, 2} //room 9 timers 0 to 3
};
//Timer Settings room, timer, hour on, minute on, hour off, minute off
byte room_timers[10][4][4] = {
{
{5, 35, 6, 5}, //room 1 timer 1
{19, 35, 20, 15}, //room 1 timer 2
{21, 5, 21, 15}, //room 1 timer 3
{0, 0, 0, 0} //room 1 timer 4
},
{
{6, 30, 6, 50}, //room 2 timer 1
{19, 30, 20, 10}, //room 2 timer 2
{0, 0, 0, 0}, //room 2 timer 3
{0, 0, 0, 0} //room 2 timer 4
},
{
{5, 50, 6, 20}, //room 3 timer 1
{18, 10, 18, 25}, //room 3 timer 2
{19, 15, 19, 40}, //room 3 timer 3
{23, 20, 23, 35} //room 3 timer 4
},
{
{0, 0, 0, 0}, //room 4 timer 1
{17, 30, 23, 30}, //room 4 timer 2
{0, 0, 0, 0}, //room 4 timer 3
{0, 0, 0, 0} //room 4 timer 4
},
{
{5, 40, 5, 45}, //room 5 timer 1
{19, 55, 20, 10}, //room 5 timer 2
{0, 0, 0, 0}, //not used
{0, 0, 0, 0} //not used
},
{
{6, 35, 6, 45}, //room 6 timer 1
{19, 50, 20, 5}, //room 6 timer 2
{0, 0, 0, 0}, //not used
{0, 0, 0, 0} //not used
},
{
{6, 5, 6, 25}, //room 7 timer 1
{22, 50, 23, 15}, //room 7 timer 2
{0, 0, 0, 0}, //not used
{0, 0, 0, 0} //not used
},
{
{0, 0, 0, 0}, //room 8 timer 1
{22, 5, 22, 20}, //room 8 timer 2
{0, 0, 0, 0}, //not used
{0, 0, 0, 0} //not used
},
{
{5, 50, 6, 45}, //room 9 timer 1
{17, 45, 18, 30}, //room 9 timer 2
{0, 0, 0, 0}, //room 9 timer 3
{0, 0, 0, 0} //not used
},
{
{0, 0, 0, 0}, //room 10 timer 1
{0, 0, 0, 0}, //room 10 timer 2
{0, 0, 0, 0}, //not used
{0, 0, 0, 0} //not used
}
};
///////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////DO NOT MODIVY BELOW HERE///////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
////////////////////////////defining Arduino Pins/////////////////////////////
//////////////////////////////////////////////////////////////////////////////
ShiftLCD lcd(9, 11, 10); //initializing the LCD adaptor pins
const byte latchPin = 2; //5latch pin input connected to
//Arduino digital pin 2
const byte clockPin = 3; //6clock pin input connected to
//Arduino digital pin 3
const byte dataPin = 4; //7data pin input connected to
//Arduino digital pin 4
const byte latchPinOut = 5; //2latch pin output shift register
//74HC595 connected to Arduino
//digital pin 5
const byte clockPinOut = 6; //3clock pin output shift register
//74HC595 connected to Arduino
//digital pin 6
const byte dataPinOut = 7; //4data pin output shift register
//74HC595 connected to Arduino
//digital pin 7
const byte lightSensor = 0; //defining the input for the photocell
const byte doorMonitor = 8; //Arduino pin for a monitor LED
const byte setupMode = 12; //Arduino pin for switching to setup mode
/////////////////////////////////////////////////////////////////////////////
///////Variables to hold the data for each input shift register//////////////
/////////////////////////////////////////////////////////////////////////////
byte switchVar1 = 0; //data for input shift register 1
byte switchVar2 = 0; //data for input shift register 2
byte switchVar3 = 0; //data for input shift register 3
///////////////////////////////////////////////////////////////////////////////
///////////////////////////all the other variables/////////////////////////////
///////////////////////////////////////////////////////////////////////////////
////Sensor and timer variables
int 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
byte photocellSwitch = 0; //holding the switch command after
//checking sensor readings (0, 1)
byte photocellSwitchOld = 0; //switch command from the previous pass
byte lightLevel[17] ={0}; //array holding the switch state
//checking timer and photocell (0, 1)
unsigned int roomTimer[17] = {0}; //array holding the time when the PIR was last activated
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
unsigned int outsideOnTime = 0; //checking result if the time is within
//on or off time limits
////////////////////////////////////////////////////////////////////////////////////////
//////////////////////PIR and Room switch related Var's/////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
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
byte priorityStatus[17] = {0}; //array holding the priority status of each room on/off
byte switchState1Old = 0; //var to check if the priority switch state has changed
byte switchState3Old = 0; //var to check if the priority switch state has changed
byte switchState5Old = 0; //var to check if the priority switch state has changed
byte switchState7Old = 0; //var to check if the priority switch state has changed
//////////////////////////////////////////////////////////////////////////////
///////////////////////////Output/////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
unsigned long outputL = 0; //variable holding the output data
//////////////////////////////////////////////////////////////////////////////////////
///////////////////////////Service Switches///////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
byte maintenancePin = 0; //defining the var for the maintenance switch
byte maintenanceActive = 0; //holding the switch state
/////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////RTC and Holiday switch timers///////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
tmElements_t tm; //initializing RTC
byte room1Lights = 0; //var to hold the on command for room light
byte room2Lights = 0; //var to hold the on command for room light
byte room3Lights = 0; //var to hold the on command for room light
byte room4Lights = 0; //var to hold the on command for room light
byte room5Lights = 0; //var to hold the on command for room light
byte room6Lights = 0; //var to hold the on command for room light
byte room7Lights = 0; //var to hold the on command for room light
byte room8Lights = 0; //var to hold the on command for room light
byte room9Lights = 0; //var to hold the on command for room light
byte room10Lights = 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)
//Array holding the day names to replace the weekday index
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";
PROGMEM const char *weekday_table[] = {
weekday_0,
weekday_1,
weekday_2,
weekday_3,
weekday_4,
weekday_5,
weekday_6
};
char buffer[20];
///////////////////////////////////////////////////////////////////////////
///////////////////Menu and user interface/////////////////////////////////
///////////////////////////////////////////////////////////////////////////
const byte btnMenu = 1; //defining the menu button – moves through the menu
const byte btnSearch = 2; //defining the search button – moves through values
const byte btnSelect = 3; //defining the select button – selects a menu or a value
const byte btnNone = 0; //defining the non button pressed var
int act_key_in = 0; //var holding the key related sensor reading
byte menuOption = 0; //var to count current menu option
const byte menuOptions = 20; //available menu options
byte submenu = 0; //var to count current submenu option
const byte submenus = 9; //available submenu options
char buffer_M[20]; //var holding the menu strings retrieved from
//the program memory
//Storing some menu messages in the program memory
prog_char msg_0[] PROGMEM = "Not Used";
prog_char msg_1[] PROGMEM = "Saving....";
prog_char msg_2[] PROGMEM = "Setup mode";
prog_char msg_3[] PROGMEM = "Starting....";
prog_char msg_4[] PROGMEM = "RMU 1.3.1";
prog_char msg_5[] PROGMEM = "Weekday";
prog_char msg_6[] PROGMEM = "On TIMER Off";
prog_char msg_7[] PROGMEM = "Off ";
prog_char msg_8[] PROGMEM = "Active";
prog_char msg_9[] PROGMEM = "PIR Delay R";
prog_char msg_10[] PROGMEM = "T1 On/Off R";
prog_char msg_11[] PROGMEM = "T2 On/Off R";
prog_char msg_12[] PROGMEM = "T3 On/Off R";
prog_char msg_13[] PROGMEM = "ADJ Hour On";
prog_char msg_14[] PROGMEM = "ADJ Minute On";
prog_char msg_15[] PROGMEM = "ADJ Hour Off";
prog_char msg_16[] PROGMEM = "ADJ Minute Off";
prog_char msg_17[] PROGMEM = "Set Sensitivity";
prog_char msg_18[] PROGMEM = "Set photocell R";
prog_char msg_19[] PROGMEM = "Set photocell O";
prog_char msg_20[] PROGMEM = "ADJ Time Minute";
prog_char msg_21[] PROGMEM = "ADJ Time Hour";
prog_char msg_22[] PROGMEM = "ADJ Date Day";
prog_char msg_23[] PROGMEM = "ADJ Date Month";
prog_char msg_24[] PROGMEM = "ADJ Date Year";
prog_char msg_25[] PROGMEM = "T4 On/Off R";
//Creating the table for the stored menu messages
PROGMEM const char *msg_table[] = {
msg_0,
msg_1,
msg_2,
msg_3,
msg_4,
msg_5,
msg_6,
msg_7,
msg_8,
msg_9,
msg_10,
msg_11,
msg_12,
msg_13,
msg_14,
msg_15,
msg_16,
msg_17,
msg_18,
msg_19,
msg_20,
msg_21,
msg_22,
msg_23,
msg_24,
msg_25
};
//storing some special char's in the program memory
const byte char_table[] PROGMEM = {
B01111110, //Arrow right
B01111111, //Arrow left
B00110000, //0
B00111010, //seperator
B00101110, //dott
B00110001, //1
B00110010, //2
B00110011, //3
B00110100, //4
B00110101, //5
B00110110, //6
B00110111, //7
B00111000, //8
B00111001 //9
};
//storing the main menu points in the program memory
prog_char menu_0[] PROGMEM = "Date/Time";
prog_char menu_1[] PROGMEM = "Sensitivity";
prog_char menu_2[] PROGMEM = "Room photo cut";
prog_char menu_3[] PROGMEM = "Room photo limit";
prog_char menu_4[] PROGMEM = "OS photo cut";
prog_char menu_5[] PROGMEM = "OS photo limit";
prog_char menu_6[] PROGMEM = "Room 1";
prog_char menu_7[] PROGMEM = "Room 2";
prog_char menu_8[] PROGMEM = "Room 3";
prog_char menu_9[] PROGMEM = "Room 4";
prog_char menu_10[] PROGMEM = "Room 5";
prog_char menu_11[] PROGMEM = "Room 6";
prog_char menu_12[] PROGMEM = "Room 7";
prog_char menu_13[] PROGMEM = "Room 8";
prog_char menu_14[] PROGMEM = "Room 9";
prog_char menu_15[] PROGMEM = "Room 10";
prog_char menu_16[] PROGMEM = "AC 1";
prog_char menu_17[] PROGMEM = "AC 2";
prog_char menu_18[] PROGMEM = "AC 3";
prog_char menu_19[] PROGMEM = "AC 4";
PROGMEM const char *menu_table[] = {
menu_0,
menu_1,
menu_2,
menu_3,
menu_4,
menu_5,
menu_6,
menu_7,
menu_8,
menu_9,
menu_10,
menu_11,
menu_12,
menu_13,
menu_14,
menu_15,
menu_16,
menu_17,
menu_18,
menu_19
};
//storing the sub menu points in the program memory
prog_char submenu_0[] PROGMEM = "PIR delay R";
prog_char submenu_1[] PROGMEM = "HT1 Active R";
prog_char submenu_2[] PROGMEM = "Timer 1 R";
prog_char submenu_3[] PROGMEM = "HT2 Active R";
prog_char submenu_4[] PROGMEM = "Timer 2 R";
prog_char submenu_5[] PROGMEM = "HT3 Active R";
prog_char submenu_6[] PROGMEM = "Timer 3 R";
prog_char submenu_7[] PROGMEM = "HT4 Active R";
prog_char submenu_8[] PROGMEM = "Timer 4 R";
PROGMEM const char *submenu_table[] = {
submenu_0,
submenu_1,
submenu_2,
submenu_3,
submenu_4,
submenu_5,
submenu_6,
submenu_7,
submenu_8
};
void setup() {
//////////////Start Serial for Debugging/////////////////////
//Serial.begin(9600);
//printing initialisation message
lcd.begin(16, 2);
lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(msg_table[4]))));
delay(1000);
lcd.setCursor(0, 1);
lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(msg_table[3]))));
delay(2000);
//////////////////defining pin modes////////////////////
pinMode(doorMonitor, OUTPUT); //setting the LED pin to output
pinMode(setupMode, INPUT); //setup switch to activate menu
pinMode(latchPin, OUTPUT); //setting the latch pin to output
pinMode(clockPin, OUTPUT); //setting the clock pin to output
pinMode(dataPin, INPUT); //setting the data pin to input
pinMode(latchPinOut, OUTPUT);
pinMode(clockPinOut, OUTPUT);
pinMode(dataPinOut, OUTPUT);
}
void loop() {
///////////////////checking the setup switch/////////////////////////
while(digitalRead(setupMode) != 0){ //stay in here if activated
lcd.clear(); //clear display
lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(msg_table[2])))); //print Setup mode
delay(500); //small delay
button_loop(); //function call to monitore menu buttons
}
//////////////////////////////////////getting the input//////////////////////////////////////////////////
//Serial.print("switchVar1 first: ");
//Serial.println(switchVar1, BIN);
//Serial.print("switchVar2 first: ");
//Serial.println(switchVar2, BIN);
//Serial.print("switchVar3 first: ");
//Serial.println(switchVar3, BIN);
//pulse the latch pin, set to high to collect serial data
digitalWrite(latchPin, HIGH);
//give it chance to collect the data
delayMicroseconds(25);
//set latch pin to low to transmit data serially
digitalWrite(latchPin, LOW);
//while in serial mode, collect data into a byte
switchVar1 = shiftIn(dataPin, clockPin);
switchVar2 = shiftIn(dataPin, clockPin);
switchVar3 = shiftIn(dataPin, clockPin);
/////////////do something with the collected Data/////////////////////
//checks for debugging
//Serial.println(); //debug only
//Serial.print("Switch variable 1: "); //debug only
//Serial.println(switchVar1, BIN); //debug only
//Serial.println("-------------------"); //debug only
//Serial.println(); //debug only
//Serial.print("Switch variable 2: "); //debug only
//Serial.println(switchVar2, BIN); //debug only
//Serial.println("-------------------"); //debug only
//Serial.println(); //debug only
//Serial.print("Switch variable 3: "); //debug only
//Serial.println(switchVar3, BIN); //debug only
//Serial.println("-------------------"); //debug only
////////////loop through the 8 input pins to check their status////////////
for(int n=0; n<=7; n++){
//shift register 1
if(switchVar1 & (1 << 0)) { //checking S1
//Serial.println("Switch 1 was activated."); //debug only
switchState[0] = 1;
}
else {
switchState[0] = 0;
}
if(switchVar1 & (1 << 1)) { //checking S2
//Serial.println("Switch 2 was activated."); //debug only
switchState[1] = 1;
}
else {
switchState[1] = 0;
}
if(switchVar1 & (1 << 2)) { //checking S3
//Serial.println("Switch 3 was activated."); //debug only
switchState[2] = 1;
}
else {
switchState[2] = 0;
}
if(switchVar1 & (1 << 3)) { //checking S4
//Serial.println("Switch 4 was activated."); //debug only
switchState[3] = 1;
}
else {
switchState[3] = 0;
}
if(switchVar1 & (1 << 4)) { //checking S8
//Serial.println("Switch 8 was activated."); //debug only
switchState[7] = 1;
}
else {
switchState[7] = 0;
}
if(switchVar1 & (1 << 5)) { //checking S7
//Serial.println("Switch 7 was activated."); //debug only
switchState[6] = 1;
}
else {
switchState[6] = 0;
}
if(switchVar1 & (1 << 6)) { //checking S6
//Serial.println("Switch 6 was activated."); //debug only
switchState[5] = 1;
}
else {
switchState[5] = 0;
}
if(switchVar1 & (1 << 7)) { //checking S5
//Serial.println("Switch 5 was activated."); //debug only
switchState[4] = 1;
}
else {
switchState[4] = 0;
}
//shift register 2
if(switchVar2 & (1)) { //checking S9
//Serial.println("Switch 9 was activated."); //debug only
switchState[8] = 1;
}
else {
switchState[8] = 0;
}
if(switchVar2 & (1 << 1)) { //checking S10
//Serial.println("Switch 10 was activated."); //debug only
switchState[9] = 1;
}
else {
switchState[9] = 0;
}
if(switchVar2 & (1 << 2)) { //checking S11
//Serial.println("Switch 11 was activated."); //debug only
switchState[10] = 1;
}
else {
switchState[10] = 0;
}
if(switchVar2 & (1 << 3)) { //checking S12
//Serial.println("Switch 12 was activated."); //debug only
switchState[11] = 1;
}
else {
switchState[11] = 0;
}
if(switchVar2 & (1 << 4)) { //checking S16
//Serial.println("Switch 16 was activated."); //debug only
switchState[15] = 1;
}
else {
switchState[15] = 0;
}
if(switchVar2 & (1 << 5)) { //checking S15
//Serial.println("Switch 15 was activated."); //debug only
switchState[14] = 1;
}
else {
switchState[14] = 0;
}
if(switchVar2 & (1 << 6)) { //checking S14
//Serial.println("Switch 14 was activated."); //debug only
switchState[13] = 1;
}
else {
switchState[13] = 0;
}
if(switchVar2 & (1 << 7)) { //checking S13
//Serial.println("Switch 13 was activated."); //debug only
switchState[12] = 1;
}
else {
switchState[12] = 0;
}
//shift register 3
if(switchVar3 & (1)) { //checking S17
//Serial.println("Switch 17 was activated."); //debug only
switchState[16] = 1;
}
else {
switchState[16] = 0;
}
if(switchVar3 & (1 << 1)) { //checking S18
//Serial.println("Switch 18 was activated."); //debug only
switchState[17] = 1;
}
else {
switchState[17] = 0;
}
if(switchVar3 & (1 << 2)) { //checking S19
//Serial.println("Switch 19 was activated."); //debug only
switchState[18] = 1;
}
else {
switchState[18] = 0;
}
if(switchVar3 & (1 << 3)) { //checking S20
//Serial.println("Switch 20 was activated."); //debug only
maintenancePin = 1;
}
else {
maintenancePin = 0;
}
if(switchVar3 & (1 << 4)) { //checking S21
//Serial.println("Switch 20 was activated."); //debug only
switchState[20] = 1;
}
else {
switchState[20] = 0;
}
if(switchVar3 & (1 << 5)) { //checking S22
//Serial.println("Switch 21 was activated."); //debug only
switchState[21] = 1;
}
else {
switchState[21] = 0;
}
if(switchVar3 & (1 << 6)) { //checking S23
//Serial.println("Switch 22 was activated."); //debug only
switchState[22] = 1;
}
else {
switchState[22] = 0;
}
}
//////////////Debug Statements//////////////////////////////////
/*for(int c=0; c<21; c++){
Serial.print("Switch state: ");
Serial.print(c);
Serial.print(" / ");
Serial.println(switchState[c]);
delay(100);
}*/
//////////////////checking the light status//////////////////////
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;
//Serial.print("Sensor value: ");
//Serial.println(sensorValue);
//////////////////processing the input/////////////////////
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
}
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]))));
lcd.print(" ");
if(currentDoM < 10) lcd.write(pgm_read_byte(&char_table[2])); //print 0
lcd.print(currentDoM);
lcd.write(pgm_read_byte(&char_table[4])); //print dott
if(currentMonth < 10) lcd.write(pgm_read_byte(&char_table[2])); //print 0
lcd.print(currentMonth);
lcd.print(" ");
if(currentHour < 10) lcd.write(pgm_read_byte(&char_table[2]));
//if the hour is less than 10
//we print a 0 to keep 2 digits
lcd.print(currentHour); //print current time (hour)
lcd.write(pgm_read_byte(&char_table[3])); //print seperator
if(currentMinute < 10) lcd.write(pgm_read_byte(&char_table[2]));
//if the minute is less than
//10 print 0 to keep 2 digits
lcd.print(currentMinute); //print current time (minutes)
//Serial.print("Light level room 1: ");
//Serial.println(lightLevel[0]);
//Serial.print("Light level room 4: ");
//Serial.println(lightLevel[3]);
photocellSwitch = getSensorValue(sensorValue, photoCellCutOff,
photoCellCutOn, photocellSwitchOld);
photocellSwitchOld = photocellSwitch;
if(photocellSwitch == 1 && currentHour >= 17 && currentHour <= 23) {
//Serial.println("Entered first loop!");
for(int i=0; i<9; i++){
lightLevel[i] = 1;
}
lightLevel[15] = 1;
}
else if(photocellSwitch == 1 && currentHour >= 0 && currentHour <= 8){
//Serial.println("Entered second loop!");
for(int i=0; i<9; i++){
lightLevel[i] = 1;
}
lightLevel[15] = 1;
}
else if(photocellSwitch == 0 && currentHour >= 5 && currentHour <= 8){
//Serial.println("Entered third loop!");
for(int c=0; c<17; c++){
lightLevel[c] = 0;
}
}
//////////////Holiday lighting/////////////////////////
if(switchState[20] == 1) { //check if the holliday switch
//is activated
lightOutput[14] = 0; //make sure the master relay is off
//Serial.print("Current date: ");
//Serial.print(days[currentDay - 1]);
//Serial.print(", ");
//Serial.print(currentDoM);
//Serial.print("/");
//Serial.print(currentMonth);
//Serial.print("/");
//Serial.println(currentYear);
//Serial.print("Current Time: ");
//Serial.print(currentHour);
//Serial.print(" : ");
//Serial.println(currentMinute);
//Serial.print("Photo cell switch: ");
//Serial.println(photocellSwitch);
//Serial.print("Light level room 1 after: ");
//Serial.println(lightLevel[0]);
//Serial.print("photocell switch: ");
//Serial.println(photocellSwitch);
//Serial.print("Light level room 3 after: ");
//Serial.println(lightLevel[2]);
//Serial.print("Light level room 4 after: ");
//Serial.println(lightLevel[3]);
///////Room 1 (Bed 1) /////////////
if(timer_active[0][0] == 1 && currentHour >= room_timers[0][0][0] &&
currentHour <= (room_timers[0][0][2] + 1)){ //checking if we came passed
//the hour where the lights
//to be switched on
//checking the times
room1Lights = checkOnTime(room_timers[0][0][0], room_timers[0][0][1],
room_timers[0][0][2], room_timers[0][0][3]);
}
if(timer_active[0][1] == 1 && currentHour >= room_timers[0][1][0] &&
currentHour <= (room_timers[0][1][2] + 1)){ //checking if we came passed
//the hour where the lights
//to be switched on
//checking the times
room1Lights = checkOnTime(room_timers[0][1][0], room_timers[0][1][1],
room_timers[0][1][2], room_timers[0][1][3]);
}
if(timer_active[0][2] == 1 && currentHour >= room_timers[0][2][0] &&
currentHour <= (room_timers[0][2][2] + 1)){ //checking if we came passed
//the hour where the lights
//to be switched on
//checking the times
room1Lights = checkOnTime(room_timers[0][2][0], room_timers[0][2][1],
room_timers[0][2][2], room_timers[0][2][3]);
}
if(timer_active[0][3] == 1 && currentHour >= room_timers[0][3][0] &&
currentHour <= (room_timers[0][3][2] + 1)){ //checking if we came passed
//the hour where the lights
//to be switched on
//checking the times
room1Lights = checkOnTime(room_timers[0][3][0], room_timers[0][3][1],
room_timers[0][3][2], room_timers[0][3][3]);
}
if(room1Lights == 1 && lightLevel[0] == 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;
}
////////Room 2 (Bed 2)//////////////
if(timer_active[1][0] ==1 && currentHour >= room_timers[1][0][0]
&& currentHour <= (room_timers[1][0][2] + 1)){
room2Lights = checkOnTime(room_timers[1][0][0], room_timers[1][0][1],
room_timers[1][0][2], room_timers[1][0][3]);
}
if(timer_active[1][1] == 1 && currentHour >= room_timers[1][1][0] &&
currentHour <= (room_timers[1][1][2] + 1)){
room2Lights = checkOnTime(room_timers[1][1][0], room_timers[1][1][1],
room_timers[1][1][2], room_timers[1][1][3]);
}
if(timer_active[1][2] == 1 && currentHour >= room_timers[1][2][0] &&
currentHour <= (room_timers[1][2][2] + 1)){
room2Lights = checkOnTime(room_timers[1][2][0], room_timers[1][2][1],
room_timers[1][2][2], room_timers[1][2][3]);
}
if(timer_active[1][3] == 1 && currentHour >= room_timers[1][3][0] &&
currentHour <= (room_timers[1][3][2] + 1)){
room2Lights = checkOnTime(room_timers[1][3][0], room_timers[1][3][1],
room_timers[1][3][2], room_timers[1][3][3]);
}
if(room2Lights == 1 && lightLevel[1] == 1){
lightOutput[1] = 2;
}
else {
lightOutput[1] = 0;
lightLevel[1] =0;
}
////////Room 3 (Bed 3) ////////////
if(timer_active[2][0] == 1 && currentHour >= room_timers[2][0][0] &&
currentHour <= (room_timers[2][0][2] + 1)){
room3Lights = checkOnTime(room_timers[2][0][0], room_timers[2][0][1],
room_timers[2][0][2], room_timers[2][0][3]);
}
if(timer_active[2][1] == 1 && currentHour >= room_timers[2][1][0] &&
currentHour <= (room_timers[2][1][2] + 1)){
room3Lights = checkOnTime(room_timers[2][1][0], room_timers[2][1][1],
room_timers[2][1][2], room_timers[2][1][3]);
}
if(timer_active[2][2] == 1 && currentHour >= room_timers[2][2][0] &&
currentHour <= (room_timers[2][2][2] + 1)){
room3Lights = checkOnTime(room_timers[2][2][0], room_timers[2][2][1],
room_timers[2][2][2], room_timers[2][2][3]);
}
if(timer_active[2][3] == 1 && currentHour >= room_timers[2][3][0] &&
currentHour <= (room_timers[2][3][2] + 1)){
room3Lights = checkOnTime(room_timers[2][3][0], room_timers[2][3][1],
room_timers[2][3][2], room_timers[2][3][3]);
}
if(room3Lights == 1 && lightLevel[2] == 1){
lightOutput[2] = 4;
}
else {
lightOutput[2] = 0;
lightLevel[2] = 0;
}
////////Room 4 (living)/////////////////////
if(timer_active[3][0] == 1 && currentHour >= room_timers[3][0][0] &&
currentHour <= (room_timers[3][0][2] + 1)){
room4Lights = checkOnTime(room_timers[3][0][0], room_timers[3][0][1],
room_timers[3][0][2], room_timers[3][0][3]);
}
if(timer_active[3][1] == 1 && currentHour >= room_timers[3][1][0] &&
currentHour <= (room_timers[3][1][2] + 1)){
room4Lights = checkOnTime(room_timers[3][1][0], room_timers[3][1][1],
room_timers[3][1][2], room_timers[3][1][3]);
}
if(timer_active[3][2] == 1 && currentHour >= room_timers[3][2][0] &&
currentHour <= (room_timers[3][2][2] + 1)){
room4Lights = checkOnTime(room_timers[3][2][0], room_timers[3][2][1],
room_timers[3][2][2], room_timers[3][2][3]);
}
if(timer_active[3][3] == 1 && currentHour >= room_timers[3][3][0] &&
currentHour <= (room_timers[3][3][2] + 1)){
room4Lights = checkOnTime(room_timers[3][3][0], room_timers[3][3][1],
room_timers[3][3][2], room_timers[3][3][3]);
}
if(room4Lights == 1 && lightLevel[3] == 1){
lightOutput[3] = 8;
}
else {
lightOutput[3] = 0;
lightLevel[3] = 0;
}
////////Room 5 (Bath 1)/////////////////////
if(timer_active[4][0] == 1 && currentHour >= room_timers[4][0][0] &&
currentHour <= (room_timers[4][0][2] + 1)){
room5Lights = checkOnTime(room_timers[4][0][0], room_timers[4][0][1],
room_timers[4][0][2], room_timers[4][0][3]);
}
if(timer_active[4][1] == 1 && currentHour >= room_timers[4][1][0] &&
currentHour <= (room_timers[4][1][2] + 1)){
room5Lights = checkOnTime(room_timers[4][1][0], room_timers[4][1][1],
room_timers[4][1][2], room_timers[4][1][3]);
}
if(room5Lights == 1 && lightLevel[4] == 1){
lightOutput[4] = 16;
}
else {
lightOutput[4] = 0;
lightLevel[4] =0;
}
////////Room 6 (Bath 2)/////////////////////
if(timer_active[5][0] == 1 && currentHour >= room_timers[5][0][0] &&
currentHour <= (room_timers[5][0][2] + 1)){
room6Lights = checkOnTime(room_timers[5][0][0], room_timers[5][0][1],
room_timers[5][0][2], room_timers[5][0][3]);
}
if(timer_active[5][1] == 1 && currentHour >= room_timers[5][1][0] &&
currentHour <= (room_timers[5][1][2] + 1)){
room6Lights = checkOnTime(room_timers[5][1][0], room_timers[5][1][1],
room_timers[5][1][2], room_timers[5][1][3]);
}
if(room6Lights == 1 && lightLevel[5] == 1){
lightOutput[5] = 32;
}
else {
lightOutput[5] = 0;
lightLevel[5] = 0;
}
////////Room 7 (Bath 3)/////////////////////
if(timer_active[6][0] == 1 && currentHour >= room_timers[6][0][0] &&
currentHour <= (room_timers[6][0][2])){
room7Lights = checkOnTime(room_timers[6][0][0], room_timers[6][0][1],
room_timers[6][0][2], room_timers[6][0][3]);
}
if(timer_active[6][1] == 1 && currentHour >= room_timers[6][1][0] &&
currentHour <= (room_timers[6][1][2] + 1)){
room7Lights = checkOnTime(room_timers[6][1][0], room_timers[6][1][1],
room_timers[6][1][2], room_timers[6][1][3]);
}
if(room7Lights == 1 && lightLevel[6] == 1){
lightOutput[6] = 64;
}
else {
lightOutput[6] = 0;
lightLevel[6] = 0;
}
////////Room 8 (Bath 4)/////////////////////
if(timer_active[7][0] == 1 && currentHour >= room_timers[7][0][0] &&
currentHour <= (room_timers[7][0][2] + 1)){
room8Lights = checkOnTime(room_timers[7][0][0], room_timers[7][0][1],
room_timers[7][0][2], room_timers[7][0][3]);
}
if(timer_active[7][1] == 1 && currentHour >= room_timers[7][1][0] &&
currentHour <= (room_timers[7][1][2] + 1)){
room8Lights = checkOnTime(room_timers[7][1][0], room_timers[7][1][1],
room_timers[7][1][2], room_timers[7][1][3]);
}
if(room8Lights == 1 && lightLevel[7] == 1){
lightOutput[7] = 128;
}
else {
lightOutput[7] = 0;
lightLevel[7] = 0;
}
////////Room 9 (kitchen)/////////////////////
if(timer_active[8][0] == 1 && currentHour >= room_timers[8][0][0] &&
currentHour <= (room_timers[8][0][2] + 1)){
room9Lights = checkOnTime(room_timers[8][0][0], room_timers[8][0][1],
room_timers[8][0][2], room_timers[8][0][3]);
}
if(timer_active[8][1] == 1 && currentHour >= room_timers[8][1][0] &&
currentHour <= (room_timers[8][1][2] + 1)){
room9Lights = checkOnTime(room_timers[8][1][0], room_timers[8][1][1],
room_timers[8][1][2], room_timers[8][1][3]);
}
if(room9Lights == 1 && lightLevel[8] == 1){
lightOutput[8] = 256;
}
else {
lightOutput[8] = 0;
lightLevel[8] = 0;
}
////////Room 10 (corridor)/////////////////////
if(timer_active[9][0] == 1 && currentHour >= room_timers[9][0][0] &&
currentHour <= (room_timers[9][0][2] + 1)){
room10Lights = checkOnTime(room_timers[9][0][0], room_timers[9][0][1],
room_timers[9][0][2], room_timers[9][0][3]);
}
if(timer_active[9][1] == 1 && currentHour >= room_timers[9][1][0] &&
currentHour <= (room_timers[9][1][2] + 1)){
room9Lights = checkOnTime(room_timers[9][1][0], room_timers[9][1][1],
room_timers[9][1][2], room_timers[9][1][3]);
}
if(room10Lights == 1 && lightLevel[9] == 1){
lightOutput[9] = 512;
}
else {
lightOutput[9] = 0;
lightLevel[9] = 0;
}
////////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
}*/
if(outsideOnTime == 1 && lightLevel[15] == 1){
lightOutput[15] = 32768;
}
else {
lightOutput[15] = 0;
lightLevel[15] = 0;
}
}
else {
////////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
}*/
if(outsideOnTime == 1 && lightLevel[15] == 1){
lightOutput[15] = 32768;
}
else {
lightOutput[15] = 0;
lightLevel[15] = 0;
}
//////////////////room lights//////////////////////////////
lightStatus[16] = check_master(0); //check if doorswitch 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);
/////////////////////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 ////////////////////
//Serial.print("switchState 18 :");
//Serial.println(switchState[18]);
//Serial.print("Switch state old: ");
//Serial.println(masterSwitchStateOld);
//Serial.print("Light status 16: ");
//Serial.println(lightStatus[16]);
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
//Serial.println("Checking off status"); //debug only
currentTime = millis()/1000; //setting the time reference
offTime = roomTimer[16] + delayTime[14]; //setting the allowed delay time
//Serial.print("off Time: ");
//Serial.println(offTime);
//Serial.print("current Time: ");
//Serial.println(currentTime);
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
/*Serial.print("Light Output "); //debug only
Serial.print(i); //debug only
Serial.print(": "); //debug only
Serial.println(lightOutput[i]); //debug only
Serial.print("Light status: "); //debug only
Serial.println(lightStatus[i]); //debug only
Serial.print("Room Timer: "); //debug only
Serial.println(roomTimer[i]); //debug only
delay(500);*/
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
}
lcd.setCursor(0,0);
lcd.print(outputL, BIN);
//Serial.print("Output value: ");
//Serial.print(outputL);
//Serial.print(" ");
//Serial.println(outputL, BIN);
digitalWrite(latchPinOut, LOW); //setting the latch pin to low to
//be able to send the data
shiftOut(dataPinOut, clockPinOut, MSBFIRST, (outputL >> 8)); //sending the date for the
//second shift register
shiftOut(dataPinOut, clockPinOut, MSBFIRST, outputL); //sending the data for the
//first shift register
digitalWrite(latchPinOut, HIGH); //setting the latch pin back to
//high to finish the data transmission
outputL = 0; //setting the var holding the output
//number back to 0
delay(sensitivity); //delay to adjust how responsive the
//system will react
}
////////////////Shift In Function for Input processing ////////////
byte shiftIn(int myDataPin, int myClockPin) {
int i;
int temp = 0;
int pinState;
byte myDataIn = 0;
pinMode(myClockPin, OUTPUT);
pinMode(myDataPin, INPUT);
for(i=7; i>=0; i--) {
digitalWrite(myClockPin, LOW);
delayMicroseconds(2);
temp = digitalRead(myDataPin);
if(temp) {
pinState = 1;
myDataIn = myDataIn | (1 << i);
}
else {
pinState = 0;
}
//Serial.print("PinState: "); //debug only
//Serial.print(pinState); //debug only
//Serial.print(" "); //debug only
//Serial.println(myDataIn, BIN); //debug only
digitalWrite(myClockPin, HIGH);
}
//Serial.println(); //debug only
//Serial.println(myDataIn, BIN); //debug only
return myDataIn;
}
////////////function to check timer/////////
byte checkOnTime(byte hourOn, byte minuteOn, byte hourOff, byte minuteOff){
tmElements_t tm;
byte onTime = 0;
long timeNow = 0;
long onTrigger = 0;
long offTrigger = 0;
if(RTC.read(tm)){
timeNow = tmConvert_t(tmYearToCalendar(tm.Year), tm.Month, tm.Day, tm.Hour, tm.Minute, tm.Second);
onTrigger = tmConvert_t(tmYearToCalendar(tm.Year), tm.Month, tm.Day, hourOn, minuteOn, 0);
if(hourOff < hourOn) {
offTrigger = tmConvert_t(tmYearToCalendar(tm.Year), tm.Month, tm.Day+1, hourOff, minuteOff, 0);
}
else {
offTrigger = tmConvert_t(tmYearToCalendar(tm.Year), tm.Month, tm.Day, hourOff, minuteOff, 0);
}
if(timeNow >= onTrigger && timeNow < offTrigger) {
onTime = 1;
}
else {
onTime = 0;
}
}
//Serial.print(" Time now: ");
//Serial.println(timeNow);
//Serial.print(" On trigger: ");
//Serial.println(onTrigger);
//Serial.print("Off Trigger: ");
//Serial.println(offTrigger);
return onTime;
}
/////function to convert real time to unix timne////////
time_t tmConvert_t(int YYYY, byte MM, byte DD, byte hh, byte mm, byte ss){
tmElements_t tmSet;
tmSet.Year = YYYY - 1970;
tmSet.Month = MM;
tmSet.Day = DD;
tmSet.Hour = hh;
tmSet.Minute = mm;
tmSet.Second = ss;
return makeTime(tmSet); //convert to time_t
}
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;
}
}
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;
}
byte check_master(byte swNo){
if(switchState[swNo] == 1 && lightStatus[16] == 1) { //checking if PIR with switch Number was
//activated (bed 1)
lightStatus[16] = 0; //resetting master off
digitalWrite(doorMonitor, LOW); //resetting the door Monitor LED
}
//else {
//lightStatus[16] = 1;
// }
return lightStatus[16];
}
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
//set bed 1
if(switchState[pir] == 1 && priorityStatus[room] == 0) { //check if the PIR in bed 1 was
//activated and no priority was set
//Serial.println("We switch in the lights in bedroom 1"); //Debug only
lightOutput[room] = light; //switching on the lights – binary
//000000000000000000000001
lightStatus[room] = 1; //setting the light status for bed 1
lightOutput[14] = 16384; //make sure the master relay
//stays on
lightStatus[14] = 1; //setting the master 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];
}
int read_act_buttons(){
act_key_in = analogRead(1); //reading the sensor
delay(250); //button debounce delay
//Readings centered at 170 for menu
//203 for search and 252 for select
//Serial.print("Reading: ");
//Serial.println(act_key_in);
if(act_key_in < 160) return btnNone; //most likely result first
//adding a range of +/- 10 to compensate for bouncing
//readings
if(act_key_in > 160 && act_key_in < 180) return btnMenu;
if(act_key_in > 193 && act_key_in < 213) return btnSearch;
if(act_key_in > 242 && act_key_in < 262) return btnSelect;
return btnNone;
}
//Checking for a pressed menu button
void button_loop(){
//Serial.println("in button loop");
byte button = read_act_buttons(); //function call to read the buttons
if(button == btnMenu){ //if button menu was pressed
selectMenu(); //delay for readability
}
}
void selectMenu(){
//Serial.println("SelectMenu");
byte button = 0; //var holding the button value
byte subButton = 0; //var holding the subButton value
menuOption = 1; //current menu option
lcd.clear(); //clear screen
//print the retrieved string on lcd
lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(menu_table[0]))));
while(menuOption <= menuOptions){ //loop through menu options
button = read_act_buttons(); //check if button was pressed
if(button == btnMenu){ //if it was btn menu
menuOption++; //add 1 to menu option
if(menuOption == 2){ //if it's menu option 2
lcd.clear(); //clear display
//print retrieved string on lcd
lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(menu_table[1]))));
}
if(menuOption == 3){ //if it's menu option 3
lcd.clear(); //clear display
//print retrieved string on lcd
lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(menu_table[2]))));
}
if(menuOption == 4){ //if it's menu option 4
lcd.clear(); //clear lcd
//print retrieved string on lcd
lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(menu_table[3]))));
lcd.setCursor(0, 1); //set cursor to row 2 column 1
//print tetrieved message sdting
lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(msg_table[0]))));
}
if(menuOption == 5){ //if it's menu option 5
lcd.clear(); //clear display
//print retrieved string on lcd
lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(menu_table[4]))));
}
if(menuOption == 6){ //if it's menu option 6
lcd.clear(); //clear lcd
//print retrieved string on lcd
lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(menu_table[5]))));
lcd.setCursor(0, 1); //set cursor to row 2 column 1
//print retrieved message string
lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(msg_table[0]))));
}
if(menuOption == 7){ //if it's menu option 7
lcd.clear(); //clear lcd
//print retrieved string on lcd
lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(menu_table[6]))));
lcd.setCursor(15, 0); //set cursor to row 2 column 1
//print tetrieved message string
lcd.write(pgm_read_byte(&char_table[0]));
}
if(menuOption == 8){ //if it's menu option 8
lcd.clear(); //clear lcd
//print retrieved string on lcd
lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(menu_table[7]))));
lcd.setCursor(15, 0); //set cursor to row 2 column 1
//print tetrieved message string
lcd.write(pgm_read_byte(&char_table[0]));
}
if(menuOption == 9){ //if it's menu option 9
lcd.clear(); //clear lcd
//print retrieved string on lcd
lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(menu_table[8]))));
lcd.setCursor(15, 0); //set cursor to row 2 column 1
//print tetrieved message string
lcd.write(pgm_read_byte(&char_table[0]));
}
if(menuOption == 10){ //if it's menu option 10
lcd.clear(); //clear lcd
//print retrieved string on lcd
lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(menu_table[9]))));
lcd.setCursor(15, 0); //set cursor to row 2 column 1
//print tetrieved message string
lcd.write(pgm_read_byte(&char_table[0]));
}
if(menuOption == 11){ //if it's menu option 12
lcd.clear(); //clear lcd
//print retrieved string on lcd
lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(menu_table[10]))));
lcd.setCursor(15, 0); //set cursor to row 2 column 1
//print tetrieved message string
lcd.write(pgm_read_byte(&char_table[0]));
}
if(menuOption == 12){ //if it's menu option 13
lcd.clear(); //clear lcd
//print retrieved string on lcd
lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(menu_table[11]))));
lcd.setCursor(15, 0); //set cursor to row 2 column 1
//print tetrieved message sdting
lcd.write(pgm_read_byte(&char_table[0]));
}
if(menuOption == 13){ //if it's menu option 14
lcd.clear(); //clear lcd
//print retrieved string on lcd
lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(menu_table[12]))));
lcd.setCursor(15, 0); //set cursor to row 2 column 1
//print tetrieved message string
lcd.write(pgm_read_byte(&char_table[0]));
}
if(menuOption == 14){ //if it's menu option 15
lcd.clear(); //clear lcd
//print retrieved string on lcd
lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(menu_table[13]))));
lcd.setCursor(15, 0); //set cursor to row 2 column 1
//print tetrieved message string
lcd.write(pgm_read_byte(&char_table[0]));
}
if(menuOption == 15){ //if it's menu option 16
lcd.clear(); //clear lcd
//print retrieved string on lcd
lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(menu_table[14]))));
lcd.setCursor(15, 0); //set cursor to row 2 column 1
//print retrieved message string
lcd.write(pgm_read_byte(&char_table[0]));
}
if(menuOption == 16){ //if it's menu option 17
lcd.clear(); //clear lcd
//print retrieved string on lcd
lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(menu_table[15]))));
lcd.setCursor(15, 0); //set cursor to row 2 column 1
//print tetrieved message string
lcd.write(pgm_read_byte(&char_table[0]));
}
if(menuOption == 17){ //if it's menu option 18
lcd.clear(); //clear lcd
//print retrieved string on lcd
lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(menu_table[16]))));
lcd.setCursor(15, 0); //set cursor to row 2 column 1
//print retrieved message string
lcd.write(pgm_read_byte(&char_table[0]));
}
if(menuOption == 18){ //if it's menu option 19
lcd.clear(); //clear lcd
//print retrieved string on lcd
lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(menu_table[17]))));
lcd.setCursor(15, 0); //set cursor to row 2 column 1
//print tetrieved message sdting
lcd.write(pgm_read_byte(&char_table[0]));
}
if(menuOption == 19){ //if it's menu option 20
lcd.clear(); //clear lcd
//print retrieved string on lcd
lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(menu_table[18]))));
lcd.setCursor(15, 0); //set cursor to row 2 column 1
//print tetrieved message sdting
lcd.write(pgm_read_byte(&char_table[0]));
}
if(menuOption == 20){ //if it's menu option 21
lcd.clear(); //clear lcd
//print retrieved string on lcd
lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(menu_table[19]))));
lcd.setCursor(15, 0); //set cursor to row 2 column 1
//print retrieved message string
lcd.write(pgm_read_byte(&char_table[0]));
}
}
if(button == btnSelect){ //if the select button is pressed
if(menuOption == 1){ //amd menu option is 1
adjust_date_time(); //go to adust date and time
return;
}
if(menuOption == 2){ //and menu option is 2
sensitivity = get_Timer(17, sensitivity, 0, 1000); //go to function
return;
}
if(menuOption == 3){ //and menu option is 3
photoCellCutOff = get_Timer(18, photoCellCutOff, 0, 1024); //go to function
return;
}
if(menuOption == 4) return; //and menu option is 4 return (not used)
if(menuOption == 5){ //and menu option is 5
photoOutsideOff = get_Timer(19, photoOutsideOff, 0, 1024); //go to function
return;
}
if(menuOption == 6) return; //and menu option is 6 return (not used)
if(menuOption == 7){ //and menu option is 7 (room 1)
get_submenu(0);
}
if(menuOption == 8){ //and menu option is 8 (room 2)
get_submenu(1);
} //submenu end
if(menuOption == 9){ //and menu option is 9 (room 3)
get_submenu(2);
} //submenu end
if(menuOption == 10){ //and menu option is 9 (room 4)
get_submenu(3);
}
if(menuOption == 11){ //and menu option is 11 (room 5)
get_submenu(4);
}
if(menuOption == 12){ //and menu option is 12 (room 6)
get_submenu(5);
} //submenu end
if(menuOption == 13){ //and menu option is 13 (room 7)
get_submenu(6);
} //submenu end
if(menuOption == 14){ //and menu option is 14 (room 8)
get_submenu(7);
} //submenu end
if(menuOption == 15){ //and menu option is 15 (room 9)
get_submenu(8);
} //submenu end
if(menuOption == 16){ //and menu option is 16 (room 10)
get_submenu(9);
} //submenu end
}
}
}
void get_submenu(byte room){
byte subButton = 0; //resetting the button var
submenu = 1; //submenu counter
lcd.clear(); //clear screen
//retrieving and printing first sub menu point
lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(submenu_table[0]))));
lcd.print(room + 1); //printing assigned room number
while(submenu < submenus){ //loop through the sub menu points
subButton = read_act_buttons(); //checking for pressed buttons
if(subButton == btnMenu){ //if button Menu was pressed
submenu++; //add 1 - move to the next sub menu point
if(submenu == 2){ //if we are at sub menu 2
lcd.clear();
//retrieve and print second sub menu point
lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(submenu_table[1]))));
lcd.print(room + 1); //printing assigned room number
}
if(submenu == 3){ //if we are at sub menu 3
lcd.clear();
//retrieve and print second sub menu point
lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(submenu_table[2]))));
lcd.print(room + 1); //printing assigned room number
}
if(submenu == 4){ //if we are at sub menu 4
lcd.clear();
//retrieve and print second sub menu point
lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(submenu_table[3]))));
lcd.print(room + 1); //printing assigned room number 1
}
if(submenu == 5){ //if we are at sub menu 5
lcd.clear();
//retrieve and print second sub menu point
lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(submenu_table[4]))));
lcd.write(pgm_read_byte(&char_table[5])); //printing assigned room number 1
}
if(submenu == 6){ //if we are at sub menu 6
lcd.clear();
//retrieve and print second sub menu point
lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(submenu_table[5]))));
lcd.print(room + 1); //printing assigned room number
if(timer_active[room][2] == 2){
lcd.setCursor(0, 1);
lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(msg_table[0])))); //print not used
}
}
if(submenu == 7){ //if we are at sub menu 7
lcd.clear();
//retrieve and print second sub menu point
lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(submenu_table[6]))));
lcd.print(room + 1); //printing assigned room number
if(timer_active[room][2] == 2){
lcd.setCursor(0, 1);
lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(msg_table[0])))); //print not used
}
}
if(submenu == 8){ //if we are at sub menu 6
lcd.clear();
//retrieve and print second sub menu point
lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(submenu_table[7]))));
lcd.print(room + 1); //printing assigned room number
if(timer_active[room][3] == 2){
lcd.setCursor(0, 1);
lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(msg_table[0])))); //print not used
}
}
if(submenu == 9){ //if we are at sub menu 7
lcd.clear();
//retrieve and print second sub menu point
lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(submenu_table[8]))));
lcd.print(room + 1); //printing assigned room number
if(timer_active[room][3] == 2){
lcd.setCursor(0, 1);
lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(msg_table[0])))); //print not used
}
}
}
if(subButton == btnSelect){ //if we pressed btnSelect
if(submenu == 1){ //and submenu is 1
//call the function get_delay() to change the setting
delayTime[room] = get_delay(9, room, delayTime[room]);
return;
}
if(submenu == 2){ //and sub menu is 2
//call the function get_offon to change the setting
timer_active[room][0] = get_offon(10, room, timer_active[room][0]);
return;
}
if(submenu == 3){ //and submenu is 3
//call the function get_setTime() to change timer 1
get_setTime(room_timers[room][0][0], room_timers[room][0][1],
room_timers[room][0][2], room_timers[room][0][3],
room, 0);
return;
}
if(submenu == 4){ //and submenu is 4
//call the function get_offon() to change the setting
timer_active[room][1] = get_offon(11, room, timer_active[room][1]);
return;
}
if(submenu == 5){ //and submenu is 5
//call the function get_setTime() to change timer 2
get_setTime(room_timers[room][1][0], room_timers[room][1][1],
room_timers[room][1][2], room_timers[room][1][3],
room, 1);
return;
}
if(submenu == 6 && timer_active[room][2] != 2){ //and submenu is 6
//call the function get_offon() to change the setting
timer_active[room][2] = get_offon(12, room, timer_active[room][2]);
return;
}
if(submenu == 7 && timer_active[room][2] != 2){ //and submenu == 7
//call function get_setTime() to change timer 3
get_setTime(room_timers[room][2][0], room_timers[room][2][1],
room_timers[room][2][2], room_timers[room][2][3],
room, 2);
return;
}
if(submenu == 8 && timer_active[room][3] != 2){ //and submenu is 6
//call the function get_offon() to change the setting
timer_active[room][3] = get_offon(25, room, timer_active[room][3]);
return;
}
if(submenu == 9 && timer_active[room][3] != 2){ //and submenu == 7
//call function get_setTime() to change timer 3
get_setTime(room_timers[room][3][0], room_timers[room][3][1],
room_timers[room][3][2], room_timers[room][3][3],
room, 3);
return;
}
}
}
}
byte get_setTime( byte onTimeH, byte onTimeM, byte offTimeH,
byte offTimeM, byte room, byte timer){
byte subButton = 0;
onTimeH = get_Timer(13, onTimeH, 0, 23);
if(onTimeH >= 0 && onTimeH < 24){
onTimeM = get_Timer(14, onTimeM, 0, 59);
if(onTimeM < 60){
offTimeH = get_Timer(15, offTimeH, 0, 23);
if(offTimeH >= 0 && offTimeH < 24){
offTimeM = get_Timer(16, offTimeM, 0, 59);
if(offTimeM < 60){
lcd.clear();
lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(msg_table[6]))));
lcd.setCursor(0, 1);
if(onTimeH < 10) lcd.write(pgm_read_byte(&char_table[2])); //print 0
lcd.print(onTimeH);
lcd.write(pgm_read_byte(&char_table[3])); //print seperator
if(onTimeM < 10) lcd.write(pgm_read_byte(&char_table[2])); //print 0
lcd.print(onTimeM);
lcd.setCursor(11, 1);
if(offTimeH < 10) lcd.write(pgm_read_byte(&char_table[2])); //print 0
lcd.print(offTimeH);
lcd.write(pgm_read_byte(&char_table[3])); //print seperator
if(offTimeM < 10) lcd.write(pgm_read_byte(&char_table[2])); //print 0
lcd.print(offTimeM);
while(subButton != btnSelect){
subButton = read_act_buttons();
if(subButton == btnMenu) return 0;
if(subButton == btnSelect){
lcd.clear();
lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(msg_table[1]))));
delay(1000);
room_timers[room][timer][0] = onTimeH;
room_timers[room][timer][1] = onTimeM;
room_timers[room][timer][2] = offTimeH;
room_timers[room][timer][3] = offTimeM;
return 0;
}
}
}
}
}
}
}
//function to set a timer active / inactive
byte get_offon(byte info, byte room, byte reading){
byte subButton = 0; //resetting button value
lcd.clear(); //clear screen
lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(msg_table[info])))); //print passed info text
lcd.print(room + 1);
lcd.setCursor(0, 1); //set cursor to second row column 1
if(reading != 1) lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(msg_table[7])))); //if value is not 1 timer is off
//print off
if(reading == 1) lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(msg_table[8])))); //if timer is 1, timer is active
//print active
while(subButton != btnSelect){ //waiting for btnSelect to be pressed
subButton = read_act_buttons(); //checking for pressed buttons
if(subButton == btnSearch){ //if btnSearch is pressed
if(reading == 1) reading = 0; //set to 0 if 1
else
if(reading == 0) reading = 1; //set to 1 if 0
}
lcd.setCursor(0, 1); //set cursor to first column, second row
if(reading != 1) lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(msg_table[7])))); //print off if not set to 1
if(reading == 1) lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(msg_table[8])))); //print Active if set to 1
}
return reading;
}
//function to adjust the pir delay time
int get_delay(byte info, byte room, int reading){
byte subButton = 0; //resetting the button value
byte value = reading / 60; //converting to Minutes
lcd.clear(); //clear screen
lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(msg_table[info])))); //print passed message
lcd.print(room + 1);
lcd.setCursor(0, 1); //set cursor to second row, first column
if(value < 10) lcd.write(pgm_read_byte(&char_table[2])); //print 0
lcd.print(value); //print the passed value in minutes
lcd.setCursor(4, 1); //set cursor to second row, column 6
lcd.print("Min"); //just print Min.
while(subButton != btnSelect){ //wait for select btn
subButton = read_act_buttons(); //check if a button was pressed
if(subButton == btnSearch){ //if btnSearch was pressed
if(value > 0 && value < 30){ //we are within allowed range
value++; //add 1 to value while btnSearch is pressed
}
if(value >= 30) value = 1; //if reaches upper limit set to lower limit
lcd.setCursor(0, 1); //setting the cursor
if(value < 10) lcd.write(pgm_read_byte(&char_table[2])); //print 0
lcd.print(value); //printing the updated value
}
}
return value*60;
}
void adjust_date_time(){
byte button = 0; //set button var to 0
//function call to adjust the minute part of the system time
byte minuteT = get_Timer(20, tm.Minute, 0, 59);
if(minuteT >= 0 && minuteT < 60){ //check the returned result
//function call to adjust the hour part of the system time
byte hourT = get_Timer(21, tm.Hour, 0, 23);
if(hourT >= 0 && hourT < 24){ //check the returned result
//function call to adjust the day of the week
byte weekDay = get_weekday();
if(weekDay > 0 && weekDay <= 7){ //check the returned result
//function call to adjust the day of the month
byte monthDay = get_Timer(22, tm.Day, 1, 31);
if(monthDay >= 1 && monthDay <=31){ //check the returned result
//function call to adjust the month
byte monthT = get_Timer(23, tm.Month, 1, 12);
if(monthT >= 1 && monthT <= 12){ //check returned result
//function call to adjust the year
byte yearT = get_Timer(24, tmYearToCalendar(tm.Year)-2000, 0, 99);
if(yearT >= 0 && yearT <= 99){ //check the returned results
byte value = weekDay; //passing on the variable for calculations
//the following lcd statements print the adjusted results
//on the LCD
lcd.clear();
if(hourT < 10) lcd.write(pgm_read_byte(&char_table[2])); //print 0
lcd.print(hourT);
lcd.write(pgm_read_byte(&char_table[3])); //print seperator
if(minuteT < 10) lcd.write(pgm_read_byte(&char_table[2])); //print 0
lcd.print(minuteT);
lcd.setCursor(0, 1);
lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(weekday_table[value-1]))));
lcd.print(" ");
if(monthDay < 10) lcd.write(pgm_read_byte(&char_table[2])); //print 0
lcd.print(monthDay);
lcd.write(pgm_read_byte(&char_table[4])); //print dott
if(monthT < 10) lcd.write(pgm_read_byte(&char_table[2])); //print 0
lcd.print(monthT);
lcd.write(pgm_read_byte(&char_table[4])); //print dott
lcd.print(yearT);
while(button != btnSelect){ //loop until button select is pressed
button = read_act_buttons();
if(button == btnMenu) return; //if button Menu is pressed return without saving
if(button == btnSelect){ //if button select is pressed
lcd.clear();
lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(msg_table[1])))); //print saving
delay(1000);
//function call to save the adjusted values to RTC
save_time(minuteT, hourT, weekDay, monthDay, monthT, yearT);
}
}
return;
}
}
}
}
}
}
}
void save_time(byte mi, byte hr, byte wkDay, byte da, byte mo, byte yr){
Wire.beginTransmission(DS1307_ADDRESS); //starting transmission to DS 1307 RTC
Wire.write(zero); //needed leading zero byte
Wire.write(decToBcd(0)); //set seconds to 0
Wire.write(decToBcd(mi)); //set minutes to updated value
Wire.write(decToBcd(hr)); //set hour to updated value
Wire.write(decToBcd(wkDay)); //set weekday to updated value
Wire.write(decToBcd(da)); //set month day to updated value
Wire.write(decToBcd(mo)); //set month to updated value
Wire.write(decToBcd(yr)); //set year to updated value
Wire.write(zero); //send finishing zero byte
Wire.endTransmission(); //close transmission
}
byte decToBcd(byte val){
return ((val/10*16) + (val%10));
}
int get_Timer(byte info, int reading, int startVal, int maxCount){
byte button = 0; //reseting the button var
lcd.clear(); //clear the screen
lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(msg_table[info])))); //print the passed on info text
lcd.setCursor(0, 1); //set the cursor to second row first column
lcd.print(reading); //print the passed on value to be changed
while(button != btnSelect){ //wait for a button to be pressed
button = read_act_buttons(); //check if a button is pressed
if(button == btnSearch){ //if btnSearch is pressed
//if the reading is somewhere between the limit we add 1
//to the value with every loop through while the btnSearch
//is pressed
if(reading >= startVal && reading < maxCount) reading++;
if(reading >= maxCount)reading = startVal; //reset the value to be changed to
//the lower limit
lcd.setCursor(0, 1); //setting the cursor to first column, second row
lcd.print(reading); //print the updating value
lcd.print(" "); //print 4 empty spaces to delete left overs
//if we the value changes from high to
//low limit
}
}
return reading; //return the value
}
byte get_weekday(){
byte button = 0; //reseting the button var
byte value = currentDay; //passing the global weekday variable to a
//local one for calculations
//Serial.println(currentDay); //debug only
lcd.clear(); //clear the screen
//print what we are updating (weekday)
lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(msg_table[5]))));
lcd.setCursor(0, 1); //set the cursor to second row, first column
//print the current value for weekday
lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(weekday_table[value]))));
while(button != btnSelect){ //waite for a button to be pressed
button = read_act_buttons(); //checking for a button pressed
if(button == btnSearch){ //if it was btnSearch
if(value >= 0 && value < 7) value++; //checking between 0 and 6
if(value >= 7) value = 0; //setting the value back to 0
//Serial.print("Value: "); //debug only
//Serial.println(value); //debug only
lcd.setCursor(0, 1); //set cursor to second row, first column
//printing the ubdating value
lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(weekday_table[value]))));
}
}
return value + 1; //return the value and add 1 to be stored in RTC memory
}