SMF Calculator

Browse source code on GitHub

Overview

This sample creates a basic desk calculator driven by a state machine written with the State Machine Framework.

The ‘business logic’ of the calculator is based on the statechart given in Fig 2.18 of Practical UML Statecharts in C/C++ 2nd Edition by Miro Samek. This uses a three-layer hierarchical statechart to handle situations such as ignoring leading zeroes, and disallowing multiple decimal points.

The statechart has been slightly modified to display different output on the screen in the op_entered state depending on if a previous result is available or not.

SMF Calculator Statechart

Statechart for the SMF Calculator business logic.

The graphical interface uses an LVGL button matrix for input and text label for output, based on the sample in samples/drivers/display. The state machine updates the output text label after every call to smf_run_state().

CONFIG_LV_Z_VDB_SIZE has been reduced to 14% to allow it to run on RAM-constrained boards like the Disco L475 IOT01 (B-L475E-IOT01A).

Requirements

The GUI should work with any touchscreen display supported by Zephyr. The shield must be passed to west build using the --shield option, e.g. --shield adafruit_2_8_tft_touch_v2

List of Arduino-based touchscreen shields:

The demo should also work on STM32 Discovery Kits with built-in touchscreens e.g.

etc. These will not need a shield defined as the touchscreen is built-in.

Building and Running

Below is an example on how to build for a Disco L475 IOT01 (B-L475E-IOT01A) board with a Adafruit 2.8” TFT Touch Shield v2.

west build -b disco_l475_iot1 --shield adafruit_2_8_tft_touch_v2 samples/subsys/smf/smf_calculator

For testing purpose without the need of any hardware, the native_sim board is also supported and can be built as follows;

west build -b native_sim samples/subsys/smf/smf_calculator

CLI control

As well as control through the GUI, the calculator can be controlled through the shell, demonstrating a state machine can receive inputs from multiple sources. The key <key> command sends a keypress to the state machine. Valid keys are 0 through 9 for numbers, ., +, -, *, / and = to perform the expected function, C for Cancel, and E for Cancel Entry.

GUI update speed on the Disco L475 IOT01 (B-L475E-IOT01A) with Adafruit 2.8” TFT Touch Shield v2 touchscreen is of the order of 0.8s due to button matrices invalidating the entire matrix area when pressed, rather than just the button that was selected. This could be sped up by using 18 individual buttons rather than a single matrix, but is sufficient for this demo.

References

Practical UML Statecharts in C/C++ 2nd Edition by Miro Samek https://www.state-machine.com/psicc2

See also

State Machine Framework API