Examples

<< Click to Display Table of Contents >>

Navigation:  »No topics above this level«

Examples

mapp Services V5.16

Performing a calculation using coroutines

In this example, a calculation is performed via a routine.

VAR { AT 'MyProgram' }

   Buffer : ARRAY[0..9] OF INT;

   a  : INT;

   b  : INT;

END_VAR

VAR

   handle1 : UDINT;

   c  : INT;

   i  : INT;

END_VAR

FUNCTION MathFunction : INT

  VAR_IN_OUT

       CoroutineA  : INT;

       CoroutineB  : INT;

       CoroutineI  : INT;

  END_VAR

  WHILE CoroutineI <= 9 DO

        MathFunction := CoroutineA + CoroutineB;

        COROUTINE_YIELD();

  END_WHILE

  WHILE CoroutineI = 10 DO

      COROUTINE_YIELD();

  END_WHILE

END_FUNCTION

PROGRAM _MAIN

   handle1 := COROUTINE_CREATE(MathFunction,'Routine1',(a,b,i));

  FOR i := 0 TO 9 BY 1 DO

       c := COROUTINE_RESUME(handle1);

       Buffer[i] := c;

       a := b;

       b := c;

  END_FOR

COROUTINE_DELETE(handle1);

END_PROGRAM

Three process variables were created in the Automation Studio project, "Buffer", "a" and "b". These process variables are used in the Structured Text program. This allows, for example, the initial value for "a" and "b" to be determined via user input.

The two process variables "a" and "b" should be added and the result should be stored in a buffer. The actual addition takes place in the coroutine. After the calculation has been performed, the yield statement is executed and the main program continues to run. This happens until the defined buffer is full.

simple_coroutine_example

Performing a axis movement using coroutines

In this example, two axes are moved to a desired position using routines. The axes were previously switched on and referenced.

#include 'Includes\McBase.typ'

#include 'Includes\McAxis.typ'

#include 'Includes\MpBase.typ'

#include 'Includes\MpAxisError.typ'

#include 'Includes\MpAxis.typ'

#include 'Includes\MpAxis.fun'

VAR

   handle1        : UDINT;

   handle2        : UDINT;

END_VAR

VAR {AT 'Motion'}

   Axis1                 : MpAxisBasic;

   Axis2                 : MpAxisBasic;

   AxisParameters1     : MpAxisBasicParType;

   AxisParameters2     : MpAxisBasicParType;

END_VAR

FUNCTION MoveAxis : NONE

  VAR_IN_OUT

       axis : MpAxisBasic;

  END_VAR

   axis.MoveAbsolute := TRUE; // start movement

  WHILE axis.MoveActive = FALSE DO

      COROUTINE_YIELD();     //wait for rising edge on MoveActive

  END_WHILE

  WHILE axis.MoveActive = TRUE DO

      COROUTINE_YIELD();     //wait for falling edge on MoveActive

  END_WHILE

   axis.MoveAbsolute := FALSE;   // reset

END_FUNCTION

PROGRAM _MAIN

   AxisParameters1.Position  := 200;

  // Resume the coroutine until it is finished

   handle1 := COROUTINE_CREATE(MoveAxis,'Axis1',(Axis1));

  WHILE (COROUTINE_STATE(handle1) <> 4) DO

        COROUTINE_RESUME(handle1);

  END_WHILE

  COROUTINE_DELETE(handle1);

   AxisParameters1.Position := 50;

   AxisParameters2.Position := 80;

   handle1 := COROUTINE_CREATE(MoveAxis,'Axis1',(Axis1));

   handle2 := COROUTINE_CREATE(MoveAxis,'Axis2',(Axis2));

  // Resume the coroutines until both are finished

  WHILE ((COROUTINE_STATE(handle1) <> 4) OR (COROUTINE_STATE(handle2) <> 4)) DO

      IF (COROUTINE_STATE(handle1) <> 4) THEN

          COROUTINE_RESUME(handle1);

      END_IF

      IF (COROUTINE_STATE(handle2) <> 4) THEN

          COROUTINE_RESUME(handle2);

      END_IF

  END_WHILE

END_PROGRAM

A movement is first performed on an axis ("Axis1").

The target position is 200. After creating coroutine "Axis1", the state of the coroutine is queried using a WHILE loop. The WHILE loop is executed until the coroutine reaches state 4, which means that the coroutine has completed execution. The coroutine is started within the WHILE loop and executed until the first "Yield" statement.

The command for the movement ("MoveAbsolute") is started within the coroutine. Since it can take several cycles until the axis is in motion ("MoveActive = TRUE"), the coroutine must be executed at the beginning until "MoveActive" is no longer FALSE. This means that the program jumps back and forth between the coroutine and main program until the axis starts the movement.

axis_program_1

As soon as the movement is executed ("MoveActive = TRUE"), the axis moves to the desired target position. It is important to note that the movement is always executed. The movement is not stopped as a result of executing and interrupting the coroutine. It will jump back and forth between the coroutine and main program until the target position is reached and "MoveActive" is set to FALSE. The command for the movement is reset and the coroutine reaches "END_FUNCTION". The coroutine has therefore completed execution. The state of the coroutine changes to 4 ("Finished"), and the condition of the WHILE loop is no longer met in the main program. The coroutine is deleted.

axis_program_2

In the next step, two coroutines are created, i.e. a movement is started on two different axes. The positions were defined at 50 and 80.

The procedure is exactly the same, only in this case for coroutines "Axis1" and "Axis2".

axis_program_3

The program sequence for the example is as follows:

coroutine_times

Coroutine "Axis2" is executed later as "Axis1" since "Axis1" is called before "Axis2".