Since I have already installed 3 of the
10 needed sub menus, I am running a bit short on memory again. It
went up again from 37% when we started building the menu to 53% of
RAM usage after activating the third sub menu even there where not
any additional functions etc. I don't think it has even anything to
do with the program flow it self. My closest guess is the way we are
passing the informative text messages to the functions. At this point
we will change the way we are doing this. The messages being passed
go in to the program memory together with all the other message
strings. Instead of passing the string we will pass the number
corresponding to the place in the message table and we will retrieve
the string from the program memory from the function using it. Even
not gaining a lot, I banned some numbers which been shown
repeatingly and a few other messages into the program memory.
Let's start and jump right to the
declaration part of the sketch and there in to the “menu and user
interface” section:
byte submenu = 0; //var to count current submenu option const byte submenus = 7; //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.2.7"; prog_char msg_5[] PROGMEM = "Weekday"; ///////////////////////////////////////////////////////////////////////////////// //>>>>>>>>>>>>>Addition starts here<<<<<<<<<<<< ///////////////////////////////////////////////////////////////////////////////// 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"; ////////////////////////////////////////////////////////////////////////////////// //>>>>>>>>>>>>>Addition ends here<<<<<<<<<<<<< //////////////////////////////////////////////////////////////////////////////////
Since we have everything stored in the
program memory, we have to tell the accompanying table that it's
there:
//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, //>>>>>>>>>>>>>addition starts here<<<<<<<<<<<<< //don't forget the “,” after msg_5 msg_6, msg_7, msg_8, msg_9, msg_10, msg_11, msg_12, msg_13, msg_14, msg_15, msg_16 //>>>>>>>>>>>>>addition ends here<<<<<<<<<<<<< };
We just move down to the next table and
add a few numbers:
//storing some special char's in the program memory const byte char_table[] PROGMEM = { B01111110, //Arrow right B01111111, //Arrow left B00110000, //0 B00111010, //separator B00101110, //dot //>>>>>>>>>>>>>Addition starts here<<<<<<<<<<<<< //don't forget to add “,” after B00101110 B00110001, //1 B00110010, //2 B00110011, //3 B00110100, //4 B00110101, //5 B00110110, //6 B00110111, //7 B00111000, //8 B00111001 //9 //>>>>>>>>>>>>>Addition ends here<<<<<<<<<<<<< }; //storing the main menu points in the program memory prog_char menu_0[] PROGMEM = "Date/Time"; prog_char menu_1[] PROGMEM = "Sensitivity";
Since we stored all this things in the
program memory, let's use it. We do a long jump right down to the
selectMenu() function and look at the sub menu we implemented in the
last post:
Replace all statements “lcd.print("1");
//printing assigned room number”
with
lcd.write(pgm_read_byte(&char_table[5]));
//printing assigned room number 1
if(menuOption == 6) return; //and menu option is 6 return (not used) if(menuOption == 7){ //and menu option is 7 (room 1) 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.write(pgm_read_byte(&char_table[5])); //printing assigned room number 1 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.write(pgm_read_byte(&char_table[5])); //printing assigned room number 1 } 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.write(pgm_read_byte(&char_table[5])); //printing assigned room number 1 } 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.write(pgm_read_byte(&char_table[5])); //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.write(pgm_read_byte(&char_table[5])); //printing assigned room number 1 } 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.write(pgm_read_byte(&char_table[5])); //printing assigned room number 1 } } if(subButton == btnSelect){ //if we pressed btnSelect if(submenu == 1){ //and submenu is 1 //call the function get_delay() to change the setting delayTime[0] = get_delay("R1 PIR Delay", dBed1); return; } if(submenu == 2){ //and sub menu is 2 //call the function get_offon to change the setting room1MActive = get_offon("R1 T1 On/Off", room1MActive); return; } if(submenu == 3){ //and submenu is 3 //call the function get_setTime() to change timer 1 get_setTime("R1 T1 On/Off", room1OnM[0], room1OnM[1], room1OffM[0], room1OffM[1], 1); return; } if(submenu == 4){ //and submenu is 4 //call the function get_offon() to change the setting room1O1Active = get_offon("R1 T2 On Off", room1O1Active); return; } if(submenu == 5){ //and submenu is 5 //call the function get_setTime() to change timer 2 get_setTime("R1 T2 On/Off", room1On1[0], room1On1[1], room1Off1[0], room1Off1[1], 2); return; } if(submenu == 6){ //and submenu is 6 //call the function get_offon() to change the setting room102Active = get_offon("R1 T3 On Off", room102Active); return; } if(submenu == 7){ //and submenu == 7 //call function get_setTime() to change timer 3 get_setTime("R1 T3 On/Off", room1On2[0], room1On2[1], room1Off2[0], room1Off2[1], 3); return; } } } } //submenu end Next we look at our function calls: if(submenu == 1){ //and submenu is 1 //call the function get_delay() to change the setting delayTime[0] = get_delay("R1 PIR Delay", dBed1); return; }
Remember, we stored the string “R1
PIR Delay” as “PIR Delay R” in the program memory.
We replace the string with the
msg_table place holder,
prog_char msg_9[] PROGMEM = "PIR
Delay R";
and we add the room number we are
dealing with, in that case it's room 1.
Our function call has to read now
if(submenu == 1){ //and submenu is 1 //call the function get_delay() to change the setting delayTime[0] = get_delay(9, 1, dBed1); return; }
Let's go straight to the function
get_delay() and change it so it fits our new function call.
The function entry
int get_delay(char delayText[], int reading){
changes to
int get_delay(byte info, byte room, int reading){
and the print statement
lcd.print(delayText); //print passed message
changes to
lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(msg_table[info])))); //print passed message lcd.print(room);
Now, the complete revised function
reads:
//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); 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; }
Now we go back where we left off in the
selectMenu() function and look at the next function call:
if(submenu == 2){ //and sub menu is 2 //call the function get_offon to change the setting room1MActive = get_offon("R1 T1 On/Off", room1MActive); return; }
We do the same changes as with the last
function call. We look up the string and replace it with the place
holder from the msg_table and again we add the room number we are
dealing with. The function call after changes has to read like this:
if(submenu == 2){ //and sub menu is 2 //call the function get_offon to change the setting room1MActive = get_offon(10, 1, room1MActive); return; }
Since we have this function call
another 2 times, just with different variables to be passed, let's
change them right away:
if(submenu == 4){ //and submenu is 4 //call the function get_offon() to change the setting room1O1Active = get_offon("R1 T2 On Off", room1O1Active); return; }
has to change to:
if(submenu == 4){ //and submenu is 4 //call the function get_offon() to change the setting room1O1Active = get_offon(11, 1, room1O1Active); return; }
and
if(submenu == 6){ //and submenu is 6 //call the function get_offon() to change the setting room102Active = get_offon("R1 T3 On Off", room102Active); return; }
has to change to:
if(submenu == 6){ //and submenu is 6 //call the function get_offon() to change the setting room102Active = get_offon(12, 1, room102Active); return; }
Next we go down to the function
get_offon() and match it with the function call:
The function entry
byte get_offon(char offonText[], byte reading){
changes to
byte get_offon(byte info, byte room, byte reading){
the print statement
lcd.print(offonText); //print passed info text
changes to
lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(msg_table[info])))); //print passed info text lcd.print(room);
We stay in the same function and
replace the print statement
if(reading != 1) lcd.print(“Off ”);
with
if(reading != 1) lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(msg_table[7])))); //if value is //not 1 timer is off
and
if(reading == 1) lcd.print(“Active”);
with
if(reading == 1) lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(msg_table[8])))); //if timer //is 1, print active
Please check careful, the last two
print statements are contained twice in the function. We need to
replace both of them.
Everything done? We go back again to
the selectMenu() function where we just left off and have a look at
the next function call. There I actually missed, that I was passing a
informative string to be printed, which wasn't even used for
something. So we just take out the part, where we pass it.
if(submenu == 3){ //and submenu is 3 //call the function get_setTime() to change timer 1 get_setTime("R1 T1 On/Off", room1OnM[0], room1OnM[1], room1OffM[0], room1OffM[1], 1); return; }
changes to
if(submenu == 3){ //and submenu is 3 //call the function get_setTime() to change timer 1 get_setTime(room1OnM[0], room1OnM[1], room1OffM[0], room1OffM[1], 1); return; }
We do the same thing with the other two
similar function calls.
if(submenu == 5){ //and submenu is 5 //call the function get_setTime() to change timer 2 get_setTime("R1 T2 On/Off", room1On1[0], room1On1[1], room1Off1[0], room1Off1[1], 2); return; }
changes to
if(submenu == 5){ //and submenu is 5 //call the function get_setTime() to change timer 2 get_setTime(room1On1[0], room1On1[1], room1Off1[0], room1Off1[1], 2); return; }
and
if(submenu == 5){ //and submenu is 5 //call the function get_setTime() to change timer 2 get_setTime(room1On1[0], room1On1[1], room1Off1[0], room1Off1[1], 2); return; }
to
if(submenu == 7){ //and submenu == 7 //call function get_setTime() to change timer 3 get_setTime(room1On2[0], room1On2[1], room1Off2[0], room1Off2[1], 3); return; }
Again, we have a look at the
corresponding function get_setTime() and do the changes accordingly:
byte get_setTime(char timeText[], byte onTimeH, byte onTimeM, byte offTimeH, byte offTimeM, byte room){
changes to
byte get_setTime(byte onTimeH, byte onTimeM, byte offTimeH, byte offTimeM, byte room){
the statement
onTimeH = get_Timer("ADJ Hour On", onTimeH, 0, 23);
changes to
onTimeH = get_Timer(13, onTimeH, 0, 23);
the statement
onTimeM = get_Timer("ADJ Minute On", onTimeM, 0, 59);
is replaced with
onTimeM = get_Timer(14, onTimeM, 0, 59);
the statement
offTimeH = get_Timer("ADJ Hour Off", offTimeH, 0, 23);
changes to
offTimeH = get_Timer(15, offTimeH, 0, 23);
and
offTimeM = get_Timer("ADJ Minute Off", offTimeM, 0, 59);
is replaced by
offTimeM = get_Timer(16, offTimeM, 0, 59);
The complete revised function
get_setTime reads now:
byte get_setTime( byte onTimeH, byte onTimeM, byte offTimeH, byte offTimeM, byte room){ 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 separator 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 separator 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); if(room == 1){ room1OnM[0] = onTimeH; room1OnM[1] = onTimeM; room1OffM[0] = offTimeH; room1OffM[1] = offTimeM; } if(room == 2){ room1On1[0] = onTimeH; room1On1[1] = onTimeM; room1Off1[0] = offTimeH; room1Off1[1] = offTimeM; } if(room == 3){ room1On2[0] = onTimeH; room1On2[1] = onTimeM; room1Off2[0] = offTimeH; room1Off2[1] = offTimeM; } return 0; } } } } } } }
I know, lots of changes and since we
just touched the function get_Timer(), there are a few more to come.
Let's start with the function get_Timer() itself:
int get_Timer(char timerText[], int reading, int startVal, int maxCount){
changes to
int get_Timer(byte info, int reading, int startVal, int maxCount){
and
lcd.print(timerText); //print the passed on info text
is replaced by
lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(msg_table[info])))); //print the passed on info text
Sorry, but since I forgot about the
get_Timer function in the beginning, we have to go back up and add a
few more variables to the msg_table and there fore we go back up to
the declaration part, where it says “menu and user interface” and
add:
//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.2.7"; 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"; /////////////////////////////////////////////////////////////////////////////////// //>>>>>>>>>>>>>Addition starts here<<<<<<<<<<<<< /////////////////////////////////////////////////////////////////////////////////// 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"; //>>>>>>>>>>>>>Addition ends here<<<<<<<<<<<<<
And again, not to forget to add the new
stored strings to the table below:
//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, //>>>>>>>>>>>>>Addition starts here<<<<<<<<<<<<< //please don't forget the “,” after msg_16 msg_17, msg_18, msg_19, msg_20, msg_21, msg_22, msg_23, msg_24 //>>>>>>>>>>>>>Addition ends here<<<<<<<<<<<<< }; //storing some special char's in the program memory const byte char_table[] PROGMEM = { B01111110, //Arrow right B01111111, //Arrow left B00110000, //0 B00111010, //separator
And why it's so much fun doing this, we
go back to the function selectMenu() and find the statement:
if(menuOption == 2){ //and menu option is 2 sensitivity = get_Timer("Set Sensitivity", sensitivity, 0, 1000); //go to function return; }
As we done before, we find the
placeholder for the string “Set Sensitivity” and replace it with
it, so the statement changes to:
if(menuOption == 2){ //and menu option is 2 sensitivity = get_Timer(17, sensitivity, 0, 1000); //go to function return; }
Next we find:
if(menuOption == 3){ //and menu option is 3 photoCellCutOff = get_Timer("Set photocell R", photoCellCutOff, 0, 1024); //go to function return; }
and replace it with
if(menuOption == 3){ //and menu option is 3 photoCellCutOff = get_Timer(18, photoCellCutOff, 0, 1024); //go to function return; }
The statement
if(menuOption == 5){ //and menu option is 5 photoOutsideOff = get_Timer("Set photocell O", photoOutsideOff, 0, 1024); //go to function return; }
changes to
if(menuOption == 5){ //and menu option is 5 photoOutsideOff = get_Timer(19, photoOutsideOff, 0, 1024); //go to function return; }
From here we go down to the function
adjust_date_time(); and do the following changes:
byte minuteT = get_Timer("ADJ Time Minute", tm.Minute, 0, 59);
changes to
byte minuteT = get_Timer(20, tm.Minute, 0, 59);
and
byte hourT = get_Timer("ADJ Time Hour", tm.Hour, 0, 23);
changes to
byte hourT = get_Timer(21, tm.Hour, 0, 23);
The statement
byte monthDay = get_Timer("ADJ Date Day", tm.Day, 1, 31);
is replaced by
byte monthDay = get_Timer(22, tm.Day, 1, 31);
and
byte monthT = get_Timer("ADJ Date Month", tm.Month, 1, 12);
changes to
byte monthT = get_Timer(23, tm.Month, 1, 12);
and finally
byte yearT = get_Timer("ADJ Date Year", tmYearToCalendar(tm.Year)-2000, 0, 99);
is replaced by
byte yearT = get_Timer(24, tmYearToCalendar(tm.Year)-2000, 0, 99);
If you compile the sketch now, we are
down to only 35% of RAM usage and the program memory is still only at
57%. That gives us now enough space for the rest of the sub menus. If
you couldn't follow everything, don't worry to much. Soon as the menu
is complete, I try to put another post with the fully updated sketch
together.
Now we add the next submenu and there
fore we go back right into the selectMenu() function. We start
exactly below the “}” which we marked with “//submenu end”.
If you look through, the structure is the same as the last sub menu.
A few things we need to take care of, if we just copy and paste the
sub menu. We do need to change a few variables. First, make sure to
change the statement marked with “//printing assigned room number”
to match the room you are working with. In this case we are at room 2
and the statement has to be:
lcd.write(pgm_read_byte(&char_table[6])); //printing assigned room number 2
Second, the function calls we just
changed and pass as second variable the room number, we have to make
sure, that this variable matches again with the room we are working
with like:
delayTime[0] = get_delay(9, 2, dBed2);
For room 2 we also have only two timers
set up so submenu 6 and submenu 7 are not used. So we add to the
option selection
lcd.setCursor(0, 1); lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(msg_table[0]))));
and if you have a look in the program
memory storage for the msg_table[], the place holder 0 stands for
“Not used”.
The same in the part where the
functions are called, you will notice the missing function calls:
if(submenu == 6)return; if(submenu == 7)return;
Now let's see what the complete submenu
no 2 looks like:
if(submenu == 7){ //and submenu == 7 //call function get_setTime() to change timer 3 get_setTime(room1On2[0], room1On2[1], room1Off2[0], room1Off2[1], 3); return; } } } } //submenu end /////////////////////////////////////////////////////////////////////////////////// //>>>>>>>>>>>>>Addition starts here<<<<<<<<<<<<< /////////////////////////////////////////////////////////////////////////////////// if(menuOption == 8){ //and menu option is 8 (room 2) 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.write(pgm_read_byte(&char_table[6])); //printing assigned room number 2 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.write(pgm_read_byte(&char_table[6])); //printing assigned room number 2 } 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.write(pgm_read_byte(&char_table[6])); //printing assigned room number 2 } 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.write(pgm_read_byte(&char_table[6])); //printing assigned room number 2 } 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[6])); //printing assigned room number 2 } 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.write(pgm_read_byte(&char_table[6])); //printing assigned room number 2 lcd.setCursor(0, 1); lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(msg_table[0])))); } 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.write(pgm_read_byte(&char_table[6])); //printing assigned room number 2 lcd.setCursor(0, 1); lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(msg_table[0])))); } } if(subButton == btnSelect){ //if we pressed btnSelect if(submenu == 1){ //and submenu is 1 //call the function get_delay() to change the setting delayTime[0] = get_delay(9, 2, dBed2); return; } if(submenu == 2){ //and sub menu is 2 //call the function get_offon to change the setting room2MActive = get_offon(10, 2, room2MActive); return; } if(submenu == 3){ //and submenu is 3 //call the function get_setTime() to change timer 1 get_setTime(room2OnM[0], room2OnM[1], room2OffM[0], room2OffM[1], 11); return; } if(submenu == 4){ //and submenu is 4 //call the function get_offon() to change the setting room201Active = get_offon(11, 2, room201Active); return; } if(submenu == 5){ //and submenu is 5 //call the function get_setTime() to change timer 2 get_setTime(room2On1[0], room2On1[1], room2Off1[0], room2Off1[1], 12); return; } if(submenu == 6)return; if(submenu == 7)return; } } } //submenu end
One final word to the changes we have
to make in the sub menu. One closer look to the last variable in the
get set time function call. Maybe you remember in the first submenu,
working room 1, in the 3 get_setTime() function calls, the 3 last
variables where 1, 2 and 3, standing in room 1 only for timer 1, 2
and 3. In room number 2, the 2 get_setTime() function calls contain
11 and 12 as last variables. I have to admit, being used to start
counting at 0 and not at 1, the first digit of 11 and 12 stands for
second room. The second digit of 11 and 12 stands for timer 1 and 2.
This system goes through all the following rooms. Another thing we
have to take care or is the fact, that the get_setTime() function
does not return a variable. The variables are returned within the
function and therefore we also have to update the function itself
while adding sub menus.
Let's move to get_setTime():
byte get_setTime( byte onTimeH, byte onTimeM, byte offTimeH, byte offTimeM, byte room){ 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 separator 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 separator 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); if(room == 1){ //room 1 timer 1 room1OnM[0] = onTimeH; room1OnM[1] = onTimeM; room1OffM[0] = offTimeH; room1OffM[1] = offTimeM; } if(room == 2){ //room 1 timer 2 room1On1[0] = onTimeH; room1On1[1] = onTimeM; room1Off1[0] = offTimeH; room1Off1[1] = offTimeM; } if(room == 3){ //room 1 timer 3 room1On2[0] = onTimeH; room1On2[1] = onTimeM; room1Off2[0] = offTimeH; room1Off2[1] = offTimeM; } //>>>>>>>>>>>>>Addition starts here<<<<<<<<<<<<< if(room = 11){ //room 2 timer 1 room2OnM[0] == onTimeH; room2OnM[1] == onTimeM; room2OffM[0] == offTimeH; room2OffM[1] == offTimeM; } if(room = 12){ //room 2 timer 2 room2On1[0] == onTimeH; room2On1[1] ==onTimeM; room2Off1[0] ==offTimeH; room2Off1[1] == offTimeM; } //>>>>>>>>>>>>>Addition ends here<<<<<<<<<<<<< return 0; } } } } } } }
As final for today, the submenu number
3 and looking at how things are done at the last addition, I think it
is not to difficult to follow the changes and how they where done.
if(menuOption == 9){ //and menu option is 9 (room 3) 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.write(pgm_read_byte(&char_table[7])); //printing assigned room number 3 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.write(pgm_read_byte(&char_table[7])); //printing assigned room number 3 } 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.write(pgm_read_byte(&char_table[7])); //printing assigned room number 3 } 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.write(pgm_read_byte(&char_table[7])); //printing assigned room number 3 } 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[7])); //printing assigned room number 3 } 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.write(pgm_read_byte(&char_table[7])); //printing assigned room number 3 } 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.write(pgm_read_byte(&char_table[7])); //printing assigned room number 3 } } if(subButton == btnSelect){ //if we pressed btnSelect if(submenu == 1){ //and submenu is 1 //call the function get_delay() to change the setting delayTime[0] = get_delay(9, 3, dBed3); return; } if(submenu == 2){ //and sub menu is 2 //call the function get_offon to change the setting room3MActive = get_offon(10, 3, room3MActive); return; } if(submenu == 3){ //and submenu is 3 //call the function get_setTime() to change timer 1 get_setTime(room3OnM[0], room3OnM[1], room3OffM[0], room3OffM[1], 21); return; } if(submenu == 4){ //and submenu is 4 //call the function get_offon() to change the setting room301Active = get_offon(11, 3, room301Active); return; } if(submenu == 5){ //and submenu is 5 //call the function get_setTime() to change timer 2 get_setTime(room3On1[0], room3On1[1], room3Off1[0], room3Off1[1], 22); return; } if(submenu == 6){ //and submenu is 6 //call the function get_offon() to change the setting room302Active = get_offon(12, 3, room302Active); return; } if(submenu == 7){ //and submenu == 7 //call function get_setTime() to change timer 3 get_setTime(room3On2[0], room3On2[1], room3Off2[0], room3Off2[1], 23); return; } } } } //submenu end
finally, don't forget to add the
following to the get_setTime() function:
if(room == 21){ room3OnM[0] = onTimeH; room3OnM[1] = onTimeM; room3OffM[0] = offTimeH; room3OffM[1] = offTimeM; } if(room == 22){ room3On1[0] = onTimeH; room3On1[1] = onTimeM; room3Off1[0] = offTimeH; room3Off1[1] = offTimeM; } if(room == 23){ room3On2[0] = onTimeH; room3On2[1] = onTimeM; room3Off2[0] = offTimeH; room3Off2[1] = offTimeM; }
No comments:
Post a Comment