Example: A simple menu system with OBLCD

The purpose of a menu system is to allow a user to move through a range of alternatives and select one, in order to either change an operating parameter or initiate an action. Most people nowadays are familiar with the menu systems in cellular telephones. A menu system you might design for a SPLat with LCD is similar.

The following example will assume that there are just 4 push buttons available. From top to bottom these are labeled:

Label Name/function
<- iLeftArrow
-> iRightArrow
Y iAccept
N iReject

Essentially the arrow keys will be used to select and change choices, while accept and reject keys will help finalise decisions.

The menu system will affect three memory variables:

WashTime. Duration of wash cycle, in minutes

PreWash. True or False, depending if a pre wash cycle is required

HotWash. If true, do a hot wash cycle, otherwise do a cold cycle.

It is absolutely essential that you plan your menu system on paper before you start writing any program code. The following table is a plan for the menu for a washing machine. It gives a choice of hot or cold wash and allows setting of the wash time between 5 and 25 minutes. Each row of the table corresponds to one display on the LCD. We will start by analyzing this tabulated plan, then we will see how it translates into SPLat code.

  Display <- -> Y N
0       [1]  
1

0123456789012345

Wash type: XXXX

Change?

[3] [2] Hot:[5] Cold:[4] [0]
2

0123456789012345

Wash time: xx

Change?

[1] [3] [6] [0]
3

0123456789012345

Pre-wash: Xxx

Y or N to change

[2] [1] Xxx=Yes Save Xxx=No Save
4   [5] [5] Save [2] [2]
5   [4] [4] Save [2] [2]
6

0123456789012345

Change wash time

xx

Dec xx min 5 Inc xx max 25 Save [3] [3]

Each row of the table is numbered. We call the numbers "State Numbers" and the whole table we call a "State Transition Table" or just "State Table". If you are familiar with SPLatMaps or bubble diagrams you may recognize this as an alternative way of representing a Finite State Machine.

The State table has 6 columns. One is just for the state number. The second column is for the LCD display in that state. The final 4 columns specify what happens if the user presses each of the 4 available buttons. These are the "action columns".

In an action column a number in [square brackets] means go to that new state (row) and change the display accordingly. The action columns can contain other actions as well, such as "Save" or change a variable (I've used X's as placeholders for variables both in the display column and in the action columns). I've also included a ruler line in the displays.

Let's go through the 6 states, one at a time:

State 0

This allows for the possibility of the LCD not always being "owned" by the menu system. Perhaps in this state the bottom line shows wash temperature. Pressing Y will take us into the menu system proper at state 1.

State 1

Offers us the option to change the wash type. Pressing Y to accept the offer takes us to state 4 or 5, depending on the current wash type selection (hot or cold). Pressing an arrow key takes us to 2 or 3. If you study the arrow key actions for state 1, 2 and 3 you will discover that they form a loop, allowing you to scroll through these 3 "top level" menu choices. Pressing the N button takes us back to state 0, or notionally out of menu mode.

State 2

Displays the current wash time and asks if we want to change it. If we accept (Y) we go to state 6, which allows the wash time to be changed.

State 3

Lets us change the selection of the pre-wash.

States 4 and 5

These work together as a pair to allow toggling between hot wash and cold wash. The arrow keys toggle between them, Y accepts the current selection by saving it and N exits back to the top level of the menu without changing the setting.

State 6

Displays the wash time and allows us to change it using the arrow keys. Y saves the changed value while N rejects it. Notice that the table specifies that the value can only be incremented and decremented between the limits 5 to 25.

A few notes on all this:

The menu system will affect three memory variables:

HotWash: True if the wash is to be hot, false if the wash is to be cold.

WashTime: A simple integer variable giving wash time in minutes ( range 5 to 25)

PreWash: True if a pre-wash cycle is required.

The code for each state follows a consistent pattern, with the following elements:

  1. On entering the state for the first time, creation of the display for that state.
  2. A loop to look for one of the allowable keys, with a jump to an action segment if a key is pressed
  3. One action segment for each key. This may be an update of a variable and/or the display, or a jump to another state.

Here we go with the program:

;Sample menu system for washing machine

;Define keys
iLeftArrow    iEQU          12      ;top button on MMi99
iRightArrow   iEQU          11
iAccept       iEQU          10
iReject       iEQU          9

;Define memory locations. 
;These are in the PermStore area
HotWash       mEQU          6
WashTime      mEQU          7
PreWash       mEQU          8

;These are anywhere:
ScratchMem    mEQU          9       ;Temporary storage

;initialize: Check if Permanent memory is valid, 
;            force defaults if not
          PermRecall
          GoIfZ         DataOK
          SetMem        WashTime,10    ;Default
          SetMem        PreWash,T      ;Default
          SetMem        HotWash,T      ;Default
          PermStore
          PermStore
DataOK
          OBLCD_Type    2

******** Menu system ***************************
;State 0 is easy: one message then wait for Y
SetMenu0
          OBLCD_Cls
;                        0123456789012345
          OBLCD_Text    "Y for menu"
Menu0
          GoIfInK       iAccept,SetMenu1
          GoTo          Menu0

;==============State 1========================
SetMenu1
          OBLCD_Cls
;                        0123456789012345
          OBLCD_Text    "Wash type: "
          GoSub         QryChange      ;display "Change?"
Menu1ShowType
          OBLCD_SetCur   0,11
          Recall         HotWash
          GoIfT          Menu1Hot
Menu1Cold
;                        0123456789012345
          OBLCD_Text               "Cold "
          GoTo           Menu1KeyIn
Menu1Hot
;                        0123456789012345
          OBLCD_Text               "Hot  "

;Wait for a key
Menu1KeyIn
          GoIfInK        iLeftArrow,Menu1Left
          GoIfInK        iRightArrow,Menu1Right
          GoIfInK        iAccept,Menu1Accept
          GoIfInK        iReject,Menu1Reject
          GoTo           Menu1KeyIn     ;Keep trying
Menu1Left
          GoTo           SetMenu3
Menu1Right
          GoTo           SetMenu2
Menu1Accept
          Recall         HotWash
          GoIfT          SetMenu5
          GoTo           SetMenu4
Menu1Reject
          GoTo           SetMenu0

;===========State 2========================
SetMenu2
          OBLCD_Cls
;                        0123456789012345
          OBLCD_Text    "Wash time: "
          GoSub          QryChange      ;display "Change?"
Menu2ShowTime
          OBLCD_SetCur   0,11
          Recall         WashTime
          OBLCD_UDecDispXVW
          OBLCD_Text     "m "

Menu2KeyIn
          GoIfInK        iLeftArrow,Menu2Left
          GoIfInK        iRightArrow,Menu2Right
          GoIfInK        iAccept,Menu2Accept
          GoIfInK        iReject,Menu2Reject
          GoTo           Menu2KeyIn

Menu2Left
          GoTo           SetMenu1
Menu2Right
          GoTo           SetMenu3
Menu2Accept
          GoTo           SetMenu6
Menu2Reject
          GoTo           SetMenu0

;===========State 3========================
SetMenu3
          OBLCD_Cls
;                        0123456789012345
          OBLCD_Text    "Pre-wash: "
          OBLCD_SetCur   1,0
          OBLCD_Text    "Y or N to change"
Menu3Show
          OBLCD_SetCur   0,11
          Recall         PreWash
          GoIfT          Menu3PWYes
Menu3PWNo
          OBLCD_Text     "No "
          GoTo           Menu3KeyIn
Menu3PWYes
          OBLCD_Text     "Yes"
Menu3KeyIn
          GoIfInK        iLeftArrow,Menu3Left
          GoIfInK        iRightArrow,Menu3Right
          GoIfInK        iAccept,Menu3Accept
          GoIfInK        iReject,Menu3Reject
          GoTo           Menu3KeyIn

Menu3Left
          GoTo           SetMenu2
Menu3Right
          GoTo           SetMenu1
Menu3Accept
          SetMem         PreWash,T
          PermStore
          GoTo           Menu3Show
Menu3Reject
          SetMem         PreWash,F
          PermStore
          GoTo           Menu3Show

;======= State 4 =======================
SetMenu4
          OBLCD_Cls
;                        0123456789012345
          OBLCD_Text    "Hot wash"
Menu4KeyIn
          GoIfInK        iLeftArrow,Menu4Left
          GoIfInK        iRightArrow,Menu4Right
          GoIfInK        iAccept,Menu4Accept
          GoIfInK        iReject,Menu4Reject
          GoTo           Menu4KeyIn

Menu4Left
          GoTo           SetMenu5
Menu4Right
          GoTo           SetMenu5
Menu4Accept
          SetMem         HotWash,T
          PermStore
Menu4Reject
          GoTo           SetMenu2


;======= State 5 =======================
SetMenu5
          OBLCD_Cls
;                        0123456789012345
          OBLCD_Text    "Cold wash"
Menu5KeyIn
          GoIfInK        iLeftArrow,Menu5Left
          GoIfInK        iRightArrow,Menu5Right
          GoIfInK        iAccept,Menu5Accept
          GoIfInK        iReject,Menu5Reject
          GoTo           Menu5KeyIn

Menu5Left
          GoTo           SetMenu4
Menu5Right
          GoTo           SetMenu4
Menu5Accept
          SetMem         HotWash,F
          PermStore
Menu5Reject
          GoTo           SetMenu2


;===========State 6========================
SetMenu6
          OBLCD_Cls
;                        0123456789012345
          OBLCD_Text    "Change wash time"
          Recall         WashTime
Menu6Show
          Store          ScratchMem
          OBLCD_SetCur   1,6
          Recall         ScratchMem
          OBLCD_UDecDispXVW
          OBLCD_Text     "m "

Menu6KeyIn
          GoIfInK        iLeftArrow,Menu6Left
          GoIfInK        iRightArrow,Menu6Right
          GoIfInK        iAccept,Menu6Accept
          GoIfInK        iReject,Menu6Reject
          GoTo           Menu6KeyIn
Menu6Left
          Recall         ScratchMem
          Push
          GoIfXGE        25,Menu6KeyIn
          IncX
          GoTo           Menu6Show
Menu6Right
          Recall         ScratchMem
          Push
          GoIfXLE        5,Menu6KeyIn
          DecX
          GoTo           Menu6Show
Menu6Accept
          Recall         ScratchMem
          Store          WashTime
          PermStore
Menu6Reject
          GoTo           SetMenu3

;===============================================
;Subroutine to display "Change?" (clears to EOL)
QryChange
          OBLCD_SetCur   1,0
;                         0123456789012345
          OBLCD_Text     "Change?         "
          Return
;============ End of program ================

Some notes about this code: