Learning resources for developing text UIs on microcontroller based systems  - Page 1
Forum section: electronics / general

author: NE666
author_rank: Frequent Contributor
timestamp: September 10, 2025, 01:46:27 pm
content: I don't wish to verbatim raise a question which has been asked before but for context, I've already located this thread which gives a feel for the gist of the types of system and solution to which I am referring, as well as some good responses.https://www.eevblog.com/forum/programming/simple-menu-system-with-dynamic-keypad-functions-(embedded-alphanumeric-display)In short: It's 2025 and "we" have been developing embedded systems and consumer appliances with small, simple, menu driven alphanumeric UIs for at least half a century. By 'simple', I mean the likes of small (e.g. 320x240) monochrome dot matrix displays (VFD, LED and more recently OLED), EPOS style single or double row alphanumeric displays, some push buttons and maybe a rotary encoder. Exactly as found on literally millions of devices. And yet, I'm struggling to find any reference materials that introduce the general principles of their design and implementation.To my mind, there would be some recognised and documented design patterns just as there are for other areas of system design and systems architecture (e.g. MVC, MVVC for desktop UIs). Whilst I appreciate specifics of implementation will be just that, depending on the hardware in use, general principles and typical approaches to some common use-cases should surely hold true?Does anyone have any recommendations they could make? Ideally, I'd like a 'decent' textbook but this is 2025 after all, and so course materials, wikis etc. are on the table too, so long as they offer a good introduction and go on to put some useful meat on the bone for the student. Even some example(s) of code on GitHub would be appreciated, if you think that they exemplify a good general pattern for a particular problem/use-case.I'll attempt to reduce and simply the scope of the ask by adding:- 'small' alphanumeric dot matrix displays (no 'graphics', animations etc., just text displays)- no touch screen interaction required- written in C- 'bare metal' i.e. no RTOS / OS involvement- uC: AVR32, PIC32 etc.If anyone can help, thank you.

author: radiolistener
author_rank: Super Contributor
timestamp: September 10, 2025, 03:00:44 pm
content: For a simple text-based menu, you don’t need MVC, MVVC, or other heavyweight patterns. These consume memory, which is a critical resource on microcontrollers. I have implemented a fairly extensive text menu for industrial device with cursor navigation and even with text input (similar to button-based text typing in phones of the era), entirely within a single small C file. The menu itself was defined as a static array of text entries with associated handlers. The system ran efficiently, occupied minimal memory, and was very responsive.Using a small FSM, it is straightforward to implement features such as key auto-repeat and text input, making the menu very user-friendly and reminiscent of traditional button-based phones.

author: NE666
author_rank: Frequent Contributor
timestamp: September 10, 2025, 04:33:40 pm
content: Quote from: radiolistener on September 10, 2025, 03:00:44 pmAbsolutely, I gave them only as examples of well understood, documented and frequently used design patterns for UIs. They're appropriate to the desktop and mobile application domain.The nature of my question is, what are the models and patterns appropriate to this domain, and where might I find quality documentation that describes their use in terms suitable for a beginner or student?

author: Nominal Animal
author_rank: Super Contributor
timestamp: September 12, 2025, 08:56:21 am
content: Menu systems are simplefinite-state machines.Nowadays, I design mine from the ground up, opposite to how one might think. I start by finding out the knobs/tunables/entries the user will need to adjust the important parameters and operational states, and the different ways of representing those. Then, I create the C data structures (which I keep in Flash/ROM) that should be able to facilitate those, and populate the ones needed for the tunables. Finally, I fill in the entries needed to easily navigate the state machine.Then, I create a simple C program to run on my desktop/laptop computer, to generate theactualstate transition diagram, by outputting the possible connections usingGraphvizDOT language (it's plain human-readable text), and use thedottool to render it into a visible graph.This tells me if it looks balanced, or if I have long chains of entries (that will annoy users trying to find a specific one) or other problems in the navigation. To fix, I edit the data structures, and rerun. This is an iterative process, and often means changing not just the values, but even the structures themselves. I also like to use things like function pointers for button actions, so the first versions of the structures are often just a basis I start building on.(I have also done simple domain-specific languages to dynamically generate the constant structures defining the navigation system, but honestly, they don't seem worth the effort to me. The C structures are just as easy to maintain. I have used both individual structures and pointers between entries, and a single array of structures using array indexes instead of pointers, using C99 designated initializers. As an example,const char x = { =1, =5 };andconst char x = { 0, 5, 0, 1, 0, 0, 0, 0 };are exactly equivalent.)When I believe the structure is acceptable, I create a simulator, either in HTML+JavaScript, or in terminal using e.g. Curses (ncurses). Then, I find a suitable unwittingvictimtest user, and ask them to perform some specific tasks on the simulator, similar to what one trying to use the final device would, and carefully observe their usage patterns with the interface, noting where they go wrong, where they pause to think, and so on, focusing on what does not work well in the user interface (based on mostly the body language and facial expressions of the person; distracting them with a friendly chat makes those easier to observe). The more unwittingvictimstest users I can do this with, the better the results will be.At some point, it is good enough. Perfect is the enemy of good enough, and some users are idiots who expect things to work a specific way so they can avoid thinking and instead rely on their muscle memory. Thus, you must learn where to accept defeat and/or ignore complaints. If you ever tune it so perfectly most users don't even notice the user interface and just intuitively get stuff done without any effort, the downside is that the user interface will be forgotten just as quickly. Everyone remembers a horrible interface, but nobody remembers or even notices a good one, so do expect this to be a thankless task.At some point during development, depending on how much leeway you have with the physical aspects of the user interface, you should also build a physical example of the UI, or even implement it on the actual target devices' early versions, and test it. Some things like touch screens soundneat, but if you are doing something oily, dirty, or your hands deep in dough, they suddenly become highly annoying. Same with buttons that are too small, too close, with too high or too low action pressure, and with displays that are perfect in the development environment, but in the actual use case are hard to read/see/clean.But, full disclosure: I do not do commercial development anymore, just hobbyist stuff, and can focus on the important things instead of making sure I am productive enough for the process to be commercially viable, a profit-making proposition. Do not expect companies' bean counters accept this as a reasonable development method. They'll want to do something different (i.e., cheaper and much faster).

author: NE666
author_rank: Frequent Contributor
timestamp: September 12, 2025, 10:10:16 am
content: Thanks@Nominal Animal, I appreciate you taking the time to share pointers (figurative and literal).Ground-up and Trial and Error it is then.P.S. You should write a book