
УТС Грудяева / 9091_Боброва_лаб_8
.docxМИНОБРНАУКИ РОССИИ
САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ ЭЛЕКТРОТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ
«ЛЭТИ» ИМ. В.И. УЛЬЯНОВА (ЛЕНИНА)
ОТЧЕТ
по лабораторной работе №8 по дисциплине «Проектирование распределенных систем управления»
Тема: «ПИД-регулирование»
Студентка гр. 9091 Боброва Н.Ю.
Преподаватель Грудяева Е.С.
Санкт-Петербург
2024
Цель работы
изучение работы ПИД-регулятора в PLC.
Содержание работы
1. Создать исходную программу на языке SCL для регулирования внутренней переменной.
2. Заполнить таблицу символов необходимыми данными.
3. Скомпилировать программу.
4. Осуществить загрузку программных блоков в контроллер и убедиться в отсутствии ошибок.
5. Проверить программу на работоспособность, задавая входные сигналы.
№ Варианта |
2 |
Проект будет собран на основе Лабораторной работы №1
Заполняем таблицу символов
Собираем код программы
При компиляции ошибок не обнаружено
Код программы
FUNCTION_BLOCK CONT_C
AUTHOR : SIMATIC
FAMILY : ICONT
NAME : CONT_C//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; //Время действия дифференциальной составляющей 112
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 rea
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
FUNCTION scale : real
VAR_INPUT
inVAL : REAL;
inMAX, inMIN: REAL;
outMAX, outMIN: REAL;
END_VAR
scale := (inVAL + inMIN)*(outMAX-outMIN)/(inMAX-inMIN)+outMIN;
END_FUNCTION
FUNCTION_BLOCK Vent_dP
VAR_input
control_signal : REAL; // Управляющий сигнал с ПИД-регулятора (0-100%)
END_VAR
VAR
cur, req : REAL;
dPdec: REAL;
dPinc: REAL;
init :BOOL;
END_VAR
VAR_output
dP : REAL; // перепад давления на вентиляторе (0-1500 Па)
END_VAR
IF NOT init THEN
dP := 0.0;
init:= 1;
END_IF;
req := scale (inVAL := control_signal
, inMIN := 0.0
, inMAX := 100.0
, outMIN := 0.0
, outMAX := 1500.0
);
IF cur <(req+0.15) THEN
cur := cur + 0.1;
ELSIF cur >(req-0.15) THEN
cur := cur - 0.1;
ELSE
cur := cur;
END_IF;
dP := cur;
END_FUNCTION_BLOCK
DATA_BLOCK Values
STRUCT
MAN_ON_Value : BOOL;
SP_INT_Value : REAL;
GAIN_Value : REAL;
TI_Value : TIME;
TD_Value : TIME;
PID_LMN_Value : REAL;
Vent_1 : REAL;
END_STRUCT
BEGIN
END_DATA_BLOCK
FUNCTION_BLOCK Additional1
VAR
PID_1 : CONT_C;
END_VAR
PID_1(MAN_ON := Values.MAN_ON_Value
,sp_int := Values.SP_INT_Value
,PV_IN := Values.Vent_1
,GAIN := Values.GAIN_Value
,TI := Values.TI_Value
,TD := Values.TI_Value
);
Values.PID_LMN_Value := PID_1.LMN;
;
END_FUNCTION_BLOCK
FUNCTION_BLOCK Additional2
VAR
Vent_1 : Vent_dP;
END_VAR
Vent_1(control_signal := Values.PID_LMN_Value
);
Values.Vent_1 := Vent_1.dP;
;
END_FUNCTION_BLOCK
ORGANIZATION_BLOCK OB32
VAR_TEMP
// Reserved
info : ARRAY[0..19] OF BYTE;
// Temporary Variables
END_VAR
Additional1.Additional1_DB();
;
END_ORGANIZATION_BLOCK
ORGANIZATION_BLOCK OB35
VAR_TEMP
// Reserved
info : ARRAY[0..19] OF BYTE;
// Temporary Variables
END_VAR
Additional2.Additional2_DB();
;
END_ORGANIZATION_BLOCK
Загрузим скомпилированную программу в контроллер и убедимся, что нет ошибок.
Введём нужные для отслеживания переменные в VAT-таблицу.
Мы установили значение (SP) и теперь выходной сигнал стремится к этому же значению значит ПИД–регулятор – работает.
Вывод В данной работе были получены навыки настройки ПИД-регулятора в PLC,
также изучена работа ПИД-регулятора в PLC.