MENWIZ: yet another character lcd menu wizard library

That's better than I thought. OOP programmers are often too easily dismissing the practice to have a fixed length array to store object pointers. I do what you do in different projects where objects are to be created at run time (there's a max of how much my fixed pointer array can hold but I think for arduino projects it's not bad). At your current stage, there should be some decent amount of memory left for developers to do their things. My library actually doesn't have a screen buffer. That saves some ram but also makes the program longer. I do have a buffer for 21 bytes, that is to assemble one item at a time and render to LCD after that and free the buffer for the next item.

Yes, I do'nt leave memory fragments at all.
Memory left depends from menu tree complexity and string length.
I trust on Arduino next gen...

brunialti:
Yes, I do'nt leave memory fragments at all.
Memory left depends from menu tree complexity and string length.
I trust on Arduino next gen...

On the other hand, I also have designed a family of phi-panels, serial LCD keypad panels that can render menus and long messages and sense buttons/multi-tap for you so your main arduino doesn't have to fight for memory. :wink:

I know, I know :slight_smile:
I'm from sw side and a real Arduino newbie.
Arduino is my hobby. Much better than sudoku... :slight_smile:

brunialti:
I know, I know :slight_smile:
I'm from sw side and a real Arduino newbie.
Arduino is my hobby. Much better than sudoku... :slight_smile:

It's good practice to make a library and people can use it and help you improve it too. I can't do sudoku, just not that sharp with 0-9.

Hi liudr and brunialti

Very interessting discussion. I have learned a lot today. I never thought of a dynamic menu system. Indeed, i never thought it could be possible. My own menu system (m2tklib) uses a complete static approch...

It would be interesseting to analyse these differences more closely. Something like this: Define a task which could be implemented by any of the menu libs and compare the results. Occupied flash, ram. Execution speed. Lib maintenance, usability, learning curve.

Unfortunately, github seems to be down at the moment... so its just a thought...

Oliver

I am not sure the comparison make sense, as the two libs seems quite different (e.g. graphic vs character), but why not?
Menwiz has three main sets of funcs. One to define the structure (add***). One to check the device (i.e. buttons by now). One to draw the menu (draw***).
In theory it could be possible to deep the third layer abstraction in order to use graphic rendering.
I would like to keep menwiz as simple as possible. At this stage it is not really a full fledged lib and the code is poor (unclean, redundant unstyled) due to the short time I spent to build it up.

MENWIZ requires LiquidCrystal_I2C

Will there be support for the standard Arduino LiquidCrytal lib?

Oliver

Menwiz uses only the following methods, that are the same in the two libs:
lcd->init();
lcd->setBacklight(HIGH);
lcd->setCursor(x, y);
lcd->noCursor();
lcd->createChar(0,z);
lcd->print();
lcd->write()
The lcd object is created in the sketch and not in the library (the labrary stores only the pointer to the object), therefore there should'nt be a problem. I did'nt test as I have not the lcd in my hand.
I made a small change in the menwiz.h file (the new version in github in minutes!). You will find the #define I2C. If you comment that line, the compiler include the standard LiquidCrystal lib instead of LiquidCrystal_I2C. I did'nt test it yet. If you can, please let me know.
Better solutions are welcome!

olikraus has library that works on both glcd and character lcds. There must be tricks to how that can be done :wink:

I am thinking about expanding to different displays too. My first step was to expand to different input devices.

A competition or cross comparison is definitely welcome! I'm sure I can win the "easy to get started" award since my library can run one one-line function calls.

Do you real want test such a young baby as menwiz against such a mature and wise counterparts ? :slight_smile:
My lib goals are: near asynchronous, simple coding, user defined screens (splash and default) and "overwrite callbacks" (input device scan, actions/triggers ...).
I have more work to do. If somebody is interested I am ready to go on.
I would be pleased if some could test the lib with standard LiquidCrytal.
I have noy 4/8 wires LCD available at the moment.

brunialti:
Do you real want test such a young baby as menwiz against such a mature and wise counterparts ? :slight_smile:
My lib goals are: near asynchronous, simple coding, user defined screens (splash and default) and "overwrite callbacks" (input device scan, actions/triggers ...).
I have more work to do. If somebody is interested I am ready to go on.
I would be pleased if some could test the lib with standard LiquidCrytal.
I have noy 4/8 wires LCD available at the moment.

Not to challenge you, just comparison as I suggested. So you are going into the dynamic and callbacks direction. You could get one of my shields to test out the library :wink:

I recently failed to support a user. It turned out that M2tklib is still too complicated (will i win the price for the most complicated lib?).

I would like to make M2tklib more simple. So I try to understand other approaches. And I like to see fresh libs like yours. For me a comparison about the programming interfaces would be useful (not about features). What would be the most easy approach for a beginner? What do others think about these different approches regading the programming API?

If we find something common which can be implemented by each of the libs, then i think i could get a better understanding of each programming model. And maybe other users can rate the programming effort for each API.

My idea was something about this: On a 16x4 (or 20x4) display 4 selectable lines. The user selects one line and the display shows the line number (0-3). No scrolling, just a cursor which is used to select one of four lines. Is this possible with MENWIZ?

Oliver

Looking at the direction you are going with the MENWIZ library, I think it would be worth while looking at the New LiquidCrystal library. Since you are using a pointer to the LCD, you would benefit from it by using a pointer to its base class LCD (a pure abstract LCD class). This would give you support for a wide range of drivers controlling Hitachi based LCDs.

Not only is it 3.5 times faster than the original LIquidCrystal library, it also gives you the flexibility of being compatible with a wide range of LCDs out there without changing a single line of code.

Just FYI, I am thinking about a slightly different approach compared with a base class approach. For input devices, I totally did base class approach and built my library from ground up to support all possible input devices. For displays, I'm thinking about using ANSI escape codes to control everything. I will need to write support for every new type of display so all my UI command to the displays will be entirely string commands. :slight_smile:

At this time MENWIZ needs only few methods of the LiquidCrystal class. It should work with any lib providing such methods. I cannot test it immediately as I have not a standard 4/8 wires lcd in my hand, but I'll do it after easter time.
I include the two different libraries depending on the #define I2C (first line in MENWIZ.h file). Another way could be difefrentiate MENWIZ.h in MENWIZ_I2C.h and MENWIZ.h.

The code needed to implememt the example Olikraus suggested is as following. Most part of the code is just to implement the screen showing selection choice.
An other usefull comparison could be done on a real request arose in this forum (see the GOLF code example here above).

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <buttons.h>
#include <MENWIZ.h>

menwiz menu;
LiquidCrystal_I2C lcd(0x27,20,4);

int choice=0;

void setup(){
  _menu *r;

  menu.begin(&lcd,20,4);
  menu.navButtons(9,10,7,8,12,11);

  r=menu.addMenu(MW_ROOT,NULL,"TEST MENU");           
    r->addVar(MW_LIST,&choice);                    
    r->addItem(MW_LIST,"Line 1");             
    r->addItem(MW_LIST,"Line 2");           
    r->addItem(MW_LIST,"Line 3");     
    r->addItem(MW_LIST,"Line 4");     
          
  menu.addUsrScreen(msc,3000);
  }

void loop(){
  menu.draw(); 
  }

//USER SCREEN SHOWED AFTER 3 SECS SINCE LAST BUTTON PUSH
void msc(){
  Serial.println(choice);
  lcd.setCursor(0, 0);
  lcd.print("Total uptime ");lcd.print(millis()/1000);
  lcd.setCursor(0, 1);
  lcd.print("Choice is ");lcd.print((int) choice);
  lcd.setCursor(0, 2);
  lcd.print("                    ");
  lcd.setCursor(0, 3);
  lcd.print("                    ");
  }

That's the nice thing about the "New LiquidCrystal" library, it already supports a wide range of LCD controllers:

  • I2C base on the PCF8574 or compatible
  • 4bit and 8bit parallel
  • ShiftRegister: 3wire, 2wire, 1wire (beta)

Your code would look something like this:

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C myLCD (0x27);  // Base address of IO expander

void setup ()
{
   menu.begin ( &myLCD, 20, 4 );
   ...
}

Assuming that your menu class makes the following modification:

#include <LCD.h>

void menu::begin ( LCD *iLCD, uint8_t cols, uint8_t rows )

With this LCD library you will get almost 32 fps as opposed to the one you are currently using that barely does 10fps.

Now if you want to use for example a 4bit parallel interface, the only thing that would change in you code is the creation of the LCD object:

#include <LiquidCrystal_I2C.h>

LiquidCrystal myLCD ( 12, 11, 5, 4, 3, 2 ); // Rs, E, D4, D5, D6, D7

void setup ()
{
   menu.begin ( &myLCD, 20, 4 );
   ...
}

Not a lot to do in your code really.

It seems really easy. I'll try. It would be very nice to have a broad range of compatible devices.

I cant find the MENWIZ.h file on the web :roll_eyes:
Did I missed something?
Github does not bring it either as was mentioned in oen of the previous posts.

Paco

Try this . I can see it on my mobile