Translate

Tuesday, 22 April 2014

Writing a menu for the Room Management System - Part 3


Today we add a few sub menus to make it a little more exiting. We jump right back into the variable declarations:

const int btnNone = 0;                                  //assignment for no button pressed
const byte arrowRight = B01111110;              //defining a special char to be printed
                                                                 //on the lcd (right arrow)
                                                                 //a list with special characters and it's
                                                                 //binary definitions can be found in the
                                                                 //Arduino Cookbook

int menuOption = 0;                                    //menuOption counter
int menuOptions = 19;                                 //available options

//>>>>>>>>>>addition starts here<<<<<<<<<<<<<<<<
int room1SubMenu = 0;                              //sub menu 1 option counter
int room1SubMenus = 7;                            //sub menu 1 available options
//>>>>>>>>>>addition ends here<<<<<<<<<<<<<<<<<

//The below variables are taken from the Room Management
//sketch and representing the default setup. This are also
//the values, the system will fall back to if something goes
//wrong like a power loss or even a system update.

/////////////////////////////////////////////////////////
//////////////var from RMU/////////////////////
int sensitivity = 500;                                 //var holding the over all responsiveness
                                                              //of the RMU representing a time delay
                                                              //between 0 and 1000 milliseconds at the
                                                              //of the main loop
int photoCellCutOff = 280;                        //The affected room lights switch on when
                                                              //the photocell reading goes below the set
                                                              //value
int photoOutsideOff = 260;                       //The outside light will switch on when
                                                             //the photocell reading goes below this
                                                             //value

//The following values representing delay times when lights switch
//off after the last detection off movement in a room in milliseconds
long dBed1 = 60000;

//>>>>>>>>>>addition starts here<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//this section is holding all variables related to automatic light switching
//while nobody is home.
byte room1MActive = 1;                      //variable to check if that timer is used
//>>>>>>>>>>addition ends here>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
////////////////////////////////////////////////////////
////////////////////////////////////////////////////////


From here, we move down to the end of the selectMenu() function. There we will be adding some sub menus:

if(menuOption == 4){                                //check the menu option
get_Timer("Set photo cut O", photoOutsideOff, 0, 1024); //function call
return;                                                      //return to main loop
}
if(menuOption == 5){                                //left empty cause not implemented yet
return;
}
//>>>>>>>>>>>>addition starts here<<<<<<<<<<<<<<<<<<<<
if(menuOption == 6){                                //Check the menu option
int subButton = 0;                                      //setting the button var to 0
room1SubMenu = 1;                                  //setting the sub menu to 1
lcd.clear();                                                //clear screen
lcd.print("R 1 PIR delay");                          //print the menu point
while(room1SubMenu < room1SubMenus){ //loop through the sub menus
subButton = read_buttons();                        //read button
if(subButton == btnMenu){                         //if Menu button was pressed
room1SubMenu++;                                    //add 1 to sub menu var
if(room1SubMenu == 2){                           //if sub menu = 2
lcd.clear();                                                //clear lcd screen
lcd.print("R1 HT 1 Active");                        //print menu point
}
if(room1SubMenu == 3){                            //if sub menu 3
lcd.clear();                                                 //clear screen
lcd.print("R1 Timer 1");                              //print menu point
}
if(room1SubMenu == 4){                            //if sub menu 4
lcd.clear();                                                 //clear screen
lcd.print("R1 HT 2 Active");                        //print menu point
}
if(room1SubMenu == 5){                           //if sub menu 5
lcd.clear();                                                //clear screen
lcd.print("R1 Timer 2");                             //print menu point
}
if(room1SubMenu == 6){                          //if sub menu 6
lcd.clear();                                               //clear lcd screen
lcd.print("R1 HT 3 Active");                      //print menu point
}
if(room1SubMenu == 7){                         //if sub menu 7
lcd.clear();                                              //clear screen
lcd.print("R1 Timer 3");                           //print menu point
}
}
if(subButton == btnSelect){                     //check if something was selected
if(room1SubMenu == 1){                       //if sub menu 1 was selected
get_delay("R1 PIR 1 Delay", dBed1);        //function call to set delay
return;                                                   //return to main loop
}
if(room1SubMenu == 2){                     //if sub menu 2 was selected
get_offon("R1 T1 On Off", room1MActive);    //function call to set timers active
return;                                                 //return to main loop
}
// to be continued
}
}
return;
}
}
//>>>>>>>>>>>>>>>>>addition ends here<<<<<<<<<<<<<<<<<<<<<<<<<<<
}
}


As you can see, we are walking through sub menus as we did with the main menu points. Lets have a quick look to a couple of more processing functions. We can add again right after the selectMenu() function:


//The entry variables into the function setting the time the light will stay on
//after the last detection of movement in a room during normal operation are
//again the text shown on lcd to describe what we are changing and the
//variable holding the current setting

int get_delay(char delayText[], long reading){
int subButton = 0;                   //resetting the button pressed
int value = reading / 60000;     //to show the value in minutes
                                            //we need to divide the value through
                                            //60000 since it is held in milliseconds
                                           // and 60000 milliseconds = 1 minute
lcd.clear();                           //clear lcd
lcd.print(delayText);              //print text var
lcd.setCursor(0, 1);               //set cursor to second row
lcd.print(value);                    //print current value in minutes
lcd.setCursor(6, 1);              //set cursor to pos 6 in second row
lcd.print("Min");                  //print Min for minutes
while(subButton != btnSelect){      //loop until we press select
subButton = read_buttons();          //read the button
if(subButton == btnSearch){         //if button search is pressed
if(value > 0 && value < 30){        //check if the value is within range
value++;                                     //add 1 with every loop
}
if(value >= 30){                          //if we reach max value
value = 0;                                   //start over at 0
value++;                                     //add 1 with each loop
}
lcd.setCursor(0, 1);                     //set cursor to beginning of second row
lcd.print(value);                           //print the updated results
lcd.print(" ");                               //clear the result part of the screen
}
}
if(room1SubMenu == 1){            //if select was pressed and sub menu 1 was selected
dBed1 = value * 60000;               //we convert the value back in to milliseconds
                                                 //and pass it back to the variable holding the value
                                                 //for further processing
}
}


The next function we have to have a look at is the one being responsible for changing the variable holding the on or off command for the timers activating lights on automated vacation switching.


//As in the other processing functions, we are entering with the describing text and the value we
//want to change

int get_offon(char offonText[], byte reading){
int subButton = 0;                                //setting the button var to 0
byte value = reading;                            //passing the incoming var for processing
lcd.clear();                                          //clear lcd
lcd.print(offonText);                            //print describing text
lcd.setCursor(0, 1);                             //set cursor to beginning of second row
if(value == 1){                                    //check the value of the variable
lcd.print("Active");                              //print active if 1
}
else if(value == 0){
lcd.print("Off");                                  //print off if 0
}
else {
value = 0;                                          //set to 0 if anything else is passed
lcd.print("Off");                                 //print off
}
while(subButton != btnSelect){            //loop until button select is pressed
subButton = read_buttons();                //read buttons
if(subButton == btnSearch){               //if button search is pressed
if(value == 1){                                  //and the value is 1
value = 0;                                         //change to 0
}
else if(value == 0){                            //if the value is 0
value = 1;                                         //change it to 1
}
}
lcd.setCursor(0, 1);                           //set cursor to beginning of row 2
if(value == 1){                                 //print updated values
lcd.print("Active");
}
if(value == 0){
lcd.print("Off");
}
lcd.print(" ");
}
if(room1SubMenu == 2){                   //if room1 sub menu 2 was selected
room1MActive = value;                      //pass the updated value back
}
}

The whole structure and the processing is not that difficult. The only problem with this approach is, that it is very memory consuming and only useful in small menus.
Over the next couple of days I try to add the missing function to update the timers and than I think everybody wanting to stay with this approach is able to carry on in the menu structure. I also got a delivery yesterday and I am pretty eager to get the LCD working using only 3 Atmega pins and a shift register. The next goal is to compact the menu and maybe it is still possible to squeeze it on the UNO board or the Atmega 328 without updating to a Mega...

No comments:

Post a Comment