08:24 SIEMENS SCL CONT_C FB41 Continuous Control PID S7/C7 CPUs | |
|
SIEMENS SCL CONT_C FB41 Continuous Control PID S7/C7 CPUs FB “CONT_C” is used on SIMATIC S7 programmable controllers to control technical processes with continuous input and output variables. During parameter assignment, you can activate or deactivate subfunctions of the PID controller to adapt the controller to the process. FUNCTION_BLOCK FB41 TITLE ="Непрерывный PID регулятор" AUTHOR : SIMATIC FAMILY : ICONT NAME : CONT_C VERSION : " 1.5" //reversed by komatic VAR_INPUT COM_RST : BOOL ; //Полный рестарт MAN_ON : BOOL := TRUE; //Ручной режим включить PVPER_ON : BOOL ; //Чтение входной переменной с периферии включить P_SEL : BOOL := TRUE; //Пропорциональную составляющую включить I_SEL : BOOL := TRUE; //Интегральную составляющую включить INT_HOLD : BOOL ; //Удержание интегральной составляющей I_ITL_ON : BOOL ; //Инициализировать интегральную составляющую D_SEL : BOOL ; //Дифференциальную составляющую включить CYCLE : TIME := T#1S; //Время выполнения блока SP_INT : REAL ; //Внутреннее задание PV_IN : REAL ; //Входная переменная PV_PER : WORD ; //Входная переменная (периферия) MAN : REAL ; //Ручной выход GAIN : REAL := 2.000000e+000; //Коэффициент пропорциональности TI : TIME := T#20S; //Время интегрирования TD : TIME := T#10S; //Время дифференцирования TM_LAG : TIME := T#2S; //Время действия дифференциальной составляющей DEADB_W : REAL ; //Ширина зоны нечувствительности LMN_HLM : REAL := 1.000000e+002; //Верхний предел выходного сигнала LMN_LLM : REAL ; //Нижний предел выходного сигнала PV_FAC : REAL := 1.000000e+000; //Коэффициент для корректировки входной переменной (умножение) PV_OFF : REAL ; //Коэффициент для корректировки входной переменной (сложение) LMN_FAC : REAL := 1.000000e+000; //Коэффициент для корректировки выходной переменной (умножение) LMN_OFF : REAL ; //Коэффициент для корректировки входной переменной (сложение) I_ITLVAL : REAL ; //Начальное значение интегральной составляющей DISV : REAL ; //Возмущающая переменная END_VAR VAR_OUTPUT LMN : REAL ; //Выходное значение LMN_PER : WORD ; //Выходное значение (переферия) QLMN_HLM : BOOL ; //Верхний предел выхода достигнут QLMN_LLM : BOOL ; //Нижний предел выхода достигнут LMN_P : REAL ; //Пропорциональная составляющая LMN_I : REAL ; //Интегральная составляющая LMN_D : REAL ; //Дифференциальная составляющая PV : REAL ; //Входная переменная ER : REAL ; //Сигнал рассогласования END_VAR VAR sInvAlt : REAL ; sIanteilAlt : REAL ; sRestInt : REAL ; sRestDif : REAL ; sRueck : REAL ; sLmn : REAL ; sbArwHLmOn : BOOL ; //Выход достиг максимального значения sbArwLLmOn : BOOL ; //Выход достиг минимального значения sbILimOn : BOOL := TRUE; END_VAR VAR_TEMP Hvar : REAL ; //Hilfsvariable rCycle : REAL ; //Abtastzeit in real Diff : REAL ; //Дnderungswert Istwert : REAL ; //Istwert ErKp : REAL ; //Вспомогательная переменная rTi : REAL ; //Integrationszeit in real rTd : REAL ; //Differentiationszeit in real rTmLag : REAL ; //Verzцgerungszeit in real Panteil : REAL ; //P-Anteil Ianteil : REAL ; //I-Anteil Danteil : REAL ; //D-Anteil Verstaerk : REAL ; //Verstдrkung RueckDiff : REAL ; //Differenz des Rьckkopplungswertes RueckAlt : REAL ; //Alter Rьckkopplungswert dLmn : REAL ; //Stellwert gf : REAL ; //Hilfwert rVal : REAL ; //Real Hilfsvariable END_VAR BEGIN IF COM_RST //Полный рестарт THEN // Обнуление переменных sIanteilAlt:=I_ITLVAL; LMN:=0.0; //Выходное значение QLMN_HLM:=0; //Верхний предел выхода достигнут QLMN_LLM:=0; //Нижний предел выхода достигнут LMN_P:=0.0; //Пропорциональная составляющая LMN_I:=0.0; //Интегральная составляющая LMN_D:=0.0; //Дифференциальная составляющая LMN_PER:=0; //Выходное значение (периферия) PV:=0.0; //Входная переменная ER:=0.0; //Сигнал рассогласования sInvAlt:=0.0; sRestInt:=0.0; sRestDif:=0.0; sRueck:=0.0; sLmn:=0.0; sbArwHLmOn:=0; sbArwLLmOn:=0; ELSE rCycle:= DINT_TO_REAL(TIME_TO_DINT(CYCLE)) / 1000.0; //Время выполнения блока в секундах Istwert:=INT_TO_REAL(WORD_TO_INT(PV_PER)) * 100.0 / 27648.0; // Получили входную переменную от периферии (0-2768 в 0-100) Istwert:=Istwert * PV_FAC + PV_OFF; // Скорректировали входную переменную IF NOT PVPER_ON THEN Istwert:=PV_IN; END_IF; // Если периферийный вход отключен берем переменную из PV_IN PV:= Istwert; // Входная переменная ErKp:=SP_INT - PV; // Получили рассогласование между заданием и входом IF ErKp < (-DEADB_W) THEN ER:=ErKp+DEADB_W; // Если рассогласование больше зоны нечувствительности ELSIF ErKp > DEADB_W THEN ER:=ErKp-DEADB_W; // уменьшаем рассогласование на величину зоны нечуств. ELSE ER:=0.0; // иначе принимаем рассогласование равным нулю. END_IF; ErKp:=ER * GAIN; // Рассогласование, умноженное на кфт пропорциональности rTi:=DINT_TO_REAL(TIME_TO_DINT(TI)) / 1000.0; // Время интегрирования в секундах rTd:=DINT_TO_REAL(TIME_TO_DINT(TD)) / 1000.0; // Время дифференцирования в секундах rTmLag:=DINT_TO_REAL(TIME_TO_DINT(TM_LAG)) / 1000.0; // Время действия диф.составляющей в секундах // Проверка на допустимость временных настроек регулятора IF rTi < (rCycle * 0.5) THEN rTi:=rCycle * 0.5; END_IF; // Минимальное время интегрирования - Cycle / 2 IF rTd < rCycle THEN rTd:=rCycle; END_IF; // Минимальное время дифференцирования - Cycle IF rTmLag < rCycle * 0.5 THEN rTmLag:=rCycle * 0.5; END_IF; // Минимальное время действия диф.сост.- Cycle / 2 // Вычисление пропорциональной составляющей IF P_SEL THEN Panteil:=ErKp; // Если выбрана пропорциональная составляющая ELSE Panteil:=0.0; END_IF; //--------------------------------------------------------------------------------------------- // Вычисление интегральной составляющей //--------------------------------------------------------------------------------------------- IF I_SEL //Интегральную составляющую включить THEN IF I_ITL_ON //Инициализировать интегральную составляющую THEN Ianteil:=I_ITLVAL; sRestInt:=0.0; ELSE IF MAN_ON //Ручной режим THEN Ianteil:=sLmn - Panteil - DISV; sRestInt:=0.0; ELSE //Автоматический режим Diff:=rCycle / rTi *(ErKp + sInvAlt) * 0.5 + sRestInt; IF ((Diff>0.0) AND sbArwHLmOn OR INT_HOLD)OR ((Diff<0.0) AND sbArwLLmOn) THEN Diff:=0.0; END_IF; Ianteil:=sIanteilAlt + Diff; sRestInt:=sIanteilAlt - Ianteil + Diff; END_IF; END_IF; ELSE Ianteil:=0.0; sRestInt:=0.0; END_IF; //--------------------------------------------------------------------------------------------- //Формирование дифференциальной составляющей //--------------------------------------------------------------------------------------------- Diff:=ErKp; IF (NOT MAN_ON) AND D_SEL THEN Verstaerk:= rTd / (rCycle * 0.5 + rTmLag); Danteil:= (Diff - sRueck) * Verstaerk; RueckAlt:= sRueck; RueckDiff:= rCycle / rTd * Danteil + sRestDif; sRueck:= RueckDiff + RueckAlt; sRestDif:=RueckAlt - sRueck + RueckDiff; ELSE Danteil:=0.0; sRestDif:=0.0; sRueck:=Diff; END_IF; //--------------------------------------------------------------------------------------------- //Формирование выхода //--------------------------------------------------------------------------------------------- dLmn:=Panteil + Ianteil + Danteil + DISV; IF MAN_ON // Если ручной режим THEN dLmn:=MAN; // Ручной выход ELSE IF (NOT I_ITL_ON) AND I_SEL THEN IF (Ianteil > (LMN_HLM - DISV)) AND (dLmn > LMN_HLM) AND ((dLmn - LMN_D)> LMN_HLM) THEN rVal:=LMN_HLM - DISV; gf:= dLmn - LMN_HLM; rVal:=Ianteil - rVal; IF rVal > gf THEN rVal:=gf; END_IF; Ianteil:=Ianteil - rVal; ELSE IF (Ianteil < (LMN_LLM - DISV)) AND (dLmn < LMN_LLM) AND ((dLmn - LMN_D) < LMN_LLM) THEN rVal:=LMN_LLM - DISV; gf:=dLmn - LMN_LLM; rVal:=Ianteil - rVal; IF rVal < gf THEN rVal:=gf; END_IF; Ianteil:=Ianteil - rVal; END_IF; END_IF; END_IF; END_IF; LMN_P:=Panteil; LMN_I:=Ianteil; LMN_D:=Danteil; sInvAlt:=ErKp; sIanteilAlt:=Ianteil; sbArwHLmOn:=0; sbArwLLmOn:=0; IF (dLmn >= LMN_HLM) THEN QLMN_HLM:=1; QLMN_LLM:=0; dLmn:=LMN_HLM; sbArwHLmOn:=1; ELSE QLMN_HLM:=0; IF (dLmn <= LMN_LLM) THEN QLMN_LLM:=1; dLmn:=LMN_LLM; sbArwLLmOn:=1; ELSE QLMN_LLM:=0; END_IF; END_IF; sLmn:=dLmn; dLmn:=sLmn * LMN_FAC + LMN_OFF; LMN:=dLmn; dLmn:=LMN * 2.764800e+002; IF dLmn >= 3.251100e+004 THEN dLmn:=3.251100e+004; ELSE IF dLmn <= -3.251200e+004 THEN dLmn:=-3.251200e+004; END_IF; END_IF; LMN_PER:= INT_TO_WORD(REAL_TO_INT(dLmn)); END_IF; END_FUNCTION_BLOCK | |
|
| |
| Всего комментариев: 0 | |
