Table of Contents

Step

Namespace
ZCore
Implements

The Step function block is the main tool in the Zeugwerk Framework to implement sequences.

This function bocks uses a simple statemachine to make navigation within a step easy. This allows to check if a step was just entered ( OnEntry ) or if it was just exited ( OnExit ) by using the ( SetNext ) method. This reduces the number of steps that have to be used to implement a sequence by up to a factor of 2 and make the code much more pleasant to read.

The most common way to change from one step to another step is the SetNext method. However, there are some derivatives from this function that also have its use cases (Increment, RepeatStep ). Note, that this is not the implementation of a finite statemachine. Hence, there are no conditions for step changes. Any step may be changed to or from every other step. For a more advanced implementation of a sequence that uses transitions, see StateMachine.

A step usually gets initialized with an enumeration that describes every step of a sequence. Using an ENUM instead of merely numbers allows for easy string conversion, using the to_string attribute of Codesys and make debugging much easier. Since the range of potential steps is a prerequisite for any sequence, this range is directly parametrized when construction an instance of this functionblock

Here is an example on how to use the Step fb without an enumeration, simply initialize with a start and maximum step number in between this step should function

PROGRAM MAIN
VAR
  Step : ZCore.Step(begin:=0, end:=100);
  Count : UDINT;
END_VAR
----------------------
CASE Step.CurrentIndex() OF
  0:
    IF Step.OnEntry() THEN
      Count := Count + 1;
    END_IF
 
    Step.SetNext(index:=10);

  10:
    ;
END_CASE  

This example shows how to use the Step fb with an enumeration and to_string attribute. First lets introduce an enumeration ExampleStep

{attribute 'qualified_only'}
{attribute 'to_string'}
TYPE ExampleStep :
( 
  Begin,
  Wait,
  End
);
END_TYPE

Now instantiate the Step and initialize it with this newly created enumeration.

PROGRAM MAIN
VAR
  Step : Step(begin:=ExampleStep.Begin, end:=ExampleStep.End);
  Timer : ZAux.Timer;
END_VAR
---------------------------
CASE Step.CurrentIndex() OF
  ExampleStep.Begin:
    ; // Initialize some things
    Step.SetNext(ExampleStep.Wait);

  ExampleStep.Wait:
    IF Step.OnEntry() THEN
      Timer.WaitAsync(10.0);
    END_IF

    IF Timer.Done THEN
      Step.SetNext(ExampleStep.End);
    END_IF

  ExampleStep.End:
    ; // Idling

END_CASE

Last but not least we can use this to_string feature with the Logger, see in the following example how: First lets introduce an enumeration ExampleStep

{attribute 'qualified_only'}
{attribute 'to_string'}
TYPE ExampleStep :
( 
  Begin,
  Wait,
  End
);
END_TYPE
PROGRAM MAIN
VAR
  DateTime : ZAux.DateTimeUM;
  Logger : ZAux.LoggerFile7FFUM(datetime:=DateTime, filePath:='C:\temp\logfile.log', target:='');
  Step : Step(begin:=ExampleStep.Begin, end:=ExampleStep.End);
  Timer : ZAux.Timer;
  StringBuilder : ZAux.StringBuilder;
END_VAR
-------------------------
DateTime.Cyclic();
Logger.Cyclic();

CASE Step.CurrentIndex() OF
  ExampleStep.Begin:
    IF Step.OnEntry() THEN
      Timer.WaitAsync(5.0);
    END_IF
  
    IF Logger.Operational
    THEN
      Step.SetNext(ExampleStep.Wait);
      Logger.Trace(StringBuilder.Append('Changed Step from ').Append(TO_STRING(ExampleStep.Begin)).Append(' to ').Append(TO_STRING(ExampleStep.Wait)).ToString());
    END_IF

  ExampleStep.Wait:
    IF Step.OnEntry() THEN
      Logger.Debug(StringBuilder.Append('Logger needed ').AppendLreal(Timer.ElapsedSeconds, 3).Append(' seconds for initialization').ToString());
    END_IF
   
    IF Timer.Done THEN
      Step.SetNext(ExampleStep.End);
      Logger.Trace(StringBuilder.Append('Changed Step from ').Append(TO_STRING(ExampleStep.Wait)).Append(' to ').Append(TO_STRING(ExampleStep.End)).ToString());
    END_IF
   
    IF Step.OnExit() THEN
      Logger.Debug('Exiting Wait Step!');
    END_IF

  ExampleStep.End: // Idling
    ;
   
END_CASE
Note

Although it is recommended to use enums, it is ok to use numbers directly for very simple sequences.

FUNCTION_BLOCK Step IMPLEMENTS ZCore.IStep (
 MaxConsecutiveChanges : INT)

Inputs

MaxConsecutiveChanges INT

Maximum number of consecutive, actual step changes before IsNotRepeatable returns TRUE. The value defaults to 0, which means that there are unlimited step changes allowed.

  • Setting default value to a smaller value can be done globally by adjusting ParameterList.StepMaxConsecutiveChanges or locally, which is useful for hunting done programming errors where consecutive step changes lead to an infinite loop.
  • For unittesting it is sometimes useful to set MaxConsecutiveChanges := 1 to test indiviual steps.

Outputs

Index INT

index of the step to access directly in readonly without any method, manipulation is only possible by using methods

Constructor

FB_init

When constructing this functionblock the minimum and maximum step index has to be passed to it by its constructor. Later, the methods Begin and End may be used to retrieve this values.

Constructing a step will set the CurrentIndex() to Begin and initialize the statemachine that is used within a step to entry, such that Index() = Begin() and OnEntry() = True.

METHOD FB_init (
 bInitRetains : BOOL,
 bInCopyCode : BOOL,
 begin : INT,
 end : INT) : BOOL

Inputs

bInitRetains BOOL

if TRUE, the retain variables are initialized (warm start / cold start)

bInCopyCode BOOL

if TRUE, the instance afterwards gets moved into the copy code (online change)

begin INT

first step of the sequence usually given as enumeration value

end INT

last step of the sequence usually given as enumeration value

Returns

BOOL

Methods

Begin

This method returns the index of the first step in this Sequence. It is the same value as given when this object is being constructed via FB_init

METHOD PUBLIC Begin () : INT

Returns

INT

CurrentIndex

Returns the current step in which the object is actually in

METHOD CurrentIndex () : INT

Returns

INT

End

This method returns the index of the last step in this Sequence. It is the same value as given when this object is being constructed via FB_init

METHOD PUBLIC End () : INT

Returns

INT

Increment

This method increments the step index by 1. It is the same as calling

_step.SetNext(_step.Index() + 1);
METHOD Increment ()

IsNotRepeatable

This method returns TRUE if a step is not repeatable. This means that the code within the current step has been executed at least once, such that the OnEntry method could have been entered (if the step implements a call to this method) This method is usually used in the REPEAT (...) UNTIL section of a sequence. The input variable MaxConsecutiveChanges can change this behavior by bypassing this check.

REPEAT
(...)
UNTIL _step.IsNotRepeatable() END_REPEAT
METHOD PUBLIC IsNotRepeatable () : BOOL

Returns

BOOL

OnEntry

this method return TRUE if a step is accessed for the first time calling this method will advance the internal statemachine. Hence, if this method is called once, the next time the method is called it is guaranteed to return FALSE.

METHOD PUBLIC OnEntry () : BOOL

Returns

BOOL

OnExit

this method returns TRUE whenever a step change occured. Thus, any call to SetNext makes this method return TRUE if called AFTER it. This applies also for the derivatives of SetNext() such as RepeatStep() and Increment().

METHOD OnExit () : BOOL

Returns

BOOL

Previous

This method returns the previous step index. At initialization of this function block previous is equal to 0.

METHOD PUBLIC Previous () : INT

Returns

INT

RepeatStep

Calling this method sets the next step to be taken to the same that we are already in. Use this method if it is required to get into the OnEntry section of a step. Internally, this method calls

_step.SetNext(_step.Index());
METHOD RepeatStep ()

Restart

This method changes the step index to Begin and OnExit of the actual step will trigger and OnEntry of the Begin step will also trigger.

This method can be used during execution of the sequence to jump right at the beginning and be sure to trigger OnExit and OnEntry correctly.

METHOD PUBLIC Restart ()

SetNext

Set the next provided step. Also, it changes the state of this step object to the changed status such that IsNotRepeatable will return FALSE the next time that it is called. Hence, if used properly (see Step the next step will be called in the same cycle. If index is out of bounds (Begin and End) the internal state switches to error.

METHOD PUBLIC SetNext (
 index : INT)

Inputs

index INT

index to which the step instance should switch next