Зачистил все лишнее.
Обычно таймерами не пользуюсь, просто пишу текущее время в переменную, и потом сравниваю, это уже от безысходности, но, попробую, спасибо!
Вид для печати
С таймером - не прокатило.. Изначально, управление сложнее, с бОльшим кол-вом переменных, через TIME(). Чтобы не отнимать время на кучу кода - втыкнул таймер.
Про Adjust - да, прошу прощения: это пытался вывести CASE за условие IF (Если нужна калибровка, то Adjust =1, иначе 0, энд иф. И уже далее - просто кейс. Так тоже не сработало). Вернул счет с единички - тоже самое: при калибровке - система стоит. Уже попробовал ОТКР/ЗАКР вынести в отдельную функцию, а фб оставить чисто на такие модули с таймерами. Результат тот же..
Думал ошибка инициации ФБ, уже намертво прибил Ven[1], но, с другой стороны, все 9 заслонок открываются/закрываются, значит все ок.. воткнуть RETURN после каждого шага, чтобы, условно, "не ждать сейчас таймер, заглянем потом" - так же не дают результата..Код:IF Ven[num].Flap.xAdjust THEN (* Выносим Case за IF *)
Ven[num].Flap.sAdjust:=1;
ELSE
Ven[num].Flap.sAdjust:=0;
END_IF;
CASE Ven[num].Flap.sAdjust OF (*то же, без цикла IF*)
1: Ven[num].Flap.Close:=FALSE; (*Шаг 1*)
VEN[num].Flap.Open:=TRUE;
t1(IN:=TRUE, PT:=T#40s);
IF t1.q THEN
Ven[num].Flap.sAdjust:=Ven[num].Flap.sAdjust+1;
t1(IN:=FALSE, PT:=t1.PT);
END_IF;
2: VEN[num].Flap.Close:=TRUE; (* Шаг 2*)
VEN[num].Flap.Open:=FALSE;
t1(IN:=TRUE, PT:=T#40s);
IF t1.q THEN
Ven[num].Flap.sAdjust:=Ven[num].Flap.sAdjust+1;
t1(IN:=FALSE, PT:=t1.PT);
END_IF;
3: VEN[num].Flap.Close:=FALSE; (* Шаг 3*)
VEN[num].Flap.Open:=FALSE;
Ven[num].Flap.sAdjust:=0; (* Сбрасыываем все *)
Ven[num].Flap.xAdjust:=FALSE;
END_CASE
Тоже самое, но без CASE. Не катит..Код:IF Ven[num].Flap.sAdjust = 1 THEN
Ven[num].Flap.Close:=FALSE;
VEN[num].Flap.Open:=TRUE;
t1(IN:=TRUE, PT:=T#40s);
IF t1.q THEN
Ven[num].Flap.sAdjust:=Ven[num].Flap.sAdjust+1;
t1(IN:=FALSE, PT:=t1.PT);
END_IF;
END_IF;
IF Ven[num].Flap.sAdjust = 2 THEN
VEN[num].Flap.Close:=TRUE;
VEN[num].Flap.Open:=FALSE;
t1(IN:=TRUE, PT:=T#40s);
IF t1.q THEN
Ven[num].Flap.sAdjust:=Ven[num].Flap.sAdjust+1;
t1(IN:=FALSE, PT:=t1.PT);
END_IF;
END_IF;
IF Ven[num].Flap.sAdjust = 3 THEN
VEN[num].Flap.Close:=FALSE;
VEN[num].Flap.Open:=FALSE;
Ven[num].Flap.sAdjust:=0;
Ven[num].Flap.xAdjust:=FALSE;
END_IF;
У вас переменная bool, а вы её в кейс засунули как переменную инт, и она в первом иф всегда 1...
Пардон, там x... и s...
Выносите таймеры из кейса.
Если честно, кровь из глаз чуть не пошла от этого кода. Ничего там не понял... Вернее впал в спупор.
Вы же в кодесисе... Таймеры запускаются? В кейсах или ифах сделайте переменную равную тру, у уже ей запускайте таймер вне условий. Сброс таймеров можете таким же оставить, но только с командой фальш без задания времени.И ещё одно замечание:Код:
t1(IN:=парарам, PT:=T#40s);
IF Ven[num].Flap.sAdjust = 1 THEN
Ven[num].Flap.Close:=FALSE;
VEN[num].Flap.Open:=TRUE;
Парарам :=тру;
IF t1.q THEN
Ven[num].Flap.sAdjust:=Ven[num].Flap.sAdjust+1;
t1(IN:=FALSE);
END_IF;
END_IF;
И т.д.
IF Ven[num].Flap.sAdjust = 2 THEN
VEN[num].Flap.Close:=TRUE;
VEN[num].Flap.Open:=FALSE;
t1(IN:=TRUE, PT:=T#40s);
IF t1.q THEN
Ven[num].Flap.sAdjust:=Ven[num].Flap.sAdjust+1;
t1(IN:=FALSE, PT:=t1.PT);
END_IF;
END_IF;
IF Ven[num].Flap.sAdjust = 3 THEN
VEN[num].Flap.Close:=FALSE;
VEN[num].Flap.Open:=FALSE;
Ven[num].Flap.sAdjust:=0;
Ven[num].Flap.xAdjust:=FALSE;
END_IF;
T1[I](IN:=парарам[I], PT:=T#40s);
Наверно такое хотели получить:
А какая вообще функция у данного механизма и зачем нужна калибровка?Код:IF Ven[num].Flap.xAdjust THEN (* Выносим Case за IF *)
IF Ven[num].Flap.sAdjust=0 THEN Ven[num].Flap.sAdjust:=1; END_IF;
ELSE
Ven[num].Flap.sAdjust:=0;
END_IF;
CASE Ven[num].Flap.sAdjust OF (*то же, без цикла IF*)
1: Ven[num].Flap.Close:=FALSE; (*Шаг 1*)
VEN[num].Flap.Open:=TRUE;
t1(IN:=TRUE, PT:=T#10s);
IF t1.q THEN
Ven[num].Flap.sAdjust:=2;
t1(IN:=FALSE);
END_IF;
2: VEN[num].Flap.Close:=TRUE; (* Шаг 2*)
VEN[num].Flap.Open:=FALSE;
t1(IN:=TRUE, PT:=T#10s);
IF t1.q THEN
Ven[num].Flap.sAdjust:=3;
t1(IN:=FALSE);
END_IF;
3: VEN[num].Flap.Close:=FALSE; (* Шаг 3*)
VEN[num].Flap.Open:=FALSE;
Ven[num].Flap.sAdjust:=0; (* Сбрасыываем все *)
Ven[num].Flap.xAdjust:=FALSE;
END_CASE
(*Функция открытия заслонки*)
IF Ven[num].Flap.Open THEN
IF Ven[num].Flap.Open AND NOT Ven[num].Flap.xOpen THEN
Ven[num].Flap.xOpen:=TRUE;
Ven[num].Flap.Close:=Ven[num].Flap.xClose:=FALSE;
Ven[num].Flap.t_Pos:=TIME();
ELSIF Ven[num].Flap.Open AND Ven[num].Flap.xOpen THEN
Ven[num].Flap.Pos:= Ven[num].Flap.Pos + 0.00258 * (TIME_TO_REAL(TIME() - Ven[num].Flap.t_Pos));
Ven[num].Flap.t_Pos:=TIME();
IF Ven[num].Flap.Pos > 90 THEN Ven[num].Flap.Pos:=90;
END_IF;
ELSE
Ven[num].Flap.xOpen:=FALSE;
END_IF;
END_IF;
(* Функция закрытия заслонки *)
IF Ven[num].Flap.Close THEN
IF Ven[num].Flap.Close AND NOT Ven[num].Flap.xClose THEN
Ven[num].Flap.xClose:=TRUE;
Ven[num].Flap.xOpen:= FALSE;
Ven[num].Flap.t_Pos:=TIME();
ELSIF Ven[num].Flap.Close AND Ven[num].Flap.xClose THEN
Ven[num].Flap.Pos:= Ven[num].Flap.Pos - 0.00258 * (TIME_TO_REAL(TIME() - Ven[num].Flap.t_Pos));
Ven[num].Flap.t_Pos:=TIME();
IF Ven[num].Flap.Pos < 0 THEN Ven[num].Flap.Pos:=0;
END_IF;
ELSE
Ven[num].Flap.xClose:=FALSE;
END_IF;
END_IF;
Таймеры и внутри и за CASE - работают. Работает и счетчик шагов, но не присваивались значения на выходы ПЛК..
Опыт путем выяснил следующее: если в цикл запихнуть переменную, привязанную, непосредственно к выходу ПЛК - все работает. Если (как в моем случае) - это именно функция управления - не хочет ее обработать, что достаточно печально.. Будем разбираться, как это обходить..
Не знаю, насколько правильно, но вместо таймеров провожу сравнения. Как минимум - все необходимые периоды, как правило, в одном месте, в какой-нибудь структуре..
Код:...
Ven[num].Flap.tMove:=TIME(); (*Присваиваем текущую временную метку*)
...
IF (TIME() - Ven[num].Flap.tMove) >= Ven[num].Flap.lMove THEN (*Если текущее время плк минус временная метка больше-равно нужной, то..*)
Ven[num].Flap.sAdjust:=3;
Ven[num].Flap.tMove:=TIME(); (*Обновляем метку, если нужно*)
END_IF;
Это заслонки воздуховодов одновременно, приточки, кондеев и парогенератора. То есть, помимо регулировки воздушного потока "по восстребованию", они играют роль предохранителя от затопления воздуховодов увлажнителем, если авария у УК и отвалится подача, упадет качество воздуха (докинуть свежего), факторов уйма. А калибровка - банально нет датчиков положения, есть только концевики внутри самого привода. Все равно позиционирование будет копить ошибки и раз в месяц-пару нужно синхронить положение. Плюс "не залипнут", если в одном положении давно, что уже бывало..
а накой уходить в 3й шаг? заради выключить выходы?
зачем мутилово с IF перед case? шаг 0 в case может быть из ";"
чего флапу не сделать свой action где он это все без ven[num].flap.
Порядок такой - запоминаем текущее положение -> открываемся -> закрываемся -> возвращаемся туда, "где вроде было ок" -> отстаиваемся чуть -> передаем управление обратно ПИДу. Это уже упрощенный варик, чтоб хоть как-то заставить сиё работать..
просто тест, мало ли.. с учетом перепробаванных вариантов - почему нет..
Заслонок 9 (помещений), по 2 выхода на штуку (18). Помимо них - еще куча мишуры, пресущей данным помещениям. И не хотелось бы возиться с каждым такой штукой отдельно, собственно, было написано маппирование, а управление - через циклы и аттрибуты через точки