Никаких выводов не сделали, зачем вам 8 таймеров, если одного за глаза, только время меняйте и запускайте снова, так же по шагам.
Даже пример готовый выкладывал, только кол-во шагов уменьшить осталось и нужные выходы включать.
Вид для печати
Никаких выводов не сделали, зачем вам 8 таймеров, если одного за глаза, только время меняйте и запускайте снова, так же по шагам.
Даже пример готовый выкладывал, только кол-во шагов уменьшить осталось и нужные выходы включать.
Я повторно предлагаю вам попробовать SFC, чтобы решать подобные задачи
Можно конечно применить эрзац SFC на ST:
Код:FUNCTION_BLOCK SFC
VAR_INPUT
xInBtnStart, xInBtnStop: BOOL;
InTime: INT;
END_VAR
VAR_OUTPUT
OutState: enState;
xOutError, xOutCtrl, xOutAdd: BOOL;
END_VAR
VAR
Init: BOOL;
NewState: enState := gc_step_0;
tTime: TIME;
fbBtnStart, fbBtnStop: R_TRIG;
fbTON: TON;
END_VAR
(* КОД ВЫПОЛНЯЕМЫЙ ВСЕГДА *)
fbBtnStart(CLK := xInBtnStart);
fbBtnStop(CLK := xInBtnStop);
xOutError := FALSE;
IF NOT Init THEN
Init := TRUE;
NewState := gc_step_0;
ELSE
CASE NewState OF
(* Шаг 1 *)
gc_step_0:
(* ДЕЙСТВИЯ ПРИ ВХОДЕ В ШАГ *)
IF NewState <> OutState THEN
OutState := NewState;
END_IF;
(* ДЕЙСТВИЯ *)
xOutCtrl := xInBtnStart;
(* call sw ctrl timer *)
fbTON(IN := TRUE, PT := T#10s);
(* ПЕРЕХОДЫ *)
IF fbBtnStart.Q AND fbTON.Q THEN NewState := gc_step_1; fbTON(IN := FALSE);
(*
ELSIF УСЛОВИЕ THEN NewState := НОВОЕ СОСТОЯНИЕ;
ELSIF УСЛОВИЕ THEN NewState := НОВОЕ СОСТОЯНИЕ;
*)
END_IF;
(*
(* ДЕЙСТВИЯ ПРИ ВЫХОДЕ ИЗ ШАГА *)
IF NewState <> OutState THEN
END_IF;
*)
(* Шаг 2 *)
gc_step_1:
(* ДЕЙСТВИЯ ПРИ ВХОДЕ В ШАГ *)
IF NewState <> OutState THEN
fbTON.PT := T#30s;
IF InTime > 0 THEN fbTON.PT := REAL_TO_TIME(InTime * 1000.0); END_IF;
END_IF;
(* ДЕЙСТВИЯ *)
OutState := NewState;
xOutCtrl := TRUE;
(* call sw ctrl timer *)
fbTON(IN := TRUE);
(* ПЕРЕХОДЫ *)
IF fbBtnStop.Q THEN NewState := gc_step_0;
ELSIF fbTON.Q THEN NewState := gc_step_2; fbTON(IN := FALSE);
(*
ELSIF УСЛОВИЕ THEN NewState := НОВОЕ СОСТОЯНИЕ;
ELSIF УСЛОВИЕ THEN NewState := НОВОЕ СОСТОЯНИЕ;
*)
END_IF;
(*
(* ДЕЙСТВИЯ ПРИ ВЫХОДЕ ИЗ ШАГА *)
IF NewState <> OutState THEN
END_IF;
*)
(* Шаг 3 *)
gc_step_2:
(* ДЕЙСТВИЯ ПРИ ВХОДЕ В ШАГ *)
IF NewState <> OutState THEN
OutState := NewState;
END_IF;
(* ДЕЙСТВИЯ *)
xOutError := TRUE;
xOutCtrl := FALSE;
(* ПЕРЕХОДЫ *)
IF fbBtnStop.Q THEN NewState := gc_step_0;
(*
ELSIF УСЛОВИЕ THEN NewState := НОВОЕ СОСТОЯНИЕ;
ELSIF УСЛОВИЕ THEN NewState := НОВОЕ СОСТОЯНИЕ;
*)
END_IF;
(*
(* ДЕЙСТВИЯ ПРИ ВЫХОДЕ ИЗ ШАГА *)
IF NewState <> OutState THEN
END_IF;
*)
(* ОШИБКА СОСТОЯНИЯ *)
ELSE
OutState := gc_step_0;
END_CASE;
(* КОД ВЫПОЛНЯЕМЫЙ ВСЕГДА *)
xOutAdd := NewState = gc_step_0 OR gc_step_1;
END_IF;
Вы про GetTime? Если да, то я не понимаю как это работает.
Вложение 73501
Шаг 7, это когда все узлы установки нормально запущены, то есть установка полностью в работе.
Вложение 73503
Что не понятного тут? В зависимости от входящего шага State, меняется время для таймера, для каждого шага своё время. Например для шага State=1 время t0=5.
Время в таймере надо задавать в ms, так как время конвертируется PT= UDINT_TO_TIME (CurMinute),
если не умножить на 1000, то вы получите 5ms, и шаги просто пролетят с 1 до 12 за пол секунды.
Умножение на 1000 это перевод времени в секунды, 5*1000=5000ms=5секунд,
а умножение на 60000 перевод в минуты 5*60000=300 000ms=300 секунд=5 минут
Переменная Zad и переключает либо отсчёт в секундах, либо в минутах. Там ведь даже подписано!
Всё что нужно сделать, запустить эмуляцию, нажать Старт и смотреть как работает.
Вы в этой строчке записывате значение во ВХОДНУЮ ПЕРЕМЕННУЮ "ALARM_STOP" (в принципе, не возбраняется)
чтобы потом здесьКод:IF TON8_OUT THEN ALARM_STOP:=TRUE; step:=0;END_IF
сбросить SR1Код:IF START AND SR1_OUT AND AUTO AND step=0 AND TP1_OUT THEN step:=1;END_IF
TP1(IN:=SR1_OUT, PT:=T#20s , Q=>TP1_OUT , ET=> );
SR1(SET1:=START , RESET:=ALARM_STOP , Q1=>SR1_OUT );
Но здесь значение ВХОДНОЙ ПЕРЕМЕННОЙ "ALARM_STOP" уже будет иметь то значение, что пришло на этот вход (ALARM_STOP) СНАРУЖИ.
И если это FALSE, то соответственно сброса SR1 не происходит
Ну в основном конечно это реализация входных/выходных действий и таймера шагов. Может кто-то уже занимался этим или исходник библиотеки SFC имел
Это наверно больше вопрос удобства - логика выполнения же не меняется от этого.
Мне удобнее, когда все действия шага в одном месте
Вот смотрю на варианты и всегда вижу почерк автора...
Кто-то (как ТС) выход таймера через => делает, но использует лишнюю переменную.
Кто-то (как и я) через TIMER.Q...
Сколько людей, столько и решений одной задачи. Поэтому надо свое придумывать, или перенимать наиболее понравившуюся манеру написания...