From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Building primitive LCD Menu

Hey,

 

I'm trying to build a primitive menu to be shown on a 4x20 HD44780 LCD display. Buttons will control the navigatinon within the menu and the respons will be handled by a state machine.

The thing is; I'm completely lost with regard to how I should organize the menu and manage the navigational part of it. I've thought about having a 3 dimensional array of strings to define all lines of each menu and sub menu. This array will be acompanied by an equally sized respons array that defines the respons of each menu item.

I.e. if enter is pressed in position [1,0,1]: go to the same position in the respons array and find that the respons should be to go to position [1,1,0] in the menu (a sub menu).

 

I've been searching a lot to see if I can find some sort of pre made system for this kind of thing, but I haven't been able to find any so I'm hoping some of you may have encountered this problem already.

 

I plan to use a myRIO to power the whole system, which is a single vessel brewing system.

 

Thanks a lot!

0 Kudos
Message 1 of 2
(2,510 Views)

Hi bjornsol,

 

I have some experience of this as we've just finished a project with a 4x20 LCD display with buttons around the edges and while my solution isn't perfect/completely reusable I can probably point you in the right direction!

 

Firstly, I hope you've found/seen the HD44780 LabVIEW library: https://www.ni.com/en/support/downloads/tools-network/download.lcd-touch-screen-driver.html

 

In this application for an automated machine - the LCD is used to display information to the operator while the cycle is running through various stages but there is also a maintenance menu or there might be different pages the operator can view while it's running.

 

Buttons/User Input

As for implementing the menu etc. what we did was scan for changes in the button lines (debounced by FPGA) and use this to generate user events:

2014-05-13_19-16-23.png

 

The button VI (scalar input, 2D output) compares the current button state to the previous and creates a 2D array of changes - a button index and change type (either button pushed down, button released and it also has timing to detect if the button is pressed down for longer than 1s to detect a long press).

 

I can then register for events in my display handler and respond to those events (e.g. moving between menu items, selecting an item).

 

Menu/Display

In my display handler, I initalise the LCD Driver library and then I read the current state of the machine and update the display accordingly by calling different display handler VIs. Depending on which state the machine is in, I register for the button events and then handle them and change the display. One tricky thing to figure out was how to unregister for the events when you don't know if the state will change (otherwise the events will queue up - next time it changes to the menu it will process all of the buttons you pressed while in a display-only state). I solved this by always acting on the Current-1 state (which introduces a very small delay when you change states but this isn't a problem).

 

Screenshot below shows the button events coming in (the thick blue wire) and my case for the different display modules.

2014-05-13_19-32-18.png

 

I think if you don't need to read the state from another source (e.g. you have more control over your application) then it becomes a lot simpler.

 

Display Modules

My actual display handlers contain an event structure with a timeout that listens for button events from my button handler - they draw the display when it first enters that state or periodically (using event structure time-outs if showing real-time data).

 

For the menu, I used an enum containing all of the possible menu options / pages and by getting the strings (without using a property node as no front panel on RT) of the enum I can cycle between menu items at the same level using a seperator.

 

My enum contained things like:

Menu::Maintenance::Error Log

Menu::Maintenance::Copy Log Files

Menu::Maintenance::Firmware Update

Sensor Data::Temps

Sensor Data::Pressures

 

I had a couple of case structures for each button and press type and update the state (e.g. menu page) within the handler. Rotating the menu only went between the current sub-menu items and button presses could move to another item but changing the selected enum.

 

I'm sorry - this has ended up being really long & rambly but hopefully there's something useful there you can take away and feel free to ask any further questions if you want to know more about what we did - I can't really post any code as it's all fairly application specific.

 

One of the tricks I learnt is to try and update the display only if something has changed - a lot of these LCD displays suffer from flickering if you try to clear the display and re-draw - it's better to overwrite the content you need to and create VIs for doing some simple string displaying (e.g. centre a string by padding to the width of your display). See the attached VI  (LV2012).


LabVIEW Champion, CLA, CLED, CTD
(blog)
Message 2 of 2
(2,462 Views)