Structure of text blocks

Text blocks within DUTs, GLVs and POUs consist of declarations, expressions, assignments, calls, statements or loops.

Declarations

VAR_INPUT
END_VAR
VAR_IN_OUT CONSTANT
END_VAR
VAR_IN_OUT
END_VAR
VAR_OUTPUT
END_VAR

VAR
END_VAR
VAR PERSISTENT
END_VAR
VAR CONSTANT
END_VAR

Sample:

VAR
    // Movement control
    bExecuteMovements     AT%I*  : BOOL;             (* Controls the movement
                                                        execution of car and bike *)
    bMovementsDone        AT%Q*  : BOOL;             (* Indicates if the car and
                                                        bike finished their movement *)

    // General distance variables
    nMovementTime                : INT;              // Elapsed movement time in seconds
    nDistanceTotal               : INT;              // Total distance being covered by car and bike
    nStartPosition               : INT       := 100; // General start position where car and bike begin to move

    // Car
    fbCar                        : FB_Car;           // Car-FB whose movement is controlled
    nDistanceCar                 : INT;              // Distance being covered by car

    // Bike
    fbBike                       : FB_Bike;          // Bike-FB whose movement is controlled
    nDistanceBike                : INT;              // Distance being covered by bike
END_VAR

Expressions

Examples:

nDistanceCar   := fbCar.nStartPosition + (fbCar.nVelocity * nMovementTime);
nDistanceBike  := fbBike.nStartPosition + (fbBike.nVelocity * nMovementTime);
nDistanceTotal := nDistanceCar + nDistanceBike;

Assignments

bExpressionResult := bCondition1 AND (bCondition2 OR bCondition3)
                     AND bCondition4 AND (bCondition5 OR bCondition6);

Sample:

//=========================================================
// Submodule enable

    // Sensors
    fbSensorEStop.bEnable    := bGeneralEnable AND bSensorEnable;
    fbSensorStartPos.bEnable := bGeneralEnable AND bSensorEnable;

    // Cylinder
    fbCylinderSystem1Main.bEnable := bGeneralEnable AND bCylinderEnable;
    fbCylinderSystem1Sub.bEnable  := bGeneralEnable AND bCylinderEnable; 
    fbCylinderSystem2Main.bEnable := bGeneralEnable AND bCylinderEnable;
    fbCylinderSystem2Sub.bEnable  := bGeneralEnable AND bCylinderEnable; 

    // Axes
    fbAxisSubfoil.bEnable := bGeneralEnable AND bAxisEnable AND NOT bStop;
    fbAxisMain.bEnable    := bGeneralEnable AND bAxisEnable AND NOT bStop;

//=========================================================

Calling methods/functions/function blocks

Negative sample:

fbTimerStart.IN := TRUE;
fbTimerStart.PT := T#10S;
fbTimerStart();
bStartExecution := fbTimerStart.Q;

Positive sample:

fbTimerStart( IN := TRUE,
              PT := T#10S, 
              Q  => bStartExecution);

Detailed sample:

//=========================================================
// Stop

    // Cylinder
    fbCylinderPos1.Stop(bExecute := TRUE);
    fbCylinderPos2.Stop(bExecute := TRUE);
    fbCylinderPos3.Stop(bExecute := TRUE);

    // Axes
    fbAxis1.Stop(bExecute := TRUE, bDone => bAxis1Stopped);
    fbAxis2.Stop(bExecute := TRUE, bDone => bAxis2Stopped);

//=========================================================

Statements

Sample:

IF a > 10 THEN
   …
ELSIF a < 10 THEN
   …
ELSE
   …
END_IF

IF bCondition1 AND bCondition2 AND (bCondition3 OR bCondition4)
   AND bCondition5 AND bCondition6 
   AND (bCondition7 OR bCondition8 OR bCondition9 OR bCondition10) THEN
   …
END_IF

Sample:

//=========================================================
// Cylinder sorting process

CASE eSortingState OF
    E_SortingState.DetectionOfBox: 
        fbCylinder.MoveToBase();
        sVisuMessage := 'System in detection mode.';
    
        IF fbSensorDelay.bOut THEN
            eSortingState := eSorting_MoveCylToWorkPos;
        END_IF
    
    E_SortingState.MoveCylToWorkPos:
        fbCylinder.MoveToWork();
    
        IF fbCylinder.bAtWorkPos THEN
            eSortingState := eSorting_MoveCylToBasePos;
            sVisuMessage  := '';
        ELSE
            sVisuMessage  := 'Waiting for cylinder in work pos.';
        END_IF
    
    E_SortingState.MoveCylToBasePos:
        fbCylinder.MoveToBase();
    
        IF fbCylinder.bAtBasePos THEN
            eSortingState := eSorting_DetectionOfBox;
            sVisuMessage  := '';
        ELSE
            sVisuMessage  := 'Waiting for cylinder in base pos.';
        END_IF
    
ELSE
    sVisuMessage := 'System in non-existent state. Please check application.';
END_CASE

//=========================================================

Loops (FOR, WHILE, REPEAT)

Sample:

//=========================================================
// Initialize storage areas with FOR loop

FOR nAreaCounter := cStorageStart TO cStorageEnd BY 1 DO
    aStorageAreas[nAreaCounter] := nAreaCounter;
END_FOR

//=========================================================
// Initialize delivery areas with WHILE loop

nAreaCounter := cDeliveryStart;

WHILE nAreaCounter <= cDeliveryEnd DO
    aDeliveryAreas[nAreaCounter] := nAreaCounter;
    nAreaCounter                 := nAreaCounter + 1;
END_WHILE

//=========================================================