<< Click to Display Table of Contents >> Navigation: »No topics above this level« Examples |
mapp Services V5.16
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.
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.
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.
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".
The program sequence for the example is as follows:
Coroutine "Axis2" is executed later as "Axis1" since "Axis1" is called before "Axis2".