Pages: [1] 2   Go Down
Author Topic: LCD Menu library  (Read 11776 times)
0 Members and 1 Guest are viewing this topic.
Seattle
Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi all,

I created an LCD menu library for a project I was working on, and I figured others may be able to reuse it so I have published it under a BSD license on github.  (Just let me know if you want a different license, I am happy to re-publish for you)

The library is designed to make it easy to create a menu-driven interface on a simple LCD such as a 16x2 or 16x4.  The library depends on the Liquid Crystal library to do all the drawing, but abstracts away some of the menu-intensive code.

The user is responsible for hooking up hardware navigation buttons/devices to the menu code, so you can choose when to pass control to the Menu library to do your menu navigation, and when to do do your own thing with the LCD.

For instance, if you have an app that is using the LCD to do its primary output, you can use this library to create a Settings UI to do some tweaking (code below is for a Sous vide monitor):

Code:
  //Set up the root node first
  MenuEntry * p_menuEntryRoot = new MenuEntry("Settings", NULL, NULL);
  g_menuManager.addMenuRoot( p_menuEntryRoot );
  g_menuManager.addChild( new MenuEntry("Temp ", NULL, TempCallback) );
  g_menuManager.addChild( new MenuEntry("Time", NULL, TimeCallback ) );
  g_menuManager.addChild( new MenuEntry("Beep Off", (void *)&g_beep, MenuEntry_BoolFalseCallbackFunc) );
  g_menuManager.addChild( new MenuEntry("Beep On", (void *)&beep, MenuEntry_BoolTrueCallbackFunc) );
  g_menuManager.addChild( new MenuEntry("Back", (void *)&g_MenuManager, MenuEntry_BackCallbackFunc) );\

There is also some support for getting a number from the user:

Code:
void TempCallback( char* menuText, void *userData )
{
  char *label = "Temp F";
  int numLabelLines = 1;
  int min = 100;
  int max = 200;
  int start = 135;
  //Each user input action (such as a turn of rotary enocoder or push of button
  //will step this amount
  int iStep = 1;
 
  g_menuManager.DoIntInput( min, max, start, step, &label, numLabelLines, &g_temp );
}

That code will get a number from the user and set it in the g_temp variable.

This code was designed to work with an LCD and a clickable rotary encoder, such as this one: http://www.sparkfun.com/products/9117.  To use the rotary encoder, you can detect rotate up, rotate down, and click.  You pass these events to the MenuManager as "Menu_UP", "Menu_Down", and "Menu_Select" actions.  If you have a seperate hardware back button, you can pass this as "Menu_Back", or you can add "Back" items to all your menus to support backing up.

The code works well for simple use cases, but I hope to add more functionality soon.

The setup is a bit tough to read for more complicated menus, so if you have suggestions for a simpler way to declare tree structures such as the menus built here, I would be all ears.

The code includes an fairly complex sample stopwatch/timer.  You can get it here: http://github.com/DavidAndrews/Arduino_LCD_Menu

Please give it a try and let me know what you think.  The coding style is all over the place.  I am trying to clean it up as I go, but I am not there yet.  I will [soon] remove all the hungarian and try to settle on something consistent.  My corporate coding style is showing, but I am working on exercising it from my brain.

Testing has been a bit ad-hoc, but I will try to address bugs quickly or accept submitted bug fixes even quicker.

We are creating an open hardware project to go along with this, which should be ready in time for Maker Faire, so keep an eye open at http://www.authenticinvention.com for announcements.

David
Logged

Central MN, USA
Offline Offline
Tesla Member
***
Karma: 65
Posts: 6928
Phi_prompt, phi_interfaces, phi-2 shields, phi-panels
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

David,

Very nice! Would you put up some videos to show case your library? I know a few of us also have our own menu/user interface libraries. Here is mine for your information:

http://liudr.wordpress.com/libraries/phi_prompt/


I also integrated some features of my library on a display/keypad panel produce I designed last summer:

http://liudr.wordpress.com/gadget/phi-panel/
Logged


Germany
Offline Offline
Edison Member
*
Karma: 100
Posts: 1242
If you believe something is right, you won't see what's wrong (David Straker).
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi
Good work and nice video.

In the last month i have seen several Menu Lib announced in the Arduino forum. I would suggest to add the Menu-Lib also to
http://arduino.cc/playground/Main/InterfacingWithHardware#ui so that we get an overview on the existing implementations.

Oliver
Logged

Seattle
Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for the feedback.  I am definitely going to check out the phi libraries.  That library looks very full featured and I especially like the broad range of input gathering code.  I have added LCD Menu to the playground as well, thanks for the suggestion.

If anyone has an LCD/Arduino sitting around already wired and using Liquid Crystal, I'd love feedback on whether it compiles and works on your setup, even just the sample sketch provided.  I haven't been able to run it on anything except my one configuration, but I think it should work on just about anything Liquid Crystal supports.  I think it should just work for a 4 line display, but I also haven't been able to test that yet either.

David
Logged

Dallas, TX USA
Offline Offline
Edison Member
*
Karma: 47
Posts: 2347
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I did get it to work using fm's replacement LiquidCrystal library running in 4 bit mode.
(rather than using the stock Arduino LiquidCrystal library)
https://bitbucket.org/fmalpartida/new-liquidcrystal/overview

What I wanted to do but was not able to do was to run it on a i2c or ShiftRegister interface
to the LCD.
This was because of the linkage that assumes a LiquidCrystal type constructor.

If you want to support fm's library to allow support for other interfaces other than 4 bit,
have a look a different library done recently that works with fm's library for
how the linkage works.
http://code.google.com/p/arduino-lcd-bitmap/

I also noticed that when I renamed the .ino file back to .pde to try it on 0022,
the sketch and code would not compile. It failed on the references to new and delete.
Not sure how this changed in 1.0

--- bill
Logged

rome
Offline Offline
Sr. Member
****
Karma: 15
Posts: 474
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

To use properly the fm library you must use, inside the library, the LCD abstract class.
That allows you, in the sketch, to use the different "sublibraries" (as, for instance, the I2c) and their related subclasses (for instance LiquidCrystal_I2C).
I use such an approach in my MENWIZ menu library and it works fine.
By the way, if you are interested you can find my lib at github.com/brunialti/MENWIZ
Here attached you can find a quick tour to  menwiz (sorry for my english).

* QUICK TOUR.pdf (89.23 KB - downloaded 114 times.)
« Last Edit: May 09, 2012, 11:03:38 am by brunialti » Logged

Germany
Offline Offline
Edison Member
*
Karma: 100
Posts: 1242
If you believe something is right, you won't see what's wrong (David Straker).
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I see some more entries on Playground. Thanks for that!

Oliver
Logged

Seattle
Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi liudr - I took a look at the phi libraries.  Very nice!  If it was available for commercial use, I would move over to yours.  I have looked it the way it works and taken some inspiration, so thanks!

David
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

thanks for this nice and great post keep it up...
Logged


Central MN, USA
Offline Offline
Tesla Member
***
Karma: 65
Posts: 6928
Phi_prompt, phi_interfaces, phi-2 shields, phi-panels
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi liudr - I took a look at the phi libraries.  Very nice!  If it was available for commercial use, I would move over to yours.  I have looked it the way it works and taken some inspiration, so thanks!

David


Thanks David. Just drop a reply on my blog if you want commercial use. I don't charge more than an arduino board for a license to use all my libraries any amount of times in commercial products.
Logged


Seattle
Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Someone asked if we could post a video of the library working.  You can see it in operation here:  http://www.kickstarter.com/projects/988159748/robotic-minion-start-kit-arduino-compatible  (This is a link to our kickstarter video, sorry, I don't have anything else built to show it off smiley-sad )

David


Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 13
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm kind of wondering how to "exit" the menu..    when i select a menu entry, i want it to execute a callback (which works), then NOT return to the menu.. the callback will change the interface to a "page" of settings - i'm envisioning 4 columns with top row of labels and bottom row of values.     


Otherwise, this is working pretty well..  I also would like to see some kind of input subclassing like phi prompt..   I tried the PHI library, but it also takes Mu control over my app so I'm not really able to accomplish what i want.   Plus the init code in that library is pretty nastyy..   

Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 1
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

yes i think it is the best way that my friend said, add this http://arduino.cc/playground/Main/InterfacingWithHardware#ui  into your menu

good luck my friend
Logged


0
Offline Offline
Newbie
*
Karma: 0
Posts: 28
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I think this library is a fantastic resource once a keyboard is integrated into the code and I found that very simple to do using a class I built for a 5 button analog keyboard that supports auto typing if arrow keys are held down and a Long Press on the Select key to act as a back button.

Its been a long time since I have played with Arduino and once I got going with this library,  I ran out of memory before I completed building my menu.

I have found some very inefficient code that duplicates strings passed to the function that I think doubles memory usage in the MenuEntry constructor.

So when building a menu you make calls like this:

Code:
g_menuManager.addChild( new MenuEntry("Set Home", NULL, HomeSetCallback) )

and then the constructor promptly creates another copy on the stack like this:
Code:
  m_menuText = strdup(menuText);

It is easy enough to halve memory usage by first defining the menu prompts as static strings and modify the constructor so it does
Code:
m_menuText = menuText;

but ideally it would be good to be able to use PROGMEM F() strings which will further reduce stack usage. I tried something like changing the definition from
Code:
MenuEntry::MenuEntry( char * menuText, void * userData, MENU_ACTION_CALLBACK_FUNC func)
to
Code:
MenuEntry( const __FlashStringHelper * menuText, void * userData, MENU_ACTION_CALLBACK_FUNC func);

And calling it with
Code:
g_menuManager.addChild( new MenuEntry(F("Set Home"), NULL, HomeSetCallback) )

but I ran into compiler errors.

It has been 20 odd years since I have done much with C and I am struggling with the complex casts to get this to work. a few tips would be appreciated as a Flash memory version of this would be great and should not require too much effort.

Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 36
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,

is this library going to be updated? I've got it to work but the Arduino IDE still shows many warnings and I'm hesitant to use it.
Logged

Pages: [1] 2   Go Up
Jump to: