Добавляю более читаемый код (разработан в codesys 3.5), который, думаю, можно переделать и для ПР. Остается только коды аварий самому разработать...
Эх, без аварий - косячит... Надо разбираться. Но все равно, мне на ST больше код удобен, чем на FBDКод:PROGRAM PLC_PRG
VAR
ALARMok: ARRAY [1..VOLUMEofALARM] OF BOOL; //наличие аварии для данного кода
TIMEforEACHcode: ton; //таймер на каждую активную аварию
NEXTalarm: INT:= 1; //номер шага для поиска следующей активной аварии
NEXTok: BOOL; //следующая активная авария найдена
OUTforLAMP: BOOL; //выход на сигнализацию
i: INT; //для цикла
END_VAR
VAR CONSTANT
VOLUMEofALARM: INT:= 4; //количество аварий
END_VAR
-----------------------------------------------------------
//каждые 10 секунд показывать новую аварию
TIMEforEACHcode(in:= NOT TIMEforEACHcode.q, pt:= T#10S);
//ограничение по максимуму аварий
IF NEXTalarm> VOLUMEofALARM THEN
NEXTalarm:= 1;
END_IF
//поиск следующей активной аварии
IF NOT ALARMok[NEXTalarm] AND NOT NEXTok THEN
NEXTalarm:= NEXTalarm + 1;
IF ALARMok[NEXTalarm] THEN
NEXTok:= TRUE;
END_IF
END_IF
//старт поиска следующей активной аварии
IF TIMEforEACHcode.q THEN
NEXTok:= FALSE;
NEXTalarm:= NEXTalarm + 1;
END_IF
//выход на сигнализацию
//так:
//OUTforLAMP:= (POU_SIG.OutX[1] AND (NEXTalarm= 1)) OR (POU_SIG.OutX[2] AND (NEXTalarm= 2)) OR (POU_SIG.OutX[3] AND (NEXTalarm= 3)) OR (POU_SIG.OutX[4] AND (NEXTalarm= 4));
//или так:
OUTforLAMP:= FALSE;
FOR i:= 1 TO VOLUMEofALARM DO
OUTforLAMP:= OUTforLAMP OR (POU_SIG.OutX[i] AND (NEXTalarm= i));
END_FOR

