Translate

Monday, 12 May 2014

Room Management System – The Menu – part 5


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