Modern HMIs are built as graphical user interfaces (GUI) with touch-based user interaction. Complex HMI development is always challenging because of the dynamic nature of the required behavior, underlying functions, and graphical design. Building a PoC prototype through code is time-consuming, so I prefer to model, or even better use a model-based design for the HMI behavior design. This allows me to better visualize and architect the desired GUI flow before actual coding starts. I prefer to use state machines to both model and code HMI behavior, below is an example of the ‘Connect to WiFi’ GUI state machine model I blogged about here:
The model lists events and methods the GUI will use. The methods are intentionally de-coupled from any OS/hardware specifics to provide hardware abstracted functionality. Board support package translates the GUI methods to hardware-specific code, in my case, ESP32 FreeRTOS code or a computer. This allows for independent development/testing of GUIs on other platforms, for example, on a PC, by external teams and later integration into the target embedded project.
The GUI engine is an event-driven FSM and the GUI events dispatcher is implemented using FreeRTOS queues. The queues also serve as load equalizer, ensuring no event is missed and that the HMI performs smoothly.
Event-driven GUI allows for scripted/automated testing, here is an example of a scripted load test of the GUI:
In conclusion, proper HMI application architecture, modeling and implementation contribute to quick, reliable and snappy HMI experience.