Добрый вечер. А можно как-то получить исходник (PID_INVERTER.EXP)?. С данного ресурса скачать не получается - черный экран. Спасибо.
Добрый вечер. А можно как-то получить исходник (PID_INVERTER.EXP)?. С данного ресурса скачать не получается - черный экран. Спасибо.
Теория и практика иногда сталкиваются. Когда это случается, теория проигрывает. Всегда. (Закон Линуса)
Подскажите какую библиотеку пид лучше использовать. Модель - нагревательный элемент внутри замкнутой камеры, необходимо поддерживать температуру с точностью до градуса. Нужно чтобы по приближению к уставке пид работал на опережения как бы предсказывая и уменьшал выходную мощность
т.е подбирать коэффициенты?
Прошло уже много лет, а тема до сих пор актуальна! Боролся и я в свое время с библиотечными творениями, но закончилось это написанием простого функционального блока, который устраивает в 99% случаев.
Вот код:
FUNCTION_BLOCK PID_REG
VAR_INPUT
EN:BOOL; (*Включить регулятор*)
SETP: REAL ; (*Уставка*)
FEED: REAL ; (*Обратная связь*)
MAN_IN: REAL; (*Выход в ручном режиме*)
KP: REAL ; (*Коэффициент усиления*)
KI: REAL ; (*Коэффициент усиления интегрального звена*)
KD: REAL; (*Коэффициент усиления дифференциального звена*)
MAX_V: REAL; (*Максимум выхода*)
MIN_V: REAL; (*Минимум выхода*)
RES: BOOL; (*Сброс регулятора*)
MAN: BOOL; (*Ручной режим*)
CLOCK: DINT; (*Текущее время*)
END_VAR
(*Вход CLOCK - часы, постоянно инкрементируемое двойное слово. Частота может быть любой.
Это зависит от того с какой точностью необходимо обрабатывать временные интервалы.*)
VAR_OUTPUT
END:BOOL; (*Регулятор включен*)
LMN: REAL ; (*Выход регулятора*)
END_VAR
VAR
E_N,E_N1,E_N2,U_N0,U_N1: REAL;
DELTA_T,KI_DISCR,KD_DISCR: REAL;
ST0,ST1: DINT;
END_VAR
(*Собственно код*)
IF EN THEN (*Если включено, то ПОЕХАЛИ!*)
(*Посчитаем отклонения во все моменты времени*)
E_N2:=E_N1;
E_N1:=E_N;
E_N:=SETP-FEED;
ST1:=ST0;
ST0:=CLOCK;
DELTA_T:=DINT_TO_REAL(ST0-ST1)/10.0; (*Временной интервал X Сек. Часы на входе с дискретностью X/10 Сек*)
(*А теперь с коэффициентами*)
KI_DISCR:=KI*DELTA_T;
KD_DISCR:=KD/DELTA_T;
(*Собственно - выход, то есть сумма интегрального и дифференциального звена*)
U_N0:=U_N1+KI_DISCR*E_N+KD_DISCR*(E_N-2*E_N1+E_N2);
IF KI>0 THEN
IF KP*E_N+U_N0>MAX_V THEN (*Проверка максимума*)
U_N0:=MAX_V-KP*E_N;
END_IF;
IF KP*E_N+U_N0<MIN_V THEN (*Проверка минимума*)
U_N0:=MIN_V-KP*E_N;
END_IF;
ELSE U_N0:=0;
END_IF;
IF RES=TRUE THEN (*Сброс, однако*)
U_N0:=0;
END_IF;
IF MAN=TRUE THEN (*Ручной режим*)
U_N0:=MAN_IN-KP*E_N;
END_IF;
U_N1:=U_N0;
LMN:=KP*E_N+U_N0; (*Добрались, таки до выхода*)
END:=TRUE; (*Все посчитано*)
ELSE
END:=FALSE; (*Регулятор отключен, дальше тоже ничего не выполняется*)
LMN:=0; (*Выход, на всякий случай обнулим*)
END_IF;
Пробуйте, видоизменяйте как душе угодно!
Последний раз редактировалось Алексей Дмитриев; 18.06.2013 в 09:44.
Вопрос по PID из Util.lib
Уставка 18, когда ставлю значение 18 на измеряемом входе, то выход фиксируется на том значении, которое было или становится чуть меньше или чуть больше в зависимости от предыдущего состояния.
например при входе 17,9 доползло до 100 (ограничение лимита Y_MAX), ставлю на вход 18 и значение на выходе 99,8 и снижаться начинает только если на входе 18,1
Разве не должно значение стать 0 (Y_MIN) или продолжать снижаться до 0?
Y_OFFSET равен 0