PDA

Просмотр полной версии : как воспользоваться RISING_EDGE?



Goga2000
09.11.2014, 17:09
добрый день,

судя по описанию в справке RISING_EDGE можно использовать только на ФБД и ЛД. А если на СТ пишу, то как им воспользоваться? Или только циклическая запись остается мне?

Yegor
09.11.2014, 18:28
Пост для экстрасенсов? Ладно, побуду экстрасенсом.

Когда вы ставите канал в режим работы по фронту (он же RISING™ EDGE®), то у вас в таблице привязки появляется битовая запись, к которой вы можете привязать булевую переменную. В дальнейшем на каком угодно языке в нужные вам моменты вы переводите эту переменную из FALSE в TRUE, чем и образуете передний фронт.

Goga2000
11.11.2014, 20:14
Кратовато написал я, конечно, но вы поняли правильно что я имел в виду. Попробовал, вроде работает, но не понял на какое время минамально необходимо держать в состоянии ТРУ триггерную переменную? пробовал сбрасывать на следующем цикле, не хватает ей времени, видимо. Если ставлю ТРУ и не снимаю, то срабатывает.

Yegor
12.11.2014, 06:42
КратоватоДа.

А зачем именно вам этот режим работы? У меня вот он используется всего для трёх регистров, через которые панель передаёт команды оператора на другой ПЛК, и я спокойно могу ставить хоть целую секунду — быстрее оператор всё равно не работает. Пробовал снижать значение до 50 мс — работало.

Goga2000
12.11.2014, 06:51
Да.

А зачем именно вам этот режим работы? У меня вот он используется всего для трёх регистров, через которые панель передаёт команды оператора на другой ПЛК, и я спокойно могу ставить хоть целую секунду — быстрее оператор всё равно не работает. Пробовал снижать значение до 50 мс — работало.

Хочу использовать его для релейного модуля му110-16Р, писать туда в цикле нет никакого желания - всю полосу забивают несколько релейных модулей, т.к. из-за наличия ПЧВ пришлось снизить частоту до 38200 кбод. Смысла писать постоянно одно и то же значение в течении нескольких часов нет никакого.

Lode Runner
12.11.2014, 07:40
Ну значит у вас обработка выхода триггера происходит раньше, чем вызов этого триггера, поэтому выход обрабатывается в следующем цикле ПЛК, когда он уже FALSE.
Я ради теста в пустом проекте сейчас сделал вот так - работает так, как надо, как ожидалось.


PROGRAM PLC_PRG
VAR
re: R_TRIG;
a, b: BOOL;
END_VAR

a; (*это чтобы онлайн присвоить ей правду*)
re (clk := a);
IF a THEN
a := FALSE;
END_IF;
IF re.q THEN
b := TRUE;
END_IF;

END_PROGRAM

Либо обнуляеете вход до вызова триггера.

Goga2000
12.11.2014, 07:59
Ну значит у вас обработка выхода триггера происходит раньше, чем вызов этого триггера, поэтому выход обрабатывается в следующем цикле ПЛК, когда он уже FALSE.
Я ради теста в пустом проекте сейчас сделал вот так - работает так, как надо, как ожидалось.


PROGRAM PLC_PRG
VAR
re: R_TRIG;
a, b: BOOL;
END_VAR

a; (*это чтобы онлайн присвоить ей правду*)
re (clk := a);
IF a THEN
a := FALSE;
END_IF;
IF re.q THEN
b := TRUE;
END_IF;

END_PROGRAM

Либо обнуляеете вход до вызова триггера.

я правильно понимаю, что в качестве триггера назначается b?

Lode Runner
12.11.2014, 08:22
b := true; - это действие, которое выполняется по триггеру.
Тут всё предельно просто, прочитайте повнимательнее.

capzap
12.11.2014, 09:07
Lode Runner не слишком громоздко для ловли переднего фронта?


VAR
uno,duo : BOOL;
END_VAR

IF uno AND NOT duo THEN
;(*любые действия выполняющиеся однократно по переднему фронту переменной uno*)
END_IF;
duo:=uno;

Goga2000
15.11.2014, 19:21
b := true; - это действие, которое выполняется по триггеру.
Тут всё предельно просто, прочитайте повнимательнее.

Почему просто нельзя сделать так:

re.clk = TRUE;
re.clk = FALSE;

а re.q заводим на триггер отсылки слова по 485 интерфейсу?

фронт есть? есть.
триггер должен взвестись? вроде да.

но не работает у меня, почему-то...

Goga2000
20.11.2014, 19:37
Видимо я чего-то сильно не понимаю в особенностях программирования на МЭК.

почему такой код не работает:


VAR_GLOBAL
f: BOOL := FALSE;
t: Standard.TON;
END_VAR

IF (f = FALSE) THEN
f:=TRUE;
t(IN:=f, PT:=T#2S);
END_IF

IF (t.Q) THEN
f := FALSE;
END_IF

а такой работает:


VAR_GLOBAL
f: BOOL := FALSE;
t: Standard.TON;
END_VAR

(*IF (f = FALSE) THEN *)
f:=TRUE;
t(IN:=f, PT:=T#2S);
(*END_IF*)

IF (t.Q) THEN
f := FALSE;
END_IF


???

Amko
20.11.2014, 20:01
Не понятно, что вы хотели добиться?

Goga2000
20.11.2014, 20:14
хотел, что бы t.q сработало.

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

Amko
21.11.2014, 10:57
VAR_GLOBAL
f: BOOL := FALSE;
t: Standard.TON;
END_VAR

IF (f = FALSE) THEN // При первом вызове данного ЕСЛИ мы войдем внутрь условия и начнем выполнять ФБ таймера.
f:=TRUE; // При последующих вызовах данной программы внутрь условия мы не зайдем, так как f = TRUE.
t(IN:=f, PT:=T#2S); // Чтобы таймер досчитал до 2сек., его надо вызывать. Он у вас вызвался 1 только раз, дальше вы к этому таймеру не обращаетесь
END_IF

IF (t.Q) THEN // Соответственно таймер до конца не досчитал и t.q не появилось.
f := FALSE;
END_IF
Понятно?

Ну и немного теории по работе контроллера:
15364
Прогон программы ПЛК и организация памяти: (а) действие ПЛК; (б) последовательность выполнения программы; (в) организация памяти ПЛК

Goga2000
21.11.2014, 13:10
Я себе несколько по другому это представлял. Видимо, предыдущий опыт программирования в не-МЭК средах сказывается.
Теперь вроде все встает на свои места.

т.е. обращение к t.Q для проверки его состояния не является обращением к самому таймеру?
что тогда считать обращением к ФБ? для ТОН достаточно будет обновлять значение IN, или надо еще и РТ обновлять?

Amko
21.11.2014, 13:31
Если вы хотите обратиться к выходу таймера - пишите t.Q
Чтобы таймер работал (считал, выполнялся) надо его вызывать. Т.е. таймер должен вызываться безусловно, всегда. Если таймер надо перезапустить, следует переменную на входе IN хотя бы на один такт изменить с 1 на 0 и обратно.

В следующем коде пример периодического сигнала (выход t.q) с длиной импульса = один такт.


VAR_GLOBAL
f: BOOL := FALSE;
t: Standard.TON;
END_VAR

t(IN:=f, PT:=T#2S);

IF (t.Q) THEN
f := FALSE;
ELSE
f := TRUE;
END_IF

Yegor
21.11.2014, 14:12
т.е. обращение к t.Q для проверки его состояния не является обращением к самому таймеру?Лучше, конечно, говорить о вызове, а не об обращении. «Обновлять» (а правильнее — присваивать значение) обязательно только с переменными типа VAR_IN_OUT. На примере с таймером можно один раз сделать timer(IN := TRUE, PT := T#3s), а дальше просто timer(); или даже timer; (за такое я хочу убивать), чтобы таймер работал. Однако timer.Q уже не будет вызовом ФБ таймера, это обращение к переменной ФБ без вызова.

VAR_GLOBAL
f: BOOL := FALSE;
t: Standard.TON;
END_VAR

t(IN:=f, PT:=T#2S);

IF (t.Q) THEN
f := FALSE;
ELSE
f := TRUE;
END_IFОтвыкаем писать бессмысленный код. Всё сводится к t(IN := NOT t.Q, PT := T#2s). Самосброс называется. Идиома.