Table of Contents

Timer

Namespace
ZAux
Implements

A Timer is a wrapper around the TON function block, which is a well known object in ST code.

A Timer may be started with WaitAsync with a given duration. After doing so, the Done property can be used to test if the timer has elapsed. Additionally, the object provides some useful helper methods to test if it has been started, is running and other useful methods & properties related to timing.

Note

Because the Timer implements IObject it can easily be used in throughout the framework, most notably it can be used together with the Await methods of sequences.

The following example shows the timer embedded and used within a sequence. Here the object context is used by implicitly waiting for the object interface until it is done.

IF _step.OnEntry()
THEN
  _timer.WaitAsync(5);
  _otherObject1.RunAsync(...);
  _otherObject2.RunAsync(...);
END_IF

Await3(_timer, _otherObject1, _otherObject2, ...);

Here is one example on how to use the timer without sequence context:

PROGRAM MAIN
VAR
  Timer : ZAux.Timer;
  Step : UDINT;
END_VAR
---------------------------------------
CASE Step OF
  0:
    Timer.WaitAsync(5.0); // Wait 5 seconds
    Step := 10;
  10:
    IF Timer.Done THEN
      Step := 20;
    END_IF
  20:
    ;
END_CASE

The following example shows how to log the remaining seconds of the timer:

PROGRAM MAIN
VAR
  Timer : ZAux.Timer;
  DateTime : ZAux.DateTimeUM;
  Logger : ZAux.LoggerFile7FFUM(datetime:=DateTime, filePath:='C:\temp\logfile.log', target:='');
  Step : Step(begin:=0, end:=100); 
  StringBuilder : ZAux.StringBuilder;
END_VAR
----------------------------------------
DateTime.Cyclic();
Logger.Cyclic();

CASE Step.CurrentIndex() OF
  0:
    IF Step.OnEntry() THEN
      Timer.WaitAsync(5.0);
    END_IF
  
    IF Logger.Operational
    THEN
      Step.SetNext(10);
    END_IF

  10:
    IF Step.OnEntry() THEN
      Logger.Debug(StringBuilder.Append('Logger needed ').AppendLreal(Timer.ElapsedSeconds, 3).Append(' seconds for initialization').ToString());
    END_IF
   
    Step.SetNext(20);
   
  20: // Idling
    ;
   
END_CASE

The error state never applies to a Timer.

FUNCTION_BLOCK Timer IMPLEMENTS ZCore.ITimer, ZCore.IObject, ZCore.IError

Constructor

FB_init

In its constructor, the Timer function block sets its initial state to idle. A timer does not have any initial phase and so, this state is directly skipped here.

METHOD FB_init (
 bInitRetains : BOOL,
 bInCopyCode : BOOL) : 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)

Returns

BOOL

Properties

Busy

This property returns TRUE if the timer is still running. If this property is called after the duration that has been specified with the WaitAsync method, the timer has been elapsed and this property will return FALSE.

PROPERTY Busy : BOOL

Property Value

BOOL

Done

This property return TRUE if the timer got started and the requested time has elapsed or it has never been started.

PROPERTY Done : BOOL

Property Value

BOOL

Duration

Returns the duration of the last time that the timer got started with WaitAsync. The unit of the returned value is seconds.

PROPERTY Duration : LREAL

Property Value

LREAL

ElapsedSeconds

This property returns the actual elapsed seconds as LREAL, if the timer has been started e.g. for logging purposes. The timer must not be called manually, this is automatically done by calling the property.

PROGRAM MAIN
VAR
  Timer : ZAux.Timer;
  Step, Count : UDINT;
  Es : LREAL;
END_VAR
-----------------------
CASE Step OF
  0:
    Timer.WaitAsync(20.0);
    Count := 0;
    Step := 10;

  10:
    count := count + 1;
    IF count > 1000 THEN
      Step := 20;
    END_IF

  20:
    Es := Timer.ElapsedSeconds; // should return about 10.02 on a 10ms cycle time
    Step := 30;
 
  30:
    ;
   
END_CASE
PROPERTY ElapsedSeconds : LREAL

Property Value

LREAL

RemainingSeconds

This property returns the actual remaining seconds as LREAL of the timer for e.g. logging purposes The timer must not be called manually, this is automatically done by calling the property.

PROGRAM MAIN
VAR
  Timer : ZAux.Timer;
  Step, Count : UDINT;
  Rs : LREAL;
END_VAR
-----------------------
CASE Step OF
  0:
    Timer.WaitAsync(20.0);
    Count := 0;
    Step := 10;

  10:
    count := count + 1;
    IF count > 1000 THEN
      Step := 20;
    END_IF

  20:
    Rs := Timer.RemainingSeconds; // should return about 9.98 on a 10ms cycle time
    Step := 30;
 
  30:
    ;
   
END_CASE
PROPERTY RemainingSeconds : LREAL

Property Value

LREAL

Started

This property returns TRUE if the timer is currently running or it has been just started. The Started flag is only reset by explicitly calling the stop method or calling WaitAsync(duration:=0).

PROPERTY Started : BOOL

Property Value

BOOL

State

PROPERTY State : ZCore.ObjectState

Property Value

ObjectState

Methods

ElapsedTimeNormalized

Time that has been passed since WaitAsync was called. The return value is scaled to the interval [0, 1] and if the timer has elapsed this method returns 1 and if it has just been started it returns 0.

For the special case that the timer has been started with duration=0 this method returns 1, which is in agreement to the returned value of Done and other methods & properties in this case.

METHOD ElapsedTimeNormalized () : LREAL

Returns

LREAL

OnDone

This method returns TRUE for the first time that it is called and the timer is elapsed. Internally it is a rising trigger on the Done property.

METHOD OnDone () : BOOL

Returns

BOOL

RemainingTimeNormalized

Remaining time for the timer to be elapsed. The return value is scaled to the interval [0, 1] such that 1 means the timer has just been started and 0 means that the timer is elapsed.

For the special case that the timer has been started with duration=0 this method returns 1, which is in agreement to the returned value of Done and other methods & properties in this case.

METHOD RemainingTimeNormalized () : LREAL

Returns

LREAL

SetBusy

METHOD PROTECTED SetBusy (
 busy : BOOL)

Inputs

busy BOOL

SetIdle

This method resets the error state. It can be used as a shortcut for SetBusy(FALSE)

Note

this method is commonly used in constructors (i.e. FB_init) and thus, must not be overwritten, since this can cause problems when using SUPER

METHOD PROTECTED FINAL SetIdle ()

Stop

This method stops the Timer and set its state to Idle. Notably, the method also resets the Started flag.

METHOD Stop ()

TraceErrorStack

This method is used internally when recording an error trace.

METHOD TraceErrorStack (
 trace : ZCore.IErrorTrace)

Inputs

trace IErrorTrace

UpdateState

METHOD PROTECTED UpdateState ()

WaitAsync

This method starts the Timer and sets its state to Busy transfering it into its busy state. After doing so, the object can be polled for completion by calling Busy or Timer.Done. The timer has completed once duration has elapsed, where duration is given in seconds.

If duration <=0 the stop method is called internally, which in turn resets the Started flag.

METHOD WaitAsync (
 duration : LREAL)

Inputs

duration LREAL

in seconds