“Simple but powerful, multitasking menus for Micropython, using a little display board and a rotary encoder.
This is a simple GUI menu system for micropython using a rotary encoder and a display. Menus are defined as lists and do not require complex programming. The root menu may have unlimited submenus. Data can be entered in the form of string selections through the menu or as integers by twiddling the encoder. Extra Information can be displayed, such as status information. A menu-item calls a function to perform an action. The action can be a normal python function or a co-routine (for multitasking) . Multitasking allows long running functions (for instance a neopixel display) to run without stopping the menu system. Source: https://github.com/sgall17a/encodermenu
Hardware used in development
The menu system was developed on a Raspberry Pi Pico with Micropython and standard hardware libraries. The encoder was from Sparkfun and had a switched and illuminated shaft. An 128x64 pixel OLED was used for the display. The switch or button used was just the shaft switch on the encoder.
The neopixel example uses a “GlowBit rainbow” from Core electronics which is a convenient form of neopixels for development. The neopixel driver software was adapted from the PIO examnple in the Raspberry Pi documentation.
The test setup was built on a breadboard with DuPont connector and crocodile clips and seemed to work fine.
A menu item has two parts, a caption which is a string, and an action which is a function. The function is called when the menuitem is clicked.. The action function that takes no parameters (more about this later).
A menu is defined as a list of menuitems and is “wrapped” into a function that makes the menu active.
The action of menuitem can be another menu. This way we can have any depth of submenus.
Get Numerical input (get_integer)
We might need to enter some numerical information to our system. For instance we may need to enter hours, minutes and seconds in to set up a clock. A function called get_integer is provided for this purpose.
Getting text input (get_selection)
We can enter some string or text value similar to the select box in HTML. A selection is defined as list of pairs composed of caption,data. This is similar to the definition of a menu.
Show textual information (info)
info allows us to show some text on the screen. The text can be just a simple string or can be a function that returns a string. The function could, for instance allow us to show the current time.
Often we need to enter a sequence of numbers, for instance hour,minute second or year, month day which is the function of a wizard. While wizards are not essential they are useful . Wizards are defined a bit like menus and selections.
Getting data out of a menu
We need some way to read the information that we entered with get_integer or selection. To do this, the information getting functions have a field. The field is used a key for in a global dictionary called data.
For instance after we entered a values for hours (by clicking on the value) it then becomes available as the global variable .
simplemenu.data[‘hours’] = 10
What about actions?
Actions are just python functions that have no parameters.
For instance a function could fill a neopixel string with a color. The colour could be fixed but we could use the value in the data dictionary set previously with selection.
What about parameters for action functions?
Having functions with no parameters seems a bit limiting. Fortunately there a couple of workarounds.
1. A function can have default parameters. These are used as the parameters if the function is called with no parameters.
2. Another way is to use closures. Most people are less familiar with closures but they are actually very simple and are equivalent to and a little bit more flexible than default parameters. This is the way we we wrap up menus and selections and wizards.”