Translate

Friday 30 May 2014

Room Management System – The Menu - part 11


First thing today, we are building the missing function from my last post, adj_seasons(). But before we start doing this, we need to add a few more variables first. As usual we start with the declaration part and this time we jump right down into the “menu and user interface” section. There we add a few lines to the msg_table:

//Storing some menu messages in the program memory

prog_char msg_0[] PROGMEM = "Not Used";

prog_char msg_1[] PROGMEM = "Saving....";

prog_char msg_2[] PROGMEM = "Setup mode";

prog_char msg_3[] PROGMEM = "Starting....";

prog_char msg_4[] PROGMEM = "RMU 1.3.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";

prog_char msg_17[] PROGMEM = "Set Sensitivity";

prog_char msg_18[] PROGMEM = "Set photocell R";

prog_char msg_19[] PROGMEM = "Set photocell O";

prog_char msg_20[] PROGMEM = "ADJ Time Minute";

prog_char msg_21[] PROGMEM = "ADJ Time Hour";

prog_char msg_22[] PROGMEM = "ADJ Date Day";

prog_char msg_23[] PROGMEM = "ADJ Date Month";

prog_char msg_24[] PROGMEM = "ADJ Date Year";

prog_char msg_25[] PROGMEM = "T4 On/Off R";

prog_char msg_26[] PROGMEM = "ADJ AC Mode";

prog_char msg_27[] PROGMEM = "AC Set Temp";

prog_char msg_28[] PROGMEM = "AC Switch Delay";

//>>>>>>>>>>>>>Addition starts here<<<<<<<<<<<<<<

prog_char msg_29[] PROGMEM = "AC Seas 1 Start";

prog_char msg_30[] PROGMEM = "AC Seas 1 End";

prog_char msg_31[] PROGMEM = "AC Seas 2 Start";

prog_char msg_32[] PROGMEM = "AC Seas 2 End";

prog_char msg_33[] PROGMEM = "AC Seas 3 Start";

prog_char msg_34[] PROGMEM = "AC Seas 3 End";

prog_char msg_35[] PROGMEM = "AC Seas 4 Start";

prog_char msg_36[] PROGMEM = "AC Seas 4 End";

//>>>>>>>>>>>>>ADDITION ends here<<<<<<<<<<<<<

//Creating the table for the stored menu messages

PROGMEM const char *msg_table[] = {

msg_0,

msg_1,

msg_2,

msg_3,

msg_4,

msg_5,

msg_6,

msg_7,

msg_8,

msg_9,

msg_10,

msg_11,

msg_12,

msg_13,

msg_14,

msg_15,

msg_16,

msg_17,

msg_18,

msg_19,

msg_20,

msg_21,

msg_22,

msg_23,

msg_24,

msg_25,

msg_26,

msg_27,

msg_28, //<<<<<<<<<<<<<Don't forget to add ','

//>>>>>>>>>>>>>Addition starts here<<<<<<<<<<<<<<

msg_29,

msg_30,

msg_31,

msg_32,

msg_33,

msg_34,

msg_35,

msg_36

//>>>>>>>>>>>>>>Addition ends here<<<<<<<<<<<<<

};

//storing some special char's in the program memory

While I was writing the Ac-menu part, my little mix up with numbers caught me again. We all now arrays start counting with a 0 and having 20 spaces in an array the last count is 19. Going in to a counting routine, giving a min count of 0 and a max count of 20, it always will go through the 20 spaces in an array from 0 to 19. But using the same routine and counting through 20 event, starting with 1 and giving it min count of 1 and a max count of 20, we always will miss the last event. Doesn't make sense?
OK, lets look at the get_Timer function get_Timer(varForInfoText, actValue, minCount, maxCount).
Lets forget about the first 2 variables we are passing and concentrate on the minCount and maxCount.
The routine dealing with this values is a if-statement:
if(reading >= startVal && reading < maxCount) reading++;

Lets get it apart. If the variable reading is equal to or bigger than the var startVal (minCount) and the variable reading is smaller than maxCount we add 1 to the variable reading.
Back to our array example. If I pass the numbers stepping through an array with a max count of 20 and a min value of 0 because arrays start counting at 0, I always get my 20 values done since the last counter in the array is 19, matches with smaller than 20 (maxCount).
If I need to count through other values like days of a month, the first one is 1 and the last one is 31 and I pass this in to my function minCount 1 and maxCount 31, with the same routine my 31 day will never show since the we are stating “and the variable reading is smaller than maxCount” (&& reading < maxCount). If we want the same routine to step through 31 days we need to pass as maxCount 32! The same goes for month. To step through 12 month, we need to pass as max count 13 cause of “&& reading < maxCount”. Now it make sense I hope. Since we need to change a couple of variables in the get_ac_setup() function and that is also the reason why we are passing on a 13 as max count while going through month etc.

Lets jump into the get_ac_setup() function

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

if(acSetup == 2){ //if we are at submenu 2 (Set Temp)

lcd.clear(); //clear screen

//retrieving and printing second sub menu point

lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(ac_setup_table[1]))));

}

if(acSetup == 3){ //if we are at submenu 3 (Seasons)

lcd.clear();

//retrieving and printing the third sub menu point

lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(ac_setup_table[2]))));

}

if(acSetup == 4){ //if we are at submenu 4 (Switch delay)

lcd.clear(); //clear screen

//retrieving and printing sub menu point 4

lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(ac_setup_table[3]))));

}

}

if(subButton == btnSelect){ //if btn select was pressed

if(acSetup == 1){ //and sub menu is 1

//call function get_Timer

ac_op_mode = get_Timer(26, ac_op_mode, 1, 3); //<<<<<<<<<<<<<CHANGE to get_Timer(26, ac_op_mode, 1, 4)

return;

}

if(acSetup == 2){ //and sub menu is 2

//call function get_Timer

ac_set_temp = get_Timer(27, ac_set_temp, 18, 32);

return;

}

if(acSetup == 3){ //and submenu is 3

//call function adj_Seasons

adj_seasons();

return;

}

if(acSetup == 4){

//call function get_Timer

acSwitchDelay = get_Timer(28, acSwitchDelay, 1, 5);

return;

}

}

}

}

OK, now we can go through the 3 available operating modes. Next task today is building the function to adjust the seasonal boundaries.

void adj_seasons(){

byte subButton = 0; //set button var to 0

ac_periode[0][0] = get_Timer(29, ac_periode[0][0], 0, 13); //get the first value

if(ac_periode[0][0] >= 0 && ac_periode[0][0] <= 12){ //check if it is within range

if(ac_periode[0][0] == 12){ //predefine closing value

ac_periode[0][1] = 1;

ac_periode[0][1] = get_Timer(30, ac_periode[0][1], 1, 13);

}

else if(ac_periode[0][0] != 12){

ac_periode[0][1] = ac_periode[0][0] + 1;

ac_periode[0][1] = get_Timer(30, ac_periode[0][1], ac_periode[0][1], 13);

}

if(ac_periode[0][1] >= 0 && ac_periode[0][1] <= 12){

ac_periode[1][0] = get_Timer(31, ac_periode[1][0], 0, 13);

if(ac_periode[1][0] >= 0 && ac_periode[1][0] <= 12){

if(ac_periode[1][0] == 12){

ac_periode[1][1] = 1;

ac_periode[1][1] = get_Timer(32, ac_periode[1][1], 1, 13);

}

else if(ac_periode[1][0] != 12){

ac_periode[1][1] = ac_periode[1][0] + 1;

ac_periode[1][1] = get_Timer(32, ac_periode[1][1], ac_periode[0][1], 13);

}

if(ac_periode[1][1] >= 0 && ac_periode[1][1] <= 12){

ac_periode[2][0] = get_Timer(33, ac_periode[2][0], 0, 13);

if(ac_periode[2][0] >= 0 && ac_periode[2][0] <= 12){

if(ac_periode[2][0] == 12){

ac_periode[2][1] = 1;

ac_periode[2][1] = get_Timer(34, ac_periode[2][1], 1, 13);

}

else if(ac_periode[2][0] != 12){

ac_periode[2][1] = ac_periode[2][0] + 1;

ac_periode[2][1] = get_Timer(34, ac_periode[2][1], ac_periode[2][1], 13);

}

if(ac_periode[2][1] >= 0 && ac_periode[2][1] <= 12){

ac_periode[3][0] = get_Timer(35, ac_periode[3][0], 0, 13);

if(ac_periode[3][0] >= 0 && ac_periode[3][0] <= 12){

if(ac_periode[3][0] == 12){

ac_periode[3][1] = 1;

ac_periode[3][1] = get_Timer(36, ac_periode[3][1], 1, 13);

}

else if(ac_periode[3][0] != 12){

ac_periode[3][1] = ac_periode[2][0] + 1;

ac_periode[3][1] = get_Timer(36, ac_periode[3][1], ac_periode[3][1], 13);

}

lcd.clear();

if(ac_periode[0][0] < 10) lcd.write(pgm_read_byte(&char_table[2])); //print 0

lcd.print(ac_periode[0][0]);

lcd.print(" | ");

if(ac_periode[0][1] < 10) lcd.write(pgm_read_byte(&char_table[2])); //print 0

lcd.print(ac_periode[0][1]);

lcd.print(" ");

if(ac_periode[1][0] < 10) lcd.write(pgm_read_byte(&char_table[2])); //print 0

lcd.print(ac_periode[1][0]);

lcd.print(" | ");

if(ac_periode[1][1] < 10) lcd.write(pgm_read_byte(&char_table[2])); //print 0

lcd.print(ac_periode[1][1]);

lcd.setCursor(0, 1);

if(ac_periode[2][0] < 10) lcd.write(pgm_read_byte(&char_table[2])); //print 0

lcd.print(ac_periode[2][0]);

lcd.print(" | ");

if(ac_periode[2][1] < 10) lcd.write(pgm_read_byte(&char_table[2])); //print 0

lcd.print(ac_periode[2][1]);

lcd.print(" ");

if(ac_periode[3][0] < 10) lcd.write(pgm_read_byte(&char_table[2])); //print 0

lcd.print(ac_periode[3][0]);

lcd.print(" | ");

if(ac_periode[3][1] < 10) lcd.write(pgm_read_byte(&char_table[2])); //print 0

lcd.print(ac_periode[3][1]);

while(subButton != btnSelect){

lcd.clear();

lcd.print(strcpy_P(buffer_M, (char*)pgm_read_word(&(msg_table[1]))));

delay(1000);

//save the values

return;

}

}

}

}

}

}

}

}

}

The basic structure is also nothing new. We have used the same structure in the date and time adjustment and in the timer adjustments. The only difference is that we add a limitation. If we start a season at February (2) the count for the end of that season will only allow to go through the remaining month of the year March to December.

Let's carry on with the AC submenu and jump back up into the declaration part of the sketch. There we have to add a couple of variables and store the ac submenu points in the program memory. We go right into the “menu and user interface” section:

///////////////////////////////////////////////////////////////////////////

///////////////////Menu and user interface/////////////////////////////////

///////////////////////////////////////////////////////////////////////////

const byte btnMenu = 1; //defining the menu button – moves through the menu

const byte btnSearch = 2; //defining the search button – moves through values

const byte btnSelect = 3; //defining the select button – selects a menu or a value

const byte btnNone = 0; //defining the non button pressed var

int act_key_in = 0; //var holding the key related sensor reading

byte menuOption = 0; //var to count current menu option

const byte menuOptions = 21; //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

//>>>>>>>>>>>>>ADDITION starts here<<<<<<<<<<<<<<<

byte acSubOption = 0; //var to count current ac sub menu options

const byte acSubOptions = 10; //available ac sub menu options

//>>>>>>>>>>>>>>Addition ends here<<<<<<<<<<<<<<<

from here we go down to the msg_table[] and add a couple of lines:

//Storing some menu messages in the program memory

prog_char msg_0[] PROGMEM = "Not Used";

prog_char msg_1[] PROGMEM = "Saving....";

prog_char msg_2[] PROGMEM = "Setup mode";

prog_char msg_3[] PROGMEM = "Starting....";

prog_char msg_4[] PROGMEM = "RMU 1.3.8";

prog_char msg_5[] PROGMEM = "Weekday";

prog_char msg_6[] PROGMEM = "On TIMER Off";

prog_char msg_7[] PROGMEM = "Off ";

prog_char msg_8[] PROGMEM = "Active";

prog_char msg_9[] PROGMEM = "PIR Delay R";

prog_char msg_10[] PROGMEM = "T1 On/Off R";

prog_char msg_11[] PROGMEM = "T2 On/Off R";

prog_char msg_12[] PROGMEM = "T3 On/Off R";

prog_char msg_13[] PROGMEM = "ADJ Hour On";

prog_char msg_14[] PROGMEM = "ADJ Minute On";

prog_char msg_15[] PROGMEM = "ADJ Hour Off";

prog_char msg_16[] PROGMEM = "ADJ Minute Off";

prog_char msg_17[] PROGMEM = "Set Sensitivity";

prog_char msg_18[] PROGMEM = "Set photocell R";

prog_char msg_19[] PROGMEM = "Set photocell O";

prog_char msg_20[] PROGMEM = "ADJ Time Minute";

prog_char msg_21[] PROGMEM = "ADJ Time Hour";

prog_char msg_22[] PROGMEM = "ADJ Date Day";

prog_char msg_23[] PROGMEM = "ADJ Date Month";

prog_char msg_24[] PROGMEM = "ADJ Date Year";

prog_char msg_25[] PROGMEM = "T4 On/Off R";

prog_char msg_26[] PROGMEM = "ADJ AC Mode";

prog_char msg_27[] PROGMEM = "AC Set Temp";

prog_char msg_28[] PROGMEM = "AC Switch Delay";

prog_char msg_29[] PROGMEM = "AC Seas 1 Start";

prog_char msg_30[] PROGMEM = "AC Seas 1 End";

prog_char msg_31[] PROGMEM = "AC Seas 2 Start";

prog_char msg_32[] PROGMEM = "AC Seas 2 End";

prog_char msg_33[] PROGMEM = "AC Seas 3 Start";

prog_char msg_34[] PROGMEM = "AC Seas 3 End";

prog_char msg_35[] PROGMEM = "AC Seas 4 Start";

prog_char msg_36[] PROGMEM = "AC Seas 4 End";

//>>>>>>>>>>>>>Addition starts here<<<<<<<<<<<<<

prog_char msg_37[] PROGMEM = "AC Off delay";

prog_char msg_38[] PROGMEM = "AC master byp";

//>>>>>>>>>>>>>Addition ends here<<<<<<<<<<<<<

//Creating the table for the stored menu messages

PROGMEM const char *msg_table[] = {

msg_0,

msg_1,

msg_2,

msg_3,

msg_4,

msg_5,

msg_6,

msg_7,

msg_8,

msg_9,

msg_10,

msg_11,

msg_12,

msg_13,

msg_14,

msg_15,

msg_16,

msg_17,

msg_18,

msg_19,

msg_20,

msg_21,

msg_22,

msg_23,

msg_24,

msg_25,

msg_26,

msg_27,

msg_28,

msg_29,

msg_30,

msg_31,

msg_32,

msg_33,

msg_34,

msg_35,

msg_36, //<<<<<<<<<<<<<Don't forget to add the ','

//>>>>>>>>>>>>>>ADDITION starts here<<<<<<<<<<<<<<

msg_37,

msg_38

//>>>>>>>>>>>>>Addition ends here<<<<<<<<<<<<<<

};

//storing some special char's in the program memory

Now we move down a little and just after the ac_setup_table we start building the ac_sub_table:

//storing the AC sub menu

prog_char ac_sub_0[] PROGMEM = "AC off delay R";

prog_char ac_sub_1[] PROGMEM = "AC Master byp R";

prog_char ac_sub_2[] PROGMEM = "AC ST1 Active R";

prog_char ac_sub_3[] PROGMEM = "AC Timer 1 R";

prog_char ac_sub_4[] PROGMEM = "AC ST2 Active R";

prog_char ac_sub_5[] PROGMEM = "AC Timer 2 R";

prog_char ac_sub_6[] PROGMEM = "AC ST3 Active R";

prog_char ac_sub_7[] PROGMEM = "AC Timer 3 R";

prog_char ac_sub_8[] PROGMEM = "AC ST4 Active R";

prog_char ac_sub_9[] PROGMEM = "AC Timer 4 R";

PROGMEM const char *ac_sub_table[] = {

ac_sub_0,

ac_sub_1,

ac_sub_2,

ac_sub_3,

ac_sub_4,

ac_sub_5,

ac_sub_6,

ac_sub_7,

ac_sub_8,

ac_sub_9

};

So far so good, a big jump now, to the end of the selectMenu() function where we have to add also a few statements:

if(menuOption == 16){ //and menu option is 16 (room 10) 

  get_submenu(9); 

}//submenu end 

if(menuOption == 17){ //and menu option is 17 (AC setup) 

   get_ac_setup(); 

  //submenu end 

} 

 //>>>>>>>>>>>>>ADDITION starts here<<<<<<<<<<<<<<

 if(menuOption == 18){ //and menu option is 18 (AC room 1) 

  get_ac_sub(10);

  //submenu end 

} 

 if(menuOption == 19){ //and menu option is 19 (AC room 2)

   get_ac_sub(11); 

  //submenu end 

} 

 if(menuOption == 20){ //and menu option is 20 (AC room 3) 

   get_ac_sub(12); 

  //submenu end 

}

if(menuOption == 21){ //and menu option is 21 (AC room 4) 

  get_ac_sub(13); 

  //submenu end

} 

//>>>>>>>>>>>>>>Addition ends here<<<<<<<<<<<<<< } } } 

 

 void get_submenu(byte room){

From here we move down to the end of the get_ac_setup() function where we build the new get_ac_sub() 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

if(acSubOption == 2){ //if we are at sub menu 2

lcd.clear();

//retrieving and printing second sub menu point

lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(ac_sub_table[1]))));

lcd.print(room - 9); //printing assigned room number

}

if(acSubOption == 3){ //if we are at sub menu 3

lcd.clear();

//retrieving and printing second sub menu point

lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(ac_sub_table[2]))));

lcd.print(room - 9); //printing assigned room number

}

if(acSubOption == 4){ //if we are at sub menu 4

lcd.clear();

//retrieving and printing second sub menu point

lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(ac_sub_table[3]))));

lcd.print(room - 9); //printing assigned room number

}

if(acSubOption == 5){ //if we are at sub menu 5

lcd.clear();

//retrieving and printing second sub menu point

lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(ac_sub_table[4]))));

lcd.print(room - 9); //printing assigned room number

}

if(acSubOption == 6){ //if we are at sub menu 6

lcd.clear();

//retrieving and printing second sub menu point

lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(ac_sub_table[5]))));

lcd.print(room - 9); //printing assigned room number

}

if(acSubOption == 7){ //if we are at sub menu 7

lcd.clear();

//retrieving and printing second sub menu point

lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(ac_sub_table[6]))));

lcd.print(room - 9); //printing assigned room number

}

if(acSubOption == 8){ //if we are at sub menu 8

lcd.clear();

//retrieving and printing second sub menu point

lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(ac_sub_table[7]))));

lcd.print(room - 9); //printing assigned room number

}

if(acSubOption == 9){ //if we are at sub menu 9

lcd.clear();

//retrieving and printing second sub menu point

lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(ac_sub_table[8]))));

lcd.print(room - 9); //printing assigned room number

}

if(acSubOption == 10){ //if we are at sub menu 10

lcd.clear();

//retrieving and printing second sub menu point

lcd.print(strcpy_P(buffer, (char*)pgm_read_word(&(ac_sub_table[9]))));

lcd.print(room - 9); //printing assigned room number

}

}

if(subButton == btnSelect){ //if btn select was pressed

if(acSubOption == 1){ //and submenu point is 1

//call the function get_delay() to change the setting

delayTime[room] = get_delay(37, room, delayTime[room]);

return;

}

if(acSubOption == 2){ //and sub menu point is 2

//call the function get_offon to change setting

ac_master_bypass[room - 10] = get_offon(38, room, ac_master_bypass[room - 10]);

return;

}

if(acSubOption == 3){ //and sub menu point is 3

//call the function get_offon to change setting

timer_active[room][0] = get_offon(10, room, timer_active[room][0]);

return;

}

if(submenu == 4){ //and submenu is 4

//call the function get_setTime() to change timer 1

get_setTime(room_timers[room][0][0], room_timers[room][0][1],

room_timers[room][0][2], room_timers[room][0][3],

room, 0);

return;

}

if(submenu == 5){ //and submenu is 5

//call the function get_offon() to change the setting

timer_active[room][1] = get_offon(11, room, timer_active[room][1]);

return;

}

if(submenu == 6){ //and submenu is 6

//call the function get_setTime() to change timer 2

get_setTime(room_timers[room][1][0], room_timers[room][1][1],

room_timers[room][1][2], room_timers[room][1][3],

room, 1);

return;

}

if(submenu == 7 && timer_active[room][2] != 2){ //and submenu is 7

//call the function get_offon() to change the setting

timer_active[room][2] = get_offon(12, room, timer_active[room][2]);

return;

}

if(submenu == 8 && timer_active[room][2] != 2){ //and submenu == 8

//call function get_setTime() to change timer 3

get_setTime(room_timers[room][2][0], room_timers[room][2][1],

room_timers[room][2][2], room_timers[room][2][3],

room, 2);

return;

}

if(submenu == 9 && timer_active[room][3] != 2){ //and submenu is 9

//call the function get_offon() to change the setting

timer_active[room][3] = get_offon(25, room, timer_active[room][3]);

return;

}

if(submenu == 10 && timer_active[room][3] != 2){ //and submenu == 10

//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;

}

}

}

}


No comments:

Post a Comment