Не, это все полумеры. Причем кривые. Начиная с того что библиотечный ПИД не имеет зоны нечувствительности по рассогласованию...
Вид для печати
Не имеет зоны нечувствительности? Добавим http://www.owen.ru/forum/showthread....l=1#post158489
Остальная кривизна в чем?
Скрин - фрагмент из реального проекта, это был регулятор уровня воды в барабане котла ДКВР. Работает по сей день и даже не подозревает о том, что он якобы "кривой".
Посмотрите вложение выше, я сделал именно на основе dz2. Дайте замечания.
Да в том даже, что чтобы повторит Ваш скрин нужно подключить кучу разных библиотек, и ни в одной из них не обнаружить загадочного блока GEN_PULS. Но не в этом дело, а в том, что за столько лет в библиотеках не появилось классического импульсного ПИД регулятора, с заведомо правильной логикой работы непосредственно от разработчика.
GEN_PULSE - из библиотеки OSCAT
Вложение 24049
Если лень подключать эту библиотеку, то вот код
Код:FUNCTION_BLOCK GEN_PULSE
VAR_INPUT
ENQ : BOOL := TRUE;
PTH : TIME;
PTL : TIME;
END_VAR
VAR_OUTPUT
Q : BOOL;
END_VAR
VAR
tx: TIME;
tn: TIME;
init: BOOL;
END_VAR
IF enq THEN
tx := DWORD_TO_TIME(T_PLC_MS());
IF NOT init THEN init := TRUE; tn := tx; END_IF;
IF tx - tn >= SEL(Q, PTL, PTH) THEN
tn := tn + SEL(Q, PTL, PTH);
Q := NOT Q;
END_IF;
ELSE
Q := FALSE;
init := FALSE;
END_IF;
Подскажите пожалуйста, какой блок ПИД-регулятора использовать для языка LD? Может нужно как то особенно блок вставлять? Ругается, что на вход идет BOOL, а не REAL, для LD это понятно...
Добрый день! Подскажите пожалуйста есть ли ошибки в подходу к построению импульсного ПИД в сообщении http://www.owen.ru/forum/showthread....l=1#post206540 ? У меня основной вопрос по формированию 1 импульса. Как классически должна расчитываться его длительность?
Хочу использовать "функциональный блок регулятора с АНР для трехпозиционного ИМ без
датчика положения (APID_VALVE)" из биб-ки PID_Reg2
Для поддержки т-ры.
Вложение 24541
Есть пара вопросов:
1.
PV_0:REAL – начальное значение регулируемого параметра или значение параметра при
нулевой мощности управляющего сигнала. Это какое нужно установить значение?
2.
SYNC:BOOL – установка положения задвижки через вход PV. При установке значения True
положение задвижки (в диапазоне от 0 до 1) считывается из входа PV и сохраняется во
внутренней переменной ФБ. Это как? Можно на пальцах?
В данный момент использую ручное управление задвижкой без датчика положения - (VALVE_REG_NO_POS) из биб-ки PID_Regulators
3.
Возможна ли такая логика работы: Регулирование происходит APID_VALVE при нажатии "Ручное управление" управляю блоком VALVE_REG_NO_POS? В APID_VALVE нет времени реверса ИМ, как с этим быть?
Т.к. датчик положения регулирующего органа не предусмотрен, то для устранения рассогласования между реальным положением и виртуальным, сделал импульсы доводки, по аналогии с ТРМ-ами.
Для этого и нужен блок "GEN_PULSE".
Импульсы доводки формируются если на входе "VALVE_REG_NO_POS" значение равно "0" или "100".
И снова здравствуйте.
Помогите пожалуйста разобраться с нелегким вопросом))
У меня имеется контроллер ПЛК150 с тремя подключенными датчиками температуры и 2 регулируемых клапана. Один датчик температуры наружного воздуха и два датчика теплоносителя, каждый на свой клапан.
Какой регулятор стоит выбрать? Какие значения мне нужно знать чтобы регулировать клапаны по 4-20? До этого работал только в языке LD и только с релейной логикой. Сильно не пинайте.
Заранее спасибо за советы.
У пид регулятора есть выходной сигнал OUT: REAL; – выходной сигнал регулятора, от -100 до 100% относительной мощности;
Можно этот сигнал использовать на задвижку напрямую?
Как понять от -100 до 100% относительной мощности, никак не допрет, получается всего навсего преобразовать (- 100 +100) в (0 +100)?
В теории сигнал У ПИДа аналговый от: 1.175494351e-38 до 3.402823466e+38, но обычно такими значениями не разбрасываются и ограничивают сигнал сверху и снизу, то есть вы можете установить любое значение если используете PID из библиотеки util. Далее если у вас задвижка с дискретным управлением, вам надо аналог преобразовать в дискрету, пропустив сигнал через ШИМ. У меня почему-то проблемы были с блоком VALVE_NO_POS.
Подскажите: PID_2POS сохраняет настройки ПИД-коэффициентов или при новом включении необходимо опять включать автонастройку? Сам блок очень понравился в работе (правда настольном), но вот на сколько будет удобно всякий раз автонастраивать - большой вопрос.
Хочу спросить у Вас! У меня 3х поз. задвижка без д.д. Я настроил ее откр/закр. через блок VALVE_REG_NO_POS. Она у меня откр/закр от 0 до 100% как надо.
Теперь нужно настроить регулирование. Взял PID_3POS_IM_ANR + VALVE_REG_NO_POS. Регулирую температуру. При открытии темп.повышается, а при закрытии понижается, использую сигнал от 0 до +100 отрезая отрицательную часть. Короче говоря при завершении АНР начинаются колебания от 0 до 100, т.е. задвижка полностью закрывается и открывается. Устаканивания не происходит. Инертность около 2 минут.
1. Время хода задвижки в блоке PID_3POS_IM_ANR TVAL в секундах?
2. Может использовать "Холодильник"?
3.Из -за чего может быть такая болтанка?
я с этой бибкой не работаю, мне достаточно классического ПИД-а из степа или оскат, у меня используется оборудование аналоговое с регулированием от 0 до 100% без всяких 3-х позиционных или ШИМ-ов и т.п., для обратной зависимости достаточно пропорциональный задавать с минусом. По поводу колебаний это и должно быть при автонастройке и в это время вмешиваться в работу нельзя, как долго это будет происходить известно только самой программе
Добрый день, уважаемые форумчане.
Много было тем про регуляторы и управление электроприводами клапанов по сигналу "Больше", "Стоп" и "Меньше", но к моему большому сожалению ни один из них не оправдал моих ожиданий и работали они не очень корректно, возможно потому, что применялись не на контроллерах ОВЕН а на контроллерах BECKHOFF, вот и пришлось мне написать небольшую программку "прокладку", как тут все называют для PID регулятора из библиотеки UTIL. Буду рад комментариям и замечаниям. Не получилось у меня отредактировать код, так чтобы он был наглядным, поэтому приложил файл с программой.
FUNCTION_BLOCK VALVE_3_POS
VAR
RANGE: REAL; (*ДИАПАЗОН ПИД РЕГУЛЯТОРА*)
PERIOD: TIME; (*ПЕРИОД ИМПУЛЬСОВ*)
TIME_PULSE: TIME; (*ВРЕМЯ ИМПУЛЬСА*)
TIME_PULSE_R: REAL;
TIME_PAUSE: TIME; (*ВРЕМЯ ПАУЗЫ*)
TIME_PAUSE_R: REAL;
TMR_MAX_HIGHT: TP; (*ТАЙМЕР ВЫДАЧИ ИМПУЛЬСА ПРИ ПИД > 0*)
TMR_MIN_HIGHT: TP; (*ТАЙМЕР ВЫДАЧИ ИМПУЛЬСА ПРИ ПИД < 0*)
TMR_MAX_LOW: TP; (*ТАЙМЕР ВЫДАЧИ ПАУЗЫ ИМПУЛЬСА ПРИ ПИД > 0*)
TMR_MIN_LOW: TP; (*ТАЙМЕР ВЫДАЧИ ПАУЗЫ ИМПУЛЬСА ПРИ ПИД < 0*)
PERIOD_R: REAL;
MIN_TIME_PULSE_R: REAL;
MIN_TIME_PULSE:TIME; (*МИНИМАЛЬНОЕ ВРЕМЯ ИМПУЛЬСА*)
F_TRIG_MAX:F_TRIG; (*ТРИГГЕР ЗАПУСКА ТАЙМЕРА ПАУЗЫ ПРИ ПИД > 0*)
F_TRIG_MIN:F_TRIG; (*ТРИГГЕР ЗАПУСКА ТАЙМЕРА ПАУЗЫ ПРИ ПИД < 0*)
END_VAR
VAR_INPUT
IN_VAL: REAL; (*ВЫХОД ПИД*)
IN_VAL_MIN: REAL := -100; (*МИНИМАЛЬНОЕ ЗНАЧЕНИЕ ПИД НА ВЫХОДЕ ЛУЧШЕ ЗАДАТЬ -15*)
IN_VAL_MAX: REAL := 100; (*МАКСИМАЛЬНОЕ ЗНАЧЕНИЕ ПИД НА ВЫХОДЕ ЛУЧШЕ ЗАДАТЬ 15*)
FULL_MOTION_TIME: REAL := 120; (*ВРЕМЯ ХОДА ПРИВОДА ПРИМЕР: 120*)
DEAD_ZONE: REAL := 0.1; (*ЗОНА НЕЧУВСТВИТЕЛЬНОСТИ ПРИМЕР: 0.1*)
AUTO: BOOL := TRUE; (*АВТОМАТИЧЕСКИЙ РЕЖИМ РАБОТЫ ЕСЛИ TRUE и РУЧНОЙ РЕЖИМ РАБОТЫ ЕСЛИ FALSE*)
OPENED: BOOL := FALSE; (*ОТКРЫТИЕ*)
CLOSED: BOOL := FALSE; (*ЗАКРЫТИЕ*)
END_VAR
VAR_OUTPUT
MORE: BOOL; (*БОЛЬШЕ*)
LESS: BOOL; (*МЕНЬШЕ*)
END_VAR
(*\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\НАЧ АЛО\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*)
(*АВТОМАТИЧЕСКИЙ РЕЖИМ РАБОТЫ*)
IF AUTO THEN
RANGE := IN_VAL_MAX - IN_VAL_MIN; (*ОТПРЕДЕЛЕНИЕ ДИАПАЗОНА*)
MIN_TIME_PULSE_R := ( FULL_MOTION_TIME * 0.005 )*1000; (*ОПРЕДЕЛЕНИЕ МИНИМАЛЬНОЙ ДЛИТ. ИМПУЛЬСА*)
MIN_TIME_PULSE := REAL_TO_TIME( MIN_TIME_PULSE_R ); (*ПРЕОБРАЗОВАНИЕ ТИПОВ*)
PERIOD_R := ( FULL_MOTION_TIME / 20 ); (*ОПРЕДЕЛЕНИЕ ПЕРИОДА ИМПУЛЬСОВ*)
PERIOD := REAL_TO_TIME( PERIOD_R ) * 1000; (*ПРЕОБРАЗОВАНИЕ ТИПОВ*)
(*\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*)
(*ВЫДАЧА ИМПУЛЬСА ПРИ ПОЛОЖИТЕЛЬНОМ ЗНАЧЕНИИ НА ВЫХОДЕ ПИД*)
IF (IN_VAL_MIN <0 AND IN_VAL_MAX >0) AND IN_VAL > (0 + DEAD_ZONE) THEN
LESS := FALSE; (*ОБНУЛЕНИЕ СИГНАЛА "МЕНЬШЕ" ЕСЛИ ОСТАЛСЯ АКТИВИРОВАНЫМ*)
TMR_MIN_LOW (IN:= FALSE, PT := TIME_PAUSE); (*ОБНУЛЕНИЕ ТАЙМЕРА ПАУЗЫ*)
TIME_PULSE_R := ( ( IN_VAL * PERIOD_R) / (RANGE / 2) )* 1000; (*РАСЧЕТ ТЕК ВРЕМЕНИ ИМПУЛЬСА*)
TIME_PAUSE_R := (PERIOD_R*1000 - TIME_PULSE_R); (*РАСЧЕТ ТЕКУЩЕГО ВРЕМЕНИ ПАУЗЫ*)
TIME_PULSE := REAL_TO_TIME ( TIME_PULSE_R );
TIME_PAUSE := REAL_TO_TIME ( TIME_PAUSE_R );
IF TIME_PULSE > MIN_TIME_PULSE THEN (*СРАВНЕНЕНИЕ МИН ВРЕМЕНИ ИМПУЛЬСА И РАСЧ ТЕКУЩЕГО*)
TMR_MAX_HIGHT (IN:= TRUE AND NOT TMR_MAX_LOW.Q, PT := TIME_PULSE); (*ЗАПУСК ТАЙМЕРА*)
END_IF
F_TRIG_MAX (CLK := TMR_MAX_HIGHT.Q); (*ТРИГГЕР ЗАУСКА ТАЙМЕРА ПАУЗЫ ПРИ*)
TMR_MAX_LOW (IN:= F_TRIG_MAX.Q, PT := TIME_PAUSE); (*ЗАПУСК ТАЙМЕРА ПАУЗЫ*)
END_IF
(*ОБНУЛЕНИЕ ТАЙМЕРА ВЫДАЮЩЕГО ИМПУЛЬСЫ ПОКА РАБОТАЕТ ТАЙМЕР ПАУЗЫ*)
IF TMR_MAX_LOW.Q OR (TIME_PULSE < MIN_TIME_PULSE) THEN
TMR_MAX_HIGHT (IN:= FALSE, PT := TIME_PULSE);
END_IF
(*АКТИВАЦИЯ ВЫХОДА РЕГУЛЯТОРА "БОЛЬШЕ" ПОКА РАБОТАЕТ ТАЙМЕР ИМПУЛЬСА И РАСЧЕТНЫМ ВРЕМЕНЕМ*)
IF (TMR_MAX_HIGHT.Q OR IN_VAL = IN_VAL_MAX) AND NOT LESS THEN
MORE := TRUE; (*АКТИВАЦИЯ "БОЛЬШЕ"*)
ELSE
MORE := FALSE; (*ИНАЧЕ ДЕАКТИВАЦИЯ "БОЛЬШЕ"*)
END_IF
(*\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*)
(*\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*)
(*ВЫДАЧА ИМПУЛЬСА ПРИ ОТРИЦАТЕЛЬНОМ ЗНАЧЕНИИ НА ВЫХОДЕ ПИД*)
IF (IN_VAL_MIN <0 AND IN_VAL_MAX >0) AND IN_VAL < (0 - DEAD_ZONE) THEN
MORE := FALSE; (*ОБНУЛЕНИЕ СИГНАЛА "БОЛЬШЕ" ЕСЛИ ОСТАЛСЯ АКТИВИРОВАННЫМ*)
TMR_MAX_LOW (IN:= FALSE, PT := TIME_PAUSE); (*ОБНУЛЕНИЕ ТАЙМЕРА ПАУЗЫ*)
TIME_PULSE_R := ( ( IN_VAL * PERIOD_R *(-1) ) / ( RANGE / 2) ) * 1000; (*РАСЧЕТ ВРЕМЕНИ ИМПУЛЬСА*)
TIME_PAUSE_R := (PERIOD_R*1000 - TIME_PULSE_R); (*РАСЧЕТ ТЕКУЩЕГО ВРЕМЕНИ ПАУЗЫ*)
TIME_PULSE := REAL_TO_TIME ( TIME_PULSE_R );
TIME_PAUSE := REAL_TO_TIME ( TIME_PAUSE_R );
IF TIME_PULSE > MIN_TIME_PULSE THEN (*СРАВНЕНЕНИЕ МИН ВР ИМПУЛЬСА И РАСЧЕТНОГО ТЕКУЩЕГО*)
TMR_MIN_HIGHT (IN:= TRUE AND NOT TMR_MIN_LOW.Q, PT := TIME_PULSE); (*ЗАПУСК ТАЙМЕРА*)
END_IF
F_TRIG_MIN (CLK := TMR_MIN_HIGHT.Q); (*ТРИГГЕР ЗАУСКА ТАЙМЕРА ПАУЗЫ ПРИ*)
TMR_MIN_LOW (IN:= F_TRIG_MIN.Q, PT := TIME_PAUSE); (*ЗАПУСК ТАЙМЕРА ПАУЗЫ ИМПУЛЬСА*)
END_IF
(*ОБНУЛЕНИЕ ТАЙМЕРА ВЫДАЮЩЕГО ИМПУЛЬСЫ ПОКА РАБОТАЕТ ТАЙМЕР ПАУЗЫ*)
IF TMR_MIN_LOW.Q OR (TIME_PULSE < MIN_TIME_PULSE) THEN
TMR_MIN_HIGHT (IN:= FALSE, PT := TIME_PULSE);
END_IF
(*АКТИВАЦИЯ ВЫХОДА РЕГУЛЯТОРА "МЕНЬШЕ" ПОКА РАБОТАЕТ ТАЙМЕР ИМПУЛЬСА И РАСЧЕТНЫМ ВРЕМЕНЕМ*)
IF (TMR_MIN_HIGHT.Q OR IN_VAL = IN_VAL_MIN) AND NOT MORE THEN
LESS := TRUE; (*АКТИВАЦИЯ "МЕНЬШЕ"*)
ELSE
LESS := FALSE; (*ИНАЧЕ ДЕАКТИВАЦИЯ "МЕНЬШЕ"*)
END_IF
END_IF
(*\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\*)
(*\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\*)
(*РУЧНОЙ РЕЖИМ РАБОТЫ*)
IF NOT AUTO THEN
IF OPENED AND NOT LESS THEN (*ЕСЛИ АВТИВИРОВАН ВХОД "OPENED" и НЕ АКТИВНО "МЕНЬШЕ"*)
MORE := TRUE; (*АКТИВАЦИЯ "БОЛЬШЕ"*)
ELSE
MORE := FALSE; (*ИНАЧЕ ДЕАКТИВАЦИЯ "БОЛЬШЕ"*)
END_IF
IF CLOSED AND NOT MORE THEN (*ЕСЛИ АВТИВИРОВАН ВХОД "CLOSED" и НЕ АКТИВНО "БОЛЬШЕ"*)
LESS := TRUE; (*АКТИВАЦИЯ "МЕНЬШЕ"*)
ELSE
LESS := FALSE; (*ИНАЧЕ ДЕАКТИВАЦИЯ "МЕНЬШЕ"*)
END_IF
END_IF
(*\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\*)
(*\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\К ОНЕЦ\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\*)
А не проще выложить сразу файлом?
Выкладываю ФБ в собранном виде, кому лень. ФБ с комментариями, но если что-то будет не понятно, спрашивайте..
На вход ФБ IN_VAL нужно подключить выход ФБ PID из библиотеки UTIL, на ФБ PID входы Y_MIN должен быть равен входу ФБ VALVE_3_POS IN_VAL_MIN, а Y_MAX должен быть равен IN_VAL_MAX. Вроде все, остальное должно быть понятно.
Что-то жутко большой размер кода для такой задачи.
ну как вариант LESS := CLOSED AND NOT MORE;
я не работаю с трехпозиционными клапанами, не знаю как должно быть
Я один понимаю, почему классический ПИД нельзя использовать с 3-х позиционными регуляторами???
Бибку я уже выкладывал. Повторяю.
X - измеряемая величина
XS - уставка
К, Т - пропорциональный и интегральный коэффициенты ПИ регулятора (диф составляющая в POU отсутствует)
Step - время цикла пересчета регулятора
MinPulse - минимальное время импульса на привод. При меньшем вычисленном в цикле времени происходит суммирование с предыдущем накоплением и запоминание суммы.
Stroke - время полного хода привода
Low, Hight - ручное управление выходами.
Вы исходный код просмотрите, он открытый.
Грубо, произведен перевод обычного ПИД (ПИ) регулятора в дифференциальную форму dt (с) = (dY(%)/100%) * Stroke (с)
Поэтому указанные П и И коэффициенты "классического" ПИДа пересчитываются. Так удобнее.