Best LCD Menu Library ?

Hello,

For you, what is the best menu library for 16x2 LCD, i have a DFRobot LCD shield with buttons and i want to start a project for a programmable UV sensor with alarms. I need to modify some variables with LCD and configures some options.

Best regards,

The one I use is my own. I designed it for the same purposes as you want to use it and it is meant for 1 or 2 line displays (like LCD modules).

Find it at https://github.com/MajicDesigns/MD_Menu

OK thanks it's look nice

I'll bump the post again as I have the same question.
MD_menu may suit but I'd like a native 20x4 screen capability.

MENWIZ.h would have been a a good choice but its now legacy and I can't make it work now with IDE 1.8.5.

Any other tried and trusted options outside those suggested on arduino.cc out there?
Thanks a lot!

Hi, did you see that one?


quote author=fkuashum link=msg=3852474 date=1535266253]
I'll bump the post again as I have the same question.
MD_menu may suit but I'd like a native 20x4 screen capability.

MENWIZ.h would have been a a good choice but its now legacy and I can't make it work now with IDE 1.8.5.

Any other tried and trusted options outside those suggested on arduino.cc out there?
Thanks a lot!
[/quote]

I don’t like bumping old threads but this is not that old.

I’ve got a menu library that is currently going through active development. I’ve not yet really exposed it much to the outside world as it is quite new. Think Early BETA.

It’s able to render to most lcd screen sizes including i2c and also adafruit GFX compatible displays. I’m also planning to write an oled 1306 renderer. Writing a new renderer is quite straightforward.

It provides support for input from a rotary encoder or switches. Attached either directly or on an IOexpander.

It includes a designer app that works on most desktop platforms that generates the menu code and can round trip.

It’s main standout feature is remote control. It has Ethernet and Serial based endpoints with a Java API client side and fully documented protocol for other languages. There is an example javaFX client that demonstrates the remote capabilities. Writing new remote endpoints is straightforward. It works on anything from Uno upwards.

Tested on Uno, Mega and Mkr ranges.

davetcc:
I don’t like bumping old threads but this is not that old.

I’ve got a menu library that is currently going through active development. I’ve not yet really exposed it much to the outside world as it is quite new. Think Early BETA.

It’s able to render to most lcd screen sizes including i2c and also adafruit GFX compatible displays. I’m also planning to write an oled 1306 renderer. Writing a new renderer is quite straightforward.

It provides support for input from a rotary encoder or switches. Attached either directly or on an IOexpander.

It includes a designer app that works on most desktop platforms that generates the menu code and can round trip.

It’s main standout feature is remote control. It has Ethernet and Serial based endpoints with a Java API client side and fully documented protocol for other languages. There is an example javaFX client that demonstrates the remote capabilities. Writing new remote endpoints is straightforward. It works on anything from Uno upwards.

Tested on Uno, Mega and Mkr ranges.

https://github.com/davetcc/tcMenu

I tried this out and it's really promising!

I had trouble getting it to work with my i2c lcd backpack. so I did my own renderer using the hd44780 library. Is there a way to get it to leave my renderer in place when regenerating menu code?

I had trouble getting it to work with my i2c lcd backpack. so I did my own renderer using the hd44780 library. Is there a way to get it to leave my renderer in place when regenerating menu code?

Thanks for trying TcMenu. This is planned for a version very soon. In fact could probably be put in 1.1 due this week.

Also if you’d consider contributing back I would be glad to help you putting into the new structure and making it another option.

davetcc:
Thanks for trying TcMenu. This is planned for a version very soon. In fact could probably be put in 1.1 due this week.

Also if you’d consider contributing back I would be glad to help you putting into the new structure and making it another option.

Well, "my own renderer" was actually no more than changing the #includes in tcMenuLiquidCrystal.h and adjusting the lcd() constructor in MyProject.cpp.

And then I realized the generated code did work, just with no backlight. Saw your updates today, and that's working as well. Thanks!

It took me a while to figure out some other stuff, like eeprom load/save. An example project would come in really handy.

Yep, examples were missing from v1.0. There has been a quite long delay between versions because of a few tooling changes. This is all but sorted now. New release within the next few days.

When the next version comes out it will have a couple of long overdue examples too. Along with that I have a few starter videos and updates to the quick start planned.

Great news. I'll second the request for acceleration I saw in another thread. My plan is to use this for a stepper controller, and being able to use one of those analog menu items, through its full 64K range would be really valuable.

Yep acceleration has been asked for a few times now. created an issue against ioabstraction: https://github.com/davetcc/IoAbstraction/issues/37

Just today V1.1 of TcMenu has been released. It has quite a few improvements, including shipping with three examples ready built for common configurations.

I'm going to put some time into improving the examples, videos, and documentation as I think these are most important at the moment. There's now a lot of people trying to use it, and the documentation in some areas is either old or thin on the ground.

After that I'll look at acceleration for both rotary encoders and switches (switchinput) as that's getting quite a lot of requests now.

Hi!

Here an alternative https://github.com/neu-rah/ArduinoMenu

see for yourself, the supported platforms and display's is huge, active maintained, usage hardened library.

Provides a useful set of controls and plugins

I just wrote my own for my wheelieometer, basically in Setup if the button is held down it goes into a setup mode and prompts the user to release the button. It then prompts for each parameter in turn; for each pressing the button increments the value by one (there is a debounce, so holding the button increments the value slowly), the value reverts to its minimum if the maximum is exceeded. If the button isn’t pressed for a specified period, the value is accepted and the user is prompted for the next value.

Example (could do with using more generic functions!):

if (!digitalRead(PinDisplayButton)) //Read button directly as we don't need debounce
  {
    //Button Pressed, enter setup mode
    oled.print(F("Setup Mode"));
    oled.clearToEOL();
    oled.setCursor(0,4);
    oled.print(F("Release"));
    oled.clearToEOL();
    oled.setCursor(0,6);
    oled.print(F("Button!"));
    oled.clearToEOL();

    //Wait for button to be released
    do
    {
    } while (!digitalRead(PinDisplayButton));
    OldDisplayButtonTime = millis(); //Reset time of last button press
    
    if(ClockAvailable)
    {
      byte RTCDataMax[6]; //Array to hold maximum value of each element of the date and time
      RTCDataMax[0] = 59; //Maximum seconds
      RTCDataMax[1] = 59; //Maximum minute
      RTCDataMax[2] = 23; //Maximum hour
      RTCDataMax[3] = 31; //Maximum date (no check made for shorter months)
      RTCDataMax[4] = 12; //Maximum month
      RTCDataMax[5] = 99; //Maximum year
  
      byte RTCDataMin[6]; //Array to hold minimum value of each element of the date and time
      RTCDataMin[0] = 0; //Minimum seconds
      RTCDataMin[1] = 0; //Minimum minute
      RTCDataMin[2] = 0; //Minimum hour
      RTCDataMin[3] = 1; //Minimum date
      RTCDataMin[4] = 1; //Minimum month
      RTCDataMin[5] = 0; //Minimum year
      
      byte RtcData[6]; //Array to save clock values
      
      //Print fixed text to screen
      oled.setCursor(0,2);
      oled.print(F("Set Clock"));
      oled.clearToEOL();
      oled.setCursor(0,4);
      oled.print(F("Set"));
      oled.clearToEOL();
      oled.setCursor(0,6);
      oled.clearToEOL();      

      //Retrieve current time
      HCRTC.RTCRead(I2CDS1307Add); 
      RtcData[0] = HCRTC.GetSecond(); //Seconds
      RtcData[1] = HCRTC.GetMinute(); //Minutes
      RtcData[2] = HCRTC.GetHour(); //Hours
      RtcData[3] = HCRTC.GetDay(); //Date
      RtcData[4] = HCRTC.GetMonth(); //Month
      RtcData[5] = HCRTC.GetYear(); //Year 
      
      //Loop over elements of date and time
      for (byte ClockElement = 5;  ClockElement < 6; ClockElement--) //After 0 value will overload to 255 hence the end condition
      {
        //State what is being set
        oled.setCursor(49,4); //Position to write
        switch (ClockElement)
        {
          case 5:
            oled.print(F("Year"));
            break;
          case 4:
            oled.print(F("Month"));
            break;
          case 3:
            oled.print(F("Date"));
            break;
          case 2:
            oled.print(F("Hour"));
            break;
          case 1:
            oled.print(F("Minute"));
            break;     
          case 0:
            oled.print(F("Second"));
            break;                            
        }
        oled.clearToEOL();
  
        //Print current value to screen
        oled.setCursor(0,6);
        oled.print(RtcData[ClockElement]);
        oled.clearToEOL();
  
        //Wait for button presses to change value
        do
        {
          if (CheckDisplayButton())
          {
            //Button pressed: increment value
            RtcData[ClockElement]++;
            if(RtcData[ClockElement] > RTCDataMax[ClockElement]) //Jump to minimum value
            {
              RtcData[ClockElement] = RTCDataMin[ClockElement];
            }
            //Update display
            oled.setCursor(0,6);
            oled.print(RtcData[ClockElement]);
            oled.clearToEOL();
          } 
         } while (!IntervalCheck(OldDisplayButtonTime, SetupTimeout)); //After timeout, proceed 
        OldDisplayButtonTime = millis(); //Reset timeout for next element
      }
      
      HCRTC.RTCWrite(I2CDS1307Add, RtcData[5], RtcData[4], RtcData[3], RtcData[2], RtcData[1], RtcData[0], 1);  //Set Clock, last parameter is weekday and not used
      delay(100); //Delay to let the clock be set
    }

    //Minimum angle to trigger a wheelie
    oled.setCursor(0,2);
    oled.print(F("Set Angle"));
    oled.clearToEOL();
    oled.setCursor(0,4);
    oled.print(F("Threshold"));
    oled.clearToEOL();

    //Read current angle from non-volatile EEPROM memory
    MinAngle = EEPROM.read(MinAngleEEPROMAddress);

    //Check MinAngle in range, if not default to smallest
    if((MinAngle < MinAngleMin) || (MinAngle > MinAngleMax))
    {
      MinAngle = MinAngleMin;
    }

    //Write current value to screen
    oled.setCursor(0,6);
    oled.clearToEOL();
    oled.setCursor(25,6);
    oled.set1X();
    oled.print(F("o"));
    oled.set2X();
    oled.setCursor(0,6);
    oled.print(MinAngle,0);

    //Wait for button presses to change value
    do
    {
      if (CheckDisplayButton())
      {
        //Button pressed: increment value by 5 degrees
        MinAngle += 5;
        if(MinAngle > MinAngleMax) //Jump to minimum value
        {
          MinAngle = MinAngleMin;
        }
        //Update display
        oled.setCursor(0,6);
        oled.print(F("  "));
        oled.setCursor(0,6);
        oled.print(MinAngle,0);
      } 
    } while (!IntervalCheck(OldDisplayButtonTime, SetupTimeout)); //After timeout, proceed 
    OldDisplayButtonTime = millis(); //Reset timeout for next element

    EEPROM.update(MinAngleEEPROMAddress, (int)MinAngle); //Update stored value

neu-rah:
Hi!

Here an alternative https://github.com/neu-rah/ArduinoMenu

see for yourself, the supported platforms and display's is huge, active maintained, usage hardened library.

Provides a useful set of controls and plugins

Hi neu-rah and everyone.

It is really hard to find something (about scrollable menu I speak) to fit into an already working/running project without modifying a lot.
I do not know if the suggested menu library fits to my need but any idea would be appreciated.

I started in 2015 an automation controller for a heating system with 4 pumps (relays), 5 way button (analog input, button takes values 0-5, no_button/left/up/right/down/ok), i2c LCD 20x4, DS3231 RTC i2c, 10 DS18B20 temperature sensors.
During the time I extended it, added features and one month ago I integrated a gas boiler in the system using another 2 relays.
I have now 10 different screens (no repeating pattern to reuse) navigating left/right with rollover, 2 of them having also some options up/ok/down.

What I need?
I wish to build one more screen with with settings/parameters.

I have about 15 parameters (usually temperature limits and hysteresis units, and some options 0/1) which I want them in a single scrollable menu (3...4 parameters on sight, the second line selected in order to see what is the previous/next)
On the right side each parameter has its actual value.
So... scrolling up/down with rollover from last to first and viceversa.
Ok button will choose the parameter and jumps on level2 where up/down increments/decrements the value of the parameter in some limits, ok will confirm, left button will jump back to level1 (in the list where we left previously)

The problem is that everything is on 328p Ardino Nano. The available space in flash is about 5000 bytes and 950 bytes RAM.
I have to use the existing configuration for lcd i2c of Malpartida (from 3-4 years ago) or something else would need a lot of adaptation.

Thanks in advance.

The problem is that everything is on 328p Ardino Nano. The available space in flash is about 5000 bytes and 950 bytes RAM

From a tcmenu perspective the RAM would be fine, but the flash may be a bit of an issue depending what libraries are shared between your code and tcMenu. An atmega328 is the minimum chip we support and we’ll try and keep at least a branch working on it for a while yet.

You can easily try tcMenu by downloading the designer UI package from github and generate a menu. I think it would do most of what you want out of the box. It would probably take half an hour to an hour to get a prototype in place.

TcMenu is now used in many designs and is also capable of serial, Bluetooth, WiFi and Ethernet remote control. There are many users with different use cases. The menu structure is easy to access in code.

In terms of how you could use it in an existing sketch, there’s support for taking control of the display and giving it back. You can listen for changes to items or just get the value as needed.

However, you would need to accept that menu library depends on IOAbstraction.

Thanks for the response.

I had a quick look over the Designer but it is not enough. I have to read the documentation.

There may be a variant to redesign my existing 10 screens in order to embed in the TcMenu.

Actually those 10 screens are separate voids() (displayscreen01...03 etc.) which are accessed cyclic (100-200ms) through a switch/case depending the "meniu" variable (0-9) which is incremented/decremented by the variable "button" (1/3 a.k.a. left/right).
Each "void" has lcd.setCursor, lcd.print(****) for fixed text and variables and actions for the buttons 2/4/5 if applicable, so it is the basic way how I designed this.

I think that whichever library you were to choose, there would be a significant amount of rework to include it.

I think it comes down to determining which one fits the best. There are a few good choices.

I’d say the biggest thing to check is if there would be enough flash to fit the menu and your code in there at once. For tcMenu it would be a very close call if indeed there was enough space with only 5k flash available.

Rendering in tcMenu is handled by there being a menu manager and a rendering class. Generally the manager keeps hold of the currently displayed menu and active or edited item while the renderer runs in a loop working out if anything needs to be updated. You can take over and give back the display for times when you want to hold the display.

There are rendering classes for LCD, AdaGfx and U8G2. Other could easily be added. Input is from rotary encoder, switches, analog switches, matrix keypad or joystick. Again, input is easily extended to new devices.

@davetcc, is there a plan to add IR control to tcMenu anytime soon?