PDA

Просмотр полной версии : Вопрос. Управление механизмами по уровню в двух бункерах.



alexval2006
06.02.2016, 21:18
Доброго времени суток.
Возник вопрос не могу сам решить запутался.
надумало моё руководство доработать существующую линию на заводе системой подмешивания зерна в продукт. И как всегда заказали проект на механику сказали дорого обошлось электрику и автоматику клепайте сами от бумаг до воплощения в железе.
Основная задача состоит в управлении заполнением двух бункеров зерном по уровню в них.
В начале стоит задвижка MS1 далее Нория EL_EV1460 далее транспортёр TKF1. На котором над первым бункером стоит задвижка MS2 она и переключает в какой бункер сыпать зерно если открыта то в первый если закрыта то во второй.

Проект ниже. Для ПЛК110_60КМ
При запуске системы проверяем уровень в бункере №1 если там нету среднего или нижнего уровня то начинаем закачку в него MS2 откр, TKF1 старт, EL_EV1460 старт, MS1 откр. Заполняем до верхнего уровня. Если в этот момент уходит средний уровень в бункере №2 то ставим его в очередь. Закачаем его когда закончим с бункером №1. Если же в это время в бункере №2 вышел и нижний уровень то нужно перейти на его заполнение до верхнего уровня и пока не закачаем на другие запросы не реагировать. У меня получилось сделать очередь и закачку для работы средние верхние уровни в обоих бункерах. А с нижними проблема не получается. Даже если задвижку MS2 переключит по нижнему уровню и закачает бункер до верха то не возвращает задвижку обратно для стоящего в очереди второго бункера у которого ушли верхний и средний уровни.
вот основная программа. Для тестирования в визуализации собрано управление уровнями а также есть кнопка тест её нужно нажать чтобы выходы начали работать на входы так как реальной схемы вокруг ПЛК пока не собрано.

Разобрался сам Исправленный код разбил задачу на части и нарисовал релейную схемку подумал перерисовал несколько раз и получил рабочую схемку перевел в на язык ST попробовал работает. Архив с проектом тоже заменён на рабочий.
Это программа управления загрузочными механизмами задвижка MS1, Нория EL_EV1460, транспортёр TKF1 так как они общие для обоих маршрутов.


PROGRAM PRG_U_MECH_ST
(*Программа управления механизмами TKF1, MS1, EL_EV1460 по отсутствию ВУ и СУ или НУ любого из бункеров*)
VAR
LEVEL_FLAG: BOOL;
BUNKER_ZAGRUZ_ON: BOOL;
SR_BUNKER_ZAGRUZ_ON: SR;
SR_BUNKER_ZAGRUZ_OFF: SR;
timer_OFF_1, timer_OFF_2, timer_OFF_3: TON;
timer_ON_1, timer_ON_2, timer_ON_3: TON;
R_TRIG_BUNKER_ZAGRUZ_ON: R_TRIG;
R_TRIG_BUNKER_ZAGRUZ_OFF: R_TRIG;
END_VAR
(************************************************* ************************************************** ***)
(*ЕСЛИ ХОТЬ В ОДНОМ ИЗ БУНКЕРОВ УРОВЕНЬ НИЖЕ НОРМЫ ЗАПУСКАЕМ МЕХАНИЗМЫ ЗАКАЧКИ ПРОДУКТА В БУНКЕРА*)
IF (NU1=FALSE OR SU1=FALSE OR NU2=FALSE OR SU2=FALSE OR LEVEL_FLAG=TRUE) THEN
LEVEL_FLAG:=TRUE;
BUNKER_ZAGRUZ_ON:=TRUE;
END_IF
(*И КАЧАЕМ ДО ВЕРХНЕГО УРОВНЯ В ОБОИХ БУНКЕРАХ *)
IF (VU1=TRUE AND VU2=TRUE) THEN
LEVEL_FLAG:=FALSE;
BUNKER_ZAGRUZ_ON:=FALSE;
END_IF
(*****************ВКЛЮЧЕНИЕ МЕХАНИЗМОВ ЗАКАЧКИ ПО УРОВНЮ*******************************)
R_TRIG_BUNKER_ZAGRUZ_ON(CLK:=BUNKER_ZAGRUZ_ON);
SR_BUNKER_ZAGRUZ_ON(SET1:=R_TRIG_BUNKER_ZAGRUZ_ON. Q, RESET:=timer_ON_3.Q);
timer_ON_1(in:=SR_BUNKER_ZAGRUZ_ON.Q1, pt:=T#1s, Q=>TKF1_AUTO_START); (*ВКЛЮЧЕНИЕ ТР-Р TKF1*)
timer_ON_2(in:=timer_ON_1.Q, pt:=T#1s, Q=>EL_EV1460_AUTO_START); (*ВКЛЮЧЕНИЕ НОРИИ EL_EV1460*)
timer_ON_3(in:=timer_ON_2.Q, pt:=T#1s, Q=>MS1_AUTO_OPEN); (*ОТКРЫТИЕ ЗАДВИЖКИ MS1*)
(*****************ВЫКЛЮЧЕНИЕ МЕХАНИЗМОВ ЗАКАЧКИ ПО УРОВНЮ*******************************)
R_TRIG_BUNKER_ZAGRUZ_OFF(CLK:=BUNKER_ZAGRUZ_ON=FAL SE);
SR_BUNKER_ZAGRUZ_OFF(SET1:=R_TRIG_BUNKER_ZAGRUZ_OF F.Q, RESET:=timer_OFF_3.Q);
timer_OFF_1(in:=SR_BUNKER_ZAGRUZ_OFF.Q1, pt:=T#2s, Q=>MS1_AUTO_CLOSED);(*ЗАКРЫТИЕ ЗАДВИЖКИ MS1*)
timer_OFF_2(in:=timer_OFF_1.Q, pt:=T#2s, Q=>EL_EV1460_AUTO_STOP); (*ВЫКЛЮЧЕНИЕ НОРИИ EL_EV1460*)
timer_OFF_3(in:=timer_OFF_2.Q, pt:=T#2s, Q=>TKF1_AUTO_STOP); (*ВЫКЛЮЧЕНИЕ ТР-Р TKF1*)


А эта программа управляет задвижкой MS2 которая переключает загрузку между бункерами.


PROGRAM PRG_U_MS2_ST
(*Программа управления задвижкой MS2, для закачки бункеров по отсусвию ВУ и СУ или НУ любого из бункеров*)
VAR
B1_SU_FLAG: BOOL;
B2_SU_FLAG: BOOL;
B1_ZAGRUZ_ON: BOOL;
B2_ZAGRUZ_ON: BOOL;
B1_NU_FLAG: BOOL;
B2_NU_FLAG: BOOL;
R_TRIG_MS2_B_ZAGRUZ_OPEN: R_TRIG;
R_TRIG_MS2_B_ZAGRUZ_CLOSED: R_TRIG;
SR_MS2_B_ZAGRUZ_OPEN: SR;
SR_MS2_B_NU_CLOSED: SR;
SR_MS2_B_ZAGRUZ_CLOSED: SR;
timer_B_CLOSED: TON;
timer_B_OPEN: TON;
END_VAR
(************************************************* ************************************************** )
(*Если сработал НУ бункера №1 и флаг загрузки по нижнему уровню бункера №2 неустановлен*)
(*Если сработал НУ бункера №2 и флаг загрузки по нижнему уровню бункера №2 неустановлен*)
(*****************Бункер №1************************************************ ***************************)
(*СРЕДНИЙ И НИЖНИЙ УРОВЕНЬ*)
IF (SU1=FALSE AND B2_SU_FLAG=FALSE AND B1_SU_FLAG) OR (NU1 = FALSE AND B1_NU_FLAG) THEN
B1_ZAGRUZ_ON:=TRUE;(*установим флаг закачки в бункер №1 по СУ и незанятости маршрута бункером №2*)
ELSE
B1_ZAGRUZ_ON:=FALSE;
END_IF
(*ВЕРХНИЙ УРОВЕНЬ*)
IF VU1=FALSE THEN
B1_SU_FLAG:=TRUE; (*флаг закачки в бункер №1 по СУ*)
B1_NU_FLAG:=TRUE; (*флаг закачки в бункер №1 по НУ*)
ELSE
B1_SU_FLAG:=FALSE;
B1_NU_FLAG:=FALSE;
END_IF
(*****************Бункер №2************************************************ ************************)
(*СРЕДНИЙ И НИЖНИЙ УРОВЕНЬ*)
IF (SU2=FALSE AND B1_SU_FLAG=FALSE AND B2_SU_FLAG) OR (NU2 = FALSE AND B2_NU_FLAG) THEN
B2_ZAGRUZ_ON:=TRUE;(*установим флаг закачки в бункер №1 по СУ и незанятости маршрута бункером №2*)
ELSE
B2_ZAGRUZ_ON:=FALSE;
END_IF
(*ВЕРХНИЙ УРОВЕНЬ*)
IF VU2=FALSE THEN
B2_SU_FLAG:=TRUE; (*флаг закачки в бункер №1 по СУ*)
B2_NU_FLAG:=TRUE; (*флаг закачки в бункер №1 по НУ*)
ELSE
B2_SU_FLAG:=FALSE;
B2_NU_FLAG:=FALSE;
END_IF

(**УПРАВЛЕНИЕ ЗАДВИЖКОЙ MS2 ДЛЯ ВЫБОРА В КАКОЙ ИЗ БУНКЕРОВ ЗАКАЧИВАТЬ**)
(***************Переход на загрузку бункера №1 по срабатыванию SU1 или NU1******************)
R_TRIG_MS2_B_ZAGRUZ_OPEN(CLK:=B1_ZAGRUZ_ON);
SR_MS2_B_ZAGRUZ_OPEN(SET1:=R_TRIG_MS2_B_ZAGRUZ_OPE N.Q, RESET:=timer_B_OPEN.Q);
timer_B_OPEN(in:=SR_MS2_B_ZAGRUZ_OPEN.Q1, pt:=T#1s, Q=>MS2_AUTO_OPEN); (*ОТКРЫТИЕ ЗАДВИЖКИ MS2*)
(***************Переход на загрузку бункера №2 по срабатыванию SU2****************************)
R_TRIG_MS2_B_ZAGRUZ_CLOSED(CLK:=B2_ZAGRUZ_ON);
SR_MS2_B_ZAGRUZ_CLOSED(SET1:=R_TRIG_MS2_B_ZAGRUZ_C LOSED.Q, RESET:=timer_B_CLOSED.Q);
timer_B_CLOSED(in:=SR_MS2_B_ZAGRUZ_CLOSED.Q1, pt:=T#1s, Q=>MS2_AUTO_CLOSED); (*ЗАКР ЗАДВИЖКИ MS2*)

alex55
07.02.2016, 09:35
Тот редкий случай когда от st(великого языка) рябит в глазах. На элеваторах такие вещи проще делать на LD(это мое мнение). Надо набраться терпения(ведь у каждого своя логика и подход к решению проблемы и чтобы подсказать совсем чуть-чуть надо перелопатить всю программу) и дожать начатое до конца самостоятельно.

alexval2006
07.02.2016, 19:48
Разобрался сам спасибо за идею с ладом. Я разбил задачу на части и нарисовал релейную схемку подумал перерисовал несколько раз и получил рабочую схемку перевел в на язык ST попробовал работает. В первом посте исправил и архив с проектом тоже заменён на рабочий.

rovki
07.02.2016, 20:02
Разобрался сам спасибо за идею с ладом. Я разбил задачу на части и нарисовал релейную схемку подумал перерисовал несколько раз и получил рабочую схемку перевел в на язык ST попробовал работает. В первом посте исправил и архив с проектом тоже заменён на рабочий.
А на SFC не могли бы скрин выложить ...?

Yegor
08.02.2016, 06:28
Тот редкий случай когда от st(великого языка) рябит в глазах.Тот стопицотый случай, когда целые блоки тавтологии...
(*СРЕДНИЙ И НИЖНИЙ УРОВЕНЬ*)
IF (SU1=FALSE AND B2_SU_FLAG=FALSE AND B1_SU_FLAG) OR (NU1 = FALSE AND B1_NU_FLAG) THEN
B1_ZAGRUZ_ON:=TRUE;(*установим флаг закачки в бункер №1 по СУ и незанятости маршрута бункером №2*)
ELSE
B1_ZAGRUZ_ON:=FALSE;
END_IF
(*ВЕРХНИЙ УРОВЕНЬ*)
IF VU1=FALSE THEN
B1_SU_FLAG:=TRUE; (*флаг закачки в бункер №1 по СУ*)
B1_NU_FLAG:=TRUE; (*флаг закачки в бункер №1 по НУ*)
ELSE
B1_SU_FLAG:=FALSE;
B1_NU_FLAG:=FALSE;
END_IF
(*****************Бункер №2************************************************ ************************)
(*СРЕДНИЙ И НИЖНИЙ УРОВЕНЬ*)
IF (SU2=FALSE AND B1_SU_FLAG=FALSE AND B2_SU_FLAG) OR (NU2 = FALSE AND B2_NU_FLAG) THEN
B2_ZAGRUZ_ON:=TRUE;(*установим флаг закачки в бункер №1 по СУ и незанятости маршрута бункером №2*)
ELSE
B2_ZAGRUZ_ON:=FALSE;
END_IF
(*ВЕРХНИЙ УРОВЕНЬ*)
IF VU2=FALSE THEN
B2_SU_FLAG:=TRUE; (*флаг закачки в бункер №1 по СУ*)
B2_NU_FLAG:=TRUE; (*флаг закачки в бункер №1 по НУ*)
ELSE
B2_SU_FLAG:=FALSE;
B2_NU_FLAG:=FALSE;
END_IF ... можно переписать в десять раз короче:
B1_ZAGRUZ_ON := (NOT SU1 AND NOT B2_SU_FLAG AND B1_SU_FLAG) OR (NOT NU1 AND B1_NU_FLAG);
B1_SU_FLAG := B1_NU_FLAG := NOT VU1;
B2_ZAGRUZ_ON := (NOT SU2 AND NOT B1_SU_FLAG AND B2_SU_FLAG) OR (NOT NU2 AND B2_NU_FLAG);
B2_SU_FLAG := B2_NU_FLAG := NOT VU2;И это вне контекста целой программы. Если же взглянуть на проект, то можно вообще двумя строками обойтись. BX_SU_FLAG и BX_NU_FLAG всегда равны.
B1_ZAGRUZ_ON := (NOT SU1 AND VU2 AND NOT VU1) OR (NOT NU1 AND NOT VU1);
B2_ZAGRUZ_ON := (NOT SU2 AND VU1 AND NOT VU2) OR (NOT NU2 AND NOT VU2);

rovki
08.02.2016, 08:22
Высший пилотаж ;)Теперь да же мне понятно ,что на ПР такая задача реализуется за 5минут :rolleyes:

alexval2006
08.02.2016, 21:08
Спасибо за красивый код попробую. А по поводу неоптимального кода так извините неразу непрограмист киповцы мы, как умеем так коряво и пишим. Но всегда готв учится.