I currently have a menu system accessible through an LCD button shield with the buttons used for menu navigation.
Currently, the program logic is as following:
Ask for user to select part family using up and down arrows.
Press select to choose family and display will show selected family
Now, I’d like to create a secondary submenu for each part family
EX: Able to scroll through and select CFM Parts 1-5 as individual items in CFM family.
As I am very new at programming and Arduino, I figured you guys would now what next steps to take.
My current wiring is a simple LCD button shield wired normally to Arduino MEGA with the extra analog input for the buttons.
My current code is:
#include <LiquidCrystal.h>
// Initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
//States for the menu.
int currentMenuItem = 0;
int lastState = 0;
void setup() {
//Set the characters and column numbers.
lcd.begin(16, 2);
//Print default title.
clearPrintTitle();
}
void loop() {
//Call the main menu.
mainMenu();
}
void mainMenu() {
//State = 0 every loop cycle.
int state = 0;
//Refresh the button pressed.
int x = analogRead (0);
//Set the Row 0, Col 0 position.
lcd.setCursor(0,0);
//Check analog values from LCD Keypad Shield
if (x < 100) {
//Right
} else if (x < 200) {
//Up
state = 1;
} else if (x < 400){
//Down
state = 2;
} else if (x < 600){
//Left
} else if (x < 800){
//Select
state = 3;
}
//If we are out of bounds on the menu, then reset it.
if (currentMenuItem < 0 || currentMenuItem > 4) {
currentMenuItem = 0;
}
//If we have changed Index, saves re-draws.
if (state != lastState) {
if (state == 1) {
//If Up
currentMenuItem = currentMenuItem - 1;
displayMenu(currentMenuItem);
} else if (state == 2) {
//If Down
currentMenuItem = currentMenuItem + 1;
displayMenu(currentMenuItem);
} else if (state == 3) {
//If Selected
selectMenu(currentMenuItem);
}
//Save the last State to compare.
lastState = state;
}
//Small delay
delay(5);
}
//Display Menu Option based on Index.
void displayMenu(int x) {
switch (x) {
case 1:
clearPrintTitle();
lcd.print ("-> CFM");
break;
case 2:
clearPrintTitle();
lcd.print ("-> FAM X");
break;
case 3:
clearPrintTitle();
lcd.print ("-> FAM Y");
break;
case 4:
clearPrintTitle();
lcd.print ("-> FAM Z");
break;
}
}
//Print a basic header on Row 1.
void clearPrintTitle() {
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Part Family?");
lcd.setCursor(0,1);
}
//Show the selection on Screen.
void selectMenu(int x) {
switch (x) {
case 1:
clearPrintTitle();
lcd.print ("Selected CFM");
//Call the function that belongs to Option 1
break;
case 2:
clearPrintTitle();
lcd.print ("Selected FAM X");
//Call the function that belongs to Option 2
break;
case 3:
clearPrintTitle();
lcd.print ("Selected FAM Y");
//Call the function that belongs to Option 3
break;
case 4:
clearPrintTitle();
lcd.print ("Selected FAM Z");
//Call the function that belongs to Option 4
break;
}
}
Please read Nick Gammon's two posts at the top of this Forum on the guidelines for posting, especially the use of code tags when listing your source code. It will help us help you.
I took a look at the menwiz already, but honestly, I'd rather use the approach I have currently only since it seems I need to 'tack on' a submenu for each part family option listed in my sketch.
I feel like I'm close to the solution I'm looking for this method!
The problem I run into, is that I am not sure how to throw secondary menus into the mix.
The additions I'd like to make to the current sketch are:
-secondary menus consisting of 5 new item options for each part family
-the ability to hit the 'Left' button on the shield and go back 1 menu
EDIT: I realize currently pressing up and down once a family is selected will return to the part family menu, but this functionally would be replaced by the "left to go back 1 menu"implementation
-Upon selecting "Part 1 of Family X" through the two submenus, pressing an external con
cave push button once activates a servo
The last bullet is the least important, not meant for immediate implementation. That'll be adressed once the menu is working
The menu system will only require two menus: "Part Family" and "Parts in Family", therefore, I don't believe it will be overly complicated if following my current approach.
void displayMenu(int x) {
switch (x) {
case 1:
clearPrintTitle();
lcd.print ("-> CFM");
break;
case 2:
clearPrintTitle();
lcd.print ("-> FAM X");
break;
case 3:
clearPrintTitle();
lcd.print ("-> FAM Y");
break;
case 4:
clearPrintTitle();
lcd.print ("-> FAM Z");
break;
}
}
You look at an index, and decide what text to show. Instead, put the text into an array and get the approriate text to display using the index to the array. You can have a second array with another set of selection texts. When you want a different menu, then you just change which array you are getting the text from.
So all I'll need to do is first create individual arrays of every possible menu item and sub menu item?
EX: Part Family-> CFM, FAM X, FAM Y,...
EX: Parts in Family -> CFM1,CFM2, CFM3.......FAMX1,FAMX2.....FAMY1,FAMY2,.....
So each individual item will have an array of its own, as will each main menu option?
This still confuses me however, as I am unsure what to code once a part family is selected.
For example, if I choose CFM, do I just tell it to print the next array as submenu1 (CFM) option1 (CFM 1)?
My issue lies with moving from one menu to the next
In my code below, upon selecting a part family, it wil display the selected family.
But my code implies I can call another function at this time as well.
Can I set a delay between the printing of "Selected _______" and that case creating a submenu for that part family?
In other words, once a part family is selected and printed to screen, a time delay occurs, and then the "parts in family" submenu appears.
The time delay I can do, but as for each case moving to it's own 'parts in family' submenu, this is where I am struggling.
I feel as if this can be achieved, but I am not sure how to go about it.
//Show the selection on Screen.
void selectMenu(int x) {
switch (x) {
case 1:
clearPrintTitle();
lcd.print ("Selected CFM");
//Call the function that belongs to Option 1
break;
case 2:
clearPrintTitle();
lcd.print ("Selected FAM X");
//Call the function that belongs to Option 2
break;
case 3:
clearPrintTitle();
lcd.print ("Selected FAM Y");
//Call the function that belongs to Option 3
break;
case 4:
clearPrintTitle();
lcd.print ("Selected FAM Z");
//Call the function that belongs to Option 4
break;
}
}
char* menu1[] = {"Menu1Item1" , "Menu1Item2", "Menu1Item3"};
char* menu2[] = {"Menu2Item1" , "Menu2Item2", "Menu2Item3"};
char** menus[] = { menu1, menu2};
int currentMenu = 0; // This line at top of program at global scope
void displayMenu(int x) {
clearPrintTitle();
lcd.print (menus[currentMenu][x]);
}
#include <LiquidCrystal.h>
// Initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
//States for the menu.
int currentMenuItem = 0;
int lastState = 0;
//Create each Menu as an array with each corresponding item.
char* partfamily[] = {"CFM", "FAM X", "FAM Y", "FAM Z"};
char* CFMparts[] = {"CFM 1", "CFM 2", "CFM 3", "CFM 4"};
char* FAMXparts[] = {"FAM X 1", "FAM X 2", "FAM X 3", "FAM X 4"};
char* FAMYparts[] = {"FAM Y 1", "FAM Y 2", "FAM Y 3", "FAM Y 4"};
char* FAMZparts[] = {"FAM Z 1", "FAM Z 2", "FAM Z 3", "FAM Z 4"};
char** menus[] ={ partfamily, CFMparts, FAMXparts, FAMYparts, FAMZparts};
void setup() {
//Set the characters and column numbers.
lcd.begin(16, 2);
//Print default title.
clearPrintTitle();
}
void loop() {
//Call the main menu.
mainMenu();
}
void mainMenu() {
//State = 0 every loop cycle.
int state = 0;
//Refresh the button pressed.
int x = analogRead (0);
//Set the Row 0, Col 0 position.
lcd.setCursor(0,0);
//Check analog values from LCD Keypad Shield
if (x < 100) {
//Right
} else if (x < 200) {
//Up
state = 1;
} else if (x < 400){
//Down
state = 2;
} else if (x < 600){
//Left
} else if (x < 800){
//Select
state = 3;
}
//If we are out of bounds on the menu, then reset it.
if (currentMenuItem < 0 || currentMenuItem > 4) {
currentMenuItem = 0;
}
//If we have changed Index, saves re-draws.
if (state != lastState) {
if (state == 1) {
//If Up
currentMenuItem = currentMenuItem - 1;
displayMenu(currentMenuItem);
} else if (state == 2) {
//If Down
currentMenuItem = currentMenuItem + 1;
displayMenu(currentMenuItem);
} else if (state == 3) {
//If Selected
selectMenu(currentMenuItem);
}
//Save the last State to compare.
lastState = state;
}
//Small delay
delay(5);
}
//Menu options are to be displayed using arrays.
void displayMenu(int x){
clearPrintTitle();
lcd.print (menus[currentMenu][x]);
}
I am unsure what to do at the end of this code; how start at part family menu and then from there
I’m new at all of this, so I’m don’t understand what you mean.
I can’t seem to figure out the array method, so I’ve attempted to create submenu cases within each part family selection.
Here is my code so far. I can’t seem to figure out whats wrong/how to proceed.
#include <LiquidCrystal.h>
// Initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
//States for the menu.
int currentMenuItem = 0;
int lastState = 0;
void setup() {
//Set the characters and column numbers.
lcd.begin(16, 2);
//Print default title.
clearPrintTitle();
}
void loop() {
//Call the main menu.
mainMenu();
}
void mainMenu() {
//State = 0 every loop cycle.
int state = 0;
//Refresh the button pressed.
int x = analogRead (0);
//Set the Row 0, Col 0 position.
lcd.setCursor(0,0);
//Check analog values from LCD Keypad Shield
if (x < 100) {
//Right
} else if (x < 200) {
//Up
state = 1;
} else if (x < 400){
//Down
state = 2;
} else if (x < 600){
//Left
} else if (x < 800){
//Select
state = 3;
}
//If we are out of bounds on the menu, then reset it.
if (currentMenuItem < 0 || currentMenuItem > 4) {
currentMenuItem = 0;
}
//If we have changed Index, saves re-draws.
if (state != lastState) {
if (state == 1) {
//If Up
currentMenuItem = currentMenuItem - 1;
displayMenu(currentMenuItem);
} else if (state == 2) {
//If Down
currentMenuItem = currentMenuItem + 1;
displayMenu(currentMenuItem);
} else if (state == 3) {
//If Selected
selectMenu(currentMenuItem);
}
//Save the last State to compare.
lastState = state;
}
//Small delay
delay(5);
}
//Display Menu Option based on Index.
void displayMenu(int x) {
switch (x) {
case 1:
clearPrintTitle();
lcd.print ("-> CFM");
break;
case 2:
clearPrintTitle();
lcd.print ("-> FAM X");
break;
case 3:
clearPrintTitle();
lcd.print ("-> FAM Y");
break;
case 4:
clearPrintTitle();
lcd.print ("-> FAM Z");
break;
}
}
//Print a basic header on Row 1.
void clearPrintTitle() {
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Part Family?");
lcd.setCursor(0,1);
}
//Show the selection on Screen.
void selectMenu(int x) {
switch (x) {
//CASE 1: User selected CFM family
case 1:
clearPrintTitle();
lcd.print ("Selected CFM");//Display selected family to user
delay(150); //Wait some time
//Switch to Parts in CFM Family Menu
switch (x) {
case a:
clearPrintTitle();
lcd.print ("CFM 1");
break;
case b:
clearPrintTitle();
lcd.print ("CFM 2");
break;
case c:
clearPrintTitle();
lcd.print ("CFM 3");
break;
case d:
clearPrintTitle();
lcd.print ("CFM 4");
break;
break;
//CASE 2: User selected FAM X
case 2:
clearPrintTitle();
lcd.print ("Selected FAM X");
delay(150); //Wait some time
//Switch to Parts in Family X Menu
switch (x) {
case e:
clearPrintTitle();
lcd.print ("FAM X 1");
break;
case f:
clearPrintTitle();
lcd.print ("FAM X 2");
break;
case g:
clearPrintTitle();
lcd.print ("FAM X 3");
break;
case h:
clearPrintTitle();
lcd.print ("FAM X 4");
break;
break;
//CASE 3: User selected Family Y:
case 3:
clearPrintTitle();
lcd.print ("Selected FAM Y");
delay(150); //Wait some time
//Switch to Parts in Family Y Menu
switch (x) {
case i:
clearPrintTitle();
lcd.print ("FAM Y 1");
break;
case j:
clearPrintTitle();
lcd.print ("FAM Y 2");
break;
case k:
clearPrintTitle();
lcd.print ("FAM Y 3");
break;
case l:
clearPrintTitle();
lcd.print ("FAM Y 4");
break;
break;
//CASE 4: User selected Family Z:
case 4:
clearPrintTitle();
lcd.print ("Selected FAM Z");
delay(150); //Wait some time
//Switch to Parts in Family Z Menu
switch (x) {
case i:
clearPrintTitle();
lcd.print ("FAM Z 1");
break;
case j:
clearPrintTitle();
lcd.print ("FAM Z 2");
break;
case k:
clearPrintTitle();
lcd.print ("FAM Z 3");
break;
case l:
clearPrintTitle();
lcd.print ("FAM Z 4");
break;
break;
}
}