Description
Need sugestions on creating a component that has a menu system.
This post has two parts. Component and Menus.
What MCU/Processor/Board and compiler are you using?
ESP32 with ESP-IDF (cmake)
What do you want to achieve?
I’m building a project that has a menu system, as in you click a button and are taken to another screen.
I’m using LVGL for the whole UI part of the project.
I need to turn my code into a component. This is the first time I’m doing this so I have lots of questions, mostly because of LVGL variable declarations and how to properly build a menu system with LVGL.
What have you tried so far?
First I will have to explain how my component is structured in order for the menu questions to make sense.
Component
Right now I have some working code and menus.
I had all the code in one my_component.c
, on the same level as main.c
.
As it was getting lengthy and I’ve since decided to partition it in several files, leaving only the component’s global functions in the my_component.c
file.
The component structure is as follows:
- project/ - CMakeLists.txt - main.c - components/ - lvgl/ - CMakeLists.txt - ... - my_component/ - CMakeLists.txt - my_component.c - my_component.h - menus/ - menu_main.h - menu_main.c - menu_options.h - menu_options.c
In my_component/CMakeLists.txt
I have:
idf_component_register(SRCS "my_component.c"
"menus/menu_main.c"
"menus/menu_options.c"
INCLUDE_DIRS "." "menus"
REQUIRES lvgl
)
I have the following includes:
/* my_component.c */
#include “my_component.h”
/* my_component.h */
#include “lvgl/lvgl.h”
And
/* menu_main.c */
#include “menu_main.h”
/* menu_main.h */
#include “my_component.h”
The same is true for the menu_options.c
and menu_options.h
files.
I have some variables I need for multiple menus. For example, I need the same icon for several menus (back icon, home icon, etc).
Before turning this into a component I would simply declare them as static variables in the my_component.c
file that was on the project’s root directory.
Menus
The way I’m doing the menu system is I have one create_menu(lv_obj_t * parent)
functions for each menu which creates the objects for the whole screen.
I then have a global function in my_component.c
to create the selected menu:
lv_obj_t * scr;
void my_component_select_menu(int menu_id){
lv_obj_t * old_scr = lv_scr_act();
scr = lv_obj_create(NULL, NULL);
lv_obj_del(old_scr);
switch(menu_id){
case MENU_ID_MAIN:
create_main_menu(scr);
break;
case MENU_ID_OPTIONS:
create_options_menu(scr);
break;
default: return;
}
lv_scr_load(scr);
}
my_component_select_menu
is called when a new menu is to be drawn (e.g.: a button is pressed).
Questions:
- Should I re-arrange the component structure?
- How should I declare the image variables so I can use them in multiple files? Should I declare them as static variables in each menu file?
- Is there a better way of doing the menu system?
- Should I create all the menus with different screen global variables and then just select them as the active screen when I need that specific menu instead of creating the whole screen on the same global screen variable?
- In some menus I have variables that need to be constantly updated (some by hardware input (sensors), some by lvgl button action, e.g: increasing a value when a button is pressed on screen). How should I go about this? Redraw the whole screen? Only redraw the label containing the value?
- I’ve had some memory issues (not enough memory) with the last question. I’m not sure what the best practices are in this case. Increase the LV_MEM_SIZE? Change the way I’m drawing the menus?
These might be some basic questions/problems, but being new to LVGL and ESP-IDF I’m somewhat lost.
Let me know if there are any more details or clarifications needed.
Thank you!