skizziks_53

reddit 20x4 menu v1.0

May 9th, 2019
127
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 32.36 KB | None | 0 0
  1. /*
  2.    Reddit menu example - May 8, 2019
  3.     Displays a multi-level menu on a 20x4 LCD screen, with 5-button navigation.
  4.     Board = Uno
  5.     Other hardware: 20x4 I2C LCD
  6.                     5 series-resistive buttons
  7.  
  8.  
  9.   Button 1 should be left, button 2 down, button 3 up, button 4 right. 5 = select.
  10.   buttons, resistors, pin levels:
  11.   1   220Ω  394
  12.   2   470Ω  329
  13.   3   1KΩ   264
  14.   4   2.2KΩ   194
  15.   5   4.7KΩ   114
  16.  
  17.  
  18.    The default screen = no menu [press right button to enter menu]
  19.   The normal screen #1 is numbered (1). You can have more than one default screen and set which one you want through the menu.
  20.   (-the idea here is that you could contnuously monitor different sensors on different screens, since the screen isn't big enough to show all the sensors-)
  21.  
  22.   Main Menu >
  23.       Air Quality [menu_first_level=1]
  24.           > Settings (target values to set temp/humidty) [menu_second_level=]
  25.               set temp [menu_third_level=] <--------------------------------------------------------- (this is assumed to be a temperature level in F, from 60 to 90) air_settings__temperature_target
  26.               set humidity [menu_third_level=] <----------------------------------------------------- (this is assumed to be a humidity level in 5% increments, from 25 to 75) air_settings__humidity_target
  27.           > AQ Monitor (temp, humidity, CO2 ppm) [menu_second_level=]
  28.               temp [menu_third_level=] <------------------------------------------------------------- (this is assumed to be viewing a temperature reading) air_readings__temperature
  29.               humidity [menu_third_level=] <--------------------------------------------------------- (this is assumed to be viewing a humidity setting) air_readings__humidity
  30.               co2 ppm [menu_third_level=] <---------------------------------------------------------- (this is assumed to be viewing a CO2 reading) air_readings__co2
  31.  
  32.       Water Quality [menu_first_level=2]
  33.           > Settings (target values to set pH, drain/fill interval) [menu_second_level=]
  34.               set ph [menu_third_level=] <----------------------------------------------------------- (set pH fron zero to 14 in .5 increments) water_settings__ph_target
  35.               set drain/fill interval [menu_third_level=] <------------------------------------------ (set time interval in 30 minute increments) water_settings__refill_interval
  36.           > WQ Monitor (temp, pH, dissolved O2 ppm, conductivity, time since drain) [menu_second_level=]
  37.               temp [menu_third_level=] <------------------------------------------------------------- (show water temperature) water_readings_temperature
  38.               ph [menu_third_level=] <--------------------------------------------------------------- (show PH level) water_readings__ph_level
  39.               dissoved 02 [menu_third_level=] <------------------------------------------------------ (show dissolved O2) water_readings__dissolved_02
  40.               conductivity [menu_third_level=] <----------------------------------------------------- (show conductivity) water_readings__conductivity
  41.               time since drain [menu_third_level=] <------------------------------------------------- (show time since previous drain/fill) water_readings__last_refill_time
  42.  
  43.       Power (value = 3) [menu_first_level=3]
  44.           > Generator Monitor (volts, amps) [menu_second_level=]
  45.               volts [menu_third_level=] <------------------------------------------------------------ (show volts reading) power_readings__generator_volts
  46.               amps [menu_third_level=] <------------------------------------------------------------- (show amps reading ???? see notes below) power_readings__generator_amps
  47.           > Load Monitor (volts, amps) [menu_second_level=]
  48.               volts [menu_third_level=] <------------------------------------------------------------ (show volts ?????) power_readings__load_volts
  49.               amps [menu_third_level=] <------------------------------------------------------------- (show amps ???) power_readings__load_amps
  50.  
  51.               @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  52.               Just a note: you can't really measure the 'amps' of a generator without any load attached; you can only measure the amps flowing through {some electrical load} on the generator.
  53.               And the volts that the generator puts out is going to be the same voltage drop across any single load.
  54.               So it doesn't make much sense to show the volts and amps for both the generator and a single load.
  55.               I put them in the menu anyway, but just so you know.
  56.               Instead, just show the volts that the generator is producing, and the amps through the load.
  57.  
  58.               If you had more than one load on a generator, then you could show the current through all, or any one of the separate loads.
  59.               @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  60.  
  61.       Change default screen: this is a menu choice that I added to show how to change the default screen shown.
  62.           > up/down changes the default screen through four different versions. Each of these could constantly show differnt things, if desired. -----> default_screen_to_use
  63.  
  64. */
  65.  
  66. #include "Wire.h" // For I2C
  67. #include "LiquidCrystal_I2C.h" // Library location --- https://www.arduinolibraries.info/libraries/liquid-crystal-i2-c
  68. LiquidCrystal_I2C lcd(0x27, 20, 4); // 0x27 is -usually- the default I2C bus address of the backpack
  69.  
  70. bool use_serial_messages = true; // general prototyping messages (allows disabling them for speed reasons)
  71.  
  72. // The variables below is just for detecting button presses.
  73. int buttonInput_pin = A0; // The physical input pin for buttons.
  74. int buttonInput_pinValue = 0; // This is used for storing the actual pin value.
  75. int button_pressed_current_value = 0;
  76. int button_pressed_previous_value = 0;
  77.  
  78. // Button 1 should be left, button 2 down, button 3 up, button 4 right. 5 = select.
  79. // The variables below is what is used in the menu function.
  80. int button_defined = 0; // This variable holds one of the values below:
  81. const int button_defined__no_button = 0;
  82. const int button_defined__left = 1;
  83. const int button_defined__down = 2;
  84. const int button_defined__up = 3;
  85. const int button_defined__right = 4;
  86. const int button_defined__select = 5;
  87.  
  88.  
  89.  
  90. // The variables below are used to debounce button presses.
  91. // The buttons are going to be checked ten times a second.
  92. // Only one button press will be detected for each time the button is pressed. Holding the button down should not result in additional 'presses' being detected.
  93. bool buttons_enabled = true; // Used for debouncing buttons.
  94. int button_debounce_time = 100; // A time in milliseconds to debounce the buttons.
  95. unsigned long button_press_begin_time = 0;
  96. unsigned long button_press_current_time = 0;
  97.  
  98.  
  99. // This sketch shows a default screen, and then pressing the [right] button changes to the menu.
  100. int default_screen_to_use = 1; // This sketch has four different default screens provided. zero value is not used.
  101. int max_default_screen = 4; // This is to limit the default screen selection value.
  102.  
  103. int menu_level = 0; // The left and right buttons change this value.
  104. // zero = show the default screen. 1 = navigate the menu. 2 = input values.
  105.  
  106. int menu_end_state = 1; // The [up] and [down] buttons alter this value, if menu_level = 2.
  107. int menu_end_state__maximum_value = 17;
  108.  
  109. /*
  110.    The possible menu end points are shown below.
  111.    Some of these are for setting target values and others are for viewing sensor values.
  112.   1 = air quality > settings > set temp
  113.   2 = air quality > settings > set humidity
  114.   3 = air monitor > temperature
  115.   4 = air monitor > humidity
  116.   5 = air monitor > co2 ppm
  117.   6 = water quality > settings > ph
  118.   7 = water quality > settings > drain/fill interval
  119.   8 = water monitor > temp
  120.   9 = water monitor > ph
  121.   10 = water monitor > dissolved 02
  122.   11 = water monitor > conductivity
  123.   12 = water monitor > last refill time
  124.   13 = power > generator volts
  125.   14 = power > generator current
  126.   15 = power > load volts
  127.   16 = power > load amps
  128.   17 = change default screen
  129. */
  130.  
  131. // Variables for all of the end states above are declared below.
  132. // Some of these have initial values in them, just to provide something more interesting than having everything set to zeros.
  133. int air_quality__target_temperature = 75;
  134. float air_quality__target_humidity = 70;
  135. int air_quality__current_temperature = 80;
  136. float air_quality__current_humidity = 50;
  137. int air_monitor__current_co2_ppm = 220; // If co2 ppm goes over 32,000, we will all be dead anyway.
  138. float water_quality__target_ph = 8.0;
  139. int water_quality__refill_interval = 24; // assumed to be hours?
  140. int water_monitor__current_temperature = 70;
  141. float water_monitor__current_ph = 8.4;
  142. int water_monitor__dissolved_co2 = 700; // I am guessing what a typical figure for this might be?
  143. float water_monitor__conductivity = 25; // Also this
  144. int water_monitor__time_since_last_refill = 7; // assumed to be hours
  145. int power__generator_volts = 0;
  146. int power__generator_amps = 0;
  147. int power__load_volts = 0;
  148. int power__load_amps = 0;
  149.  
  150. // related variables for the above variables,,,, are declared below
  151. // All of the target values need a minimum, maximum and change values defined.
  152. int air_quality__target_temperature_minimum_value = 0;
  153. int air_quality__target_temperature_maximum_value = 120;
  154. int air_quality__target_temperature_change_interval = 5;
  155.  
  156. float air_quality__target_humidity_minimum_value = 20;
  157. float air_quality__target_humidity_maximum_value = 100;
  158. float air_quality__target_humidity_change_interval = 5;
  159.  
  160. float water_quality__target_ph_minimum = 0;
  161. float water_quality__target_ph_maximum = 14;
  162. float water_quality__target_ph_change_interval = .2;
  163.  
  164. int water_quality__refill_interval_minimum = 3;
  165. int water_quality__refill_interval_maximum_value = 96;
  166. int water_quality__refill_interval_change_interval = 3;
  167.  
  168.  
  169.  
  170.  
  171. bool update_menu_display = true; // If the display needs to be changed, this is set to true and refresh_menu() is called.
  172.  
  173.  
  174.  
  175.  
  176.  
  177. void setup() {
  178.   Serial.begin(9600);
  179.   lcd.init();
  180.   lcd.backlight();
  181.   // buttonInput_pin is analogRead(), doesn't require declaration
  182.   // I2C pins A4, A5 are fixed and don't require declaration
  183.   lcd_clear_all_lines();
  184.   show_menu();
  185.   if (use_serial_messages == true) {
  186.     Serial.println("Exiting setup()");
  187.   }
  188. }
  189.  
  190. void loop() {
  191.  
  192.   if (buttons_enabled == true) {
  193.     check_buttons();
  194.     start_button_timer();
  195.   }
  196.   else {
  197.     check_button_timer();
  198.   }
  199.  
  200. } // end of main loop
  201.  
  202.  
  203.  
  204. void check_buttons() {
  205.  
  206.   button_pressed_current_value = analogRead(buttonInput_pin);
  207.   if (button_pressed_previous_value < 50 && button_pressed_current_value > 50) {
  208.  
  209.     // Your button values:
  210.     if (button_pressed_current_value > 50 && button_pressed_current_value < 130) {
  211.       button_pressed__select();
  212.     }
  213.     if (button_pressed_current_value > 180 && button_pressed_current_value < 220) {
  214.       button_pressed__right();
  215.     }
  216.     if (button_pressed_current_value > 230 && button_pressed_current_value < 290) {
  217.       button_pressed__up();
  218.     }
  219.     if (button_pressed_current_value > 300 && button_pressed_current_value < 360) {
  220.       button_pressed__down();
  221.     }
  222.     if (button_pressed_current_value > 370 && button_pressed_current_value < 430) {
  223.       // left button
  224.       button_pressed__left();
  225.     }
  226.  
  227.     /*
  228.         // Below is the button values I had to use with the Robotdyne keypad running off USB voltage
  229.         if (button_pressed_current_value > 635 && button_pressed_current_value < 655) {
  230.           button_pressed__select(); // 645
  231.         }
  232.         if (button_pressed_current_value > 590 && button_pressed_current_value < 610) {
  233.           button_pressed__right(); // 601
  234.         }
  235.         if (button_pressed_current_value > 813 && button_pressed_current_value < 833) {
  236.           button_pressed__up(); // 823
  237.         }
  238.         if (button_pressed_current_value > 519 && button_pressed_current_value < 539) {
  239.           button_pressed__down(); // 529
  240.         }
  241.         if (button_pressed_current_value > 685 && button_pressed_current_value < 705) {
  242.           // left button
  243.           button_pressed__left(); // 695
  244.         }
  245.     */
  246.   }
  247.   button_pressed_previous_value = button_pressed_current_value;
  248. }
  249.  
  250.  
  251. void operate_menu(int buttonPress) {
  252.  
  253.   // int menu_level = 0; // The left and right buttons change this value.
  254.   // zero = show the default screen. 1 = navigate the menu. 2 = input values.
  255.   // The left and right buttons always do the same thing, no matter where you are in the menu.
  256.   if (buttonPress == button_defined__right) {
  257.     if (menu_level < 2) {
  258.       menu_level = menu_level + 1;
  259.       update_menu_display = true;
  260.       if (use_serial_messages == true) {
  261.         Serial.print("+menu_level = ");
  262.         Serial.println(menu_level);
  263.       }
  264.     }
  265.   }
  266.   if (buttonPress == button_defined__left) {
  267.     if (menu_level > 0) {
  268.       menu_level = menu_level - 1;
  269.       update_menu_display = true;
  270.       if (use_serial_messages == true) {
  271.         Serial.print("-menu_level = ");
  272.         Serial.println(menu_level);
  273.       }
  274.     }
  275.   }
  276.  
  277.   if (menu_level == 0) {
  278.     // Do nothing with the up and down button presses.
  279.     // If menu_level is zero, then the program is on the default screen and the up and down buttons won't do anything.
  280.   }
  281.  
  282.   // If menu_level = 1, the up and down buttons navigate over the menu choices.
  283.   if (menu_level == 1) {
  284.     if (buttonPress == button_defined__down) {
  285.       if (menu_end_state < menu_end_state__maximum_value) {
  286.         menu_end_state += 1;
  287.         update_menu_display = true;
  288.       }
  289.       if (use_serial_messages == true) {
  290.         Serial.print("menu_end_state = ");
  291.         Serial.println(menu_end_state);
  292.       }
  293.     }
  294.     if (buttonPress == button_defined__up) {
  295.       if (menu_end_state > 1) {
  296.         menu_end_state -= 1;
  297.         update_menu_display = true;
  298.       }
  299.       if (use_serial_messages == true) {
  300.         Serial.print("menu_end_state = ");
  301.         Serial.println(menu_end_state);
  302.       }
  303.     }
  304.   }
  305.  
  306.   // If menu_level = 2 then the up and down buttons change the values of the selected menu choice, if it is a setting.
  307.   // Each menu choice for a setting has different values and limitations involved.
  308.   if (menu_level == 2) {
  309.     switch (menu_end_state) {
  310.       case 1:
  311.         // 1 = air quality > settings > set temp
  312.         if (buttonPress == button_defined__down) {
  313.           if (air_quality__target_temperature > air_quality__target_temperature_minimum_value) {
  314.             air_quality__target_temperature -= air_quality__target_temperature_change_interval;
  315.             update_menu_display = true;
  316.           }
  317.         }
  318.         if (buttonPress == button_defined__up) {
  319.           if (air_quality__target_temperature < air_quality__target_temperature_maximum_value) {
  320.             air_quality__target_temperature += air_quality__target_temperature_change_interval;
  321.             update_menu_display = true;
  322.           }
  323.         }
  324.         break;
  325.       case 2:
  326.         // 2 = air quality > settings > set humidity
  327.         if (buttonPress == button_defined__down) {
  328.           if (air_quality__target_humidity > air_quality__target_humidity_minimum_value) {
  329.             air_quality__target_humidity -= air_quality__target_humidity_change_interval;
  330.             update_menu_display = true;
  331.           }
  332.         }
  333.         if (buttonPress == button_defined__up) {
  334.           if (air_quality__target_humidity < air_quality__target_humidity_maximum_value) {
  335.             air_quality__target_humidity += air_quality__target_humidity_change_interval;
  336.             update_menu_display = true;
  337.           }
  338.         }
  339.         break;
  340.       case 6:
  341.         // 6 = water quality > settings > ph
  342.         if (buttonPress == button_defined__down) {
  343.           if (water_quality__target_ph > water_quality__target_ph_minimum) {
  344.             water_quality__target_ph -= water_quality__target_ph_change_interval;
  345.             update_menu_display = true;
  346.           }
  347.         }
  348.         if (buttonPress == button_defined__up) {
  349.           if (water_quality__target_ph < water_quality__target_ph_maximum) {
  350.             water_quality__target_ph += water_quality__target_ph_change_interval;
  351.             update_menu_display = true;
  352.           }
  353.         }
  354.         break;
  355.       case 7:
  356.         // 7 = water quality > settings > drain/fill interval
  357.         if (buttonPress == button_defined__down) {
  358.           if (water_quality__refill_interval > water_quality__refill_interval_minimum) {
  359.             water_quality__refill_interval -= water_quality__refill_interval_change_interval;
  360.             update_menu_display = true;
  361.           }
  362.         }
  363.         if (buttonPress == button_defined__up) {
  364.           if (water_quality__refill_interval < water_quality__refill_interval_maximum_value) {
  365.             water_quality__refill_interval += water_quality__refill_interval_change_interval;
  366.             update_menu_display = true;
  367.           }
  368.         }
  369.         break;
  370.       case 17:
  371.         // 17 = change default screen
  372.         if (buttonPress == button_defined__down) {
  373.           if (default_screen_to_use > 1) {
  374.             default_screen_to_use -= 1;
  375.             update_menu_display = true;
  376.           }
  377.         }
  378.         if (buttonPress == button_defined__up) {
  379.           if (default_screen_to_use < max_default_screen) {
  380.             default_screen_to_use += 1;
  381.             update_menu_display = true;
  382.           }
  383.         }
  384.         break;
  385.     }
  386.   }
  387.  
  388.  
  389. }
  390.  
  391.  
  392. void refresh_menu() {
  393.   if (update_menu_display == true) {
  394.     show_menu();
  395.   }
  396. }
  397.  
  398.  
  399. void show_menu() {
  400.   // This re-prints the menu to the LCD display.
  401.   lcd_clear_all_lines();
  402.  
  403.   // int menu_level = 0; // The left and right buttons change this value.
  404.   // zero = show the default screen. 1 = navigate the menu. 2 = input values.
  405.   if (menu_level == 0) {
  406.     // This is the option to cause the default screen to be shown.
  407.     lcd__display_default_screen();
  408.   }
  409.   else {
  410.     switch (menu_end_state) {
  411.       case 1:
  412.         // 1 = air quality > settings > set temp
  413.         menu_top_line__air_settings();
  414.         menu_second_line__settings();
  415.         menu_third_line__air_target_temperature();
  416.         // Note: if you wanted to, you could just write each menu screen out here if you wanted.
  417.         // That will take up some more program space, but it's only at 27% as it is.
  418.         // I just tried to re-use commands as often as I could by putting re-usable ones into their functions.
  419.         break;
  420.       case 2:
  421.         // 2 = air quality > settings > set humidity
  422.         menu_top_line__air_settings();
  423.         menu_second_line__settings();
  424.         menu_third_line__air_target_humidity();
  425.         break;
  426.       case 3:
  427.         // 3 = air monitor > temperature
  428.         menu_top_line__air_monitor();
  429.         menu_second_line__monitor();
  430.         menu_third_line__air_monitor_temperature();
  431.         break;
  432.       case 4:
  433.         // 4 = air monitor > humidity
  434.         menu_top_line__air_monitor();
  435.         menu_second_line__monitor();
  436.         menu_third_line__air_monitor_humidity();
  437.         break;
  438.       case 5:
  439.         // 5 = air monitor > co2 ppm
  440.         menu_top_line__air_monitor();
  441.         menu_second_line__monitor();
  442.         menu_third_line__air_monitor_co2_ppm();
  443.         break;
  444.       case 6:
  445.         // 6 = water quality > settings > ph
  446.         menu_top_line__water_settings();
  447.         menu_second_line__settings();
  448.         menu_third_line__water_settings_ph();
  449.         break;
  450.       case 7:
  451.         // 7 = water quality > settings > drain/fill interval
  452.         menu_top_line__water_settings();
  453.         menu_second_line__settings();
  454.         menu_third_line__water_settings_refill_interval();
  455.         break;
  456.       case 8:
  457.         // 8 = water monitor > temp
  458.         menu_top_line__water_monitor();
  459.         menu_second_line__monitor();
  460.         menu_third_line__water_monitor_temperature();
  461.         break;
  462.       case 9:
  463.         // 9 = water monitor > ph
  464.         menu_top_line__water_monitor();
  465.         menu_second_line__monitor();
  466.         menu_third_line__water_monitor_ph();
  467.         break;
  468.       case 10:
  469.         // 10 = water monitor > dissolved 02
  470.         menu_top_line__water_monitor();
  471.         menu_second_line__monitor();
  472.         menu_third_line__water_monitor_co2();
  473.         break;
  474.       case 11:
  475.         // 11 = water monitor > conductivity
  476.         menu_top_line__water_monitor();
  477.         menu_second_line__monitor();
  478.         menu_third_line__water_monitor_conductivity();
  479.         break;
  480.       case 12:
  481.         // 12 = water monitor > last refill time
  482.         menu_top_line__water_monitor();
  483.         menu_second_line__monitor();
  484.         menu_third_line__water_monitor_time_since_last_refill();
  485.         break;
  486.       case 13:
  487.         // 13 = power > generator volts
  488.         menu_top_line__power_monitor();
  489.         menu_second_line__monitor();
  490.         menu_third_line__power_generator_volts();
  491.         break;
  492.       case 14:
  493.         // 14 = power > generator current
  494.         menu_top_line__power_monitor();
  495.         menu_second_line__monitor();
  496.         menu_third_line__power_generator_amps();
  497.         break;
  498.       case 15:
  499.         // 15 = power > load volts
  500.         menu_top_line__power_monitor();
  501.         menu_second_line__monitor();
  502.         menu_third_line__power_load_volts();
  503.         break;
  504.       case 16:
  505.         // 16 = power > load amps
  506.         menu_top_line__power_monitor();
  507.         menu_second_line__monitor();
  508.         menu_third_line__power_load_amps();
  509.         break;
  510.       case 17:
  511.         // 17 = change default screen
  512.         menu_top_line__default_screen();
  513.         // This screen prints its own second line automagically.
  514.  
  515.         break;
  516.     }
  517.   }
  518.  
  519.  
  520.  
  521. }
  522.  
  523.  
  524. void button_pressed__select() {
  525.   button_defined = button_defined__select;
  526.   operate_menu(button_defined);
  527.   refresh_menu();
  528.   if (use_serial_messages == true) {
  529.     Serial.println("button = select");
  530.   }
  531. }
  532.  
  533. void button_pressed__right() {
  534.   button_defined = button_defined__right;
  535.   operate_menu(button_defined);
  536.   refresh_menu();
  537.   if (use_serial_messages == true) {
  538.     Serial.println("button = right");
  539.   }
  540. }
  541.  
  542. void button_pressed__up() {
  543.   button_defined = button_defined__up;
  544.   operate_menu(button_defined);
  545.   refresh_menu();
  546.   if (use_serial_messages == true) {
  547.     Serial.println("button = up");
  548.   }
  549. }
  550.  
  551. void button_pressed__down() {
  552.   button_defined = button_defined__down;
  553.   operate_menu(button_defined);
  554.   refresh_menu();
  555.   if (use_serial_messages == true) {
  556.     Serial.println("button = down");
  557.   }
  558. }
  559.  
  560. void button_pressed__left() {
  561.   button_defined = button_defined__left;
  562.   operate_menu(button_defined);
  563.   refresh_menu();
  564.   if (use_serial_messages == true) {
  565.     Serial.println("button = left");
  566.   }
  567. }
  568.  
  569. void button_pressed__no_button() {
  570.   button_defined = button_defined__no_button;
  571.   operate_menu(button_defined);
  572.   refresh_menu();
  573. }
  574.  
  575.  
  576. void start_button_timer() {
  577.   // This is for starting the button timer. This is done every time the button input is checked.
  578.   buttons_enabled = false;
  579.   button_press_begin_time = millis();
  580. }
  581.  
  582.  
  583. void check_button_timer() {
  584.   // This function re-enables the button input if button_debounce_time has passed.
  585.   button_press_current_time = millis();
  586.   if (button_press_current_time >= button_press_begin_time) {
  587.     if (button_press_current_time >= (button_press_begin_time + button_debounce_time)) {
  588.       buttons_enabled = true;
  589.     }
  590.   }
  591.   else {
  592.     button_press_begin_time = millis();
  593.   }
  594. }
  595.  
  596.  
  597. void lcd_clear_all_lines() {
  598.   lcd_print_blank_line(1);
  599.   lcd_print_blank_line(2);
  600.   lcd_print_blank_line(3);
  601.   lcd_print_blank_line(4);
  602. }
  603.  
  604. void lcd_print_blank_line(int lineNumber) {
  605.   // This function 'erases' a given line by printing 20 spaces in it.
  606.   int sLine = lineNumber - 1;
  607.   lcd.setCursor(0, sLine);
  608.   lcd.print("                    ");
  609. }
  610.  
  611. // copy this onto the main file before posting...
  612.  
  613.  
  614. // The functions to print all the top lines for every menu option are below:
  615.  
  616. void menu_top_line__air_settings() {
  617.   lcd.setCursor(0, 0);
  618.   lcd.print("Air quality:");
  619. }
  620.  
  621. void menu_top_line__air_monitor() {
  622.   lcd.setCursor(0, 0);
  623.   lcd.print("Air monitor:");
  624. }
  625.  
  626. void menu_top_line__water_settings() {
  627.   lcd.setCursor(0, 0);
  628.   lcd.print("Water quality:");
  629. }
  630.  
  631. void menu_top_line__water_monitor() {
  632.   lcd.setCursor(0, 0);
  633.   lcd.print("Water monitor:");
  634. }
  635.  
  636. void menu_top_line__power_monitor() {
  637.   lcd.setCursor(0, 0);
  638.   lcd.print("Power:");
  639. }
  640.  
  641. void menu_top_line__default_screen() {
  642.   lcd.setCursor(0, 0);
  643.   lcd.print("Default screen:");
  644.   lcd.setCursor(0, 1);
  645.   lcd.print("current = ");
  646.   lcd.setCursor(10, 1);
  647.   lcd.print(default_screen_to_use);
  648.   //lcd.setCursor(0, 2);
  649.   //lcd.print("up/down to change");
  650. }
  651.  
  652.  
  653. // There is only two kinds of second lines used:
  654.  
  655. void menu_second_line__settings() {
  656.   lcd.setCursor(1, 1);
  657.   lcd.print("Settings:");
  658. }
  659.  
  660. void menu_second_line__monitor() {
  661.   lcd.setCursor(1, 1);
  662.   lcd.print("Monitor:");
  663. }
  664.  
  665.  
  666. // The functions to print every possible third-line message are below:
  667.  
  668. void menu_third_line__air_target_temperature() {
  669.   lcd.setCursor(2, 2);
  670.   lcd.print("Temp = ");
  671.   lcd.setCursor(9, 2);
  672.   lcd.print(air_quality__target_temperature);
  673.   if (menu_level == 1) {
  674.     lcd.setCursor(0, 3);
  675.     lcd.print("R=change value");
  676.   }
  677.   if (menu_level == 2) {
  678.     lcd.setCursor(0, 3);
  679.     lcd.print("U/D=value,left=exit");
  680.   }
  681. }
  682.  
  683. void menu_third_line__air_monitor_temperature() {
  684.   lcd.setCursor(2, 2);
  685.   lcd.print("Temp = ");
  686.   lcd.setCursor(9, 2);
  687.   get_sensor_data__air_current_temperature();
  688.   lcd.print(air_quality__current_temperature);
  689. }
  690.  
  691. void menu_third_line__air_target_humidity() {
  692.   lcd.setCursor(2, 2);
  693.   lcd.print("Humidity = ");
  694.   lcd.setCursor(13, 2);
  695.   lcd.print(air_quality__target_humidity);
  696.   if (menu_level == 1) {
  697.     lcd.setCursor(0, 3);
  698.     lcd.print("R=change value");
  699.   }
  700.   if (menu_level == 2) {
  701.     lcd.setCursor(0, 3);
  702.     lcd.print("U/D=value,left=exit");
  703.   }
  704. }
  705.  
  706. void menu_third_line__air_monitor_humidity() {
  707.   lcd.setCursor(2, 2);
  708.   lcd.print("Humidity = ");
  709.   lcd.setCursor(13, 2);
  710.   get_sensor_data__air_current_humidity();
  711.   lcd.print(air_quality__current_humidity);
  712. }
  713.  
  714. void menu_third_line__air_monitor_co2_ppm() {
  715.   lcd.setCursor(2, 2);
  716.   lcd.print("CO2 ppm = ");
  717.   lcd.setCursor(12, 2);
  718.   get_sensor_data__air_current_co2_ppm();
  719.   lcd.print(air_monitor__current_co2_ppm);
  720. }
  721.  
  722. void menu_third_line__water_settings_ph() {
  723.   lcd.setCursor(2, 2);
  724.   lcd.print("pH = ");
  725.   lcd.setCursor(7, 2);
  726.   lcd.print(water_quality__target_ph);
  727.   if (menu_level == 1) {
  728.     lcd.setCursor(0, 3);
  729.     lcd.print("R=change value");
  730.   }
  731.   if (menu_level == 2) {
  732.     lcd.setCursor(0, 3);
  733.     lcd.print("U/D=value,left=exit");
  734.   }
  735. }
  736.  
  737. void menu_third_line__water_settings_refill_interval() {
  738.   lcd.setCursor(2, 2);
  739.   lcd.print("Refill hrs = ");
  740.   lcd.setCursor(15, 2);
  741.   lcd.print(water_quality__refill_interval);
  742.   if (menu_level == 1) {
  743.     lcd.setCursor(0, 3);
  744.     lcd.print("R=change value");
  745.   }
  746.   if (menu_level == 2) {
  747.     lcd.setCursor(0, 3);
  748.     lcd.print("U/D=value,left=exit");
  749.   }
  750. }
  751.  
  752. void menu_third_line__water_monitor_temperature() {
  753.   lcd.setCursor(2, 2);
  754.   lcd.print("Temp = ");
  755.   lcd.setCursor(9, 2);
  756.   get_sensor_data__water_current_temperature();
  757.   lcd.print(water_monitor__current_temperature);
  758. }
  759.  
  760. void menu_third_line__water_monitor_ph() {
  761.   lcd.setCursor(2, 2);
  762.   lcd.print("pH = ");
  763.   lcd.setCursor(7, 2);
  764.   get_sensor_data__water_current_ph();
  765.   lcd.print(water_monitor__current_ph);
  766. }
  767.  
  768. void menu_third_line__water_monitor_co2() {
  769.   lcd.setCursor(2, 2);
  770.   lcd.print("CO2 = ");
  771.   lcd.setCursor(8, 2);
  772.   get_sensor_data__water_dissolved_co2();
  773.   lcd.print(water_monitor__dissolved_co2);
  774. }
  775.  
  776. void menu_third_line__water_monitor_conductivity() {
  777.   lcd.setCursor(2, 2);
  778.   lcd.print("conduct = ");
  779.   lcd.setCursor(12, 2);
  780.   get_sensor_data__water_conductivity();
  781.   lcd.print(water_monitor__conductivity);
  782. }
  783.  
  784. void menu_third_line__water_monitor_time_since_last_refill() {
  785.   lcd.setCursor(2, 2);
  786.   lcd.print("last refill = ");
  787.   lcd.setCursor(16, 2);
  788.   get_sensor_data__water_time_since_last_refill();
  789.   lcd.print(water_monitor__time_since_last_refill);
  790. }
  791.  
  792. void menu_third_line__power_generator_volts() {
  793.   lcd.setCursor(2, 2);
  794.   lcd.print("gen volts = ");
  795.   lcd.setCursor(14, 2);
  796.   get_sensor_data__generator_volts();
  797.   lcd.print(power__generator_volts);
  798. }
  799.  
  800. void menu_third_line__power_generator_amps() {
  801.   lcd.setCursor(2, 2);
  802.   lcd.print("gen amps = ");
  803.   lcd.setCursor(13, 2);
  804.   get_sensor_data__generator_amps();
  805.   lcd.print(power__generator_amps);
  806. }
  807.  
  808. void menu_third_line__power_load_volts() {
  809.   lcd.setCursor(2, 2);
  810.   lcd.print("load volts = ");
  811.   lcd.setCursor(14, 2);
  812.   get_sensor_data__load_volts();
  813.   lcd.print(power__load_volts);
  814. }
  815.  
  816. void menu_third_line__power_load_amps() {
  817.   lcd.setCursor(2, 2);
  818.   lcd.print("load amps = ");
  819.   lcd.setCursor(13, 2);
  820.   get_sensor_data__load_amps();
  821.   lcd.print(power__load_amps);
  822. }
  823.  
  824.  
  825. // There are currently no functions to print anything on the fourth line.
  826.  
  827.  
  828.  
  829.  
  830.  
  831.  
  832.  
  833. void lcd__display_default_screen() {
  834.  
  835.   // This function shows the default screen, based on the value currently stored in default_screen_to_use.
  836.   switch (default_screen_to_use) {
  837.     case 1:
  838.       lcd.setCursor(0, 0);
  839.       lcd.print("default screen #1");
  840.       lcd.setCursor(0, 1);
  841.       lcd.print("press R for menu");
  842.       // Since each of the default screens is printed separately, you can show different things on each of them.
  843.       break;
  844.     case 2:
  845.       lcd.setCursor(0, 0);
  846.       lcd.print("default screen #2");
  847.       lcd.setCursor(0, 1);
  848.       lcd.print("press R for menu");
  849.       break;
  850.     case 3:
  851.       lcd.setCursor(0, 0);
  852.       lcd.print("default screen #3");
  853.       lcd.setCursor(0, 1);
  854.       lcd.print("press R for menu");
  855.  
  856.       break;
  857.     case 4:
  858.       lcd.setCursor(0, 0);
  859.       lcd.print("default screen #4");
  860.       lcd.setCursor(0, 1);
  861.       lcd.print("press R for menu");
  862.  
  863.       break;
  864.     default:
  865.       // error: incorrect value
  866.       lcd.setCursor(0, 0);
  867.       lcd.print("error!");
  868.       lcd.setCursor(0, 1);
  869.       lcd.print("default screen:");
  870.       lcd.setCursor(0, 2);
  871.       lcd.print("invalid code");
  872.       break;
  873.   }
  874.  
  875. }
  876.  
  877.  
  878. void get_sensor_data__air_current_temperature() {
  879.   // This function is for getting the current air temperature from whatever sensor you use.
  880.   // store that value in air_quality__current_temperature
  881.  
  882. }
  883.  
  884. void get_sensor_data__air_current_humidity() {
  885.   // This function is for getting the current air humidity from whatever sensor you use.
  886.   // Store that value in air_quality__current_humidity
  887.  
  888. }
  889.  
  890. void get_sensor_data__air_current_co2_ppm() {
  891.   // This function is for getting the current air co2 from whatever sensor you use.
  892.   // Store that value in air_monitor__current_co2_ppm
  893.  
  894. }
  895.  
  896. void get_sensor_data__water_current_temperature() {
  897.   // This function is for getting the current water temperature from whatever sensor you use.
  898.   // Store that value in water_monitor__current_temperature
  899.  
  900. }
  901.  
  902. void get_sensor_data__water_current_ph() {
  903.   // This function is for getting the current water ph from whatever sensor you use.
  904.   // Store that value in water_monitor__current_ph
  905.  
  906. }
  907.  
  908. void get_sensor_data__water_dissolved_co2() {
  909.   // This function is for getting the current water co2 from whatever sensor you use.
  910.   // Store that value in water_monitor__dissolved_co2
  911.  
  912. }
  913.  
  914. void get_sensor_data__water_conductivity() {
  915.   // This function is for getting the current water conductivity from whatever sensor you use.
  916.   // Store that value in water_monitor__conductivity
  917.  
  918. }
  919.  
  920. void get_sensor_data__water_time_since_last_refill() {
  921.   // This isn't really a sensor, unless you consider a RTC a sensor. But anyway.
  922.   // This function is for getting the current water elapsed time since the last refill.
  923.   // Store that value in water_monitor__time_since_last_refill
  924.  
  925. }
  926.  
  927. // The last four functions are below, even though all of them aren't really needed.
  928.  
  929. void get_sensor_data__generator_volts() {
  930.   // The variable for this is power__generator_volts
  931.  
  932. }
  933.  
  934. void get_sensor_data__generator_amps() {
  935.   // The variable for this is power__generator_amps
  936.  
  937. }
  938.  
  939.  
  940. void get_sensor_data__load_volts() {
  941.   // The variable for this is power__load_volts
  942.  
  943. }
  944.  
  945. void get_sensor_data__load_amps() {
  946.   // The variable for this is power__load_amps
  947.  
  948. }
Add Comment
Please, Sign In to add comment