Нда, спасибо, видел уже, вся моя работа на смарку :(.
Вид для печати
Нда, спасибо, видел уже, вся моя работа на смарку :(.
Petera спасибо за помощь.
Добрый день господа! Подскажите пожалуйста, как записать контроль за параметром в течении определенного времени. например при испытаниях изделия в течении 15 минут контроль давления. если за время давление не упало то гуд. если упало то авария.
WHILE на 15 минут?
Не получится, в ПЛК так нельзя.
Можно, например такЦитата:
Добрый день господа! Подскажите пожалуйста, как записать контроль за параметром в течении определенного времени. например при испытаниях изделия в течении 15 минут контроль давления. если за время давление не упало то гуд. если упало то авария.
Код:PROGRAM PLC_PRG
VAR
Pusk: BOOL; (*Старт тестирования, например Н.Р. кнопка*)
Stop: BOOL; (*Стоп тестирования, например Н.Р. кнопка, для прерывания процесса тестирования*)
Sbros: BOOL; (*Сброс аварийного состояния, например Н.Р. кнопка*)
P: REAL:= 20; (*Измеренное давление*)
time_Test: TIME := t#40s; (*Время испытания изделия*)
limit_P: REAL := 10; (*Допустимое значение падения давления.*)
Trig1: R_TRIG;
time_Start: TIME ;
state: INT;
END_VAR
CASE state OF
0: (*Исходное состояние*)
Trig1(CLK:=Pusk); (*Ожидаем сигнал на старт тестирования*)
state:=BOOL_TO_INT(Trig1.Q);
1:
(*здесь добавить действия
например включить клапан
...................................................
и т.д.*)
state:=2;
time_Start:=TIME();
2: (*Собственно процесс тестирования*)
IF P < limit_P THEN state:=3; END_IF; (*если упало то авария*)
IF TIME() - time_Start >= time_Test OR Stop THEN state:=4; END_IF (*Если время тестирования закончилось, или его нужно прервать*)
3: (*Состояние для аварии*)
(*Здесь написать действия при аварии, например
снять давление(откл.клапан) или вкл. сигнализацию
...................................................
и т.д.*)
IF Sbros THEN
(*здесь добавить действия
например откл сигнализацию
...................................................
и т.д.*)
state:=0; (* Перейти в начало*)
END_IF
4: (*Состояние при нормальном завершении теста*)
(*здесь добавить действия
например сбросить давление, включить лампу "ОК"
...................................................
и т.д.*)
state:=0; (* Перейти в начало*)
END_CASE
Помощь нужна? Температурный график расчет 43 строки данных типа при 10 градусах подача 36.6. те.есть должна автоматически меняться уставка температуры исходя расчета графика температуры.
И зачем 43 точки в отопительном графике?
Вы что-нибудь про кусочно-линейную аппроксимацию слышали?
Скрытый текст:
Это когда непрерывная функция заменяется ломаной линией с конечным числом прямолинейных отрезков. Т.е. график по оси Х разбивается на N частей, для каждого X(i) по графику непрерывной функции определяется значение Y(i). При чем интервалы по оси Х не обязательно должны быть равномерными! Полученные пары значений записываются в таблицу.
Теперь в программе, для текущего значения Х, нужно найти интервал между соседними точками X(i) и X(i+1) в который попадает Х.
Т.е. в таблице из N строк, найти номер строки - i для которой выполняется условие
Х(i) < X <= X(i+1)
И по приведенной выше формуле рассчитать значение Y.
Если делать поиск простым перебором во всех строках, то нужно проделать от 1 до N итераций.
Не мудрено для большой таблицы, вызвать злую собаку.
Может Вам и 10 точек хватит?
Хотя, "Я угадаю эту мелодию с шести нот", в смысле могу предложить способ, при котором для таблицы из 43 строк понадобится не более ШЕСТИ итераций.:rolleyes:
И чем больше строк в таблице, тем более экономичным будет поиск по сравнения с тупым перебором.
для 8 точек графика нужно не более 3 итераций
при 9..16 точек в графике нужно не более 4 итераций
при 17..32 точек в графике нужно не более 5 итераций
при 33..64 точек в графике нужно не более 6 итераций
при 65..128 точек в графике нужно не более 7 итераций
и т.д. согласно - два в степени(кол.итераций).
Для этого я применю метод поиска делением интервала пополам, известный также как двоичный поиск или Дихотомия.
Метод деления отрезка в золотом сечении я еще не пробовал.
И так, у меня получилась вот такая функция
Здесь для таблицы используется пользовательский тип данных - Point_GRКод:FUNCTION MyGraf_p : REAL
VAR_INPUT
IN: REAL; (*Входной сигнал*)
pt : POINTER TO ARRAY[0..99] OF Point_GR; (*Массив точек графика, не более 100 пар точек X,Y*)
size : UINT;
END_VAR
VAR
a: INT; (*Начало интервала поиска*)
b: INT; (*Конец интервала поиска*)
N: INT; (*Число точек в графике*)
i: INT;
END_VAR
N:= SHR(size,3)-1; (*Число точек в графике*)
(*Начальные значения интнрвала поиска*)
a:=0;
b:=N-1;
(*Обрезание графика для крайних точек*)
IF IN<=pt^[0].X THEN
MyGraf_p:=pt^[0].Y;
ELSIF IN>=pt^[N-1].X THEN
MyGraf_p:=pt^[N-1].Y;
(*Теперь можно начать поиск*)
ELSE
WHILE (b-a) <> 1 DO (*В конце концов, входной сигнал ТОЧНО попадет между двумя соседними точками X(a) и Х(а+1)*)
i:=(a+b)/2; (*Делим интервал поиска пополам*)
IF IN=pt^[i+1].X THEN (*Может нам повезло, и мы сразу нашли точку? *)
a:=i; b:=i+1; (*Бинго! прекращаем итераций, нечего в пустую молотить :) *)
(*мимо :( ,тогда посмотрим в какую половину интервала попали*)
ELSIF IN>pt^[i].X THEN (*Если входной сигнал больше середины интервала поиска,*)
a:=i; (*то следующий поиск будем делать начиная от середины и до конца массива*)
ELSE (*А если входной сигнал меньше середины интервала поиска,*)
b:=i; (*то следующий поиск будем делать начиная от начала и до середины массива*)
END_IF
(*Таким образом на каждой итерации отбрасываем из поиска заведомо ненужную половину значений
две соседние координаты X(a) и Х(а+1), меду которыми попадает входной сигнал найдем очень быстро
для 8 точек графика нужно не более 3 итераций
при 9..16 точек в графике нужно не более 4 итераций
при 17..32 точек в графике нужно не более 5 итераций
при 33..64 точек в графике нужно не более 6 итераций
при 65..128 точек в графике нужно не более 7 итераций
инфа точная - 100% ;) *)
END_WHILE
(*Теперь самое простое - сделать линейную аппроксимацию по двум точкам ;) *)
MyGraf_p:=pt^[b].Y-(pt^[b].X-IN)*(pt^[b].Y-pt^[a].Y)/(pt^[b].X-pt^[a].X);
END_IF
Максимальное кол. точек в график ограничил 100. Хотя если надо можно и больше, только не знаю, где такой график может понадобиться. Если реально будет меньше точек, то в функции ничего не менять! Все само подстроится под нужный размер.Код:TYPE Point_GR :
STRUCT
X,Y: REAL;
END_STRUCT
END_TYPE
Сам массив структур передается в функцию через указатель, по этому вызывать ее нужно так
MyGraf_p(IN, ADR(Имя_Массива), SIZEOF(Имя_Массива))
Пример программы на ST
Пример программы на CFCКод:PROGRAM PLC_PRG
VAR
GR: ARRAY [0..49] OF Point_GR:=
(X:=0, Y:=15),(X:=3, Y:=25),(X:=4, Y:=45),(X:=8, Y:=75),(X:=15, Y:=45),
(X:=16, Y:=45),(X:=20, Y:=65),(X:=22, Y:=75),(X:=40, Y:=95),(X:=50, Y:=105),
(X:=110, Y:=15),(X:=120, Y:=25),(X:=130, Y:=45),(X:=140, Y:=75),(X:=150, Y:=45),
(X:=160, Y:=45),(X:=200, Y:=65),(X:=220, Y:=75),(X:=240, Y:=95),(X:=250, Y:=305),
(X:=301, Y:=15),(X:=305, Y:=25),(X:=324, Y:=45),(X:=380, Y:=75),(X:=415, Y:=45),
(X:=416, Y:=45),(X:=420, Y:=65),(X:=422, Y:=75),(X:=440, Y:=495),(X:=450, Y:=505),
(X:=511, Y:=15),(X:=515, Y:=25),(X:=524, Y:=45),(X:=580, Y:=75),(X:=615, Y:=45),
(X:=416, Y:=45),(X:=420, Y:=65),(X:=422, Y:=75),(X:=440, Y:=495),(X:=450, Y:=505),
(X:=621, Y:=15),(X:=625, Y:=25),(X:=634, Y:=45),(X:=680, Y:=75),(X:=695, Y:=45),
(X:=676, Y:=45),(X:=680, Y:=65),(X:=692, Y:=75),(X:=740, Y:=495),(X:=750, Y:=505);
IN: REAL;
OUT: REAL;
END_VAR
(*ВАЖНО!
Таблица должна быть обязательно отсортирована по X в порядке возрастания значений.*)
OUT:=MyGraf_p(IN, ADR(GR), SIZEOF(GR));
Вложение 56577
ЗЫ.
ВАЖНО!
Таблица должна быть отсортирована по X в порядке возрастания.
Спасибо большое ! буду изучать дальше!!! очень мне помогают ваши советы!
День добрый. Подскажите кто нибудь подключал ПЛК и ПКП1 через 4..20мА (для управления)???