PDA

Просмотр полной версии : Цикл на языке ST



servo
10.04.2012, 18:03
Прошу помочь в такой задаче: Нужно опрашивать датчик давления один раз в 5 секунд и сравнивать с предыдущим значением. Если этот алгоритм реализовать на языке ST через цикл FOR, то как установить время (Опроса)задержки, возможно для этого использовать оператор Delay или есть другие решения? Заранее спасибо!

SBER
10.04.2012, 18:46
tm1(PT:=T#5s);
IF tm1.IN=0 THEN tm1.IN:=1; DAT_PREV:=DAT;
END_IF;
IF tm1.Q=1 THEN
IF DAT_PREV>DAT THEN DAT_BOOL:=1; ELSE DAT_BOOL:=0;
END_IF;
DAT_REAL:=DAT_PREV-DAT;
tm1.IN:=0;
END_IF;

DAT - текущие показания датчика;
DAT_BOOL - логическое сравнение двух показаний;
DAT_REAL - разница между предыдущим и текущим значением;
tm1 - таймер TON.

lara197a
10.04.2012, 18:47
Функция-BLINK. По фронту импульса Проводите сравнение значения входа и промежуточной переменной, затем записываете значение входа в промежуточную переменную

Yegor
11.04.2012, 08:27
А почему именно раз в пять секунд? Что мешает опрашивать постоянно?
возможно для этого использовать оператор DelayЗабудьте, что вы знали о программировании на ПК. Здесь поток тормозить нельзя.

servo
11.04.2012, 11:22
А почему именно раз в пять секунд? Что мешает опрашивать постоянно?Забудьте, что вы знали о программировании на ПК. Здесь поток тормозить нельзя.

Циклы опроса мне необходимы для определения разницы между предыдущим значением с датчика и последующим, таким образом хочу реализовать алгоритм определения момента когда давление перестает расти, не превысит какое-то заданное значение , а именно момент когда перестает расти давление.

servo
11.04.2012, 14:27
всё что описываете, это должен делать ПИД-регулятор а не Вы

У меня немного не так, регулирование мне не нужно, мне нужно перейти от аналоговой величины(давление) к дискретной переменной которая будет инициировать запуск устройств. т.е. другими словами такое условие: если давление перестало расти и не меняется в течении скажем 30сек, то я могу запускать устройства, мешалки, шнеки и.т.д.

Yegor
11.04.2012, 18:05
Тогда всё проще. Надо определить порог значимого изменения и запоминать время, когда такое изменение накапливается. А дальше это время сравнивать с текущим, и если оно, скажем, больше 30 сек, то производить нужные вам действия. Как-то так:

thrs, cur, last: REAL;
lastTimeStamp: TIME;

IF ABS(last - cur) > thrs THEN
last := cur;
lastTimeStamp := TIME();
END_IF

IF TIME() - lastTimeStamp > T#30s THEN
whatever;
END_IF

capzap
11.04.2012, 22:28
повторюсь, это все работа регулятора, надо просто представлять как себя ведет регулятор когда входная величина перестает изменятся
А хотя ладно, можете и по формуле искать желаемое

IF ABS(curr-2*last+last2)>const THEN ; (* что то там *) END_IF
last2:=last
last:=curr

Nich1122
30.05.2019, 11:57
здравствуйте! подскажите пожалуйста как сделать , чтоб давление подавалось (открывались клапаны) заданное количество раз. То есть клапаны открываются на 15 мс и закрываютсяю Цикл не работает

Uniqum
31.05.2019, 13:17
CTU TP BLINK RS

Nich1122
03.06.2019, 09:56
CTU TP BLINK RS

три функции надо использовать?

Nich1122
03.06.2019, 14:06
повторюсь, это все работа регулятора, надо просто представлять как себя ведет регулятор когда входная величина перестает изменятся
А хотя ладно, можете и по формуле искать желаемое я так понимаю цикл на плк работает по другому? я пытаюсь с помощью цикла управлять клапанами , но не выходит

Nich1122
04.06.2019, 07:09
Это набор чего-то неработающего (по вашим словам) Зачем мне это ? Половина переменных неизвестно где и как ставятся... ребус предлагаете ?
Задачу опишите. а что не ясно? нужно клапаны подсоединенные на выход плк , открывались и закрывались с промежутком в 10 секунд заданное количество раз.

Nich1122
06.06.2019, 07:22
ну хорошо )))

VAR_INPUT
start : BOOL; //думаецца понятно что
cnt : WORD; //скока нужна поклацать ..
END_VAR
VAR_OUTPUT
q : BOOL; //.. выходом
END_VAR
VAR
t : TON := (pt := t#10s);
w : WORD;
END_VAR
-------------------------------------------
t(in := NOT t.Q AND w > 0);
w := SEL(w < cnt * 2, 0, w + SEL((start AND w = 0) OR t.q, 0, 1));
start := 0;
q := w.0;

или так

VAR_INPUT/OUTPUT
... тоже самое
END_VAR
VAR_INPUT
t : TIME;
d : DWORD;
END_VAR
-------------------------------------------
t := SEL(start, t, TIME());
start := 0;
d := TIME_TO_DWORD(TIME() - t);
q := ((d MOD 20000) < 10000) AND (d < 20000 * cnt);

И не говорите что не работает.
Все понятно ?

PS
Почему-то кажется что так писать не надо )))

не совсем... и не работает)

Nich1122
06.06.2019, 07:46
Не совсем чего ?
У меня - работает)) Видимо - у меня.

d := TIME_TO_DWORD(TIME() - t);
q := ((d MOD 20000) < 10000) AND (d < 20000 * cnt);
вот это не пойму . q у меня битовые переменные.
дело в том , чтобы мне запустить в работу таймер надо закрыть блок, не подскажите почему?

klpn1 := 1;
klpn2 := 1;
END_IF (*без закрытия этого блока не работает таймер. а если его закрыть, то при запуске плк начинает работать блок открытия и закрытия клапанов, а мне надо по нажатию на кнопку)
IF for1*162 > a THEN
tm1 (in := NOT tm1.Q, pt:=t#10s);
IF tm1.Q THEN

klpn1 :=0;
klpn2 :=0;
ELSE
klpn1 := 1;
klpn2 := 1;

Nich1122
06.06.2019, 07:53
Что такое "закрыть блок* ?

end_if , если перед таймером его не поставить не работает таймер

Nich1122
06.06.2019, 08:06
Что такое "закрыть блок* ?
У меня q булевская - какие с ней проблемы ?

Область использования второго несколько уже области первого. Лучше юзать первый. (но лучше четче сформулировать задачу и вообще по другому написать)))
Устанавливается давление и кол-во циклов. при открытии клапана подается давление, клапаны закрываются держат давление 10 сек и сбрасывают давление и так заданное кол-во раз. Спасибо за вашу помощь.

Nich1122
06.06.2019, 16:00
Описанный процесс - долгий и последовательный. Ничего лучшего кроме автомата для этого нет. Он же наиболее наглядный и легко модифицируемый.

program/function_block
var_input //входы свободно меняются в любой момент
tmOn,
tmOff : time; //время в откр/закр состоянии
CountSwitch : int; //кол-во клацаний
end_var
var_output
CurrentSwith : int; //на посмотреть
Q : bool; //соббсно на клапан[ы]
end_var
var
Step : (WAIT, ON, OFF); //собсно автомат
t : time;
OnPress : r_trig; //событие нажатия на кнопу (63/73 - старт/стоп ?)
end_var
***************************
OnPress(CLK := _KEY = ..); //_KEY - в конфигурации 63/73
case Step of
WAIT:
CurrentSwith := 0;
if OnPress.Q then //есть есть у революции принуд. начало ...
CurrentSwitch := 1;
t := time();
Step := ON;
end_if
ON:
if OnPress.Q then // .. и конец тоже может быть, коли "СТАРТ/СТОП"
Step := WAIT;
elsif (time() - t) > tmOn then
t := time();
CurrentSwitch := CurrentSwitch + 1;
Step := sel(CurrentSwitch > CountSwitch, OFF, WAIT);
end_if
OFF:
if OnPress.Q then // ..
Step := WAIT;
elsif (time() - t) > tmOff then
t := time();
Step := ON;
end_if
end_case
Q := Step = ON;
Наверно второй раз в жизни так комментировал код. Он же сам себя комментит.

Спасибо! работает, плк у меня 73 )) у вас по нажатию на клавишу вкл. откл? правильно у меня работает?