sterretje:
/*
forward declarations
*/
struct MENU;
// menu functions
void showMenu();
void ledOn();
void ledOff();
// all defined menus although we might not need all
extern MENU mainMenu;
extern MENU ledMenu;
extern MENU subMenu2;
extern MENU subMenu21;
/*
end of forward declarations
*/
/*
menu structures
*/
struct MENU_ITEM
{
// key that activates menu item
char key;
// display title
char *title;
// function to execute
void (*menufunction)(void);
// associated sub menu
MENU *subMenu;
};
struct MENU
{
// items in a menu
MENU_ITEM items;
// number of items
byte numItems;
};
/
end of menu structures
*/
/*
menus
*/
// main menu
MENU_ITEM mainMenu_Items[] =
{
{'1', "Led", showMenu, &ledMenu}, // activate Led sub menu by pressing '1', execute function showMenu and set current menu to ledMenu
{'2', "sub 2", showMenu, &subMenu2}
};
MENU mainMenu = {mainMenu_Items, sizeof(mainMenu_Items) / sizeof(MENU_ITEM)};
// led menu
MENU_ITEM ledMenu_Items[] =
{
{'1', "Led on", ledOn, NULL}, // switch led on by pressing '1', execute function ledOn and no menu associated with this menu item
{'2', "Led off", ledOff, NULL},
{'*', "Back", showMenu, &mainMenu},
{'0', "Home", showMenu, &mainMenu}
};
MENU ledMenu = {ledMenu_Items, sizeof(ledMenu_Items) / sizeof(MENU_ITEM)};
// another sub menu
MENU_ITEM subMenu2_Items[] =
{
{'1', "sub 2_1", showMenu, &subMenu21},
{'2', "sub 2_2", NULL, NULL},
{'*', "Back", showMenu, &mainMenu}
};
MENU subMenu2 = {subMenu2_Items, sizeof(subMenu2_Items) / sizeof(MENU_ITEM)};
// sub menu of sub menu
MENU_ITEM subMenu21_Items[] =
{
{'1', "sub 2_1_1", NULL, NULL},
{'2', "sub 2_2_1", NULL, NULL},
{'', "Back", showMenu, &subMenu2},
{'0', "Home", showMenu, &mainMenu}
};
MENU subMenu21 = {subMenu21_Items, sizeof(subMenu21_Items) / sizeof(MENU_ITEM)};
/
end of menus
*/
// current menu
MENU *currMenu = &mainMenu;
/*
show the current menu
*/
void showMenu()
{
// safety net to prevent crashes in case something was incorrectly set up
if(currMenu->items == NULL || currMenu->numItems)
{
return;
}
Serial.println(currMenu->numItems);
for (int cnt = 0; cnt < currMenu->numItems; cnt++)
{
Serial.print(currMenu->items[cnt].key);
Serial.print('\t');
Serial.println(currMenu->items[cnt].title);
}
}
/*
switch led on pin 13 on
*/
void ledOn()
{
digitalWrite(13, HIGH);
}
/*
switch led on pin 13 off
*/
void ledOff()
{
digitalWrite(13, LOW);
}
void setup()
{
Serial.begin(9600);
// led pin initialisation
pinMode(13, OUTPUT);
digitalWrite(13, LOW);
// show current menu
showMenu();
}
void loop()
{
char ch = 0;
if (Serial.available() > 0)
{
ch = Serial.read();
}
for (int cnt = 0; cnt < currMenu->numItems; cnt++)
{
// check if character is known in current menu
if (currMenu->items[cnt].key == ch)
{
// get the function to execute
void (*func)() = currMenu->items[cnt].menufunction;
// if there is a sub menu specified, change the current menu
if (currMenu->items[cnt].subMenu != NULL)
{
currMenu = currMenu->items[cnt].subMenu;
}
// if a function was specified, execute it
if (func != NULL)
{
func();
}
}
}
}
setup() is basically straight forward. I used serial monitor for testing, so the Serial port is configured, the led pin is configured and next the code displays the current menu (that was set to mainMenu).
loop() handles the rest. If a character is received from the serial monitor (in your case from the keypad), loop() uses a for loop to iterate through items of the the current menu and checks if 'key' in the MENU_ITEM matches the received character. If so, it saves the function pointer (in func) and checks if a menu was specified and if so changes the current menu to the specified menu. Lastly it checks if a function was specified and executes that function.
Be aware that you should only specify a subMenu in MENU_ITEM if you specify showMenu for the function !!
I understand, but I have some doubts about the syntax of programming.
- How do I view the menu on the LCD?
struct MENU
{
// items in a menu
MENU_ITEM *items;
// number of items
byte numItems;
};
- What is the use struct Menu and how it works?
- What Makes menu_item * items and byte numItems?
struct MENU_ITEM
{
// key that activates menu item
char key;
// display title
char *title;
// function to execute
void (*menufunction)(void);
// associated sub menu
MENU *subMenu;
};
-
Because MENU_ITEM items have pointers (* title, * menufunction, MENU * subMenu)?
-
That function makes "MENU * subMenu"?
showMenu does not run anything.
void showMenu()
{
// safety net to prevent crashes in case something was incorrectly set up
if(currMenu->items == NULL || currMenu->numItems)
{
return;
}
Serial.println(currMenu->numItems);
for (int cnt = 0; cnt < currMenu->numItems; cnt++)
{
Serial.print(currMenu->items[cnt].key);
Serial.print('\t');
Serial.println(currMenu->items[cnt].title);
}
}
- Do not understood the symbol "->"?
- What does currMenu?
Serial.print(currMenu->items[cnt].key);
Serial.println(currMenu->items[cnt].title);
struct MENU
{
// items in a menu
MENU_ITEM *items;
// number of items
byte numItems;
};
- ¿Items [ctrl].key refers to MENUITEM * items?
MENU_ITEM mainMenu_Items[] =
{
{'1', "Led", showMenu, &ledMenu}, // activate Led sub menu by pressing '1', execute function showMenu and set current menu to ledMenu
{'2', "sub 2", showMenu, &subMenu2}
};
MENU mainMenu = {mainMenu_Items, sizeof(mainMenu_Items) / sizeof(MENU_ITEM)};
- Why "& ledMenu" has pointer and showMenu not?
I say this because * title; void (* menu function) (void); MENU * subMenu; They have pointers.
MENU mainMenu = {mainMenu_Items, sizeof(mainMenu_Items) / sizeof(MENU_ITEM)};
10.What Does "MENU mainMenu" and because it uses "sizeof (mainMenu Items) / sizeof (menu_item)"?
for (int cnt = 0; cnt < currMenu->numItems; cnt++)
{
// check if character is known in current menu
if (currMenu->items[cnt].key == ch)
{
// get the function to execute
void (*func)() = currMenu->items[cnt].menufunction;
// if there is a sub menu specified, change the current menu
if (currMenu->items[cnt].subMenu != NULL)
{
currMenu = currMenu->items[cnt].subMenu;
}
// if a function was specified, execute it
if (func != NULL)
{
func();
}
In void loop is a bit difficult to understand because of the symbol "->", the whole function is Chinese lol
Excuse me for many questions, maybe some questions are repeated, it is that I want to understand programming syntax in detail, for my something new is this type of menu, since only wise to do so with "switch" and "case".
I would like to adapt it to my programming