Вход

Просмотр полной версии : Блок обработки ошибок



PAVGroup
08.04.2026, 11:09
Доброе время суток.
Подскажите как можно правильно реализовать данной мероприятие? Работаю в основном с ПР100.
В проектах, у меня есть много своих ФБ, которые по различным условиям, могут выдавать ошибки. Т.е., выходные данные из блоков это число. Число передается в переменную. А эта переменная должна пойти в ФБ, где будет обрабатываться. Т.е., остановит оборудование и по номеру ошибки на дисплеи выведет номер ошибки. Проблема в том, что одну и туже переменную нельзя же перезаписать. Как тогда быть то?
Подскажите. Заранее спасибо.

1exan
08.04.2026, 11:11
У вас одна переменная ошибки на все ФБ?

PAVGroup
08.04.2026, 11:21
У вас одна переменная ошибки на все ФБ?

Error - булевая переменная, которая показывает что есть авария.
ErrorNum - целочисленная переменная, которая и передает номер ошибки.

EFrol
08.04.2026, 11:36
А где хранится номер ФБ, которая сгенерировала ошибку?
Если 2-е и более ФБ выдают разные ошибки?

PAVGroup
08.04.2026, 13:20
Не совсем понял

Dimensy
08.04.2026, 13:40
Не совсем понял

У вас две и более одновременно активных ошибок. Что будет в переменной ErrorNum?

PAVGroup
08.04.2026, 13:46
К примеру у меня есть 5 моих ФБ. 4 рабочие ФБ процесса. У которых выходные данные ErrorNum. К примеру = 1 (обрыв цепи).
Вот значение этой переменной ErrorNum, должно улететь в 5й ФБ который будет обрабатывать ошибки. На вход у него подается ErrorNum, он обрабатывает. На выходе Error = true - Авария (этот сигнал потом остановит оборудование), ErrorNumIPP - передает номер ошибки на панель. Оператор это видит.

kondor3000
08.04.2026, 13:49
Error - булевая переменная, которая показывает что есть авария.
ErrorNum - целочисленная переменная, которая и передает номер ошибки.

Вот пример на 12 аварий, код аварии запоминается и выводится на экран (по очереди) или мигает на F1.

Если у вас вышел код 1, сравниваете с 1 и включаете 1 вход. Код 2 включаете 2 вход и т. д.

melky
08.04.2026, 13:57
В одну переменную можно записать ошибки от разных блоков, при условии, что одновременно не будет ошибок в разных блоках. Для этого используются блоки SEL.
Другой вариант - это разбить 32-х битное число на сегменты и использовать для ошибок разных блоков в одной переменной.

PAVGroup
08.04.2026, 14:15
Вот пример на 12 аварий, код аварии запоминается и выводится на экран (по очереди) или мигает на F1.

Если у вас вышел код 1, сравниваете с 1 и включаете 1 вход. Код 2 включаете 2 вход и т. д.

Это не много не то. Мне ненужно привязывать к физическим входам и выходам.

Dimensy
08.04.2026, 14:27
Если вам нужно записать ошибки от разных блоков в одну переменную, то можно сделать так. В одну целочисленную переменную можно записать до 32 ошибок
88784

EFrol
08.04.2026, 14:57
К примеру у меня есть 5 моих ФБ. 4 рабочие ФБ процесса. У которых выходные данные ErrorNum. К примеру = 1 (обрыв цепи).
Вот значение этой переменной ErrorNum, должно улететь в 5й ФБ который будет обрабатывать ошибки. На вход у него подается ErrorNum, он обрабатывает. На выходе Error = true - Авария (этот сигнал потом остановит оборудование), ErrorNumIPP - передает номер ошибки на панель. Оператор это видит.

Если будет остановка по событию, то Вам нужно фиксировать какой ФБ вызвал остановку и по какой ошибке.
Примерно так:


function_block FixError

var_input
ErrorFromFB1, ErrorFromFB2, ErrorFromFB3, ErrorFromFB4 : udint; // Состояние ФБ
end_var

var_output
ErrorFB, ErrorCode : udint; // Кто? Чего?
end_var

if ErrorFromFB1 > 0 then
ErrorCode := ErrorFromFB1; ErrorFb := 1;
elsif ErrorFromFB2 > 0 then
ErrorCode := ErrorFromFB2; ErrorFb := 2;
elsif ErrorFromFB3 > 0 then
ErrorCode := ErrorFromFB3; ErrorFb := 3;
elsif ErrorFromFB4 > 0 then
ErrorCode := ErrorFromFB4; ErrorFb := 4;
else
ErrorCode := 0; ErrorFb := 0;
end_if
end_function_block

PAVGroup
08.04.2026, 15:00
Если будет остановка по событию, то Вам нужно фиксировать какой ФБ вызвал остановку и по какой ошибке.
Примерно так:


function_block FixError

var_input
ErrorFromFB1, ErrorFromFB2, ErrorFromFB3, ErrorFromFB4 : udint; // Состояние ФБ
end_var

var_output
ErrorFB, ErrorCode : udint; // Кто? Чего?
end_var

if ErrorFromFB1 > 0 then
ErrorCode := ErrorFromFB1; ErrorFb := 1;
elsif ErrorFromFB2 > 0 then
ErrorCode := ErrorFromFB2; ErrorFb := 2;
elsif ErrorFromFB3 > 0 then
ErrorCode := ErrorFromFB3; ErrorFb := 3;
elsif ErrorFromFB4 > 0 then
ErrorCode := ErrorFromFB4; ErrorFb := 4;
else
ErrorCode := 0; ErrorFb := 0;
end_if
end_function_block


Завтра буду на работе, попробую. Заранее спасибо.

keysansa
09.04.2026, 20:35
Доброе время суток.
Подскажите как можно правильно реализовать данной мероприятие? Работаю в основном с ПР100.
В проектах, у меня есть много своих ФБ, которые по различным условиям, могут выдавать ошибки. Т.е., выходные данные из блоков это число. Число передается в переменную. А эта переменная должна пойти в ФБ, где будет обрабатываться. Т.е., остановит оборудование и по номеру ошибки на дисплеи выведет номер ошибки. Проблема в том, что одну и туже переменную нельзя же перезаписать. Как тогда быть то?
Подскажите. Заранее спасибо.

У меня другой метод, который я использую в разных контроллерах.

"Выходные данные из блоков - это число" - это принцип программиста "С", "Pascal".
В FBD/ST - могут возникать несколько ошибок одновременно.
Поэтому, я использую для каждой ошибки - свой бит. Если у макроса FDB/ST блока - 3-4 ошибки - для каждой использую свой Out. Если больше- упаковываю в Word - но все равно - один бит - одна ошибка.
Если есть вложение макросов - переупаковываю слова ошибок от каждого вложенного макроса, формируя выходные переменные Errors1, Errors2...

ЗЫ. В итоге, на панели оператора, при нажатии на кнопку, например пуска транспортера выводится цепочка ошибок:
"Транспортер 12: Ошибка - Запрет пуска, принимающий транспортер не включился"
"Транспортер 11: Ошибка - Нет вращения"
"Транспортер 11: Ошибка - Нет сигнала с датчика вращения SQ122, модуль А2 DI 131"

ЗЫЫ. Такое управление аварийными ситуациями удобно и в самой программе. Например


function_block
vEnable:= jEnable AND jPrevRun AND NOT( eOnTimeout OR eConcurrence);
oOn:= vEnable AND ((jAuto AND jAutoON) OR (NOT jAuto AND btnManuOn));
tonOnTimeout(IN: oOn AND NOT iOn, PT:= 500ms);
eOnTimeout:= tonOnTimeout.Q OR (eOnTimeout AND NOT jResetErr);
end_function_block


i - Input, j- Job, e - Error, o - Output, ton - TON, v - local Variable. btn, sw - BuTtoN, SWitch - не всегда использую, но иногда полезно в большом проекте, сократить имена переменных (бывает и iOn и btnOn и swOn в одном макросе).