FUNCTION_BLOCK PN_DIAG_SCL
//************************
VAR_IN_OUT
OBxx_TRIGGER : BOOL;
END_VAR
VAR_INPUT
PN_ID : INT; //100..?
END_VAR
VAR_OUTPUT
IS_BUSY : BOOL;
HAS_IO_DEV : BOOL;
PN_OK : BOOL;
END_VAR
VAR // static variables
REQ : STRUCT
REQ1 : BOOL;
REQ2 : BOOL;
END_STRUCT;
BUSY : STRUCT
BUSY1 : BOOL;
BUSY2 : BOOL;
END_STRUCT;
STEP : INT; //0..5
IO_DEV_STATE_RETR : STRUCT
PLANNED : ARRAY[1..128] OF INT;
WORKING : ARRAY[1..128] OF INT;
END_STRUCT;
IO_DEV_STATE : ARRAY[1..128] OF BOOL; //WinCC-Interface (FALSE = OK/NO_INFO; TRUE = ERROR)
IO_DEV_COUNT : INT;
TIMER_RETRIGGER : SFB4;
END_VAR
VAR_TEMP // temporary variables
ERROR : INT;
SZL_HEADER : STRUCT
LENTHDR : WORD;
N_DR : WORD;
END_STRUCT;
i : INT;
PN_OK_TEMP : BOOL;
END_VAR
//************************
BEGIN // statements
//IF(IO_DEV_COUNT <= 0) THEN STEP := 5; END_IF; //end
IF((STEP <= 0) AND (OBxx_TRIGGER OR TIMER_RETRIGGER.Q)) THEN
OBxx_TRIGGER := FALSE; //reset
PN_OK_TEMP := TRUE;
STEP := 1;
END_IF;
IS_BUSY := (STEP > 0);
// PLANNED
REQ.REQ1 := ((STEP = 1) OR (STEP = 2));
ERROR := RDSYSST(REQ := REQ.REQ1
,SZL_ID := W#16#0094 //Retrieve planned IO-stations
,INDEX := PN_ID
,BUSY := BUSY.BUSY1
,SZL_HEADER := SZL_HEADER
,DR := IO_DEV_STATE_RETR.PLANNED
);
IF((STEP = 1) AND (BUSY.BUSY1 OR (ERROR = 0))) THEN STEP := 2; END_IF;
IF((STEP = 2) AND NOT BUSY.BUSY1) THEN STEP := 3; END_IF;
// WORKING
REQ.REQ2 := ((STEP = 3) OR (STEP = 4));
ERROR := RDSYSST(REQ := REQ.REQ2
,SZL_ID := W#16#0294 //Retrieve working IO-stations
,INDEX := PN_ID
,BUSY := BUSY.BUSY2
,SZL_HEADER := SZL_HEADER
,DR := IO_DEV_STATE_RETR.WORKING
);
IF((STEP = 3) AND (BUSY.BUSY2 OR (ERROR = 0))) THEN STEP := 4; END_IF;
IF((STEP = 4) AND NOT BUSY.BUSY1) THEN STEP := 5; END_IF;
// EVALUATION
IF(STEP >= 5) THEN
IO_DEV_COUNT := 0; //reset
FOR i := 1 TO 128 DO
IO_DEV_STATE[i] := 0; //clear
IF(IO_DEV_STATE_RETR.PLANNED[i] > 0) THEN
IO_DEV_COUNT := IO_DEV_COUNT + 1;
IF(IO_DEV_STATE_RETR.WORKING[i] > 0) THEN
IO_DEV_STATE[i] := FALSE; //OK
ELSE
IO_DEV_STATE[i] := TRUE; //ERROR
PN_OK_TEMP := FALSE;
END_IF;
END_IF;
END_FOR;
HAS_IO_DEV := (IO_DEV_COUNT > 0);
PN_OK := (HAS_IO_DEV AND PN_OK_TEMP);
STEP := 0; //reset
END_IF;
TIMER_RETRIGGER (IN := (STEP = 0)
,PT := T#60s
);
END_FUNCTION_BLOCK