Lecture 03
Lecture 03
com/zybook/Ak78Fta73x/chapter/3/print
Like most programming languages, C was not designed for time-ordered behavior. C uses a
sequential instructions computation model, wherein statements (instructions) in a list are executed
sequentially (one after another) until the list's end is reached. A sequential instructions model is
good for capturing algorithms that transform given input data into output data, known as data
processing behavior. However, the sequential instructions model is poorly-suited for capturing
time-ordered behavior.
For example, consider a system on a carousel (merry-go-round) that increments B whenever the
carousel rotates once, detected by a sensor that brieKy pulses A0 for each rotation. The following
RIMS code captures the system's behavior.
PARTICIPATION
ACTIVITY 3.1.1: Pulse counting code for a carousel.
void main()
{
B = 0; Sensor Output
while (1) {
while (!A0); A0: 1 B: 2
B = B + 1;
while (A0);
}
}
Animation content:
C program:
#include "RIMS.h"
void main()
1 of 44 12/02/2024, 09:34
zyBooks https://learn.zybooks.com/zybook/Ak78Fta73x/chapter/3/print
{
B = 0;
while (1) {
while (!A0);
B = B + 1;
while (A0);
} ©zyBooks 02/12/24 09:33 231883
} Lawrence Nderu
Ak78Fta73x
Animation captions:
The code's statements like while (!A0); may look unusual to a beginning embedded
programmer. The statement loops as long as A0 is 0, and the immediate ; means no statements
execute within the loop. Because C isn't designed to capture such time-oriented behavior, the code
is slightly awkward, but understandable. However, the code becomes less understable as more
time-oriented behavior is introduced, such as having a button A1 that resets B, as shown below.
#include "RIMS.h"
void main()
{
B = 0;
while (1) {
while (!A1 &&
!A0);
if (A1) {
B = 0; //
Reset
©zyBooks 02/12/24 09:33 231883
}
else { Lawrence Nderu
B = B + 1; Ak78Fta73x
while (A0);
}
}
}
2 of 44 12/02/2024, 09:34
zyBooks https://learn.zybooks.com/zybook/Ak78Fta73x/chapter/3/print
The code is becoming harder to understand. The text itself is simple, but how the code interacts
with the inputs over time is not obvious, and requires plenty of mental execution to understand the
system's behavior. With even more time-oriented behavior introduced, the code may become a
spaghetti-like mess whose behavior is extremely hard to understand.
The lesson is this: Capturing time-ordered behavior directly into C's sequential instructions
computation model is challenging. Instead, a computation model better suited for capturing time-
ordered behavior is needed. State machines, introduced in another©zyBooks
section, 02/12/24 09:33
is one such 231883
model.
Lawrence Nderu
Ak78Fta73x
PARTICIPATION
ACTIVITY 3.1.2: Time-ordered behavior.
3 of 44 12/02/2024, 09:34
zyBooks https://learn.zybooks.com/zybook/Ak78Fta73x/chapter/3/print
A state machine is a computation model intended for capturing time-ordered behavior. Numerous
kinds of state machines exist. Common features of state machines are a set of inputs and outputs,
a set of states with actions, a set of transitions with conditions, and an initial state. A drawing of a
state machine is called a state diagram.
Consider a simple time-oriented system that turns on a light (by setting B0 = 1) if a user presses a
button (A0 is 1 when pressed). The light stays on even after the button is released. Pressing a
second button (A1 is 1) turns the light off. The following ]gure captures that behavior as a state
machine.
PARTICIPATION
ACTIVITY 3.2.1: A basic light toggle SM.
!A0 !A1
A0 A0
0
Unlit Lit B0
A1 0
A1 B0 = 0; B0 = 1;
0
Animation content:
©zyBooks 02/12/24 09:33 231883
Shown state machine has input A0 and A1 and output B0, and the statesLawrence Nderu
Unlit (with action B0 =
Ak78Fta73x
0) and Lit (with action B0 = 1).
The Unlit state has two transitions with conditions A0 and !A0. The !A0 condition transitions back
to Unlit and A0 transitions to Lit.
The Lit state has two transitions with conditions A1 and !A1. The !A1 condition transitions back to
Lit and A1 transitions to Unlit.
4 of 44 12/02/2024, 09:34
zyBooks https://learn.zybooks.com/zybook/Ak78Fta73x/chapter/3/print
Animation captions:
1. The SM has two inputs, A0 and A1, and one output, B0. The SM has two states Unlit and Lit.
The Unlit state turns off the LED by setting B0 = 0. The Lit state turns on the LED by setting
B0 = 1.
2. The SM implements a basic light toggle that turns on a light if a user presses the button
connected to A0. ©zyBooks 02/12/24 09:33 231883
3. The light remains on even after the button to A0 is released. Pressing a second
Lawrence button,
Nderu
Ak78Fta73x
connected to A1, turns the light off.
The above animation shows a state machine with inputs A0 and A1 and output B0 (each 1 bit), and
the states Unlit (with action B0 = 0) and Lit (with action B0 = 1). The state machine has four
transitions with conditions !A0, A0, !A1, and A1, and the initial state is Unlit (denoted by the special
"initial transition" arrow).
A system described by a state machine executes as follows. At any time, the system is "in" some
state, called the current state. Upon starting, the transition to the initial state is taken and that
state's actions are executed once. The following process then occurs, called a tick of the SM:
• A transition T leaving the current state and having a true condition is taken
• Transition T's target state has its actions executed once and becomes the current state
The ticking process repeats. Each tick takes a tiny but non-zero (perhaps nearly-in]nitesimally
small) amount of time, during which no event is assumed to occur. Ticks are assumed to occur at a
much faster rate than input events, so no input events are missed. The following animation
illustrates SM ticking.
PARTICIPATION
ACTIVITY 3.2.2: SM ticks.
1 !A0 !A1
A0 A0 ©zyBooks 02/12/24 09:33 231883
1
Unlit Lit B0 Lawrence Nderu
0 A1 Ak78Fta73x
A1 B0 = 0; B0 = 1;
5 of 44 12/02/2024, 09:34
zyBooks https://learn.zybooks.com/zybook/Ak78Fta73x/chapter/3/print
Animation content:
Shown state machine has input A0 and A1 and output B0, and the states Unlit (with action B0 =
0) and Lit (with action B0 = 1).
The Unlit state has two transitions with conditions A0 and !A0. The !A0 condition transitions back
to Unlit and A0 transitions to Lit.
The Lit state has two transitions with conditions A1 and !A1. The !A1 condition transitions back to
Lit and A1 transitions to Unlit. ©zyBooks 02/12/24 09:33 231883
Lawrence Nderu
Ak78Fta73x
Animation captions:
For the above example, upon startup the system takes the transition to state Unlit and executes B0
= 0 once. For subsequent ticks, if A0 is 0 then the system takes the transition back to state Unlit
and executes B0 = 0 again. At some time, if A0 is 1 then the system takes the transition to state Lit
and executes B0 = 1. The system stays in that state until A1 becomes 1, at which time the system
takes the transition back to state Unlit.
PARTICIPATION
ACTIVITY 3.2.3: Tracing execution of an SM.
Given the following timing diagram and the above light on/off SM, determine the value of
B0 at the speci]ed times.
1) 0 s
1
0
6 of 44 12/02/2024, 09:34
zyBooks https://learn.zybooks.com/zybook/Ak78Fta73x/chapter/3/print
2) 1 s
1
0
3) 2 s
1 ©zyBooks 02/12/24 09:33 231883
Lawrence Nderu
0 Ak78Fta73x
4) 3 s
1
0
5) 4 s
1
0
6) 5 s
1
0
For the above input sequence, the light was on from about 0.5 seconds when A0's button was
pressed, until about 2.5 seconds when A1's button was pressed.
If none of the current state's transitions has a true condition for a given tick, an implicit transition
back to the state itself is taken (thus causing the state's actions to execute each such tick). Good
practice, however, is to have an explicit transition point back to the same state with the proper
condition, rather than relying on the implicit transition from a state to itself. The above system has
an explicit transition with condition !A0 from Unlit back to Unlit, for example, making very clear what
happens when in state Unlit and A0 is 0.
For a state machine to be precisely de]ned, transitions leaving a particular state should have
mutually exclusive transition conditions, meaning only one condition could 02/12/24
©zyBooks possibly 09:33
be true at any
231883
time (otherwise, which of two transitions with true conditions should be taken? TheNderu
Lawrence state machine
Ak78Fta73x
becomes non-deterministic in that case). For example, state Unlit transitions have conditions A0
and !A0, only one of which can possibly be true at any time.
A transition may be speci]ed to have a condition of "true" or 1, meaning the transition should
always be taken. That transition of course should be the only one leaving a particular state, else
mutual exclusivity would not exist. A common shorthand notation omits the "true"; a transition with
no condition is known to have a true condition.
7 of 44 12/02/2024, 09:34
zyBooks https://learn.zybooks.com/zybook/Ak78Fta73x/chapter/3/print
A state may have multiple actions, such as B0 = 1; B1 = 1; or may have no actions at all. A
state's actions execute once each time that a tick takes the state machine to that state, even if a
transition points back to the same state.
We will use a particular form of a state machine model, referred to in this material just as an SM,
intended for creating C programs that support time-ordered behavior. An SM uses declared C
variables rather than explicit inputs and outputs; the lone exception is the use of RIMS' implicitly-
declared A and B input and output variables though. The SM's state ©zyBooks
actions02/12/24 09:33
consist of C 231883
Lawrence Nderu
statements, and the SM's transitions consist of C expressions. Variable values (such as B0 = 1)
Ak78Fta73x
persist between ticks.
Using an SM, the earlier section's pulse counting system for a carousel can be captured as follows.
Note how the SM more clearly de]nes the time-oriented behavior, versus the earlier section's
awkward C code.
A reset behavior that returns the state machine to the initial state when A1 is pressed can be easily
added, as shown below.
The following timing diagram shows a sample sequence of inputs to the above SM.
8 of 44 12/02/2024, 09:34
zyBooks https://learn.zybooks.com/zybook/Ak78Fta73x/chapter/3/print
Figure 3.2.3: Sample timing diagram for pulse counter with reset.
PARTICIPATION
ACTIVITY 3.2.4: Tracing the pulsing counting SM.
Given the above SM input sequence, type the SM's current state at the speci]ed times. At
time 0 ms, the answer is: Init.
1) 0 s
2) 0.5 s
3) 1 s
9 of 44 12/02/2024, 09:34
zyBooks https://learn.zybooks.com/zybook/Ak78Fta73x/chapter/3/print
time 4 s?
Complete the above timing diagram by showing the current state and also the B0 signal
value.
Notice that the SM model and the C code from an earlier section have the same behavior. However,
the SM more explicitly captures the desired time-ordered behavior. This straightforwardness can be
further seen by trying to extend the SM.
Extend the pulse counter SM to set B7 = 1 to indicate when the value of B reaches 99 (for
the carousel system, such an indication may tell the ride operator to do a routine safety
check). Note that 99 requires only the lower 7 bits of B, so B7 can be used for such
indication. When 99 is reached, counting stops until a rising event on A1 resets the count.
The following pattern is common in SMs for detecting a rising edge©zyBooks 02/12/24
of a signal. 09:33
The SM 231883
stays in the
Lawrence Nderu
state while A0 is 0. When A0 becomes one, the transition is taken to anotherAk78Fta73x
state. Detecting a
falling edge is similar, with the condition swapped.
10 of 44 12/02/2024, 09:34
zyBooks https://learn.zybooks.com/zybook/Ak78Fta73x/chapter/3/print
PARTICIPATION
ACTIVITY 3.2.5: State machines. ©zyBooks 02/12/24 09:33 231883
Lawrence Nderu
Ak78Fta73x
1) An SM tick consists of:
Executing the current state's
actions and then transitioning
to the next state.
Transitioning to the next state
and executing that state's
actions an unknown # of times.
Transitioning to the next state
and executing that state's
actions once.
Exploring further:
11 of 44 12/02/2024, 09:34
zyBooks https://learn.zybooks.com/zybook/Ak78Fta73x/chapter/3/print
PARTICIPATION
ACTIVITY 3.3.1: RIBS: Low and high example. Full screen
12 of 44 12/02/2024, 09:34
zyBooks https://learn.zybooks.com/zybook/Ak78Fta73x/chapter/3/print
LoHi +
A0 0
A1 0
PARTICIPATION
ACTIVITY 3.3.2: RIBS basics. ©zyBooks 02/12/24 09:33 231883
Lawrence Nderu
Ak78Fta73x
1) The SM's initial state is set by double-
clicking the state.
True
False
PARTICIPATION
ACTIVITY 3.3.3: RIBS with export/import. Full screen
©zyBooks 02/12/24 09:33 231883
Lawrence Nderu
• SMs can be saved. Press "Export" and copy-paste the exported text. Ak78Fta73x
Modify the SM
somehow. Then paste the text into the box and press "Import" -- the previously-
exported SM is restored. (Users can save the exported text in a ]le or email for
future use.)
13 of 44 12/02/2024, 09:34
zyBooks https://learn.zybooks.com/zybook/Ak78Fta73x/chapter/3/print
LoHi +
A0 0
A1 0
A2 0
©zyBooks 02/12/24 09:33 231883
A3 0 Lawrence Nderu
Ak78Fta73x
A4 0
A5 0
A6 0
A7 0
A = 0
Export to RIMS
Export Import Lo hi
PARTICIPATION
ACTIVITY 3.3.4: RIBS with export.
©zyBooks 02/12/24 09:33 231883
Lawrence Nderu
1) Pressing "Export" saves the current Ak78Fta73x
SM to a ]le.
True
False
14 of 44 12/02/2024, 09:34
zyBooks https://learn.zybooks.com/zybook/Ak78Fta73x/chapter/3/print
3.4 Implementing an SM in C
Because microprocessors typically have C compilers but not SM compilers, implementing an SM in
C is necessary. Using a standard method for implementing an SM to C enhances the readability
and correctness of the resulting C code. The following illustrates such a method for the given SM
named Latch (abbreviated as LA), which saves (or "latches") the value of A102/12/24
©zyBooks onto B0 09:33
whenever A0 is
231883
1. Lawrence Nderu
Ak78Fta73x
15 of 44 12/02/2024, 09:34
zyBooks https://learn.zybooks.com/zybook/Ak78Fta73x/chapter/3/print
#include "RIMS.h"
void TickFct_Latch()
{
switch(LA_State) { // Transitions
case LA_SMStart: // Initial transition
LA_State = LA_s0;
break; ©zyBooks 02/12/24 09:33 231883
Lawrence Nderu
case LA_s0: Ak78Fta73x
if (!A0) {
LA_State = LA_s0;
}
else if (A0) {
LA_State = LA_s1;
}
break;
case LA_s1:
if (!A0) {
LA_State = LA_s0;
}
else if (A0) {
LA_State = LA_s1;
}
While the code may seem imposing,
break;the code follows a simple pattern:
default:
• State variable declarationLA_State = LA_SMStart;
break;
• Tick function } // Transitions
• main loop that calls tick function
switch(LA_State) { // State actions
case LA_s0:
State variabledeclaration: The ]rst line creates a new enum data
break; type LA_States de]ned to have
possible values of LA_SMStart,caseLA_s0
LA_s1:and LA_s1. That same code line declares global variable
LA_State to be of type LA_States. B0 enum
= A1; is a C construct for de]ning a new data type, in contrast to
break;
built-in types like char or short, whose value can be one of an "enumerated" list of values. The
default:
programmer provides the enumeration
break;
list, as in { LA_SMStart, LA_s0, LA_s1 } above. In C, each
item in the list becomes a}new constant,
// State with the ]rst item having value 0, the second item having
actions
}
value 1, etc.
void main() {
Tick function: The SM's tickB =function
0x00; carries out one tick of the SM.
// Initialize This SM's tick function is
outputs
LA_State = LA_SMStart; // Indicates initial
named TickFct_Latch(). For the current state LA_State, the tick function's 6rst switch statement
call
takes the appropriate transition to a new current state; if LA_State is LA_SMStart, the transition is to
while(1) {
the SM's initial state. The second switch statement then executes ©zyBooks
TickFct_Latch(); the actions for the 09:33
02/12/24 new current
231883
state. } Lawrence Nderu
} Ak78Fta73x
main loop that calls tick function: main() ]rst initializes outputs; good practice for any embedded
program, whether implementing an SM or not, is to start the main function by initializing all outputs.
main() then sets the current state to a value of LA_SMStart. main() then enters the normal in]nite
"while (1)" loop, which just repeatedly calls the function TickFct_Latch() to repeatedly tick the Latch
SM.
16 of 44 12/02/2024, 09:34
zyBooks https://learn.zybooks.com/zybook/Ak78Fta73x/chapter/3/print
PARTICIPATION
ACTIVITY 3.4.1: Follow an SMs execution in C. Full screen
Run the above code in RIMS. Press "Break" and then repeatedly press "Step" (setting A0
accordingly), observing how the code executes each tick of the state machine.
A0 0
©zyBooks 02/12/24 09:33 231883
A1 0 Lawrence Nderu
Ak78Fta73x
A2 0
A3 0
A4 0
A5 0
A6 0
A7 0
A = 0
1 #include "RIMS.h"
2 int main() {
3 while(1) {
4 B0 = A0 && A1;
5 }
6 return 0;
7 }
17 of 44 12/02/2024, 09:34
zyBooks https://learn.zybooks.com/zybook/Ak78Fta73x/chapter/3/print
B0 0
B1 0
B2 0
B3 0
©zyBooks 02/12/24 09:33 231883
B4 0 Lawrence Nderu
Ak78Fta73x
B5 0
B6 0
B7 0
B = 0
Compile
The transition switch statement's default case should never actually execute, but good practice is
to always include a default case for a switch statement, in case something bad happens. For a
state machine, the default case should be included for safety if the state variable ever somehow
gets corrupted. The default case commonly has a transition to the initial state, causing the SM to
start over rather than getting stuck.
Capturing behavior as an SM and then converting to C using the above method typically results in
more code than capturing behavior directly in C. However, more code does not mean worse code.
The C code generated from an SM may be more likely to be correct, may be more easily extensible
and maintainable, and has other major bene]ts that will be seen later.
18 of 44 12/02/2024, 09:34
zyBooks https://learn.zybooks.com/zybook/Ak78Fta73x/chapter/3/print
#include "RIMS.h"
void TickFct_Carousel()
{
switch(CR_State) { // Transitions
case CR_SMStart: // Initial transition
CR_State = CR_Init;
break; ©zyBooks 02/12/24 09:33 231883
Lawrence Nderu
case CR_Init: Ak78Fta73x
CR_State = CR_WaitRise;
break;
case CR_WaitRise:
if (A1) {
CR_State = CR_Init;
}
else if (!A1 && !A0) {
CR_State = CR_WaitRise;
}
else if (!A1 && A0) {
CR_State = CR_Increment;
}
break;
case CR_Increment:
CR_State = CR_WaitFall;
break;
case CR_WaitFall:
if (!A0) {
CR_State = CR_WaitRise;
}
else if (A0) {
CR_State = CR_WaitFall;
}
break;
default:
CR_State = CR_SMStart;
break;
} // Transitions
void main() {
B = 0x00; // Initialize outputs
CR_State = CR_SMStart; // Indicates initial call
while(1) {
TickFct_Carousel();
}
19 of 44 12/02/2024, 09:34
zyBooks https://learn.zybooks.com/zybook/Ak78Fta73x/chapter/3/print
}
}
PARTICIPATION
ACTIVITY 3.4.2: Method for implementing an SM in C.
PARTICIPATION
ACTIVITY
20 of 44 12/02/2024, 09:34
zyBooks https://learn.zybooks.com/zybook/Ak78Fta73x/chapter/3/print
21 of 44 12/02/2024, 09:34
zyBooks https://learn.zybooks.com/zybook/Ak78Fta73x/chapter/3/print
PARTICIPATION
ACTIVITY 3.4.4: SM to C for the light toggle system. Full screen
Strictly following the above method for implementing an SM in C, implement the above
light toggle SM in C.
A0 0
A1 0
A2 0
A3 0
A4 0
A5 0
A6 0
A7 0
A = 0
22 of 44 12/02/2024, 09:34
zyBooks https://learn.zybooks.com/zybook/Ak78Fta73x/chapter/3/print
1 #include "RIMS.h"
2 int main() {
3 while(1) {
4 B0 = A0 && A1;
5 }
6 return 0;
7 }
B0 0
B1 0
B2 0
B3 0
B4 0
B5 0
B6 0
B7 0
B = 0
Compile
Start
23 of 44 12/02/2024, 09:34
zyBooks https://learn.zybooks.com/zybook/Ak78Fta73x/chapter/3/print
A0 0
A1 0
A2 0
A3 0
©zyBooks 02/12/24 09:33 231883
A4 0
Lawrence Nderu
Ak78Fta73x
A5 0
A6 0
A7 0
A = 0
1
24 of 44 12/02/2024, 09:34
zyBooks https://learn.zybooks.com/zybook/Ak78Fta73x/chapter/3/print
B0 0
B1 0
B2 0
B3 0
©zyBooks 02/12/24 09:33 231883
B4 0 Lawrence Nderu
Ak78Fta73x
B5 0
B6 0
B7 0
B = 0
Variables
An SM can have variables declared at the SM scope (i.e., not within a state), which can be accessed
by all actions and conditions of the SM. For example, the following SM uses several variables to
output the average of 4-bit numbers that appear on A3..A0 when A7 rises.
25 of 44 12/02/2024, 09:34
zyBooks https://learn.zybooks.com/zybook/Ak78Fta73x/chapter/3/print
Variable sum maintains the sum of all 4-bit numbers seen so far, de]ned as a short to reduce
likelihood of overKow. Variable cnt counts the number of times A7 has risen. Variable inNum stores
A3..A0, that variable used just to improve code readability. (Note: A reset for the above system,
perhaps using A6, is omitted for brevity).
In RIMS, the input/output variables like A0 or B can be thought of as having been declared as
unsigned char variables.
©zyBooks 02/12/24 09:33 231883
While the variables could be initialized when declared (e.g., unsigned shortLawrence
sum=0;),Nderu
good practice
Ak78Fta73x
is to create a state named Init to carry out initializations of variables and also outputs. In this way,
not only are all initializations in one place, but the system can be re-initialized merely by
transitioning back to the Init state.
Consider an applause-meter system intended for a game show. A sound sensor measures
sound on a scale of 0 to 7 (0 means quiet, 7 means loud), outputting a three-bit binary
number, connected to RIM's A2-A0. A button connected to A3 can be pressed by the game
show host to save (when A3 rises) the current sound level, which will then be displayed on
B. The system's behavior can be captured as an SM with a variable, as shown.
When converting to C, the SM variables can be implemented as global variables above the SM's tick
function.
PARTICIPATION
ACTIVITY 3.5.1: SM variables.
26 of 44 12/02/2024, 09:34
zyBooks https://learn.zybooks.com/zybook/Ak78Fta73x/chapter/3/print
True
False
3) Failing to write an SM variable in a
particular state causes that variable
to become 0.
True
©zyBooks 02/12/24 09:33 231883
False Lawrence Nderu
Ak78Fta73x
4) When implementing an SM in C, the
SM's variables should be declared in
the main() function.
True
False
Design a system for an automobile that counts the number of times the car was put into
drive (A0 is 1) while the driver's seatbelt was not fastened (A1 is 0). Once the car starts
driving, do no further counting until the car is taken out of drive (A0 is 0). While the car is
not in drive, a mechanic can view the count by holding a button (A2 is 1) causing the count
to appear on B. B is normally 0.
Statements
The statements that can appear in actions can include more than just assignment statements. Any
C statements can appear, such as if-else statements, loops, and function calls. However, for this
material's purposes, good practice is to ensure that actions don't wait on an external input value,
such as while (!A0) {};. Waiting behavior should be captured as states and transitions so
that all time-ordered behavior is visible at the transition level. Also, a state with actions that wait
could cause the SM to violate the basic assumption that SM ticks occur faster than events so that
no events are missed. ©zyBooks 02/12/24 09:33 231883
Lawrence Nderu
The following example changes RIMS' output LED pattern from 00000001 toAk78Fta73x
00000010 to
00000100, etc., each time A0 rises. When 10000000 is reached, the pattern wraps back to
00000001.
27 of 44 12/02/2024, 09:34
zyBooks https://learn.zybooks.com/zybook/Ak78Fta73x/chapter/3/print
Extend the above applause meter SM so that if A4 becomes 1 while in the WaitRise state,
the system outputs the maximum value seen so far. When A4 is returned to 0, the system
outputs the most-recently-saved value as before. Use a variable for the most-recently-
saved value and another for the max value, and an if-else statement.
Create an SM that waits for A0 to rise, upon which the SM counts the number of 1s on
A1..A7 and outputs the count on B. That count stays on B until A0 rises again. Use the
GetBit function from an earlier section, and a for loop, as the actions of a state that counts
the 1s on A1..A7.
PARTICIPATION
ACTIVITY 3.5.2: SM statements.
28 of 44 12/02/2024, 09:34
zyBooks https://learn.zybooks.com/zybook/Ak78Fta73x/chapter/3/print
False
Conditions
• Exactly one—no more, no fewer—of a state's exiting transitions should have a condition that
evaluates to true at a given time. In this way, the next state for each tick is precisely and
clearly de]ned.
A common error is to create transitions leaving a state whose conditions are not mutually
exclusive, like one transition with condition A0 and another with condition A1, both of which could
be true simultaneously. Another common error is to create transitions such that sometimes no
transition has a true condition, like one transition with condition A0 and another with condition !A0
&& A1, which fail to cover the situation !A0 && !A1. Technically, neither situation is actually an error.
In the ]rst case, the SM becomes non-deterministic, because the model does not de]ne which of
two true transitions will be taken. In the second case, the SM will implicitly take a transition back to
the same state, but explicit transitions are preferable for clarity.
For convenience, the SM's in this material use a condition named other to indicate the transition
that should be taken if none of the state's normal transition conditions are true. For example, the
following system opens a swinging door when a person approaches the front (A0 is 1) and nobody
is directly behind the door (A1 is 0). Note that the transition that remains in the WaitPerson state is
simply "other" rather than being !(A0 && !A1), which clutters the SM and detracts the readers
attention away from the more important transition A0 && !A1 from WaitPerson to Open. Once
opening the door, the system keeps the door open as long as the person is detected near the door
©zyBooks 02/12/24 09:33 231883
as indicated by A0 || A1, again using "other" for the opposite condition.
Lawrence Nderu
Ak78Fta73x
29 of 44 12/02/2024, 09:34
zyBooks https://learn.zybooks.com/zybook/Ak78Fta73x/chapter/3/print
When implementing an SM in C, the "other" transition may be implemented as a last else branch
(with no expression) in the state's transitions if-else code.
©zyBooks 02/12/24 09:33 231883
PARTICIPATION
Lawrence Nderu
ACTIVITY 3.5.3: SM conditions. Ak78Fta73x
Transition conditions are expressions, not statements, so should not end with a
semicolon. For each, write the most direct answer.
Ex: For "A1 and A0 are true", write
A1 && A0
without parentheses, semicolons, and without == .
30 of 44 12/02/2024, 09:34
zyBooks https://learn.zybooks.com/zybook/Ak78Fta73x/chapter/3/print
31 of 44 12/02/2024, 09:34
zyBooks https://learn.zybooks.com/zybook/Ak78Fta73x/chapter/3/print
For example, the following ]gure parts (a) and (b) show SMs that increment variable cnt once for
each rising A0. The Mealy SM increments on the transition that detected the rise, and thus avoids
the need for a separate state. Note that Mealy actions are shown graphically following a transition's
condition and a /.
Figure 3.6.1: Mealy SMs can reduce states and more intuitively
represent some behavior.
32 of 44 12/02/2024, 09:34
zyBooks https://learn.zybooks.com/zybook/Ak78Fta73x/chapter/3/print
Note that the SM in (c) is wrong, incrementing B repeatedly while A0 is 1. Removing the A0
transition from WaitFall would still be wrong because the SM model would have an implicit
transition back to the state if no other transition is true.
The following implements an applause meter system (from an earlier section), using a Mealy
©zyBooks 02/12/24 09:33 231883
action on the transition that detects a rising A3, thus preventing having anLawrence
additional state.
Nderu
Ak78Fta73x
When translating to C, a transition's actions appear in the transition switch statement, in the
appropriate if-else branch.
Capture a toggle light system using an SM. A button connects to A0. B0 connects to a
light, initially off. Pressing the button (rising A0) changes the light from off to on. Another
press changes the light from on to off. And so on. First try capturing with a Moore SM.
Then try with an SM having Mealy actions, and notice that fewer states are required.
PARTICIPATION
ACTIVITY 3.6.1: Mealy actions.
©zyBooks 02/12/24 09:33 231883
Lawrence Nderu
1) A Mealy action occurs at which point Ak78Fta73x
during an SM tick?
While checking whether a
transition's condition is true or
false.
While taking a transition to the
33 of 44 12/02/2024, 09:34
zyBooks https://learn.zybooks.com/zybook/Ak78Fta73x/chapter/3/print
next state.
Upon entering a new state.
Before an SM's tick.
Step 1: A ]rst step is to list the system's basic states, adding actions if known:
©zyBooks 02/12/24 09:33 231883
Lawrence Nderu
Ak78Fta73x
Figure 3.7.1: Emergency exit door system: Basic states.
34 of 44 12/02/2024, 09:34
zyBooks https://learn.zybooks.com/zybook/Ak78Fta73x/chapter/3/print
Step 2: A second step of the process is to add transitions to each state to achieve the desired
behavior. Clearly the ]rst state to enter after initialization is the Unarmed state,
©zyBooks so we09:33
02/12/24 add 231883
a
Lawrence Nderu
conditionless (true) transition from Init to Unarmed. We add a transition to stay in Unarmed while
Ak78Fta73x
A0 is 0, and another transition to go to Armed when A0 is 1. We add a transition to stay in Armed
while the door is closed (A1 is 0), and another transition to go to Alarm if the door is opened. Finally,
we add a transition to stay in Alarm while the system is still armed (A0 is 1), and when disarmed
(A0 is 0) we could go to either Init or Unarmed; Unarmed seems reasonable so we add a transition
to there.
Step 3: The third step is to mentally check the behavior of the captured SM. This step may result in
adding more transitions, or even more states. Minimally, for each state, we should check that
exactly one transition's condition will be true, modifying the conditions or adding transitions if
necessary. Even more importantly, we should also determine whether the SM's behavior is as
desired, by mentally executing the SM and thinking what input sequences might occur. In doing so
for the above SM, we consider the possibility that a user might want to disarm the system while
armed, and notice that is not possible in the SM. Thus, we may add transitions, such as !A0 from
Armed to Unarmed (requiring that the other two transitions be modi]ed, otherwise the state's
©zyBooks 02/12/24 09:33 231883
outgoing conditions would not be mutually exclusive). Lawrence Nderu
Ak78Fta73x
When mentally executing, one might focus on a particular state, and then for each input not
explicitly on the transitions one might ask: "Does that input's value matter for this state's behavior?"
For example, the above system has two inputs, A0 and A1. For state Unarmed, does input A1's
value matter? It does not for that state. For state Armed, does input A0 matter? It does, so we need
to add transitions. For state Alarm, does A1's value matter? It does not; once the door has been
opened, the alarm continues sounding whether the door stays open or closed.
35 of 44 12/02/2024, 09:34
zyBooks https://learn.zybooks.com/zybook/Ak78Fta73x/chapter/3/print
Capturing time-ordered behavior is hard. Good designers will spend much time mentally executing
their SM and thinking of possible input sequences that need to be addressed. Re]ning an SM many
times is commonplace.
PARTICIPATION
ACTIVITY 3.7.1: Capturing behavior as an SM.
A doorway is for exit only. Sensors A0, A1, A2 detect a person passing through. A proper
©zyBooks 02/12/24 09:33 231883
exit causes A2A1A0 to be 000, then 100, then 010, then 001, then 000. Any other sequence
Lawrence Nderu
causes a buzzer to sound (B0=1) until 000. Ak78Fta73x
Design an SM using RIBS that captures the doorway behavior, and simulate using RIMS.
36 of 44 12/02/2024, 09:34
zyBooks https://learn.zybooks.com/zybook/Ak78Fta73x/chapter/3/print
An automatic door at a store has a sensor in front (A0) and behind (A1). The door opens
(B0=1) when a person approaches from the front, and stays open as long as a person is
detected in front or behind. If the door is closed and a person approaches from the behind,
the door does not open. If the door is closed and a person approaches from the front but a
person is also detected behind, the door does not open, to prevent hitting the person that
is behind.
©zyBooks 02/12/24 09:33 231883
Lawrence
Design an SM using RIBS that captures the automatic door behavior, and Nderu
simulate using
Ak78Fta73x
RIMS.
A dimmer light system has increase (A0) and decrease (A1) buttons. B sets the light
intensity, 0 is off, 255 is the maximum intensity, and:
Design an SM using RIBS that captures the dimmer light behavior, and simulate using
RIMS.
An amusement park ride has sensor mats on the left (A0) and right (A1) of a ride car. A
ride operator starts the ride by pressing a button (A7); each unique press toggles the ride
from stopped to started (B0=1) and vice-versa. If anyone leaves the ride car and steps on a
sensor mat, the ride stops and an alarm sounds (B1=1). The alarm stops sounding when
the person gets off the sensor mat. The only way for the ride to restart is for the operator
to press the button again. The ride never starts if someone is on the sensor mat.
©zyBooks
Design an SM using RIBS that captures the amusement ride behavior, and02/12/24
simulate09:33
using231883
Lawrence Nderu
RIMS. Ak78Fta73x
3.8 Testing an SM
37 of 44 12/02/2024, 09:34
zyBooks https://learn.zybooks.com/zybook/Ak78Fta73x/chapter/3/print
Testing time-ordered behavior requires generating a good set of input scenarios, where a scenario
is a sequence of inputs that should cause a particular sequence of state. Such testing is in contrast
to merely generating a good set of input combinations for a system lacking internal states, each
input combination known as a test vector.
Table 3.8.1: A few test scenarios for the emergency door system.
38 of 44 12/02/2024, 09:34
zyBooks https://learn.zybooks.com/zybook/Ak78Fta73x/chapter/3/print
Each row indicates the assumed starting state (same as previous row's ]nal state), describes the
system's input scenario and the expected system behavior, lists the expected ]nal state and output,
and ]nally lists the test vectors that will generate the scenario. For©zyBooks
example,02/12/24 09:33 2231883
the scenario starts in
Lawrence Nderu
state Unarmed, then arms to the system, which should cause a change to state Armed and output
Ak78Fta73x
B0=1. Arming the system is achieved by A1A0 being 01, which is the test vector. Scenario 5 carries
out a longer sequence, requiring several test vectors.
Scenario 6 arms and then unarms the system. Testing with the given test vectors will yield the
correct ]nal output of 0, but the ]nal state will be Armed rather than Unarmed. Thus, testing
uncovers a problem, namely that Armed is missing a transition with condition !A0 going back to
Unarmed .
As with testing systems with combinational behavior, testing a system with time-ordered behavior
should involve normal cases and border cases. Border cases speci]cally test unusual situations,
like all inputs changing from 0s to 1s simultaneously, or an input changing back and forth from 0 to
1 repeatedly.
When testing an SM, test vectors should ensure that each state and each transition is executed at
least once. Furthermore, if a state's action code has branches, then test vectors should also ensure
that every statement is executed at least once. Even more ideally, every path through the SM would
also be tested, but achieving complete path coverage is hard because huge numbers of paths may
exist.
In testing terminology, black-box testing refers to checking for correct outputs only, as in checking
the value of B0 in the above example. In white-box testing, internal values of the system are also
checked, such as the current state. One can see the advantage of white-box testing in the above
example, where the output was correct but the state was not. Further black-box testing might
discover the above problem too, but white-box is more likely to detect problems. Of course, white-
box testing is harder because a mechanism is necessary to access internal values.
Designing good test vectors can take much effort, both to formulate the scenarios, and to properly
create the test vectors. Testing is as important as capturing the SM. Good practice is to plan to
spend nearly as much time for testing a system as for designing a©zyBookssystem. 02/12/24
New programmers
09:33 231883
rarely follow this practice, believing testing is just a "sanity check" step at the end ofNderu
Lawrence design.
Ak78Fta73x
PARTICIPATION
ACTIVITY 3.8.1: Creating test vectors for the emergency door system.
Match the test vectors with the desired test scenario for the above emergency door
system. Assume each set of test vectors is applied immediately after starting the system,
so the starting state is always Unarmed. Each vector is for A1A0, so 01 means A1 is 0 and
39 of 44 12/02/2024, 09:34
zyBooks https://learn.zybooks.com/zybook/Ak78Fta73x/chapter/3/print
A0 is 1.
Reset
40 of 44 12/02/2024, 09:34
zyBooks https://learn.zybooks.com/zybook/Ak78Fta73x/chapter/3/print
The concept of thinking of program behavior as state machines, even though the actual code is in C,
is the most important concept in this book.
41 of 44 12/02/2024, 09:34
zyBooks https://learn.zybooks.com/zybook/Ak78Fta73x/chapter/3/print
#include "RIMS.h"
unsigned char x;
void TickFct_Example() {
switch(EX_State) { // Transitions
case EX_SMStart:
EX_State = EX_S0; ©zyBooks 02/12/24 09:33 231883
break; Lawrence Nderu
case EX_S0: Ak78Fta73x
if (1) {
EX_State = EX_S1;
}
break;
case EX_S2:
if (A3) {
EX_State = EX_S2;
}
else if (!A3) {
EX_State = EX_S1;
}
break;
case EX_S1:
if (!A3) {
EX_State = EX_S1;
}
else if (A3) {
EX_State = EX_S2;
x = A & 0x07;
B = x;
}
break;
default:
EX_State = EX_SMStart;
break;
}
42 of 44 12/02/2024, 09:34
zyBooks https://learn.zybooks.com/zybook/Ak78Fta73x/chapter/3/print
For any working example in RIBS having an action in a state, introduce a C syntax error by
removing the semicolon after an action. Save, generate C, then press "RIMS Simulation".
Note the error message that is generated, and strive to correlate that with the RIBS SM. Fix
the error and this time introduce an error by adding a semicolon after a transition
condition, and try running again.
PARTICIPATION
ACTIVITY 3.9.1: Capture/convert process.
43 of 44 12/02/2024, 09:34
zyBooks https://learn.zybooks.com/zybook/Ak78Fta73x/chapter/3/print
44 of 44 12/02/2024, 09:34