Просмотр полной версии : Цикл на языке ST
Прошу помочь в такой задаче: Нужно опрашивать датчик давления один раз в 5 секунд и сравнивать с предыдущим значением. Если этот алгоритм реализовать на языке ST через цикл FOR, то как установить время (Опроса)задержки, возможно для этого использовать оператор Delay или есть другие решения? Заранее спасибо!
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. По фронту импульса Проводите сравнение значения входа и промежуточной переменной, затем записываете значение входа в промежуточную переменную
А почему именно раз в пять секунд? Что мешает опрашивать постоянно?
возможно для этого использовать оператор DelayЗабудьте, что вы знали о программировании на ПК. Здесь поток тормозить нельзя.
А почему именно раз в пять секунд? Что мешает опрашивать постоянно?Забудьте, что вы знали о программировании на ПК. Здесь поток тормозить нельзя.
Циклы опроса мне необходимы для определения разницы между предыдущим значением с датчика и последующим, таким образом хочу реализовать алгоритм определения момента когда давление перестает расти, не превысит какое-то заданное значение , а именно момент когда перестает расти давление.
всё что описываете, это должен делать ПИД-регулятор а не Вы
У меня немного не так, регулирование мне не нужно, мне нужно перейти от аналоговой величины(давление) к дискретной переменной которая будет инициировать запуск устройств. т.е. другими словами такое условие: если давление перестало расти и не меняется в течении скажем 30сек, то я могу запускать устройства, мешалки, шнеки и.т.д.
Тогда всё проще. Надо определить порог значимого изменения и запоминать время, когда такое изменение накапливается. А дальше это время сравнивать с текущим, и если оно, скажем, больше 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
повторюсь, это все работа регулятора, надо просто представлять как себя ведет регулятор когда входная величина перестает изменятся
А хотя ладно, можете и по формуле искать желаемое
IF ABS(curr-2*last+last2)>const THEN ; (* что то там *) END_IF
last2:=last
last:=curr
Nich1122
30.05.2019, 11:57
здравствуйте! подскажите пожалуйста как сделать , чтоб давление подавалось (открывались клапаны) заданное количество раз. То есть клапаны открываются на 15 мс и закрываютсяю Цикл не работает
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 )) у вас по нажатию на клавишу вкл. откл? правильно у меня работает?
Powered by vBulletin® Version 4.2.3 Copyright © 2026 vBulletin Solutions, Inc. All rights reserved. Перевод: zCarot