10
\$\begingroup\$

Is there a pattern out there for a simple menu system in C for a text LCD. I find myself re-writing code a lot for handling simple text LCD menus.

I find most systems have a main menu and some sub-menus that when selected allow you to set a parameter with within some minimum and maximum value.

Ideally this menu system could be navigated with 4 simple keys such as enter, cancel, up, and down.

In my application I'm using a 2 line x 16 character text LCD though an ideal solution should be able to be applied to any NxM display.

\$\endgroup\$
  • \$\begingroup\$ Nothing to do with electronic design! Question will be closed. \$\endgroup\$ – Leon Heller Oct 13 '11 at 20:01
  • 5
    \$\begingroup\$ I was under the impression programming questions if they applied to embedded systems could be asked here too. Maybe I was wrong... \$\endgroup\$ – mjh2007 Oct 13 '11 at 20:11
  • \$\begingroup\$ I was under similar impression too. Is there an official note about that? \$\endgroup\$ – AndrejaKo Oct 13 '11 at 20:30
  • \$\begingroup\$ Only very low-level stuff, according to the FAQ. This question is about the user interface. \$\endgroup\$ – Leon Heller Oct 13 '11 at 20:39
  • 3
    \$\begingroup\$ +1 I would be interested too...I've always hand-brewed them. Are you using a console output or a NxM character display....not that I have an answer for either :) On several embedded 2xN display systems, I've implemented two button interfaces with combining Enter/Cancel and have Next which is a ring buffer and eliminates the need for up/next & down/back. \$\endgroup\$ – kenny Oct 13 '11 at 21:17
5
\$\begingroup\$

The pattern I use for menu systems in C is something like this:

struct menuitem
{
  const char *name; // name to be rendered
  functionPointer handlerFunc; // handler for this leaf node (optionally NULL)
  struct menu *child; // pointer to child submenu (optionally NULL)
};

struct menu
{
  struct menu *parent; // pointer to parent menu
  struct **menuitem; // array of menu items, NULL terminated
};

I then declare an array of menus each containing menuitems and pointers to child submenus. Up and down moves through the currently selected array of menuitems. Back moves to the parent menu and forward/select either moves to a child submenu or calls a handlerFunc for a leaf node.

Rendering a menu just involves iterating through its items.

The advantage of this scheme is that it's fully data driven, the menu structures can be statically declared in ROM independent of the renderer and handler functions.

| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

Toby's answer is a very good starting point. The structures mentioned assume that the menus are static and you just navigate through them.

If you want dymanic menus (e.g. displaying certain values, such as temperature, time, etc), then you need to be able to generate that.

One way could be to have register a function to build your string.

struct menuitem
{
  const char *name; // name to be rendered
  const char * (*builderFunc)( const char *name );  // callback to generate string, if not null.
  functionPointer handlerFunc; // handler for this leaf node (optionally NULL)
  struct menu *child; // pointer to child submenu (optionally NULL)
};
| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.