This is a simple menu system I've used for a volt/ammeter project and use it to calibrate and store the values, It's not fully commented (as I did not have time) but it should be easy to use and learn and understand. it's a quick stripped down system from my main program
It may be of use or just for learning there are plenty of other ways
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
//**************************************************************************************|
const int menubuttonPin = 11;//pin to which the button is conected to
const int downbuttonpin = 12;//Pin to which downbutton is conected to.
const int upbuttonpin = 13;//Pin to which upbutton is conected to.
int menubuttonPushCounter = 0;
int menubuttonState = 0;
int lastmenuButtonState = 0;
boolean menubuttonbool = false;
long currentMillis = 0;
long tpreviousMillis = 0;
long tinterval = 1000; // interval at which to update time
long tcurrentMillis = 0;
int upbuttonState;
int lastupbuttonState;
int upbutton;
int downbuttonState;
int lastdownbuttonState;
int downbutton;
int menucounter = 0;
long buttontimer;
long synctimer;
float counter =0;
// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0; // will store last time LED was updated
// constants won't change :
const long interval = 1000; // interval at which to blink (milliseconds)
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address
void setup() {
lcd.begin (20, 4); // for 16 x 2 LCD module
lcd.setBacklight(HIGH);
pinMode(menubuttonPin, INPUT);
digitalWrite(menubuttonPin, HIGH);
pinMode(downbuttonpin, INPUT);
digitalWrite(downbuttonpin, HIGH);
pinMode(upbuttonpin, INPUT);
digitalWrite(upbuttonpin, HIGH);
}
//------------------------------------Main Program-------------------------------------
void loop() {
// here is where you'd put code that needs to be running all the time.
//**********************************************************************************
// This is just a added sample to show the program running, needs to be be removed *
//**********************************************************************************
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
counter = counter + 1;
}
//*****************************************
// continues to run mian program from her *
//*****************************************
// display the counter
lcd.setCursor(0, 0);
lcd.print(counter);
menubuttonState = digitalRead(menubuttonPin); // checks if the menu button is pressed
if (menubuttonState != lastmenuButtonState)
{
if (menubuttonState == LOW)
{
delay(100);
menubuttonPushCounter = 3; //change this to how many Sub menus are required
menubuttonbool = true;
}
if (menubuttonState == HIGH)
{
menubuttonbool = false;
}
}
if (menubuttonbool == true && menubuttonPushCounter == 3) // Max number of Sub Menus
{
menucounter = 0;
menu();
}
lastmenuButtonState = menubuttonState;
}
int menu()
{
lcd.clear(); // clear the LCD
delay(1000);
while (menucounter < 3) ///while Menu equals less than max number of menus
{
menubuttonState = digitalRead(menubuttonPin);
upbutton = digitalRead(upbuttonpin);
downbutton = digitalRead(downbuttonpin);
if (menubuttonState != lastmenuButtonState)
{
lcd.clear();
if (menubuttonState == LOW)
{
delay(200);
menucounter++;
}
}
lastmenuButtonState = menubuttonState;
// show the menu's
switch (menucounter) {
case 0: //menu 1
// add your code here if you need to adjust or alter any values
lcd.setCursor(0, 0);
lcd.print("** MAIN MENU 1 ***");
lcd.setCursor(0, 1);
lcd.print(" Display dtata here ");
lcd.setCursor(0, 2);
lcd.print(" press enter to ");
lcd.setCursor(0, 3);
lcd.print(" move to next screen ");
break;
case 1://menu 2
// add your code here if you need to adjust or alter any values
lcd.setCursor(0, 0);
lcd.print("** MAIN MENU 2 ***");
lcd.setCursor(0, 1);
lcd.print(" Display dtata here ");
lcd.setCursor(0, 2);
lcd.print(" press enter to ");
lcd.setCursor(0, 3);
lcd.print(" move to next screen ");
break;
case 2:// menu 3
// add your code here if you need to adjust or alter any values
lcd.setCursor(0, 0);
lcd.print("** MAIN MENU 3 ***");
lcd.setCursor(0, 1);
lcd.print(" Display dtata here ");
lcd.setCursor(0, 2);
lcd.print(" press enter to ");
lcd.setCursor(0, 3);
lcd.print(" move to next screen ");
break;
case 3: //menu 4, This is where you save the values, this restarts the aruino form loop so it needs to be last
lcd.setCursor(0, 0);
lcd.print("** MAIN MENU 4 ***");
lcd.setCursor(0, 1);
lcd.print(" this is where you ");
lcd.setCursor(0, 2);
lcd.print(" save any values ");
lcd.setCursor(0, 3);
lcd.print(" to eeprom ");
delay(4000);
lcd.clear();
menucounter = 5;
menubuttonPushCounter = 0;
break;
/* NOTE THIS IS ONLY LEFT IN FOR AN EAXMPLE
* lcd.setCursor(0, 0);
lcd.print(" Saving Values ");
lcd.setCursor(0, 1);
lcd.print(" *****....***** ");
EEPROM.writeFloat(0, volts_scale);
delay(200);
EEPROM.writeFloat(10, amps_scale);
delay(200);
delay(2000);
lcd.setCursor(0, 0);
lcd.print(" Setting Values ");
lcd.setCursor(0, 1);
lcd.print(" *****....***** ");
volts_scale = EEPROM.readFloat(0);
amps_scale = EEPROM.readFloat(10);
delay(1000);
menucounter = 5;
menubuttonPushCounter = 0;
break;
*/
}
}
}
Another project where I set values in the setup loop and stays there until I press enter
while (digitalRead(manual_pin) == HIGH) { //keep in the setup, once you press enter it will contiue to main loop
lcd.setCursor(4, 1);
lcd.print("SET CAPACITY ");
manual = true;
// other code goes here
like change menu/values
if (digitalRead(upbuttonpin) ==LOW){
capacity--;
if (capacity <0)
capacity= 0;
}
if (digitalRead(downbutton) == LOW) {
capacity++; //If down up button is pressed increase value
if (capacity >400)
capacity = 400;
}
capacity_math=capacity;
lcd.setCursor(8, 2);
lcd.print(capacity_math,0);
lcd.print("AH ");
delay(100);
}
lcd.clear();
}