Today we need to add the outside lights
into the menu and make some changes to the selectMenu() and the sub menu functions.
Lets start with adding the outside
lights as menu point. Therefore we go int the declaration part of our
sketch and jump into the “menu and user interface section”.
First we find the constant where we declare the amount of menu points
and change it to 22.
///////////////////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 //>>>>>>>>>>>>The line below change from menuOptions = 21 to menuOptions = 22 <<<<<<<<<<<<< const byte menuOptions = 22; //available menu options byte submenu = 0; //var to count current submenu option const byte submenus = 10; //available submenu options byte acSetup = 0; //var to count current ac setup menu options const byte acSetups = 4; //available ac setup menu options
Than we move down just a bit and add
the menu point to the menu_table:
//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 Setup"; prog_char menu_17[] PROGMEM = "AC 1"; prog_char menu_18[] PROGMEM = "AC 2"; prog_char menu_19[] PROGMEM = "AC 3"; prog_char menu_20[] PROGMEM = "AC 4"; //>>>>>>>>>>>>>ADD the line below<<<<<<<<<<<<<< prog_char menu_21[] PROGMEM = "Outside Lights"; 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, menu_20, //<<<<<<<<<<<<<don't forget to add ',' //>>>>>>>>>>>>>ADD the line below<<<<<<<<<<<<<< menu_21 };
Now we move down to the selectMenu()
function and change the if-statements going through the menu points
into a switch – statement:
OK, lets move down into the
selectMenu() function and change it to:
void selectMenu(){ //Serial.println("Select Menu"); 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 //>>>>>>>>>>>>>Modification starts here<<<<<<<<<<<<< lcd.clear(); //clear screen //retrieve and print the actual menu point lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(menu_table[menuOption -1])))); switch(menuOption){ case 2: //only menu point no option case 3: //only menu point no option case 5: //only menu point no option break; case 4: //menu point with option not used case 6: //menu point with option not used lcd.setCursor(0,1); //set cursor column 0, row 1 //retrieve and print "not used" lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(msg_table[0])))); break; case 7: //menu point with option arrow right case 8: //menu point with option arrow right case 9: //menu point with option arrow right case 10: //menu point with option arrow right case 11: //menu point with option arrow right case 12: //menu point with option arrow right case 13: //menu point with option arrow right case 14: //menu point with option arrow right case 15: //menu point with option arrow right case 16: //menu point with option arrow right case 17: //menu point with option arrow right case 18: //menu point with option arrow right case 19: //menu point with option arrow right case 20: //menu point with option arrow right case 21: //menu point with option arrow right case 22: //menu point with option arrow right lcd.setCursor(15,0); //set cursor column 15, row 0 //retrieve and print "arrow right" lcd.write(pgm_read_byte(&char_table[0])); break; } //>>>>>>>>>>>>>>Modification ends here<<<<<<<<<<<<<< } if(button == btnSelect){ //if the select button is pressed if(menuOption == 1){ //and menu option is 1 adjust_date_time(); //go to adjust date and time return; }
What have we done here. First we placed
another lcd.print statement right after
menuOption++
again, we retrieve the menu option and
print it but as counter we the variable menuOption – 1.
- 1 again cause of counting issues, arrays and tables start counting at 0...
lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(menu_table[menuOption – 1]))));
And now comes the actual trick –
Thank you Reuben – I didn't know you can group the cases in a
switch command so nice.
Instead of going through all the single
menu points we look at the ones printing out the same kind of
message.
Option 2, 3 and 5 are printing only the
plain menu point
which we are doing with
lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(menu_table[menuOption – 1]))));
This and the needed lcd.clear() command
is done right after menuOption++.
In that case we do not need to add
anything into the switch cases. We group them together and finish the
group with a break command.
The options 4 and 6 are implemented
but not used yet. This 2 options are printing a additional
informative message, that this menu point is not used. Now we group
menu point 4 and 6 together and add the additional code after the
last case in the group and close the group again with a break command
like:
case 4: //menu point with option not used case 6: //menu point with option not used lcd.setCursor(0,1); //set cursor column 0, row 1 //retrieve and print "not used" lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(msg_table[0])))); break;
The menu points 7 to 22 also have one
thing in common, they all print a right arrow after the menu point to
indicate an existing sub menu for this point. Here again we group
them together and add the code needed to print the arrow after the
last case in the group, ending the group again with a break command:
case 7: //menu point with option arrow right case 8: //menu point with option arrow right case 9: //menu point with option arrow right case 10: //menu point with option arrow right case 11: //menu point with option arrow right case 12: //menu point with option arrow right case 13: //menu point with option arrow right case 14: //menu point with option arrow right case 15: //menu point with option arrow right case 16: //menu point with option arrow right case 17: //menu point with option arrow right case 18: //menu point with option arrow right case 19: //menu point with option arrow right case 20: //menu point with option arrow right case 21: //menu point with option arrow right case 22: //menu point with option arrow right lcd.setCursor(15,0); //set cursor column 15, row 0 //retrieve and print "arrow right" lcd.write(pgm_read_byte(&char_table[0])); break;
Now adding another menu point is easy
and if you have a closer look, I already sneaked the menu point (case
22:) for the outside lights in.
But first, why we are at it, we change
our sub menus the same way. We jump down to the get_submenu()
function and change it like this:
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 //>>>>>>>>>>>>>CHANGES start here<<<<<<<<<<<<< lcd.clear(); //clear screen //retrieve and print menu options lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(submenu_table[submenu -1])))); lcd.print(room + 1); //printing assigned room number switch(submenu){ case 2: //only sub menu point no option case 3: //only sub menu point no option case 4: //only sub menu point no option case 5: //only sub menu point no option break; case 6: //menu point + checking timer 2 options case 7: //menu point + checking timer 2 options if(timer_active[room][2] == 2){ //if set to 2 lcd.setCursor(0, 1); //set cursor to column 0, row 1 //retrieve and print not used lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(msg_table[0])))); //print not used } break; case 8: //menu point + checking timer 3 options case 9: //menu point + checking timer 3 options if(timer_active[room][3] == 2){ //if set to 2 lcd.setCursor(0, 1); //set cursor to column 0, row 1 //retrieve and print not used lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(msg_table[0])))); //print not used } break; } //>>>>>>>>>>>>>>CHANGES end here<<<<<<<<<<<<<< } 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; }
Next we do the ac_get_setup() function.
Since we don't have any changes in the menu point handling, we can
deal with it a little different. Again a big thank you to Reuben for
explaining. Here we replace the whole function as follows:
void get_ac_setup(){ byte subButton = 0; acSetup = 1; //submenu counter (AC Mode) lcd.clear(); //clear screen //retrieving and printing first sub menu point lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(ac_setup_table[0])))); while(acSetup <= acSetups){ //loop through the submenu points subButton = read_act_buttons(); //checking for pressed buttons if(subButton == btnMenu){ //if button menu was pressed acSetup++; //add 1 - move to the next point lcd.clear(); //printing and retrieving the menu points lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(ac_setup_table[acSetup - 1])))); } if(subButton == btnSelect){ //if btn select was pressed switch(acSetup){ //going right through the options case 1: //call the function get_timer() to update settings ac_op_mode = get_Timer(26, ac_op_mode, 1, 4); return; case 2: //call the function get_timer() to update settings ac_set_temp = get_Timer(27, ac_set_temp, 18, 32); return; case 3: adj_seasons(); return; case 4: //call the function get_timer() to update settings acSwitchDelay = get_Timer(28, acSwitchDelay, 1, 5); return; } } } }
and the ac_get_sub() function, we change the same way as the get_ac_setup() function:
void get_ac_sub(byte room){ byte subButton = 0; //resetting the button var acSubOption = 1; //submenu counter lcd.clear(); //clear screen //retrieving and printing first submenu point lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(ac_sub_table[0])))); lcd.print(room - 9); //printing assigned room number while(acSubOption <= acSubOptions){ //loop through the submenu points subButton = read_act_buttons(); //checking for pressed buttons if(subButton == btnMenu){ //if btn menu was pressed acSubOption++; // add 1 to move to the next sub menu point lcd.clear(); //retrieving and printing the menu points lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(ac_sub_table[acSubOption - 1])))); lcd.print(room - 9); //printing assigned room number } if(subButton == btnSelect){ switch(acSubOption){ case 1: //only sub menu point no option //call the function get_delay() to change the setting delayTime[room] = get_delay(37, room, delayTime[room]); return; case 2: //only sub menu point no option //call the function get_offon to change setting ac_master_bypass[room - 10] = get_offon(38, room, ac_master_bypass[room - 10]); return; case 3: //only sub menu point no option //call the function get_offon to change setting timer_active[room][0] = get_offon(10, room, timer_active[room][0]); return; case 4: //only sub menu point no option //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; case 5: //only sub menu point no option //call the function get_offon() to change the setting timer_active[room][1] = get_offon(11, room, timer_active[room][1]); return; case 6: //only sub menu point no option //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; case 7: //only sub menu point no option //call the function get_offon() to change the setting timer_active[room][2] = get_offon(12, room, timer_active[room][2]); return; case 8: //only sub menu point no option //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; case 9: //only sub menu point no option //call the function get_offon() to change the setting timer_active[room][3] = get_offon(25, room, timer_active[room][3]); return; case 10: //only sub menu point no option //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; } } } }
Before we start building the submenu
for the outside lights, lets try and make a little space again in our
memory. We jump up into the declaration part again and remove all the
single delay declarations since we are storing them in an array after
anyway:
//>>>>>>>>>>>>>Add the delayTime – array with the actual delay times<<<<<<<<<<<<< int delayTime[16] = {120, 120, 120, 600, 180, 180, 180, 180, 120, 120, 120, 120, 120, 120, 240, 0}; //The block below can actually be deleted. However, I left it commented out just to have //a better few of what is what in the array /*delayTime[0] = 120; //int dBed1 = 120; //delay time in seconds for bedroom 1 delayTime[1] = 120; //int dBed2 = 120; //delay time in seconds for bedroom 2 delayTime[2] = 120; //int dBed3 = 120; //delay time in seconds for bedroom 3 delayTime[3] = 600; //int dLiving = 600; //delay time in seconds for living area delayTime[4] = 180; //int dBath1 = 180; //delay time in seconds for bathroom 1 delayTime[5] = 180; //int dBath2 = 180; //delay time in seconds for bathroom 2 delayTime[6] = 180; //int dBath3 = 180; //delay time in seconds for bathroom 3 delayTime[7] = 180; //int dBath4 = 180; //delay time in seconds for bathroom 4 delayTime[8] = 120; //int dKitchen = 120; //delay time in seconds for kitchen delayTime[9] = 120; //int dCorridor = 60; //delay time in seconds for corridor delayTime[10] = 120; //int dAC1 = 120; //delay time in seconds for AC 1 (bed1) delayTime[11] = 120; //int dAC2 = 120; //delay time in seconds for AC 2 (bed2) delayTime[12] = 120; //int dAC3 = 120; //delay time in seconds for AC 3 (bed3) delayTime[13] = 120; //int dAC4 = 120; //delay time in seconds for AC 4 (living) delayTime[14] = 240; //int dMaster = 240; //delay time in seconds for Master Off delayTime[15] = 0; //free*/
Now we have to go down to the “/all
the other variables/” section and delete the delayTime array
residing there.
///////////////////////////all the other variables///////////////////////////// /////////////////////////////////////////////////////////////////////////////// //////////////Sensor and timer variables////////////// //>>>>>>>>>>>>>>DELETE the statement below<<<<<<<<<<<<< int delayTime[16] = {dBed1, dBed2, dBed3, dLiving, dBath1, dBath2, dBath3, dBath4, dKitchen, dCorridor, dAC1, dAC2, dAC3, dAC4, dMaster, 0}; //>>>>>>>>>>>>>>Delete ends here<<<<<<<<<<<<<< byte temperatur1 = 0; //holding temperature for room 1 unsigned int lastRun[4] = {0}; //var to hold var when ac was last running int sensorValue = 0; //holding the indicated sensor value of the photocell byte photocellSwitch = 0; //holding the switch command after
No comments:
Post a Comment