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
Basically, one needs to push the unique button to change mode. A bird’s eye view of the system would give the following finite state machine:

Finite-State Machine overview of a servo tester.

Finite-State Machine overview of a servo tester.

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:


servotester-approx-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.