<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="FeedCreator 1.8" -->
<?xml-stylesheet href="https://www.sinelabore.com/lib/exe/css.php?s=feed" type="text/css"?>
<rss version="2.0">
    <channel xmlns:g="http://base.google.com/ns/1.0">
        <title>SinelaboreRT - wiki:examples</title>
        <description>Productivity for embedded software development</description>
        <link>https://www.sinelabore.com/</link>
        <lastBuildDate>Wed, 08 Apr 2026 03:01:06 +0000</lastBuildDate>
        <generator>FeedCreator 1.8</generator>
        <image>
            <url>https://www.sinelabore.com/lib/exe/fetch.php/favicon.ico</url>
            <title>SinelaboreRT</title>
            <link>https://www.sinelabore.com/</link>
        </image>
        <item>
            <title>Electric Window Lift Controller Example</title>
            <link>https://www.sinelabore.com/doku.php/wiki/examples/car_window_lift_controller</link>
            <description>
&lt;h1 class=&quot;sectionedit1&quot; id=&quot;electric_window_lift_controller_example&quot;&gt;Electric Window Lift Controller Example&lt;/h1&gt;
&lt;div class=&quot;level1&quot;&gt;

&lt;p&gt;
The following example describes an electric window lift as it can be found in most modern cars today. The example is based on a requirement specification that is provided from &lt;a href=&quot;http://www.iese.fhg.de/fhg/iese/index.jsp&quot; class=&quot;urlextern&quot; title=&quot;http://www.iese.fhg.de/fhg/iese/index.jsp&quot; rel=&quot;ugc nofollow&quot;&gt;Fraunhofer IESE&lt;/a&gt; and can be downloaded &lt;a href=&quot;http://publica.fraunhofer.de/starweb/servlet.starweb?path=pub.web&amp;amp;search=N-10473&quot; class=&quot;urlextern&quot; title=&quot;http://publica.fraunhofer.de/starweb/servlet.starweb?path=pub.web&amp;amp;search=N-10473&quot; rel=&quot;ugc nofollow&quot;&gt;here&lt;/a&gt;. In the document it is stated that the specification has a similar complexity and level of detail as it can be found in real specifications written by car manufactures. But it does not describe a real existing system.
&lt;/p&gt;

&lt;p&gt;
The specification describes a complete door controller. One small part of it - the window lift unit - is modelled here. In fact only the opening of the pane was realized. The closing part is very similar and was left out to make it easier to follow the example. 
Unfortunately the specification is available in German language only. Therefore the window lift related parts are presented below in English.
&lt;/p&gt;

&lt;p&gt;
Besides showing how the requirements are transfered into a state machine it also shows how to integrate a state machine into a real-time operating system. In this example the Windows emulation of embos from &lt;a href=&quot;http://www.segger.com/&quot; class=&quot;urlextern&quot; title=&quot;http://www.segger.com/&quot; rel=&quot;ugc nofollow&quot;&gt;Segger&lt;/a&gt; was used.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Electric Window Lift Controller Example&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;electric_window_lift_controller_example&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:1,&amp;quot;range&amp;quot;:&amp;quot;1-1282&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit2&quot; id=&quot;electric_window_lift_specification&quot;&gt;Electric Window Lift Specification&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
The movement of the pane is controlled through keys in the car doors. Pane movement continues as long as the stimulus is present or the pane has reached its end-position (either open or close). While closing the pane it is controlled if a barrier disturbes the movement. If yes, the closing operation is stopped and the pane is opened totally (clamping protection).
&lt;/p&gt;

&lt;p&gt;
In reality the number and kind of stimuli depends a lot on the car type. Here the implementation of just one type is shown.
&lt;/p&gt;

&lt;/div&gt;

&lt;h4 id=&quot;opening_a_pane&quot;&gt;Opening a pane&lt;/h4&gt;
&lt;div class=&quot;level4&quot;&gt;

&lt;p&gt;
When receiving an opening command the opening starts if the battery voltage is above 10V. Below this level a “LowBatt” message is sent to the central control unit. 
&lt;/p&gt;

&lt;p&gt;
The following cases needs to be considered for moving:
&lt;/p&gt;

&lt;p&gt;
If the command is “pane down manually” the pane will be moved downwards. Downwards movement will be stopped under the following conditions:
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; the down command is not anymore present &lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; the pane is totally open&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; there is a new command &lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; the movement sensor detects no movement anymore  although the window is not totally open and the motor was  switched on (an error message is sent in this case)&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; The total traveling time is longer than 3 sec but the pane is not totally open (an error message is sent in this case)&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
When receiving the command “pane down automatically” the pane will be moved downwards until it is completely open. Downwards movement will be stopped under the following conditions:
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; the pane is totally open&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; there is a new command &lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; the movement sensor detects no movement anymore  although the window is not totally open and the motor was switched on (an error message is sent in this case)&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; The total traveling time is longer than 3 sec but the pane is not totally open (an error message is sent in this case)&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; It is not necessary that the “pane down” command is pending &lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; during the complete traveling time.&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
Mechanically it is not possible to move the electric window lift command key directly from “pane down auto” into the “not pressed” state. Therefore the command “pane down manual” is ignored up to 0.5sec if the previous position was “pane down auto”. If the command key is present longer than 0.5 sec the mode will be changed to manual moving mode. Releasing the command key afterwards stopps the movement immediately.
&lt;/p&gt;

&lt;/div&gt;

&lt;h4 id=&quot;the_sample_solution&quot;&gt;The Sample Solution&lt;/h4&gt;
&lt;div class=&quot;level4&quot;&gt;

&lt;p&gt;
The figure below shows a possible state chart of the window lift. 
&lt;/p&gt;

&lt;p&gt;
&lt;img src=&quot;https://www.sinelabore.com/lib/exe/fetch.php/wiki/examples/car_window_lift_sm.png&quot; class=&quot;mediacenter&quot; loading=&quot;lazy&quot; alt=&quot;&quot; /&gt;
&lt;/p&gt;

&lt;p&gt;
The generated state machine is executed in an embos task. Therefore it blocks until an event was recieved. Embos provides several mechanisms for inter task communication. In the example events were used to signal timeouts, pane movement and new key commands. The event selection code is specified in an &amp;#039;action:&amp;#039; note (see image at the top). The action code is executed at the very beginning of the generated state machine function.
&lt;/p&gt;
&lt;pre class=&quot;code c&quot;&gt;&lt;span class=&quot;coMULTI&quot;&gt;/* action code */&lt;/span&gt;
evt &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; OS_WaitEvent&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;nu12&quot;&gt;0xff&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;co1&quot;&gt;// wait blocking&lt;/span&gt;
&lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;evt&lt;span class=&quot;sy0&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; msg&lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt;evTimeoutLongMove&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kw1&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;evt&lt;span class=&quot;sy0&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; msg&lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt;evTimeoutMoving&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kw1&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;evt&lt;span class=&quot;sy0&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; msg&lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt;evTimeoutInter&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kw1&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;evt&lt;span class=&quot;sy0&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; msg&lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt;evMotion&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kw1&quot;&gt;else&lt;/span&gt; msg&lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt;keybMsg&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
Important! SinelaboreRT does not restrict you in any way on how to send events to a state machine.
&lt;/p&gt;

&lt;p&gt;
The motor is simulated in a second task (see motor.c / motor.h). If the motor is switched &amp;#039;on&amp;#039; the task sends  evMotion events every 20ms. As long as the motor is &amp;#039;off&amp;#039; the task is suspended and does not send events.
&lt;/p&gt;

&lt;p&gt;
For the supervision timers (long move, moving, inter) embos software timers were used. In their callback functions they simply send the according timeout event to the state machine task.
&lt;/p&gt;
&lt;pre class=&quot;code c&quot;&gt;&lt;span class=&quot;co1&quot;&gt;// Timer handler for the long move timer.&lt;/span&gt;
&lt;span class=&quot;co1&quot;&gt;// On timeout send the message to the statechart&lt;/span&gt;
&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt; TimerLongMoveFct&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
  OS_SignalEvent&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;nu12&quot;&gt;0x1&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&amp;amp;&lt;/span&gt;statemachineTaskTcb&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
A third task realizes a small test bed by sending commands like (manual down, auto down, …) to the state machine. Several test cases are realized to test the machine. For example entering the manual mode from the auto mode. Another test case tests the &amp;#039;long movement&amp;#039; requirement.
&lt;/p&gt;
&lt;pre class=&quot;code c&quot;&gt;&lt;span class=&quot;co1&quot;&gt;// This tasks sends simulated user commands.&lt;/span&gt;
&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt; SimulatorTask&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
  &lt;span class=&quot;kw2&quot;&gt;extern&lt;/span&gt; TUSIGN8 pos&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kw1&quot;&gt;while&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
    OS_Delay&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
    Trace&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;&amp;quot;&lt;span class=&quot;es1&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;es1&quot;&gt;\n&lt;/span&gt;First test. Must result in long move error.&amp;quot;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
    keybMsg&lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt;evManDown&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
    Trace&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;&amp;quot;evManDown&amp;quot;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
    OS_SignalEvent&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;nu12&quot;&gt;0x80&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&amp;amp;&lt;/span&gt;statemachineTaskTcb&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
    OS_Delay&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
   ...&lt;/pre&gt;

&lt;/div&gt;

&lt;h4 id=&quot;running_the_example&quot;&gt;Running the Example&lt;/h4&gt;
&lt;div class=&quot;level4&quot;&gt;

&lt;p&gt;
The example comes pre-built. The executable &lt;code&gt;start.exe&lt;/code&gt; can just be started. If started it does not display any output but writes its output to &lt;code&gt;trace.txt&lt;/code&gt; which is located under &lt;code&gt;c:\&lt;/code&gt;. After execution all test cases (takes about 30s) the program finishes automatically.
&lt;/p&gt;

&lt;p&gt;
&lt;img src=&quot;https://www.sinelabore.com/lib/exe/fetch.php/wiki/examples/car_window_lift_trace.jpg&quot; class=&quot;mediacenter&quot; loading=&quot;lazy&quot; alt=&quot;&quot; /&gt;
&lt;/p&gt;

&lt;p&gt;
File &lt;code&gt;main.c&lt;/code&gt; contains the simulation - and the state machine task as well as the code to initialize all tasks, timers etc. In files &lt;code&gt;motor.*&lt;/code&gt; the simple motor simulation was realized. All files starting with &lt;code&gt;window_lift.c/h&lt;/code&gt; were automatically generated from the state-chart &lt;code&gt;window_lift.cdd&lt;/code&gt;. In folder embos the Visual C++ project as well as the embos library can be found.
&lt;/p&gt;

&lt;p&gt;
To rebuilt the state machine files execute 
&lt;/p&gt;
&lt;pre class=&quot;code bash&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;java&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-jar&lt;/span&gt; codegen.jar &lt;span class=&quot;re5&quot;&gt;-p&lt;/span&gt; CADIFRA &lt;span class=&quot;re5&quot;&gt;-o&lt;/span&gt; window_lift  window_lift.cdd&lt;span class=&quot;st_h&quot;&gt;&#039; &lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
To rebuilt the executable file you have to install Microsoft C++ 2005 Express Edition (or later) which you can download from Microsoft.
&lt;/p&gt;

&lt;p&gt;
Thanks to the people from Segger allowing us to use the windows evaluation version of embos in this example.
&lt;/p&gt;

&lt;p&gt;
If you have comments or questions just send an email to &lt;a href=&quot;mailto:&amp;#105;&amp;#110;&amp;#102;&amp;#111;&amp;#64;&amp;#115;&amp;#105;&amp;#110;&amp;#101;&amp;#108;&amp;#97;&amp;#98;&amp;#111;&amp;#114;&amp;#101;&amp;#46;&amp;#99;&amp;#111;&amp;#109;&quot; class=&quot;mail&quot; title=&quot;&amp;#105;&amp;#110;&amp;#102;&amp;#111;&amp;#64;&amp;#115;&amp;#105;&amp;#110;&amp;#101;&amp;#108;&amp;#97;&amp;#98;&amp;#111;&amp;#114;&amp;#101;&amp;#46;&amp;#99;&amp;#111;&amp;#109;&quot;&gt;&amp;#105;&amp;#110;&amp;#102;&amp;#111;&amp;#64;&amp;#115;&amp;#105;&amp;#110;&amp;#101;&amp;#108;&amp;#97;&amp;#98;&amp;#111;&amp;#114;&amp;#101;&amp;#46;&amp;#99;&amp;#111;&amp;#109;&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
~~DISCUSSION:closed|Leave your comments~~
&lt;/p&gt;
&lt;div class=&quot;tags&quot;&gt;&lt;span&gt;
	&lt;a href=&quot;https://www.sinelabore.com/doku.php/tag/application_example?do=showtag&amp;amp;tag=%5BApplication_Example%5D&quot; class=&quot;wikilink1&quot; title=&quot;tag:application_example&quot; rel=&quot;tag&quot;&gt;[Application Example]&lt;/a&gt;
&lt;/span&gt;&lt;/div&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Electric Window Lift Specification&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;electric_window_lift_specification&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:2,&amp;quot;range&amp;quot;:&amp;quot;1283-&amp;quot;} --&gt;</description>
            <author>anonymous@undisclosed.example.com (Anonymous)</author>
            <pubDate>Sat, 28 Nov 2015 13:52:49 +0000</pubDate>
        </item>
        <item>
            <title>DCF77 Radio Clock</title>
            <link>https://www.sinelabore.com/doku.php/wiki/examples/dcf77_radio-clock_decoder</link>
            <description>
&lt;h1 class=&quot;sectionedit1&quot; id=&quot;dcf77_radio_clock&quot;&gt;DCF77 Radio Clock&lt;/h1&gt;
&lt;div class=&quot;level1&quot;&gt;

&lt;p&gt;
In this example a decoder for the DCF77 standard-frequency radio signal is realised based on two cooperating state machines. You will learn how to use the features of the code generator.
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; Machines based on conditional and event based triggers&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; Adding own variables to the machine instance data&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; Adding own code to the generated state machine file&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; Using an own event type that includes the event and data&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;DCF77 Radio Clock&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;dcf77_radio_clock&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:1,&amp;quot;range&amp;quot;:&amp;quot;1-454&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit2&quot; id=&quot;dcf77_basics&quot;&gt;DCF77 Basics&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
The transmitter is located nearby Frankfurt in Germany and continuously transmits a 77.5 kHz signal that encodes the local time using amplitude and phase modulation. The sender is controlled by the high-precision atomic clocks of the German institute of standards (&lt;a href=&quot;http://www.ptb.de/index_en.html&quot; class=&quot;urlextern&quot; title=&quot;http://www.ptb.de/index_en.html&quot; rel=&quot;ugc nofollow&quot;&gt;Physikalische Bundesanstalt in Braunschweig&lt;/a&gt;). The signal can be received almost everywhere in central Europe with very simple and cheap receivers. A short description about the motivation and the encoding of the DCF-77 signal can be found here &lt;a href=&quot;http://en.wikipedia.org/wiki/DCF77&quot; class=&quot;urlextern&quot; title=&quot;http://en.wikipedia.org/wiki/DCF77&quot; rel=&quot;ugc nofollow&quot;&gt;here&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
&lt;img src=&quot;https://www.sinelabore.com/lib/exe/fetch.php/wiki/examples/dcf77_receiver_hardware.jpg?w=200&amp;amp;tok=9989c1&quot; class=&quot;mediaright&quot; align=&quot;right&quot; loading=&quot;lazy&quot; title=&quot;DCF77 Radio Clock Hardware based on a Texas Instruments MSP430 Eval Board from Olimex&quot; alt=&quot;DCF77 Radio Clock Hardware based on a Texas Instruments MSP430 Eval Board from Olimex&quot; width=&quot;200&quot; /&gt;
&lt;/p&gt;

&lt;p&gt;
The DCF-77 modulation reduces the signal amplitude for 0.1 seconds (short pulse, 0-bit) or 0.2 seconds (long pulse, 1-bit) at the beginning of each second, allowing to transmit 1 bit of data per second. A simple BCD-encoding scheme is used to transmit the hours, minutes, days, and data information for the next following minute. Encoding scheme of the time information transmitted with DCF77 is presented &lt;a href=&quot;https://www.ptb.de/cms/en/ptb/fachabteilungen/abt4/fb-44/ag-442/dissemination-of-legal-time/dcf77/dcf77-time-code.html&quot; class=&quot;urlextern&quot; title=&quot;https://www.ptb.de/cms/en/ptb/fachabteilungen/abt4/fb-44/ag-442/dissemination-of-legal-time/dcf77/dcf77-time-code.html&quot; rel=&quot;ugc nofollow&quot;&gt;here&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
&lt;a href=&quot;https://www.sinelabore.com/lib/exe/detail.php/wiki/examples/dcfkode2007_en.jpg?id=wiki%3Aexamples%3Adcf77_radio-clock_decoder&quot; class=&quot;media&quot; title=&quot;wiki:examples:dcfkode2007_en.jpg&quot;&gt;&lt;img src=&quot;https://www.sinelabore.com/lib/exe/fetch.php/wiki/examples/dcfkode2007_en.jpg?w=250&amp;amp;tok=0ddd49&quot; class=&quot;mediaright&quot; align=&quot;right&quot; loading=&quot;lazy&quot; title=&quot;Source: PTB&quot; alt=&quot;Source: PTB&quot; width=&quot;250&quot; /&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
To allow synchronization into the continuously sent signal, no pulse is send during the 59th second, so that the start of the next pulse exactly marks the beginning of the minute.
&lt;/p&gt;

&lt;p&gt;
The receiver application was splitted into two separate state machines. 
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;DCF77 Basics&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;dcf77_basics&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:2,&amp;quot;range&amp;quot;:&amp;quot;455-2063&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit3&quot; id=&quot;the_pulse_detection_state_machine&quot;&gt;The pulse detection state machine&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
The pulse detection state machine runs within a cyclic  timer interrupt service routine. It initially searches for the minute start &lt;code&gt;&amp;#039;M&lt;/code&gt;&amp;#039; and then detects the long and short pulses. This state machine runs cyclically and does not need any external triggers (events). Instead all state transitions are based by the DCF77 output signal level. We call such state machines “conditional machines” because state transitions are based on some input conditions or variable values. The types of transitions are described &lt;a href=&quot;https://www.sinelabore.com/doku.php/wiki/features&quot; class=&quot;wikilink1&quot; title=&quot;wiki:features&quot; data-wiki-id=&quot;wiki:features&quot;&gt; here &lt;/a&gt; in the section about transitions.
&lt;/p&gt;

&lt;p&gt;
The CPU is normally in low-power state. But when a pulse or minute start is detected the decoder machine and wakes up the CPU.
&lt;/p&gt;
&lt;pre class=&quot;code c&quot;&gt;&lt;span class=&quot;co2&quot;&gt;#pragma vector=TIMERA0_VECTOR&lt;/span&gt;
__interrupt &lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt; Timer_A0&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
&amp;nbsp;
    &lt;span class=&quot;co1&quot;&gt;// set debug output high if pin of dcf77 signal is high&lt;/span&gt;
    &lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;P1IN &lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nu12&quot;&gt;0x01&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;==&lt;/span&gt; 1U&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; P1OUT &lt;span class=&quot;sy0&quot;&gt;|=&lt;/span&gt; &lt;span class=&quot;nu12&quot;&gt;0x04&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kw1&quot;&gt;else&lt;/span&gt; P1OUT &lt;span class=&quot;sy0&quot;&gt;&amp;amp;=&lt;/span&gt; ~&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;nu12&quot;&gt;0x04&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;                  &lt;span class=&quot;co1&quot;&gt;// clr debug pin&lt;/span&gt;
&amp;nbsp;
    P1OUT &lt;span class=&quot;sy0&quot;&gt;|=&lt;/span&gt; &lt;span class=&quot;nu12&quot;&gt;0x08&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;                          &lt;span class=&quot;co1&quot;&gt;// set debug len of irq&lt;/span&gt;
&amp;nbsp;
    dcf77_irq&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt;irqSM&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;irqSM.&lt;span class=&quot;me1&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;==&lt;/span&gt;evTick &lt;span class=&quot;sy0&quot;&gt;||&lt;/span&gt; irqSM.&lt;span class=&quot;me1&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;==&lt;/span&gt;evMinStart&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
        &lt;span class=&quot;co1&quot;&gt;// wake up main CPU, got valid pulse&lt;/span&gt;
        __bic_SR_register_on_exit&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;LPM3_bits&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
    P1OUT &lt;span class=&quot;sy0&quot;&gt;&amp;amp;=&lt;/span&gt; ~&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;nu12&quot;&gt;0x08&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;                       &lt;span class=&quot;co1&quot;&gt;// clr debug len of irq&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
The state machine was created with the integrated state diagram editor. A screenshot is shown here. The editor allows to create state machine diagrams in very efficient way. A multipart &lt;a href=&quot;https://www.sinelabore.com/doku.php/wiki/manual/editor&quot; class=&quot;wikilink1&quot; title=&quot;wiki:manual:editor&quot; data-wiki-id=&quot;wiki:manual:editor&quot;&gt;tutorial&lt;/a&gt; is available here.
&lt;/p&gt;

&lt;p&gt;
&lt;a href=&quot;https://www.sinelabore.com/lib/exe/detail.php/wiki/examples/dcf77_irq_window.png?id=wiki%3Aexamples%3Adcf77_radio-clock_decoder&quot; class=&quot;media&quot; title=&quot;wiki:examples:dcf77_irq_window.png&quot;&gt;&lt;img src=&quot;https://www.sinelabore.com/lib/exe/fetch.php/wiki/examples/dcf77_irq_window.png&quot; class=&quot;media&quot; loading=&quot;lazy&quot; title=&quot; The pulse detection state machine was realised as conditional state machine and runs in the irq context.&quot; alt=&quot; The pulse detection state machine was realised as conditional state machine and runs in the irq context.&quot; /&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
The state diagram editor allows to directly add code to various sections of the state machine. In this example some helper functions and variables were added to the begin of the state machine file. More details about the offered possibilities can be found in the &lt;a href=&quot;https://www.sinelabore.com/doku.php/wiki/manual/editor&quot; class=&quot;wikilink1&quot; title=&quot;wiki:manual:editor&quot; data-wiki-id=&quot;wiki:manual:editor&quot;&gt;tutorial part I in figure 5&lt;/a&gt; . In addition is is also possible to add variables to the state machine instance type. These variables can then be used for data exchange, storing local data etc. In this example we use this possibility to store several internal variables used for the pulse detection state machine.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;The pulse detection state machine&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;the_pulse_detection_state_machine&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:3,&amp;quot;range&amp;quot;:&amp;quot;2064-4352&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit4&quot; id=&quot;the_decoder_state_machine&quot;&gt;The decoder state machine&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
The second state machine runs in the endless main loop and executes once if a pulse was detected. Initially it waits for the minute begin. Once found the state machine processes the events coming from the pulse detection machine (in opposite to the above conditional state machine). The first 20 bits contain special information and are ignored. Then once the minutes bits come the time and date information is captured and decoded. And finally the clock is set before the cycle starts again.
&lt;a href=&quot;https://www.sinelabore.com/lib/exe/detail.php/wiki/examples/dcf77_decoder.png?id=wiki%3Aexamples%3Adcf77_radio-clock_decoder&quot; class=&quot;media&quot; title=&quot;wiki:examples:dcf77_decoder.png&quot;&gt;&lt;img src=&quot;https://www.sinelabore.com/lib/exe/fetch.php/wiki/examples/dcf77_decoder.png&quot; class=&quot;medialeft&quot; align=&quot;left&quot; loading=&quot;lazy&quot; title=&quot; Decoder state machine.&quot; alt=&quot; Decoder state machine.&quot; /&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
The following code shows the main loop which only runs if a new pulse is available for processing.
The state machine uses an own event type (see below) which is filled before the machine is called.
Then the low power mode is entered again.
&lt;/p&gt;
&lt;pre class=&quot;code c&quot;&gt;    &lt;span class=&quot;kw1&quot;&gt;while&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
      _BIS_SR&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;LPM3_bits &lt;span class=&quot;sy0&quot;&gt;+&lt;/span&gt; GIE&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;                 &lt;span class=&quot;co1&quot;&gt;// Enter LPM3 &lt;/span&gt;
      __no_operation&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
      P3OUT &lt;span class=&quot;sy0&quot;&gt;|=&lt;/span&gt; &lt;span class=&quot;nu12&quot;&gt;0x8&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;                             &lt;span class=&quot;co1&quot;&gt;// set D2 debug output&lt;/span&gt;
&amp;nbsp;
      &lt;span class=&quot;co1&quot;&gt;// update event information and call the decoder&lt;/span&gt;
      decoderEvt.&lt;span class=&quot;me1&quot;&gt;msg&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; irqSM.&lt;span class=&quot;me1&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
      decoderEvt.&lt;span class=&quot;me1&quot;&gt;len&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; irqSM.&lt;span class=&quot;me1&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
      decoder&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt;decoderSM&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt;decoderEvt&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
      P3OUT &lt;span class=&quot;sy0&quot;&gt;&amp;amp;=&lt;/span&gt; ~&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;nu12&quot;&gt;0x8&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;The decoder state machine&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;the_decoder_state_machine&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:1,&amp;quot;secid&amp;quot;:4,&amp;quot;range&amp;quot;:&amp;quot;4353-5572&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit5&quot; id=&quot;event_type&quot;&gt;Event Type&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
This example presents another feature of the code generator. The state machine handler can have different signatures. Usually a pointer to the instance data and the event to process, is handed over. Here we have defined an own event type (OWN_DECODER_EVENT_T) which contains not just the event but also some data (the length of the detected pulse). 
&lt;/p&gt;

&lt;p&gt;
For this state machine handler signature:
&lt;/p&gt;
&lt;pre class=&quot;code c&quot;&gt;&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt;  decoder&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;DECODER_INSTANCEDATA_T &lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt;instanceVar&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; OWN_DECODER_EVENT_T &lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt;userData&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;...&lt;/pre&gt;

&lt;p&gt;
the following parameters must be set in the configuration file. Note: the integrated editor has as helper function to find the right parameters for you (Code→Handler Signature).
&lt;/p&gt;
&lt;pre class=&quot;code&quot;&gt;UseInstancePointer=yes
HsmFunctionWithEventParameter=yes
InlineChangeToStateCode=yes
HsmFunctionUserDefinedEventParameter=OWN_DECODER_EVENT_T&lt;/pre&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Event Type&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;event_type&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:2,&amp;quot;secid&amp;quot;:5,&amp;quot;range&amp;quot;:&amp;quot;5573-6429&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit6&quot; id=&quot;debugging_trace&quot;&gt;Debugging Trace&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
To better understand the timing of the design some debug signals are generated in the irq handler and the main loop. The following figure shows &lt;img src=&quot;https://www.sinelabore.com/lib/exe/fetch.php/wiki/examples/dcf77_debug_view.png&quot; class=&quot;mediaright&quot; align=&quot;right&quot; loading=&quot;lazy&quot; title=&quot;capture of the debug signals&quot; alt=&quot;capture of the debug signals&quot; /&gt; the generated debug signals. D0 shows a received dcf77 pulse with a len of 100ms. D0 shows the duration of the irq handler routine. And finally D2 shows the execution time of the main loop. You can see that the most time the CPU can stay in sleep mode.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Debugging Trace&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;debugging_trace&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:4,&amp;quot;secid&amp;quot;:6,&amp;quot;range&amp;quot;:&amp;quot;6430-6930&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit7&quot; id=&quot;organization_of_the_code&quot;&gt;Organization of the Code&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
Each state machine is in its own folder. Within each folder you will find the state machine model file (*.xml) and the corresponding configuration file. You can open and edit the files easily using the state machine executable (right-click on the file and open with sinelabore.exe). In the tool you can then regenerate the code in the case you made changes. In &lt;code&gt;main.c&lt;/code&gt; the board is initialised and the state machines called. 
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Organization of the Code&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;organization_of_the_code&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:4,&amp;quot;secid&amp;quot;:7,&amp;quot;range&amp;quot;:&amp;quot;6931-7396&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit8&quot; id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
This tutorial presented how to use conditional and event based state machines to realise a complete application on a small embedded system. The whole code fits in 2kB of code and 110 bytes of ram.
&lt;/p&gt;

&lt;p&gt;
The complete source code and model files are &lt;a href=&quot;https://www.sinelabore.com/lib/exe/fetch.php/wiki/examples/dcf77_ccs.zip&quot; class=&quot;media mediafile mf_zip&quot; title=&quot;wiki:examples:dcf77_ccs.zip (95.2 KB)&quot;&gt;available for download&lt;/a&gt;. Feedback is very recommended.
&lt;/p&gt;
&lt;div class=&quot;tags&quot;&gt;&lt;span&gt;
	&lt;a href=&quot;https://www.sinelabore.com/doku.php/tag/application_example?do=showtag&amp;amp;tag=%5BApplication_Example&quot; class=&quot;wikilink1&quot; title=&quot;tag:application_example&quot; rel=&quot;tag&quot;&gt;[Application Example&lt;/a&gt;,
	&lt;a href=&quot;https://www.sinelabore.com/doku.php/tag/msp430?do=showtag&amp;amp;tag=MSP430%5D&quot; class=&quot;wikilink1&quot; title=&quot;tag:msp430&quot; rel=&quot;tag&quot;&gt;MSP430]&lt;/a&gt;
&lt;/span&gt;&lt;/div&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Conclusion&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;conclusion&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:4,&amp;quot;secid&amp;quot;:8,&amp;quot;range&amp;quot;:&amp;quot;7397-&amp;quot;} --&gt;</description>
            <author>anonymous@undisclosed.example.com (Anonymous)</author>
            <pubDate>Sat, 21 Jan 2023 15:42:29 +0000</pubDate>
        </item>
        <item>
            <title>Signal Forming Function Block Design with State Diagrams</title>
            <link>https://www.sinelabore.com/doku.php/wiki/examples/function_blocks_desing</link>
            <description>
&lt;h1 class=&quot;sectionedit1&quot; id=&quot;signal_forming_function_block_design_with_state_diagrams&quot;&gt;Signal Forming Function Block Design with State Diagrams&lt;/h1&gt;
&lt;div class=&quot;level1&quot;&gt;

&lt;p&gt;
In this tutorial you will learn
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; how to use conditions to trigger state transitions in your state machine&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; how to benefit from adding attributes to a stateful class&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; using state machines to create library of reusable function blocks for control signal forming&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
In &lt;a href=&quot;https://www.sinelabore.com/doku.php/wiki/examples/plcopen_function_block&quot; class=&quot;wikilink1&quot; title=&quot;wiki:examples:plcopen_function_block&quot; data-wiki-id=&quot;wiki:examples:plcopen_function_block&quot;&gt;another example&lt;/a&gt; you can learn how to create a PLCOpen safety function block using the same concept.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Signal Forming Function Block Design with State Diagrams&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;signal_forming_function_block_design_with_state_diagrams&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:1,&amp;quot;range&amp;quot;:&amp;quot;1-488&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit2&quot; id=&quot;what_are_conditional_events&quot;&gt;What are conditional events&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
The code generator supports two basic modes of operation which should not be mixed. Either it processes events. Only if an event is present a transition is taken. Events are eventually send to the state machine using an event queue. Alternatively transitions are triggered by boolean conditions. If a boolean condition is true a state change happens. The latter one is useful if binary signals should be processed like we will see in our example. In this case the state machine runs without receiving a dedicated event but depending on state boolean state is used to trigger state transitions.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;What are conditional events&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;what_are_conditional_events&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:2,&amp;quot;range&amp;quot;:&amp;quot;489-1123&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit3&quot; id=&quot;the_problem&quot;&gt;The Problem&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
Image an embedded system - such as an industrial control device - which has several binary inputs. Often the behaviour of such a device is influenced by the state of these inputs. E.g. an actor should be switched on, a lamp should be activated etc. But often not the raw input signal should be used but a preprocessed signal such as:
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; Trigger an activity on the rising or falling edge of an input signal (ftrig, rtrig). These bocks are useful to create an event from a boolean signal.&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; Delay the input signal for some time (so called on-delay)&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; Wait until an input signal was switched off again (so called off-delay)&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; Combination of the two above (on/off delay)&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; Offering a pause input to pause the time condition of the above signals&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; Offer an option to reset a started timing&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; Shaping an input signal - i.e. creating a pulse of defined length independent from the length of the input signal&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; Debounce inputs&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
There exist many more such functions. You might have come across them in your own practise.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;The Problem&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;the_problem&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:3,&amp;quot;range&amp;quot;:&amp;quot;1124-2175&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit4&quot; id=&quot;the_solution&quot;&gt;The Solution&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
It would be very beneficial to have a library of such functions that can be easily integrated into a system design. All the above ones require some state so it makes sense of course to model them as state machines.
The design presented here is based on Enterprise Architect and uses the option to model additional attributes in the class. Such attribute are added to the instance data. It can be used for internal variables but also as interface to the outside. We will use both in the examples here. Lets start with the &lt;strong&gt;ftrig&lt;/strong&gt; and &lt;strong&gt;rtrig&lt;/strong&gt; functions first. They do not depend on time and are therefor a bit simpler to model.
&lt;/p&gt;

&lt;p&gt;
Before looking into the state machines take a look in the class diagram first. 
&lt;/p&gt;

&lt;p&gt;
&lt;a href=&quot;https://www.sinelabore.com/lib/exe/detail.php/wiki/examples/function_blocks_class_diagramm.png?id=wiki%3Aexamples%3Afunction_blocks_desing&quot; class=&quot;media&quot; title=&quot;wiki:examples:function_blocks_class_diagramm.png&quot;&gt;&lt;img src=&quot;https://www.sinelabore.com/lib/exe/fetch.php/wiki/examples/function_blocks_class_diagramm.png&quot; class=&quot;mediacenter&quot; loading=&quot;lazy&quot; title=&quot; Class diagram of the function block library&quot; alt=&quot; Class diagram of the function block library&quot; /&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
Each function is modelled as class. The classes have more or less additional attributes. All have binary signals such as &lt;em&gt;q&lt;/em&gt; (output) and &lt;em&gt;set&lt;/em&gt;. Others have also the additional binary signals &lt;em&gt;pause&lt;/em&gt; and &lt;em&gt;reset&lt;/em&gt; or variables defining the delay times. Then also internal data is modelled e.g. to store the elapsed time.
&lt;/p&gt;

&lt;p&gt;
To model attributes it is recommend to define your own data types using the &amp;#039;primate data type&amp;#039; feature of &lt;abbr title=&quot;Unified Modeling Language&quot;&gt;UML&lt;/abbr&gt;. This allows to ensure the use of a consistent set of data types with the rest of your code not modelled in &lt;abbr title=&quot;Unified Modeling Language&quot;&gt;UML&lt;/abbr&gt;. The following figure shows the model tree with the classes and data type definitions inside a common package.
&lt;a href=&quot;https://www.sinelabore.com/lib/exe/detail.php/wiki/examples/model_tree_signal_processing.png?id=wiki%3Aexamples%3Afunction_blocks_desing&quot; class=&quot;media&quot; title=&quot;wiki:examples:model_tree_signal_processing.png&quot;&gt;&lt;img src=&quot;https://www.sinelabore.com/lib/exe/fetch.php/wiki/examples/model_tree_signal_processing.png&quot; class=&quot;mediacenter&quot; loading=&quot;lazy&quot; title=&quot;Model tree with classes and data type definitions&quot; alt=&quot;Model tree with classes and data type definitions&quot; /&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;The Solution&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;the_solution&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:4,&amp;quot;range&amp;quot;:&amp;quot;2176-3781&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit5&quot; id=&quot;rtrig_and_ftrig_function&quot;&gt;RTRIG and FTRIG Function&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
The following two state diagrams show the models for the falling edge (ftrig) and the rising edge (rtrig) function. There is no time information needed. Only the status of the previous input signal. Conditional triggers are marked with a hash # as first character.
&lt;a href=&quot;https://www.sinelabore.com/lib/exe/detail.php/wiki/examples/sm_rtrig.png?id=wiki%3Aexamples%3Afunction_blocks_desing&quot; class=&quot;media&quot; title=&quot;wiki:examples:sm_rtrig.png&quot;&gt;&lt;img src=&quot;https://www.sinelabore.com/lib/exe/fetch.php/wiki/examples/sm_rtrig.png?w=600&amp;amp;tok=352682&quot; class=&quot;mediacenter&quot; loading=&quot;lazy&quot; title=&quot;rising edge state machine&quot; alt=&quot;rising edge state machine&quot; width=&quot;600&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;https://www.sinelabore.com/lib/exe/detail.php/wiki/examples/sm_ftrig.png?id=wiki%3Aexamples%3Afunction_blocks_desing&quot; class=&quot;media&quot; title=&quot;wiki:examples:sm_ftrig.png&quot;&gt;&lt;img src=&quot;https://www.sinelabore.com/lib/exe/fetch.php/wiki/examples/sm_ftrig.png?w=600&amp;amp;tok=50bfab&quot; class=&quot;mediacenter&quot; loading=&quot;lazy&quot; title=&quot;falling edge state machine&quot; alt=&quot;falling edge state machine&quot; width=&quot;600&quot; /&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;RTRIG and FTRIG Function&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;rtrig_and_ftrig_function&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:5,&amp;quot;range&amp;quot;:&amp;quot;3782-4212&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit6&quot; id=&quot;pulse_function&quot;&gt;Pulse Function&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
The single pulse function is shaping the length of an input signal to a defined pulse length at the output. It requires a notion of time. The implementation just uses the system tick to get time information and calculating the elapsed time with each call of the state machine. 
&lt;/p&gt;

&lt;p&gt;
&lt;a href=&quot;https://www.sinelabore.com/lib/exe/detail.php/wiki/examples/sm_single_pulse.png?id=wiki%3Aexamples%3Afunction_blocks_desing&quot; class=&quot;media&quot; title=&quot;wiki:examples:sm_single_pulse.png&quot;&gt;&lt;img src=&quot;https://www.sinelabore.com/lib/exe/fetch.php/wiki/examples/sm_single_pulse.png&quot; class=&quot;mediacenter&quot; loading=&quot;lazy&quot; title=&quot;Pulse former state machine&quot; alt=&quot;Pulse former state machine&quot; /&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Pulse Function&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;pulse_function&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:6,&amp;quot;range&amp;quot;:&amp;quot;4213-4586&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit7&quot; id=&quot;onoff_delay_with_pause_and_reset_inputs&quot;&gt;On/Off Delay with Pause and Reset Inputs&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
This function block is the most complex one. It requires several internal variables to store temporary information and two independent time settings. The reset and pause inputs make the function even more flexible.
&lt;/p&gt;

&lt;p&gt;
&lt;a href=&quot;https://www.sinelabore.com/lib/exe/detail.php/wiki/examples/sm_ond_offd.png?id=wiki%3Aexamples%3Afunction_blocks_desing&quot; class=&quot;media&quot; title=&quot;wiki:examples:sm_ond_offd.png&quot;&gt;&lt;img src=&quot;https://www.sinelabore.com/lib/exe/fetch.php/wiki/examples/sm_ond_offd.png&quot; class=&quot;mediacenter&quot; loading=&quot;lazy&quot; title=&quot; On/off delay state machine&quot; alt=&quot; On/off delay state machine&quot; /&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;On\/Off Delay with Pause and Reset Inputs&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;onoff_delay_with_pause_and_reset_inputs&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:7,&amp;quot;range&amp;quot;:&amp;quot;4587-4920&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit8&quot; id=&quot;generating_code&quot;&gt;Generating Code&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
To generate code from the state machine model the following command lines were used (the class path &lt;code&gt;-cp&lt;/code&gt; points to the location of the codegen.jar file):
&lt;/p&gt;
&lt;pre class=&quot;code bash&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;java&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-cp&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;../../../*&amp;quot;&lt;/span&gt; codegen.Main &lt;span class=&quot;re5&quot;&gt;-p&lt;/span&gt; ea &lt;span class=&quot;re5&quot;&gt;-t&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;Model:signal_processing:package:on_off&amp;quot;&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-o&lt;/span&gt; ton_toff signalprocessing.xmi
&lt;span class=&quot;kw2&quot;&gt;java&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-cp&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;../../../*&amp;quot;&lt;/span&gt; codegen.Main &lt;span class=&quot;re5&quot;&gt;-p&lt;/span&gt; ea &lt;span class=&quot;re5&quot;&gt;-t&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;Model:signal_processing:package:ftrig&amp;quot;&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-o&lt;/span&gt; ftrig signalprocessing.xmi
&lt;span class=&quot;kw2&quot;&gt;java&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-cp&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;../../../*&amp;quot;&lt;/span&gt; codegen.Main &lt;span class=&quot;re5&quot;&gt;-p&lt;/span&gt; ea &lt;span class=&quot;re5&quot;&gt;-t&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;Model:signal_processing:package:rtrig&amp;quot;&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-o&lt;/span&gt; rtrig signalprocessing.xmi
&lt;span class=&quot;kw2&quot;&gt;java&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-cp&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;../../../*&amp;quot;&lt;/span&gt; codegen.Main &lt;span class=&quot;re5&quot;&gt;-p&lt;/span&gt; ea &lt;span class=&quot;re5&quot;&gt;-t&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;Model:signal_processing:package:single_pulse&amp;quot;&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-o&lt;/span&gt; single_pulse signalprocessing.xmi
clang &lt;span class=&quot;re5&quot;&gt;-l&lt;/span&gt; ncurses ton_toff.c main_on_off.c &lt;span class=&quot;re5&quot;&gt;-o&lt;/span&gt; ton_toff
clang &lt;span class=&quot;re5&quot;&gt;-l&lt;/span&gt; ncurses main_rtrig.c rtrig.c &lt;span class=&quot;re5&quot;&gt;-o&lt;/span&gt; rtrig 
clang &lt;span class=&quot;re5&quot;&gt;-l&lt;/span&gt; ncurses main_ftrig.c ftrig.c &lt;span class=&quot;re5&quot;&gt;-o&lt;/span&gt; ftrig
clang &lt;span class=&quot;re5&quot;&gt;-l&lt;/span&gt; ncurses main_single_pulse.c single_pulse.c &lt;span class=&quot;re5&quot;&gt;-o&lt;/span&gt; single_pulse&lt;/pre&gt;

&lt;p&gt;
The only two additional functions that must be provided are the ones delivering the elapsed time information.
&lt;/p&gt;
&lt;pre class=&quot;code C&quot;&gt;&lt;span class=&quot;kw4&quot;&gt;uint32_t&lt;/span&gt; getSystemMilli&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;span class=&quot;kw4&quot;&gt;struct&lt;/span&gt; timeval now&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
    gettimeofday&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt;now&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; NULL&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kw1&quot;&gt;return&lt;/span&gt; now.&lt;span class=&quot;me1&quot;&gt;tv_usec&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;1000&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;+&lt;/span&gt; now.&lt;span class=&quot;me1&quot;&gt;tv_sec&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;kw4&quot;&gt;uint32_t&lt;/span&gt; getDiffMilli&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;uint32_t&lt;/span&gt; old_milli&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;span class=&quot;kw4&quot;&gt;uint32_t&lt;/span&gt; milli &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; getSystemMilli&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kw4&quot;&gt;uint32_t&lt;/span&gt; diff &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt;  milli &lt;span class=&quot;sy0&quot;&gt;-&lt;/span&gt; old_milli&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;co1&quot;&gt;//printf(&amp;quot;Milli=%d, old_milli=%d Diff=%d&amp;quot;, milli, old_milli, diff);&lt;/span&gt;
    &lt;span class=&quot;kw1&quot;&gt;return&lt;/span&gt; diff&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
That&amp;#039;s all. All the rest is generated!
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Generating Code&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;generating_code&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:8,&amp;quot;range&amp;quot;:&amp;quot;4921-6328&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit9&quot; id=&quot;testing_the_implementation&quot;&gt;Testing the Implementation&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
To test the implementations test patters were generated with which the state machines were called. The inputs and outputs of relevant signals were displayed via the curses library over time.
Some examples:
&lt;/p&gt;
&lt;pre class=&quot;code bash&quot;&gt;ton with pause  &lt;span class=&quot;re2&quot;&gt;tond&lt;/span&gt;=&lt;span class=&quot;nu0&quot;&gt;500&lt;/span&gt;, &lt;span class=&quot;re2&quot;&gt;toffd&lt;/span&gt;=&lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;
  Set:___&lt;span class=&quot;sy0&quot;&gt;***************&lt;/span&gt;_______________
Reset:_________________________________
Pause:_____&lt;span class=&quot;sy0&quot;&gt;****&lt;/span&gt;________________________
    Q:____________&lt;span class=&quot;sy0&quot;&gt;******&lt;/span&gt;_______________
&amp;nbsp;
&amp;nbsp;
ton&lt;span class=&quot;sy0&quot;&gt;/&lt;/span&gt;toff  &lt;span class=&quot;re2&quot;&gt;tond&lt;/span&gt;=&lt;span class=&quot;nu0&quot;&gt;300&lt;/span&gt;, &lt;span class=&quot;re2&quot;&gt;toffd&lt;/span&gt;=&lt;span class=&quot;nu0&quot;&gt;800&lt;/span&gt;
  Set:__&lt;span class=&quot;sy0&quot;&gt;*******&lt;/span&gt;___________&lt;span class=&quot;sy0&quot;&gt;***&lt;/span&gt;__________
Reset:_____________________&lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt;___________
Pause:_________________________________
    Q:_____&lt;span class=&quot;sy0&quot;&gt;************&lt;/span&gt;________________
&amp;nbsp;
rtrig testcase &lt;span class=&quot;nu0&quot;&gt;2&lt;/span&gt;
Set:___&lt;span class=&quot;sy0&quot;&gt;****&lt;/span&gt;__&lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt;___
  Q:___&lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt;_____&lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt;___
&amp;nbsp;
ftrig testcase &lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;
Set:___&lt;span class=&quot;sy0&quot;&gt;****&lt;/span&gt;_&lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt;__&lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt;_
  Q:_______&lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt;_&lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt;__&lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt;
&amp;nbsp;
&amp;nbsp;
single pulse &lt;span class=&quot;kw2&quot;&gt;false&lt;/span&gt; at begin
Set:___&lt;span class=&quot;sy0&quot;&gt;*************&lt;/span&gt;______&lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt;__________
  Q:___&lt;span class=&quot;sy0&quot;&gt;***&lt;/span&gt;________________&lt;span class=&quot;sy0&quot;&gt;***&lt;/span&gt;________
&amp;nbsp;
Debounce button &lt;span class=&quot;kw3&quot;&gt;test&lt;/span&gt;
 Input__&lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt;__&lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt;_&lt;span class=&quot;sy0&quot;&gt;**&lt;/span&gt;__&lt;span class=&quot;sy0&quot;&gt;****************&lt;/span&gt;_&lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt;_&lt;span class=&quot;sy0&quot;&gt;**&lt;/span&gt;_&lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt;_&lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt;___&lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt;____&lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt;__________
 Out  _____________&lt;span class=&quot;sy0&quot;&gt;*************************&lt;/span&gt;_________________
 Cnt  0011120120012345678999999997867867564201111120000000000&lt;/pre&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Testing the Implementation&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;testing_the_implementation&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:2,&amp;quot;secid&amp;quot;:9,&amp;quot;range&amp;quot;:&amp;quot;6329-7421&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit10&quot; id=&quot;final_thoughts&quot;&gt;Final Thoughts&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
State machines with conditional transitions are a powerful way to model signal forming functions. The shown approach makes reuse more easily possible within the same or further projects. In addition it has the general benefit that the model is the documentation and both is always 100% in sync with the implementation. Alone this benefit should motivate you to not write your next state based design by hand but use a modelling tool and generate the code.
&lt;/p&gt;

&lt;p&gt;
If you are interested in the complete code just send me a mail. The model files are available here:
&lt;/p&gt;

&lt;p&gt;
EA: &lt;a href=&quot;https://www.sinelabore.com/lib/exe/fetch.php/wiki/examples/ton_toff.qea.zip&quot; class=&quot;media mediafile mf_zip&quot; title=&quot;wiki:examples:ton_toff.qea.zip (119.4 KB)&quot;&gt; Enterprise Architect Model file (created with version 16)&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
UModel: &lt;a href=&quot;https://www.sinelabore.com/lib/exe/fetch.php/wiki/examples/signalprocessing.ump.zip&quot; class=&quot;media mediafile mf_zip&quot; title=&quot;wiki:examples:signalprocessing.ump.zip (15.7 KB)&quot;&gt; UModel Model file&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
Built in Editor: &lt;a href=&quot;https://www.sinelabore.com/lib/exe/fetch.php/wiki/examples/function_blocks_xml_files.zip&quot; class=&quot;media mediafile mf_zip&quot; title=&quot;wiki:examples:function_blocks_xml_files.zip (3.5 KB)&quot;&gt; Model files for the built-in state diagram editor&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
Looking forward to receive your thoughts and ideas for other useful blocks.
&lt;/p&gt;

&lt;p&gt;
~~DISCUSSION:closed|Leave your comments~~
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Final Thoughts&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;final_thoughts&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:3,&amp;quot;secid&amp;quot;:10,&amp;quot;range&amp;quot;:&amp;quot;7422-&amp;quot;} --&gt;</description>
            <author>anonymous@undisclosed.example.com (Anonymous)</author>
            <pubDate>Wed, 17 Aug 2022 17:44:10 +0000</pubDate>
        </item>
        <item>
            <title>Automatic Light Controller</title>
            <link>https://www.sinelabore.com/doku.php/wiki/examples/light_controller</link>
            <description>
&lt;h1 class=&quot;sectionedit1&quot; id=&quot;automatic_light_controller&quot;&gt;Automatic Light Controller&lt;/h1&gt;
&lt;div class=&quot;level1&quot;&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Automatic Light Controller&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;automatic_light_controller&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:1,&amp;quot;range&amp;quot;:&amp;quot;1-42&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit2&quot; id=&quot;state_machine_example&quot;&gt;State machine example&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
Everybody knows outdoor automatic light switches. They offer the comfort to automatically switch on/off the outside light. This way they even help to save energy. Other names for such a device are: motion-activated (or motion-sensing) porchlight, dusk-to-dawn sensor porchlight
&lt;/p&gt;

&lt;p&gt;
The following figure shows a simplified state machine of such a device.
&lt;/p&gt;

&lt;p&gt;
&lt;img src=&quot;https://www.sinelabore.com/lib/exe/fetch.php/wiki/examples/simplified_light_controller.png&quot; class=&quot;mediacenter&quot; loading=&quot;lazy&quot; alt=&quot;&quot; /&gt;
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;State machine example&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;state_machine_example&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:2,&amp;quot;range&amp;quot;:&amp;quot;43-488&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit3&quot; id=&quot;functional_requirements&quot;&gt;Functional Requirements&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
The device has three modes which can be changed using a simple switch. It has the positions &lt;code&gt;OFF&lt;/code&gt;, &lt;code&gt;Auto&lt;/code&gt; and &lt;code&gt;ON&lt;/code&gt;. The switch is realized in a way that the user can only go from &lt;code&gt;OFF&lt;/code&gt; to &lt;code&gt;AUTO&lt;/code&gt; to &lt;code&gt;ON&lt;/code&gt; and vice versa.
&lt;/p&gt;

&lt;p&gt;
In &lt;code&gt;ON&lt;/code&gt; mode the light is permanently switched on. In &lt;code&gt;OFF&lt;/code&gt; mode the light is permanently switched off. In &lt;code&gt;Auto&lt;/code&gt; the light is automatically switched on and off as described in the next section.
&lt;/p&gt;

&lt;p&gt;
When its becoming dark and the auto mode is active the device automatically switches on the light if a person is detected. If the person walks away the light is switched off again. The light is on for at least a configurable time (e.g. 60s). If the person is still nearby after that time the light is kept on as long as no person can be detected anymore.
&lt;/p&gt;

&lt;p&gt;
The light should not be switched on during daylight. Therefore the device permanently measures the ambient brightness. Only if the measured value is below an adjustable threshold the device switches on the light automatically.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Functional Requirements&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;functional_requirements&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:3,&amp;quot;range&amp;quot;:&amp;quot;489-1541&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit4&quot; id=&quot;state_machine_design&quot;&gt;State Machine Design&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
The three modes of the device can be easily transferred into states. The auto state is a hierarchical state which realizes the night/day behavior when a person was detected. The design was created using the  SinelaboreRT state machine editor. The diagram is shown in the figure above.
&lt;/p&gt;

&lt;p&gt;
The &lt;a href=&quot;https://www.sinelabore.com/lib/exe/fetch.php/wiki/examples/automatic_light.zip&quot; class=&quot;media mediafile mf_zip&quot; title=&quot;wiki:examples:automatic_light.zip (17.4 KB)&quot;&gt;automatic light controller&lt;/a&gt; zip files contains the fully worked out example with a simple text based command interface. Start the executable and type in one of the supported letters to trigger the machine.
&lt;/p&gt;

&lt;p&gt;
Available commands:
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;code&gt;+&lt;/code&gt; There is a person&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;code&gt;-&lt;/code&gt; There is no person&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;code&gt;t&lt;/code&gt; Ambient brightness low (twilight, night)&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;code&gt;d&lt;/code&gt; Ambient brightness high (dawn, day)&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;code&gt;a&lt;/code&gt; Auto mode&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;code&gt;o&lt;/code&gt; Permanent on&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;code&gt;x&lt;/code&gt; Permanent off&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;code&gt;q&lt;/code&gt; Quit the program&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
The files &lt;code&gt;gui.c/h&lt;/code&gt; realizes the keyboard handling. In the file  light_trace.c a simple trace function was realized to trace the event flow. Main.c calls the state machine and checks the keyboard for new events. All other files are automatically generated from the state machine as shown above.
&lt;/p&gt;

&lt;p&gt;
To test the machine type in e.g.:   &lt;code&gt;o   x   a   t  +  … (repeat 20 times) +  -&lt;/code&gt;
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;State Machine Design&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;state_machine_design&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:4,&amp;quot;range&amp;quot;:&amp;quot;1542-2764&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit5&quot; id=&quot;graphical_trace&quot;&gt;Graphical Trace&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
The sinelaboreRT codegen tool is able to display state diagrams based on an automatic layout engine. In simulation mode trace data can be received via a UDP connection. The received evens are then used to trigger the same state changes as in the compiled C program. This makes it possible to follow the state changes of the light.exe program while we stimulate it with the keyboard events.
&lt;/p&gt;

&lt;p&gt;
The prepared example already sends the trace data via UDP (see light_trace.c).  To display the state machine start the editor in simulation mode as follows:
&lt;/p&gt;
&lt;pre class=&quot;code bash&quot;&gt;&lt;span class=&quot;co4&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;java&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-jar&lt;/span&gt; codegen.jar &lt;span class=&quot;re5&quot;&gt;-p&lt;/span&gt; ssc &lt;span class=&quot;re5&quot;&gt;-S&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-o&lt;/span&gt; automatic_light.xml automatic_light.xml&lt;/pre&gt;

&lt;p&gt;
This command line brings up a window showing the state machine&lt;sup&gt;&lt;a href=&quot;#fn__1&quot; id=&quot;fnt__1&quot; class=&quot;fn_top&quot;&gt;1)&lt;/a&gt;&lt;/sup&gt;. Start the light executable again and type in commands. You can now follow the current state of the state machine and the C-code executed as reaction to your keyboard input.
&lt;/p&gt;

&lt;p&gt;
The ZIP file contains an executable that was built with Cygwin on Windows (light.exe) and for &lt;abbr title=&quot;Operating System&quot;&gt;OS&lt;/abbr&gt; X (light_osx). To change the state machine or to generate the code yourself download the demo version of the Sinelabore code generator.
&lt;/p&gt;

&lt;p&gt;
Have fun!
&lt;/p&gt;

&lt;p&gt;
~~DISCUSSION|Leave your comments~~
&lt;/p&gt;
&lt;div class=&quot;tags&quot;&gt;&lt;span&gt;
	&lt;a href=&quot;https://www.sinelabore.com/doku.php/tag/application_example?do=showtag&amp;amp;tag=%5BApplication_Example%5D&quot; class=&quot;wikilink1&quot; title=&quot;tag:application_example&quot; rel=&quot;tag&quot;&gt;[Application Example]&lt;/a&gt;
&lt;/span&gt;&lt;/div&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Graphical Trace&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;graphical_trace&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:5,&amp;quot;range&amp;quot;:&amp;quot;2765-&amp;quot;} --&gt;&lt;div class=&quot;footnotes&quot;&gt;
&lt;div class=&quot;fn&quot;&gt;&lt;sup&gt;&lt;a href=&quot;#fnt__1&quot; id=&quot;fn__1&quot; class=&quot;fn_bot&quot;&gt;1)&lt;/a&gt;&lt;/sup&gt; 
&lt;div class=&quot;content&quot;&gt;Make sure graphviz is installed on your system and the correct path to the dot.exe (layout engine) is defined in the codegen.cfg file. Otherwise you will get an error message when starting the codegen in simulation mode.&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
</description>
            <author>anonymous@undisclosed.example.com (Anonymous)</author>
            <pubDate>Mon, 09 Dec 2019 19:00:29 +0000</pubDate>
        </item>
        <item>
            <title>ASURO programming using state diagrams</title>
            <link>https://www.sinelabore.com/doku.php/wiki/examples/mobile_robot_i</link>
            <description>
&lt;h1 class=&quot;sectionedit1&quot; id=&quot;asuro_programming_using_state_diagrams&quot;&gt;ASURO programming using state diagrams&lt;/h1&gt;
&lt;div class=&quot;level1&quot;&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;ASURO programming using state diagrams&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;asuro_programming_using_state_diagrams&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:1,&amp;quot;range&amp;quot;:&amp;quot;1-55&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit2&quot; id=&quot;state_diagrams_describe_behaviour&quot;&gt;State diagrams describe behaviour!&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
Watch the short video above. It shows a little mobile robot (ASURO&lt;sup&gt;&lt;a href=&quot;#fn__1&quot; id=&quot;fnt__1&quot; class=&quot;fn_top&quot;&gt;1)&lt;/a&gt;&lt;/sup&gt;) exploring its environment. Consider how the exploration algorithm might work …
&lt;/p&gt;
&lt;iframe src=&quot;//www.youtube-nocookie.com/embed/pIpuR_LlwY4?&quot; width=&quot;425&quot; height=&quot;239&quot; style=&quot;width:425px;height:239px;&quot; class=&quot;vshare vshare__center&quot; allowfullscreen=&quot;&quot; frameborder=&quot;0&quot; scrolling=&quot;no&quot; data-domain=&quot;www.youtube-nocookie.com&quot; loading=&quot;lazy&quot;&gt;&lt;h3&gt;&lt;/h3&gt;&lt;/iframe&gt;
&lt;p&gt;
The diagram below shows the state chart of the software running on the robot. If you examine the diagram you can clearly understand what is happening why. This is the first major benefit of state diagrams. State diagrams are perfect to fully describe reactive systems.
&lt;/p&gt;

&lt;p&gt;
Ok - does this diagram really describes the software or is it just an early design sketch which is not valid anymore because it was never updated after coding has started? 
&lt;/p&gt;

&lt;p&gt;
To make sure that this does not happen the code running on the robot was directly generated from the state diagram. This is the second major benefit. State diagrams are perfect to fully describe reactive systems and generate code out of them. If you are interested in the ASURO code just send us a mail.
&lt;/p&gt;

&lt;p&gt;
&lt;img src=&quot;https://www.sinelabore.com/lib/exe/fetch.php/wiki/articles/asuro_sm.jpg&quot; class=&quot;mediacenter&quot; loading=&quot;lazy&quot; alt=&quot;&quot; /&gt;
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;State diagrams describe behaviour!&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;state_diagrams_describe_behaviour&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:2,&amp;quot;range&amp;quot;:&amp;quot;56-1323&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit3&quot; id=&quot;whats_going_on_in_the_robot&quot;&gt;Whats going on in the robot?&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
Debugging an application that is based on generated code from a state diagram is a bit different compared to debugging hand written state machine code. Why? Because you can assume that the generated code is correct. You don’t have to worry about all the nitty gritty details of the realisation of a state machine in C (e.g. handling history, handling hierarchical designs, placement of entry/exit …). If the machine does not what it should do then most probably the model is not correct. To track down the problem - especially in deeply embedded real-time systems - typically means to add a tracing mechanism which allows you see which events do fire etc. Here the code generator can support you.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Whats going on in the robot?&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;whats_going_on_in_the_robot&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:3,&amp;quot;range&amp;quot;:&amp;quot;1324-2065&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit4&quot; id=&quot;automatic_generation_of_trace_code&quot;&gt;Automatic generation of trace code&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
The code generator can add trace code automatically. You only have to call the generator with the -Trace command line switch. In this case calls to a trace function are inserted in the generated code. The argument of the trace function is the processed event. A part of the ASURO state machine is displayed below. For every handled event the trace function is called (e.g. xxxTraceEvent(2U)). If the trace code is not anymore needed just call the codegenerator again without the -Trace option.
&lt;/p&gt;
&lt;pre class=&quot;code c&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;case&lt;/span&gt; EXPLORE&lt;span class=&quot;sy0&quot;&gt;:&lt;/span&gt;
&amp;nbsp;
	&lt;span class=&quot;kw1&quot;&gt;switch&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;instanceVar&lt;span class=&quot;sy0&quot;&gt;-&amp;gt;&lt;/span&gt;stateVarEXPLORE&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
&amp;nbsp;
		&lt;span class=&quot;coMULTI&quot;&gt;/*
		  Code for transitions starting from inner states
		 */&lt;/span&gt;
		&lt;span class=&quot;kw1&quot;&gt;case&lt;/span&gt; AHEAD&lt;span class=&quot;sy0&quot;&gt;:&lt;/span&gt;
			&lt;span class=&quot;coMULTI&quot;&gt;/* action code  */&lt;/span&gt;
			flag&lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt;drive&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;speed&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;FWD&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;flag&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
			&lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;usDist&lt;span class=&quot;sy0&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
				behaviourTraceEvent&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;2U&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
				&lt;span class=&quot;coMULTI&quot;&gt;/*Transition from AHEAD to AHEAD_WITH_BARR */&lt;/span&gt;
				evConsumed&lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt;16U&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
				&lt;span class=&quot;coMULTI&quot;&gt;/*Action code for transition */&lt;/span&gt;
				flag&lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;speed&lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;80&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt; StatusLED&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;RED&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
				instanceVar&lt;span class=&quot;sy0&quot;&gt;-&amp;gt;&lt;/span&gt;stateVarEXPLORE&lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt;AHEAD_WITH_BARR&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
			&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span class=&quot;kw1&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;msg&lt;span class=&quot;sy0&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;BEHAVIOUR_EVENT_T&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;evTimeoutT0&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
				behaviourTraceEvent&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;0U&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
				&lt;span class=&quot;coMULTI&quot;&gt;/*Transition from AHEAD to IDLE3 */&lt;/span&gt;
				evConsumed&lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt;1U&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
				&lt;span class=&quot;coMULTI&quot;&gt;/*onEntry code of state IDLE3 */&lt;/span&gt;
				startTimer&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;TIMER0&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;MotorSpeed&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
				instanceVar&lt;span class=&quot;sy0&quot;&gt;-&amp;gt;&lt;/span&gt;stateVarEXPLORE&lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt;IDLE3&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
			&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
			&lt;span class=&quot;kw1&quot;&gt;else&lt;/span&gt;
			&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
				&lt;span class=&quot;coMULTI&quot;&gt;/* Intentionally left blank  */&lt;/span&gt;
			&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
		&lt;span class=&quot;kw2&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
                ...&lt;/pre&gt;

&lt;p&gt;
If tracing is enabled an additional header file is generated which provides a table to map event ids to event strings. E.g. the argument 2U from above corresponds to the second entry in the table. This allows you to easily display the event as text.
&lt;/p&gt;
&lt;pre class=&quot;code c&quot;&gt;&lt;span class=&quot;kw4&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kw4&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;kw4&quot;&gt;const&lt;/span&gt; behaviourTraceEvents&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
	&lt;span class=&quot;st0&quot;&gt;&amp;quot;evTimeoutT0&amp;quot;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;st0&quot;&gt;&amp;quot;turned==1&amp;quot;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;st0&quot;&gt;&amp;quot;usDist&amp;lt;15&amp;quot;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;st0&quot;&gt;&amp;quot;usDist&amp;gt;30&amp;quot;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;st0&quot;&gt;&amp;quot;evKey&amp;quot;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
The trace function must be provided by yourself. Within the trace function you can decide now what to do with this trace information.
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; store it in a ring buffer and read it out later (post mortem)&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; display it somehow&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; forward it to a monitoring station&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; …&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
The following code was used on the ASURO robot and simply sends the processed event to a monitoring PC.
&lt;/p&gt;
&lt;pre class=&quot;code c&quot;&gt;&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt; behaviourTraceEvent&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;BEHAVIOUR_EVENT_T evt&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
	SerPrint&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;behaviourTraceEvents&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;evt&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
	crlf&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
On the PC it is now possible to watch the event flow in a terminal window.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Automatic generation of trace code&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;automatic_generation_of_trace_code&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:4,&amp;quot;range&amp;quot;:&amp;quot;2066-4358&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit5&quot; id=&quot;watching_events_in_a_terminal_is_not_good_enough&quot;&gt;Watching events in a terminal is not good enough&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
Watching events in a terminal window is not bad but sinelaboreRT can do even better. When starting the codegen.jar with the -S command line switch an interactive graphical simulation window pops up. The status of the state machine after startup is displayed. The events that can be handled presently are shown in blue and are also listed in left window. The output window shows the executed statemachine code. You can now send events to the machine by clicking on an event. The display is updated accordingly and shows the new status.
&lt;/p&gt;

&lt;p&gt;
&lt;img src=&quot;https://www.sinelabore.com/lib/exe/fetch.php/wiki/articles/asuro_simulator.png&quot; class=&quot;mediacenter&quot; loading=&quot;lazy&quot; alt=&quot;&quot; /&gt;
&lt;/p&gt;

&lt;p&gt;
Beside the interactive mode it is possible to send events via an UPD port. This is what we show next. A small application receives the events sent from the ASURO robot over a wireless serial link and translates it into a UDP message (see diagram below). The UDP message is received from the simulator and the display is updated accordingly. Click on the simulation image above and watch how the state diagram is updated while ASURO is exploring its environment.
&lt;/p&gt;

&lt;p&gt;
&lt;img src=&quot;https://www.sinelabore.com/lib/exe/fetch.php/wiki/articles/asuro_sim_diagram.png&quot; class=&quot;mediacenter&quot; loading=&quot;lazy&quot; alt=&quot;&quot; /&gt;
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Watching events in a terminal is not good enough&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;watching_events_in_a_terminal_is_not_good_enough&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:3,&amp;quot;secid&amp;quot;:5,&amp;quot;range&amp;quot;:&amp;quot;4359-5519&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit6&quot; id=&quot;summary&quot;&gt;Summary&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
The sinelaboreRT code generator provides several mechanisms to support you during debugging and testing of your state machine design.
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; It can automatically add trace code to the state machine&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; It provides an interactive simulation window which can display the status of your  embedded target in real-time.&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; With the UPD/IP interface a flexible mechanism is available to use the communication interface your hardware offers. A simple “event forwarder” is all what you need.&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
~~DISCUSSION:closed|Leave your comments~~
&lt;/p&gt;
&lt;div class=&quot;tags&quot;&gt;&lt;span&gt;
	&lt;a href=&quot;https://www.sinelabore.com/doku.php/tag/application_example?do=showtag&amp;amp;tag=%5BApplication_Example&quot; class=&quot;wikilink1&quot; title=&quot;tag:application_example&quot; rel=&quot;tag&quot;&gt;[Application Example&lt;/a&gt;,
	&lt;a href=&quot;https://www.sinelabore.com/doku.php/tag/asuro?do=showtag&amp;amp;tag=Asuro%5D&quot; class=&quot;wikilink1&quot; title=&quot;tag:asuro&quot; rel=&quot;tag&quot;&gt;Asuro]&lt;/a&gt;
&lt;/span&gt;&lt;/div&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Summary&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;summary&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:3,&amp;quot;secid&amp;quot;:6,&amp;quot;range&amp;quot;:&amp;quot;5520-&amp;quot;} --&gt;&lt;div class=&quot;footnotes&quot;&gt;
&lt;div class=&quot;fn&quot;&gt;&lt;sup&gt;&lt;a href=&quot;#fnt__1&quot; id=&quot;fn__1&quot; class=&quot;fn_bot&quot;&gt;1)&lt;/a&gt;&lt;/sup&gt; 
&lt;div class=&quot;content&quot;&gt;Want to know more about this robot called ASURO? ASURO is a small, freely in C programmable mobile robot kit which has been developed for educational use especially in the &lt;a href=&quot;http://www.dlr.de/rm/desktopdefault.aspx/tabid-3848/&quot; class=&quot;urlextern&quot; title=&quot;http://www.dlr.de/rm/desktopdefault.aspx/tabid-3848/&quot; rel=&quot;ugc nofollow&quot;&gt;DLR School Lab&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
</description>
            <author>anonymous@undisclosed.example.com (Anonymous)</author>
            <pubDate>Sat, 08 Feb 2020 15:51:50 +0000</pubDate>
        </item>
        <item>
            <title>Getting started with the PIC16F18446 and State Machines</title>
            <link>https://www.sinelabore.com/doku.php/wiki/examples/pic_tutorial</link>
            <description>
&lt;h1 class=&quot;sectionedit1&quot; id=&quot;getting_started_with_the_pic16f18446_and_state_machines&quot;&gt;Getting started with the PIC16F18446 and State Machines&lt;/h1&gt;
&lt;div class=&quot;level1&quot;&gt;

&lt;p&gt;
This tutorial explains the use of state machines with the &lt;a href=&quot;https://www.microchip.com/DevelopmentTools/ProductDetails/DM164144&quot; class=&quot;urlextern&quot; title=&quot;https://www.microchip.com/DevelopmentTools/ProductDetails/DM164144&quot; rel=&quot;ugc nofollow&quot;&gt;PIC16F18446 Curiosity Nano&lt;/a&gt; board. It provides 2k of RAM and 16k program memory. More than enought for this small tutorial.
&lt;/p&gt;

&lt;p&gt;
&lt;a href=&quot;https://www.sinelabore.com/lib/exe/detail.php/wiki/news/pic16f18446.png?id=wiki%3Aexamples%3Apic_tutorial&quot; class=&quot;media&quot; title=&quot;wiki:news:pic16f18446.png&quot;&gt;&lt;img src=&quot;https://www.sinelabore.com/lib/exe/fetch.php/wiki/news/pic16f18446.png&quot; class=&quot;mediacenter&quot; loading=&quot;lazy&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;
(Source: Microchip)
&lt;/p&gt;

&lt;p&gt;
Install the required software if you want to follow all steps yourself. Otherwise just go on reading.
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;https://www.oracle.com/technetwork/java/javase/downloads/index.html&quot; class=&quot;urlextern&quot; title=&quot;https://www.oracle.com/technetwork/java/javase/downloads/index.html&quot; rel=&quot;ugc nofollow&quot;&gt;Java installation&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;https://www.microchip.com/mplab/mplab-x-ide&quot; class=&quot;urlextern&quot; title=&quot;https://www.microchip.com/mplab/mplab-x-ide&quot; rel=&quot;ugc nofollow&quot;&gt;MPLab X IDE&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;https://www.sinelabore.com/doku.php/wiki/download&quot; class=&quot;wikilink1&quot; title=&quot;wiki:download&quot; data-wiki-id=&quot;wiki:download&quot;&gt;Sinelabore demo&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;https://graphviz.gitlab.io/download/&quot; class=&quot;urlextern&quot; title=&quot;https://graphviz.gitlab.io/download/&quot; rel=&quot;ugc nofollow&quot;&gt;Graphviz (for editing the state machine)&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
For this tutorial we will use just the push botton and the LED on the board. So you can follow it without any additional hardware required. The LED shall blink all the time. The frequency can be changed from slow to fast by pressing the button. Simple enough but sufficient to show all the key concepts we are going to use.
&lt;/p&gt;

&lt;p&gt;
The PINs are allocated using the MPLAP X IDE Resource Manager as well as the 4MHz system clock and the 10ms Timer0. I&amp;#039;ve not used this configurator before. But have to say that it is a very convinient way to setup the hardware. I would wish to have the same for the MSP430 μCs I also often use.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Getting started with the PIC16F18446 and State Machines&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;getting_started_with_the_pic16f18446_and_state_machines&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:1,&amp;quot;range&amp;quot;:&amp;quot;1-1385&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit2&quot; id=&quot;step_1_-_deciding_the_system_architecture&quot;&gt;Step 1 - Deciding the system architecture&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
For small systems e.g. sensor nodes it is usually sufficient use a main loop design. The main loop cycles endlessly and waits for events. Events are benefitially stored in an event queue. The queue is filled from timer events, other state machines (cooperating machines) or interrupt handlers. If events are available the state machine(s) are called from the main loop to process them.
&lt;/p&gt;

&lt;p&gt;
In our little example events are sent from the keyboad interrupt and from a software timer module which is called regulary from the cyclic hardware timer. The following figure shows the system architecture.
&lt;/p&gt;

&lt;p&gt;
&lt;a href=&quot;https://www.sinelabore.com/lib/exe/detail.php/wiki/mainloop_ext.png?id=wiki%3Aexamples%3Apic_tutorial&quot; class=&quot;media&quot; title=&quot;wiki:mainloop_ext.png&quot;&gt;&lt;img src=&quot;https://www.sinelabore.com/lib/exe/fetch.php/wiki/mainloop_ext.png?w=400&amp;amp;tok=59ea17&quot; class=&quot;mediaright&quot; align=&quot;right&quot; loading=&quot;lazy&quot; alt=&quot;&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
The below code snippets show the irq handlers and the main loop processing the evens.
&lt;/p&gt;
&lt;pre class=&quot;code c&quot;&gt;&lt;span class=&quot;co1&quot;&gt;// cyclic timer interrupt&lt;/span&gt;
&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt; TMR0_IRQHandler&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
    tick&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;co1&quot;&gt;// if a timer has fired this function stores a timer event in the message queue&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;co1&quot;&gt;// keyboard interrupt&lt;/span&gt;
&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt; SW0_IRQHandler&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
    fifoPut&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt;fifo&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;evKey&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt; main&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
    ...
&amp;nbsp;
    &lt;span class=&quot;kw1&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
	&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
        &lt;span class=&quot;kw1&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
            &lt;span class=&quot;co1&quot;&gt;// check if there are one or more events in the queue.&lt;/span&gt;
            &lt;span class=&quot;co1&quot;&gt;// if yes, process all events in the state machine&lt;/span&gt;
            retVal &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; fifoGet&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt;fifo&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt;bufVal&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;retVal &lt;span class=&quot;sy0&quot;&gt;!=&lt;/span&gt; QUEUE_EMPTY&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
                sm&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt;instData&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; bufVal&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
        &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;retVal &lt;span class=&quot;sy0&quot;&gt;!=&lt;/span&gt; QUEUE_EMPTY&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
        __delay_ms&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;10U&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
In the library folder (see project tree below) the required timer and fifo files are provided. They can easily reused also with other Controller types. I used them in several MSP430 projects before.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Step 1 - Deciding the system architecture&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;step_1_-_deciding_the_system_architecture&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:2,&amp;quot;range&amp;quot;:&amp;quot;1386-3001&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit3&quot; id=&quot;step_2_-_realizing_the_state_machine&quot;&gt;Step 2 - Realizing the state machine&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
So far we have not seen how the state machine looks like. To realize this simple job just two evens are reqired. 
- &lt;em&gt;evKey&lt;/em&gt;: Indicates that the user pressed the switch
- &lt;em&gt;evTimeout&lt;/em&gt;: Indicating that it is time to toggle the LED 
&lt;/p&gt;

&lt;p&gt;
For this simpel state machine the editor which is built into the code generator is sufficient. For more complex machines is is recommended to use an advanced &lt;abbr title=&quot;Unified Modeling Language&quot;&gt;UML&lt;/abbr&gt; modelling tool of your choice. See the list of  &lt;a href=&quot;https://www.sinelabore.com/doku.php/wiki/tools/supported_uml_tools&quot; class=&quot;wikilink1&quot; title=&quot;wiki:tools:supported_uml_tools&quot; data-wiki-id=&quot;wiki:tools:supported_uml_tools&quot;&gt;supported tools&lt;/a&gt; here. The next figure shows the complete state machine:
&lt;/p&gt;

&lt;p&gt;
&lt;a href=&quot;https://www.sinelabore.com/lib/exe/detail.php/wiki/examples/pic_example_sm.png?id=wiki%3Aexamples%3Apic_tutorial&quot; class=&quot;media&quot; title=&quot;wiki:examples:pic_example_sm.png&quot;&gt;&lt;img src=&quot;https://www.sinelabore.com/lib/exe/fetch.php/wiki/examples/pic_example_sm.png?w=400&amp;amp;tok=f6122f&quot; class=&quot;medialeft&quot; align=&quot;left&quot; loading=&quot;lazy&quot; alt=&quot;&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;
Initally the state machine enters the state &lt;em&gt;Slow&lt;/em&gt;. The initial transition triggers the start of the timer with timeout time 10U (&lt;em&gt;10U&lt;/em&gt; represents 10 times the base clock of the hardware interrupt (i.e. 100ms)). Then the machine waits for further events. Every time event &lt;em&gt;evTimeout&lt;/em&gt; occures there is a self transition and as action the LED is toggeled.
&lt;/p&gt;

&lt;p&gt;
In case &lt;em&gt;evKey&lt;/em&gt; occures a state transitions from state &lt;em&gt;Slow&lt;/em&gt; to state &lt;em&gt;Fast&lt;/em&gt; and vice versa is triggered and the timeout time is updated. 
&lt;/p&gt;

&lt;p&gt;
Example action code for the transition going from state &lt;em&gt;Slow&lt;/em&gt; to state &lt;em&gt;Fast&lt;/em&gt;.
&lt;/p&gt;
&lt;pre class=&quot;code c&quot;&gt;timerStop&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;timer_id&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
timerStart&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;timer_id&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; 10U&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Step 2 - Realizing the state machine&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;step_2_-_realizing_the_state_machine&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:1,&amp;quot;secid&amp;quot;:3,&amp;quot;range&amp;quot;:&amp;quot;3002-4304&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit4&quot; id=&quot;step_3_-_integrating_the_state_machine_in_mplab_x&quot;&gt;Step 3 - Integrating the state machine in MPLAB X&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
The generated state machine code files can be easily added to the PIC project. It is recommended to create a new folder e.g. called &lt;code&gt;state_machine_generated_files&lt;/code&gt;.  All state machine related files go in there. &lt;code&gt;sm.scc&lt;/code&gt; contains the state machine model. &lt;code&gt;sm.c/h&lt;/code&gt; contains the generated state machine code.
&lt;/p&gt;

&lt;p&gt;
The following figure shows the project tree with all generated files.
&lt;a href=&quot;https://www.sinelabore.com/lib/exe/detail.php/wiki/examples/pic_example_tree.png?id=wiki%3Aexamples%3Apic_tutorial&quot; class=&quot;media&quot; title=&quot;wiki:examples:pic_example_tree.png&quot;&gt;&lt;img src=&quot;https://www.sinelabore.com/lib/exe/fetch.php/wiki/examples/pic_example_tree.png?w=400&amp;amp;tok=39600d&quot; class=&quot;media&quot; loading=&quot;lazy&quot; alt=&quot;&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
To convienently edit the state machine model and generate code from it two batch files were created. 
Call &lt;code&gt;edit.bat&lt;/code&gt; to start up the editor. And call &lt;code&gt;gen.bat&lt;/code&gt; to generate the code. The generated files start all with the prefix &lt;code&gt;sm_&lt;/code&gt; (see command line). The output when calling &lt;code&gt;gen.bat&lt;/code&gt; is shown below. 
&lt;/p&gt;
&lt;pre class=&quot;code&quot;&gt;C:\Users\PM\develop\microchip\blink.X\state_machine_generated_files&amp;gt;java -Djava.ext.dirs=C:\Users\PM\Desktop\sinelaborert\bin\ -jar C:\Users\PM\Desktop\sinelaborert\bin\codegen.jar -p ssc -l cx -o sm sm.scc
Starting robustness tests of state machine ...
State names: ..............
Machine hierarchy: ........
Machine height = 1
Transitions: ..............
Default states: ...........
Final states: .............
Choices: ..................
No. of children in composites: ...
Connectivity of states: ...&lt;/pre&gt;

&lt;p&gt;
The code generator needs a configuration file to set basic parameters. Take a look into the configuration
file and read the &lt;a href=&quot;https://www.sinelabore.com/lib/exe/fetch.php/wiki/downloads/sinelaborert.pdf&quot; class=&quot;media mediafile mf_pdf&quot; title=&quot;wiki:downloads:sinelaborert.pdf (6.9 MB)&quot;&gt;Manual&lt;/a&gt; if the meaning of the parameters is not clear.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Step 3 - Integrating the state machine in MPLAB X&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;step_3_-_integrating_the_state_machine_in_mplab_x&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:2,&amp;quot;secid&amp;quot;:4,&amp;quot;range&amp;quot;:&amp;quot;4305-5846&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit5&quot; id=&quot;wrapup&quot;&gt;Wrapup&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
The chosen system architecture with state machines, an event queue and software timers is very
powerful. It is proven in praxis since many years and used sucessfully in many projects. Quite complex
systems can be built this way and no &lt;abbr title=&quot;Real-Time Operating System&quot;&gt;RTOS&lt;/abbr&gt; is requrid. It can be expaned easily by adding additional state
machines and by using more than one software timer.
&lt;/p&gt;

&lt;p&gt;
Use the example and expand it to learn. To receive a copy just send a mail.
&lt;/p&gt;

&lt;p&gt;
Hope you like the tutorial
&lt;/p&gt;

&lt;p&gt;
Have fun
&lt;/p&gt;

&lt;p&gt;
Peter
&lt;/p&gt;

&lt;p&gt;
~~DISCUSSION:closed|Leave your comments~~
&lt;/p&gt;
&lt;div class=&quot;tags&quot;&gt;&lt;span&gt;
	&lt;a href=&quot;https://www.sinelabore.com/doku.php/tag/pic?do=showtag&amp;amp;tag=%5BPIC&quot; class=&quot;wikilink1&quot; title=&quot;tag:pic&quot; rel=&quot;tag&quot;&gt;[PIC&lt;/a&gt;,
	&lt;a href=&quot;https://www.sinelabore.com/doku.php/tag/application_example?do=showtag&amp;amp;tag=Application_Example%5D&quot; class=&quot;wikilink1&quot; title=&quot;tag:application_example&quot; rel=&quot;tag&quot;&gt;Application Example]&lt;/a&gt;
&lt;/span&gt;&lt;/div&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Wrapup&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;wrapup&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:3,&amp;quot;secid&amp;quot;:5,&amp;quot;range&amp;quot;:&amp;quot;5847-&amp;quot;} --&gt;</description>
            <author>anonymous@undisclosed.example.com (Anonymous)</author>
            <pubDate>Wed, 17 Aug 2022 17:43:46 +0000</pubDate>
        </item>
        <item>
            <title>Safety Function Block</title>
            <link>https://www.sinelabore.com/doku.php/wiki/examples/plcopen_function_block</link>
            <description>
&lt;h1 class=&quot;sectionedit1&quot; id=&quot;safety_function_block&quot;&gt;Safety Function Block&lt;/h1&gt;
&lt;div class=&quot;level1&quot;&gt;

&lt;p&gt;
The &lt;a href=&quot;http://www.plcopen.org&quot; class=&quot;urlextern&quot; title=&quot;http://www.plcopen.org&quot; rel=&quot;ugc nofollow&quot;&gt; PLCOpen&lt;/a&gt; organization has defined a set of standard function blocks (FB) for safety-related functionality. The function block specifications are given as state diagrams. The example presented here realizes the equivalent function block. 
&lt;/p&gt;

&lt;p&gt;
&lt;img src=&quot;https://www.sinelabore.com/lib/exe/fetch.php/wiki/examples/sf_equivalent.jpg&quot; class=&quot;mediacenter&quot; loading=&quot;lazy&quot; alt=&quot;&quot; /&gt;
&lt;/p&gt;

&lt;p&gt;
According to the PLCopen specification this function block converts two equivalent SAFEBOOL inputs to one SAFEBOOL output with discrepancy time monitoring. If one channel signal changes from TRUE to FALSE the output immediately switches off (FALSE) for safety reasons. Discrepancy time monitoring: The discrepancy time is the maximum period during which both inputs may have different states without the function block detecting an error. Discrepancy time monitoring starts when the status of an input changes. The function block detects an error when both inputs do not have the same status once the discrepancy time has elapsed.
&lt;/p&gt;

&lt;p&gt;
The machine presented below is a sample realization of the state diagram specified in the PLCopen document. In opposite to the original PLCopen specification all states - which set the READY output to TRUE - are sub-states of the superstate called ACTIVE. As soon as the ENABLE input becomes inactive the ACTIVE state is left and IDLE will be entered. Using sub-states reduces the number of required transitions in the diagram a lot.
&lt;/p&gt;

&lt;p&gt;
&lt;img src=&quot;https://www.sinelabore.com/lib/exe/fetch.php/wiki/examples/state_chart_equ.jpg&quot; class=&quot;mediacenter&quot; loading=&quot;lazy&quot; alt=&quot;&quot; /&gt;
&lt;/p&gt;

&lt;p&gt;
The class diagram below shows how the sample implementation is designed. The class &lt;code&gt;io_interface&lt;/code&gt; provides a hardware abstraction layer to the inputs and outputs required by the function block. The &lt;code&gt;timer&lt;/code&gt; class provides general timer functions. Please note that it is only good enough to test the state machine. Classes are realized as C/H-Files. The class diagram shows two comments using the action and header keywords which are supported from the code generator. C-code in the „action comment“ is copied into the C-file just before the state-chart code. The listed C-code reads and stores the function block inputs in local variables for faster processing. These variables as well as some required headers etc. are defined in the other comment. Code following the header keyword is simply copied to the beginning of the generated C-file.
&lt;/p&gt;

&lt;p&gt;
&lt;img src=&quot;https://www.sinelabore.com/lib/exe/fetch.php/wiki/examples/class_diagram_equ.jpg&quot; class=&quot;mediacenter&quot; loading=&quot;lazy&quot; alt=&quot;&quot; /&gt;
&lt;/p&gt;

&lt;p&gt;
The attached example implementation shows how the generated code can be used. The inputs come from a test vector. The code is built with cygwin and gcc but can be also compiled on Linux or Mac &lt;abbr title=&quot;Operating System&quot;&gt;OS&lt;/abbr&gt; X for example. Main is the starting point of the code and initializes everything. A number of test cases are implemented wich can be commented in as needed.
&lt;/p&gt;

&lt;p&gt;
Generated Files:
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;https://www.sinelabore.com/lib/exe/fetch.php/wiki/examples/equivalent.zip&quot; class=&quot;media mediafile mf_zip&quot; title=&quot;wiki:examples:equivalent.zip (26.9 KB)&quot;&gt;Generated files as zip package&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;https://www.sinelabore.com/lib/exe/fetch.php/wiki/examples/equivalent.c&quot; class=&quot;media mediafile mf_c&quot; title=&quot;wiki:examples:equivalent.c (12.7 KB)&quot;&gt;equivalent.c&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;https://www.sinelabore.com/lib/exe/fetch.php/wiki/examples/equivalent.h&quot; class=&quot;media mediafile mf_h&quot; title=&quot;wiki:examples:equivalent.h (4.5 KB)&quot;&gt;equivalent.h&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;https://www.sinelabore.com/lib/exe/fetch.php/wiki/examples/equivalent_ext.h&quot; class=&quot;media mediafile mf_h&quot; title=&quot;wiki:examples:equivalent_ext.h (587 B)&quot;&gt;equivalent_ext.h&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;tags&quot;&gt;&lt;span&gt;
	&lt;a href=&quot;https://www.sinelabore.com/doku.php/tag/application_example?do=showtag&amp;amp;tag=%5BApplication_Example%5D&quot; class=&quot;wikilink1&quot; title=&quot;tag:application_example&quot; rel=&quot;tag&quot;&gt;[Application Example]&lt;/a&gt;
&lt;/span&gt;&lt;/div&gt;

&lt;/div&gt;
</description>
            <author>anonymous@undisclosed.example.com (Anonymous)</author>
            <pubDate>Sun, 25 Sep 2022 08:58:16 +0000</pubDate>
        </item>
        <item>
            <title>Sump Controller</title>
            <link>https://www.sinelabore.com/doku.php/wiki/examples/pump_controller</link>
            <description>
&lt;h1 class=&quot;sectionedit1&quot; id=&quot;sump_controller&quot;&gt;Sump Controller&lt;/h1&gt;
&lt;div class=&quot;level1&quot;&gt;

&lt;p&gt;
&lt;img src=&quot;https://www.sinelabore.com/lib/exe/fetch.php/wiki/examples/sump_controller.png&quot; class=&quot;mediaright&quot; align=&quot;right&quot; loading=&quot;lazy&quot; alt=&quot;&quot; /&gt;
&lt;/p&gt;

&lt;p&gt;
This example presents the software necessary to realize a simplified pump controller which might be used in a mining environment. It is based on a case study presented in &lt;sup&gt;&lt;a href=&quot;#fn__1&quot; id=&quot;fnt__1&quot; class=&quot;fn_top&quot;&gt;1)&lt;/a&gt;&lt;/sup&gt;.
&lt;/p&gt;

&lt;p&gt;
The task of the system is to pump water from a sump to the surface. There are two level monitors which start pumping if the sump is full and stop pumping if it is empty again.
&lt;/p&gt;

&lt;p&gt;
Pumping shall only start if the methane level is below a certain threshold. In case the pump is already running it shall stop automatically.
&lt;/p&gt;

&lt;p&gt;
Pumping shall only start if the methane level is below a certain threshold. In case the pump is already running it shall stop automatically.
&lt;/p&gt;

&lt;p&gt;
There is some additional requirements:
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; After starting the pump a pressure monitor must signal pressure within a defined time to ensure the pump does not run dry. Otherwise the pump becomes hot and finally breaks.&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; If stopped the run signal (checkback) from the motor must be absent (i.e. contactor opened)&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; When running the checkback signal must be present.&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; After a fault a manual reset signal is necessary to restart the controller.&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
The controller behavior can be modelled as a flat state chart. The model below was created using ArgoUML an open source modeling tool. There are two main states PumpStopped and PumpRunning. Changing from run to stopped is only possible via two intermediate states (PumpStarting, PumpStopping) which check that the pump motor checkback signal is present after a switching command. If the checkback from the motor is missing the Error state gets entered.
&lt;/p&gt;

&lt;p&gt;
&lt;img src=&quot;https://www.sinelabore.com/lib/exe/fetch.php/wiki/examples/sump_controller_sc.png&quot; class=&quot;mediacenter&quot; loading=&quot;lazy&quot; title=&quot; Sump Controller State Diagram&quot; alt=&quot; Sump Controller State Diagram&quot; /&gt;
&lt;/p&gt;

&lt;p&gt;
In another possible design all states beside the Error state are children of a NoError state. 
&lt;/p&gt;

&lt;p&gt;
To create the state machine implementation code export the diagram to an XMI file and then call the state machine generator:
&lt;/p&gt;
&lt;pre class=&quot;code bash&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;java&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-jar&lt;/span&gt; codegen.jar &lt;span class=&quot;re5&quot;&gt;-S&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-p&lt;/span&gt; ARGOUML &lt;span class=&quot;re5&quot;&gt;-t&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;sump controller:Controller&amp;quot;&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-o&lt;/span&gt; controller controller.xmi&lt;/pre&gt;

&lt;p&gt;
In this case the C implementation is generated. The &lt;code&gt;-t&lt;/code&gt; flag defines the path to the state diagram within the xmi model file. 
&lt;/p&gt;

&lt;p&gt;
With the optional -S command line flag the graphical simulation is started (see below). The graphical simulation allows to interactively send events to the machine and observe the new active state and the executed C-code. The diagram below shows the state machine in state PumpRunning. Events that are now accepted from the machine are listed on the left and are shown in blue in the diagram. To send a transition just click on the event in the list. The output window displays a trace of the executed code as provided in the diagram.
&lt;/p&gt;

&lt;p&gt;
&lt;img src=&quot;https://www.sinelabore.com/lib/exe/fetch.php/wiki/examples/sump_controller_simulation.png&quot; class=&quot;mediacenter&quot; loading=&quot;lazy&quot; title=&quot; Sump controller simulation&quot; alt=&quot; Sump controller simulation&quot; /&gt;
&lt;/p&gt;

&lt;p&gt;
It is also possible to observe a real target which is connected to the graphical simulation. More information on how to connect an embedded target e.g. via a CAN communication link is available in the sinelabore manual. If you are interested in the model file or the generated code just send a mail to info at sinelabore dot com.
&lt;/p&gt;

&lt;p&gt;
~~DISCUSSION:closed|Leave your comments~~
&lt;/p&gt;
&lt;div class=&quot;tags&quot;&gt;&lt;span&gt;
	&lt;a href=&quot;https://www.sinelabore.com/doku.php/tag/application_example?do=showtag&amp;amp;tag=%5BApplication_Example%5D&quot; class=&quot;wikilink1&quot; title=&quot;tag:application_example&quot; rel=&quot;tag&quot;&gt;[Application Example]&lt;/a&gt;
&lt;/span&gt;&lt;/div&gt;

&lt;/div&gt;
&lt;div class=&quot;footnotes&quot;&gt;
&lt;div class=&quot;fn&quot;&gt;&lt;sup&gt;&lt;a href=&quot;#fnt__1&quot; id=&quot;fn__1&quot; class=&quot;fn_bot&quot;&gt;1)&lt;/a&gt;&lt;/sup&gt; 
&lt;div class=&quot;content&quot;&gt;Burns and Wellings, Real-Time Systems and Programming Languages, Addison Wesley 2001&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
</description>
            <author>anonymous@undisclosed.example.com (Anonymous)</author>
            <pubDate>Wed, 17 Aug 2022 17:41:51 +0000</pubDate>
        </item>
        <item>
            <title>Room Thermostat</title>
            <link>https://www.sinelabore.com/doku.php/wiki/examples/room_thermostat</link>
            <description>
&lt;h1 class=&quot;sectionedit1&quot; id=&quot;room_thermostat&quot;&gt;Room Thermostat&lt;/h1&gt;
&lt;div class=&quot;level1&quot;&gt;

&lt;p&gt;
This example shows the model of a room thermostat that controls heating, cooling and a fan to maintain a user defined temperature. 
&lt;/p&gt;

&lt;p&gt;
&lt;img src=&quot;https://www.sinelabore.com/lib/exe/fetch.php/wiki/examples/thermostat_image.png&quot; class=&quot;mediaright&quot; align=&quot;right&quot; loading=&quot;lazy&quot; alt=&quot;&quot; /&gt;
&lt;/p&gt;

&lt;p&gt;
It uses &lt;strong&gt;regions&lt;/strong&gt; to model the three parts of such a controller. 
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; The user interface that allows to set the temperature for heating or cooling using the set, up and down key.&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; The temperature controller that tries to maintain the user selected temperature&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; The fan that is active in case furnace or air condition is on.&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
The thermostat model is based on an example from &lt;a href=&quot;http://testcover.com/pub/thermo.php&quot; class=&quot;urlextern&quot; title=&quot;http://testcover.com/pub/thermo.php&quot; rel=&quot;ugc nofollow&quot;&gt;Testcover.com&lt;/a&gt;. 
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Room Thermostat&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;room_thermostat&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:1,&amp;quot;range&amp;quot;:&amp;quot;1-654&amp;quot;} --&gt;
&lt;h1 class=&quot;sectionedit2&quot; id=&quot;why_regions_are_useful&quot;&gt;Why regions are useful&lt;/h1&gt;
&lt;div class=&quot;level1&quot;&gt;

&lt;p&gt;
In state diagrams usually only one state is active at a time. In &lt;abbr title=&quot;Unified Modeling Language&quot;&gt;UML&lt;/abbr&gt; state diagrams regions also allow to model concurrency - i.e. more than one state is active at a time (AND states).
&lt;/p&gt;

&lt;p&gt;
A &lt;abbr title=&quot;Unified Modeling Language&quot;&gt;UML&lt;/abbr&gt; state may be divided into regions. Each region contains sub-states. Regions are executed in parallel. You can think of regions as independent state machines displayed in one diagram. The state machine below (Fig. 1) shows three regions each running in parallel. Dashed lines are used to divide a state into regions.
&lt;/p&gt;

&lt;p&gt;
&lt;img src=&quot;https://www.sinelabore.com/lib/exe/fetch.php/wiki/examples/thermostat_state_machine.png&quot; class=&quot;media&quot; loading=&quot;lazy&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;Class diagram. In the attached comment C-code can be defined that is just included into the generated state machine code.&lt;/em&gt;
&lt;/p&gt;

&lt;p&gt;
Regions are useful in the following situations
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; Regions react on the same set of events. Implementing all the functions in one state machine does not require to model two machines with the same set of events.&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; Regions need access  to the same internal variables or helper functions. In the thermostat case the first two regions need access to the user settings such as &lt;code&gt;coolTemp&lt;/code&gt;, &lt;code&gt;heatTemp&lt;/code&gt; and the current room temperature (&lt;code&gt;roomTemp&lt;/code&gt;).&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; Regions need to know the state of other regions. In the thermostat example the &lt;code&gt;fan control&lt;/code&gt; region changes state based on the state of the &lt;code&gt;heat control&lt;/code&gt; region.&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
In fact it would be possible to model the three regions as individual machines, but due to their close interaction is makes sense to model them in one state diagram.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Why regions are useful&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;why_regions_are_useful&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:2,&amp;quot;range&amp;quot;:&amp;quot;655-2173&amp;quot;} --&gt;
&lt;h1 class=&quot;sectionedit3&quot; id=&quot;implementation&quot;&gt;Implementation&lt;/h1&gt;
&lt;div class=&quot;level1&quot;&gt;

&lt;p&gt;
The following state diagram in figure 2 shows the classes (i.e. C-files) involved in the solution. The &lt;code&gt;thermostat&lt;/code&gt; is the central state machine. It is fully generated from the state machine diagram shown in figure one. For code generation only the yellow marked information is needed. All other classes are more or less documentation.
&lt;/p&gt;

&lt;p&gt;
&lt;img src=&quot;https://www.sinelabore.com/lib/exe/fetch.php/wiki/examples/thermostat_class_model.png&quot; class=&quot;media&quot; loading=&quot;lazy&quot; alt=&quot;&quot; /&gt;
&lt;/p&gt;

&lt;p&gt;
The helper classes are just examples and simply print out the name of the called action on the console. Here is an example for the fan implementation:
&lt;/p&gt;
&lt;pre class=&quot;code c&quot;&gt;&lt;span class=&quot;co2&quot;&gt;#include &amp;lt;stdint.h&amp;gt;&lt;/span&gt;
&lt;span class=&quot;co2&quot;&gt;#include &amp;lt;stdio.h&amp;gt;&lt;/span&gt;
&lt;span class=&quot;co2&quot;&gt;#include &amp;quot;fan.h&amp;quot;&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt; fanOff&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;a href=&quot;http://www.opengroup.org/onlinepubs/009695399/functions/printf.html&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;printf&lt;/span&gt;&lt;/a&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;&amp;quot;Fan Off&lt;span class=&quot;es1&quot;&gt;\n&lt;/span&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
&amp;nbsp;
&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt; fanOn&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;a href=&quot;http://www.opengroup.org/onlinepubs/009695399/functions/printf.html&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;printf&lt;/span&gt;&lt;/a&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;&amp;quot;Fan On&lt;span class=&quot;es1&quot;&gt;\n&lt;/span&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
The timer implementation is taken from a recent article published on &lt;a href=&quot;http://www.embedded.com/electronics-blogs/embedded-round-table/4405060/Soft-timers-in-object-oriented-C&quot; class=&quot;urlextern&quot; title=&quot;http://www.embedded.com/electronics-blogs/embedded-round-table/4405060/Soft-timers-in-object-oriented-C&quot; rel=&quot;ugc nofollow&quot;&gt; Embedded.com&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
In main.c the keyboard is cyclically scanned and the user can send events to the machine (e.g. increment the room temperature).
&lt;/p&gt;

&lt;p&gt;
The following code shows an extract of the generated state machine code. In case you are interested in the full example running on various operating systems just send a request to &lt;a href=&quot;mailto:&amp;#105;&amp;#110;&amp;#102;&amp;#111;&amp;#64;&amp;#115;&amp;#105;&amp;#110;&amp;#101;&amp;#108;&amp;#97;&amp;#98;&amp;#111;&amp;#114;&amp;#101;&amp;#46;&amp;#99;&amp;#111;&amp;#109;&quot; class=&quot;mail&quot; title=&quot;&amp;#105;&amp;#110;&amp;#102;&amp;#111;&amp;#64;&amp;#115;&amp;#105;&amp;#110;&amp;#101;&amp;#108;&amp;#97;&amp;#98;&amp;#111;&amp;#114;&amp;#101;&amp;#46;&amp;#99;&amp;#111;&amp;#109;&quot;&gt;&amp;#105;&amp;#110;&amp;#102;&amp;#111;&amp;#64;&amp;#115;&amp;#105;&amp;#110;&amp;#101;&amp;#108;&amp;#97;&amp;#98;&amp;#111;&amp;#114;&amp;#101;&amp;#46;&amp;#99;&amp;#111;&amp;#109;&lt;/a&gt;.
&lt;/p&gt;
&lt;pre class=&quot;code c&quot;&gt;&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt;  thermostat&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;THERMOSTAT_INSTANCEDATA_T &lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt;instanceVar&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; THERMOSTAT_EVENT_T msg&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
&amp;nbsp;
	THERMOSTAT_EV_CONSUMED_FLAG_T evConsumed &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; 0U&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
	&lt;span class=&quot;coMULTI&quot;&gt;/* Create a copy of the instance data.
	   Changes during the machine execution are done on the copy 
	   while tests (e.g. isIn) must use the unmodified instance data */&lt;/span&gt;
	THERMOSTAT_INSTANCEDATA_T instanceVarCopy &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt;instanceVar&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
	&lt;span class=&quot;coMULTI&quot;&gt;/*execute entry code of default state once to init machine */&lt;/span&gt;
	&lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt;instanceVarCopy&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;-&amp;gt;&lt;/span&gt;thermostatEntry&lt;span class=&quot;sy0&quot;&gt;==&lt;/span&gt;1U&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
		tm_timer_init&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt;displayTimer&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
		tm_timer_init&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt;keyHTimer&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
		tm_timer_init&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt;keyCTimer&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
		tm_timer_init&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt;tempControlTimer&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
		tm_timer_init&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt;fanControlTimer&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
		tm_timer_start&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt;fanControlTimer&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; TM_1SEC&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
		roomTemp &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; getTemp&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
		display&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;&amp;quot;Room:&amp;quot;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; roomTemp&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
		tm_timer_start&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt;displayTimer&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; TM_500MSEC&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
&amp;nbsp;
		&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt;instanceVarCopy&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;-&amp;gt;&lt;/span&gt;thermostatEntry&lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt;0U&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
&amp;nbsp;
	&lt;span class=&quot;kw1&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;instanceVar&lt;span class=&quot;sy0&quot;&gt;-&amp;gt;&lt;/span&gt;stateVar&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
&amp;nbsp;
		&lt;span class=&quot;kw1&quot;&gt;case&lt;/span&gt; Thermostat&lt;span class=&quot;sy0&quot;&gt;:&lt;/span&gt;
			&lt;span class=&quot;coMULTI&quot;&gt;/* calling region code */&lt;/span&gt;
			evConsumed &lt;span class=&quot;sy0&quot;&gt;|=&lt;/span&gt; thermostatThermostatFanControl&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;instanceVar&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt;instanceVarCopy&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; msg&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
			evConsumed &lt;span class=&quot;sy0&quot;&gt;|=&lt;/span&gt; thermostatThermostatTempControl&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;instanceVar&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt;instanceVarCopy&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; msg&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
			evConsumed &lt;span class=&quot;sy0&quot;&gt;|=&lt;/span&gt; thermostatThermostatTempSet&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;instanceVar&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt;instanceVarCopy&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; msg&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;kw2&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;coMULTI&quot;&gt;/* end of case Thermostat  */&lt;/span&gt;
&amp;nbsp;
		&lt;span class=&quot;kw1&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;:&lt;/span&gt;
			&lt;span class=&quot;coMULTI&quot;&gt;/* Intentionally left blank */&lt;/span&gt;
		&lt;span class=&quot;kw2&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt; &lt;span class=&quot;coMULTI&quot;&gt;/* end switch stateVar_root */&lt;/span&gt;
&amp;nbsp;
	&lt;span class=&quot;coMULTI&quot;&gt;/* Save the modified instance data */&lt;/span&gt;
	&lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt;instanceVar &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; instanceVarCopy&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
In this example we have shows how regions can be beneficially used for modeling parallel actions and how easy it is to generate code from the state diagram. The generated code can be adjusted to your needs and requires no additional run-time libraries.
&lt;/p&gt;

&lt;p&gt;
~~DISCUSSION:closed|Leave a comment~~
&lt;/p&gt;
&lt;div class=&quot;tags&quot;&gt;&lt;span&gt;
	&lt;a href=&quot;https://www.sinelabore.com/doku.php/tag/application_example?do=showtag&amp;amp;tag=%5BApplication_Example%5D&quot; class=&quot;wikilink1&quot; title=&quot;tag:application_example&quot; rel=&quot;tag&quot;&gt;[Application Example]&lt;/a&gt;
&lt;/span&gt;&lt;/div&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Implementation&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;implementation&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:3,&amp;quot;range&amp;quot;:&amp;quot;2174-&amp;quot;} --&gt;</description>
            <author>anonymous@undisclosed.example.com (Anonymous)</author>
            <pubDate>Wed, 17 Aug 2022 17:41:57 +0000</pubDate>
        </item>
        <item>
            <title>State machine based user interfaces generation</title>
            <link>https://www.sinelabore.com/doku.php/wiki/examples/userinterfacedesign</link>
            <description>
&lt;h1 class=&quot;sectionedit1&quot; id=&quot;state_machine_based_user_interfaces_generation&quot;&gt;State machine based user interfaces generation&lt;/h1&gt;
&lt;div class=&quot;level1&quot;&gt;

&lt;p&gt;
Most developers know state diagrams for modelling control behaviour or protocol machines. But also user interfaces can be specified with their help with great clearness. 
&lt;/p&gt;

&lt;p&gt;
Often small devices monitoring or controlling a process value like drive shaft speed, temperatures or the like have a built-in display. It is used to show the current device status and to configure thresholds such as low or high limits of the process value.
&lt;/p&gt;

&lt;p&gt;
The figure below shows a simple HMI of a frequency monitoring device. The top line presents the actually measured value, whether the value is within the given limits (triangle points to the right) and the status of an output relay signalling an alarm. The bottom part of the HMI shows the frequency spectrum of the measured signal.
&lt;/p&gt;

&lt;p&gt;
&lt;a href=&quot;https://www.sinelabore.com/lib/exe/detail.php/wiki/news/hmi_main_menu.png?id=wiki%3Aexamples%3Auserinterfacedesign&quot; class=&quot;media&quot; title=&quot;wiki:news:hmi_main_menu.png&quot;&gt;&lt;img src=&quot;https://www.sinelabore.com/lib/exe/fetch.php/wiki/news/hmi_main_menu.png?w=400&amp;amp;tok=ba75fb&quot; class=&quot;media&quot; loading=&quot;lazy&quot; title=&quot;GUI of a frequency monitoring device&quot; alt=&quot;GUI of a frequency monitoring device&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
Figure 1: &lt;abbr title=&quot;Graphical User Interface&quot;&gt;GUI&lt;/abbr&gt; of a frequency monitoring device
&lt;/p&gt;

&lt;p&gt;
The state machine below is used to model the behaviour of the complete HMI. The state Display on the left allow to navigate between various displays showing the different measured values (min, max, actual). The right state Edit of the machine shows the configuration part of the HMI. The interaction is done with the help of three buttons. Two buttons are used to step up/down triggering events evInc/evDec. The third button is used for selection a menu item (evButtonLong/evButtonShort).
&lt;/p&gt;

&lt;p&gt;
&lt;a href=&quot;https://www.sinelabore.com/lib/exe/detail.php/wiki/news/hmi_machine.png?id=wiki%3Aexamples%3Auserinterfacedesign&quot; class=&quot;media&quot; title=&quot;wiki:news:hmi_machine.png&quot;&gt;&lt;img src=&quot;https://www.sinelabore.com/lib/exe/fetch.php/wiki/news/hmi_machine.png?w=800&amp;amp;tok=1dbf04&quot; class=&quot;medialeft&quot; align=&quot;left&quot; loading=&quot;lazy&quot; title=&quot;State machine of a small embedded GUI based on PicoTK toolkit&quot; alt=&quot;State machine of a small embedded GUI based on PicoTK toolkit&quot; width=&quot;800&quot; /&gt;&lt;/a&gt;
Figure 2: State machine of a small embedded &lt;abbr title=&quot;Graphical User Interface&quot;&gt;GUI&lt;/abbr&gt; based on the PicoTK toolkit.
&lt;/p&gt;

&lt;p&gt;
State machines are a flexible tool to model all kinds of stateful applications. Might it be control tasks, user interface interactions or realising protocol machines. 
&lt;/p&gt;

&lt;p&gt;
The Sinelabore code generator automatically generates code from your model. The payback comes in very short time because all the error-prone stupid coding is taken from the developer. Focus can be put on the model and model correctness. Model and code is always in sync. Fast development cycles are ensured.
&lt;/p&gt;

&lt;p&gt;
Acknowledgement: The HMI uses &lt;a href=&quot;http://picotk.sourceforge.net&quot; class=&quot;urlextern&quot; title=&quot;http://picotk.sourceforge.net&quot; rel=&quot;ugc nofollow&quot;&gt;PicoTk&lt;/a&gt; a great small footprint C &lt;abbr title=&quot;Graphical User Interface&quot;&gt;GUI&lt;/abbr&gt; kit for embedded systems
&lt;/p&gt;

&lt;p&gt;
~~DISCUSSION:closed|Leave your comments~~
&lt;/p&gt;
&lt;div class=&quot;tags&quot;&gt;&lt;span&gt;
	&lt;a href=&quot;https://www.sinelabore.com/doku.php/tag/hmi_example?do=showtag&amp;amp;tag=%5BHMI_Example%5D&quot; class=&quot;wikilink1&quot; title=&quot;tag:hmi_example&quot; rel=&quot;tag&quot;&gt;[HMI Example]&lt;/a&gt;
&lt;/span&gt;&lt;/div&gt;

&lt;/div&gt;
</description>
            <author>anonymous@undisclosed.example.com (Anonymous)</author>
            <pubDate>Wed, 17 Aug 2022 17:43:54 +0000</pubDate>
        </item>
    </channel>
</rss>
