In this previous post, I have reviewed control-flow constructs available in CPAL. Yet, I had purposely omitted Mode-Automaton.
Servo Tester
So in this post, I will start to build a servo tester in CPAL. For those of you that do not know what is a servo tester is, please first have a look at this video:
Servo Tester Video
Process definition and Black Box
Seen as a black-box, the servo tester has 2 inputs — a potentiometer and a button — and one output — the servo signal — (well the same one duplicated). So in CPAL, I will declare a process with two inputs and one output. Let’s not focus on parameters’ type yet.
processdef ServoTester(
in bool: changeModeCmd,
in uint16: manualPosition,
out int32: position)
{
/* ... */
}
Mode Automaton and State Machine
What makes a FSM a mode-automaton is binding states with an equation linking inputs and outputs. By now, I will assume the manual position is acquired by a ADC and that it uses the full range of the uint16
. Also let’s assume that the electronic board will convert the position to a PWM signal over the full range of int32
. It means that
- when
position = int32.FIRST
then the servomotor will be at minimum position, - when
position = 0
then position is neutral, - and when
position = int32.LAST
then position is maximum.
Assuming, we have a boolean telling us that the button is pushed, then, in CPAL, I could write the following code:
processdef ServoTester(
in bool: changeModeCmd,
in uint16: manualPosition,
out int32: position)
{
state Manual {
/* position depends directly and linearly
on manual inputs.*/
position = int32.as(manualPosition) + int32.FIRST;
}
on (changeModeCmd) to Neutral;
state Neutral {
position = 0;
}
on (changeModeCmd) to Auto;
state Auto {
position = ... ;/* switch here between max and min*/
}
}
Timed transitions
There are simple transitions with boolean conditions but timed transitions are also possible in CPAL. Let us focus on the Auto
state, what seems to happen is that the servomotor is switched between min and max every second. Fortunately, CPAL has a construct for that kind of transitions, and we can partially rewrite the previous automata by replacing the Auto
state with:
on (changeModeCmd) to AutoMin;
state AutoMin {
position = int32.FIRST;
}
on (changeModeCmd) to Manual;
after (1s) to AutoMax;
state AutoMax {
position = int32.LAST;
}
on (changeModeCmd) to Manual;
after (1s) to AutoMin;
Finally, one ends up with this automaton:
NB: This is the kind of views that our editor displays automatically while typing.
Conclusion
In this post, I have begun to dig into mode-automaton which is a powerful and non-ambiguous way to express the logic of the code, and graphical representation helps a lot for the understanding. But CPAL can do much more and that will be the subject of other articles. By now, you can follow us on Twitter or give a try to CPAL.