МУ_Проектирование распределенных систем управления 04.09.2023
.pdfЗадайте адреса для функционального блока Controlling и блока данных Controlling_DB, в которых будет вызываться блок CONT_C (аналогично тому, как сделано в таблице 3.2 в работе №3).
Задайте адрес функции scale.
Задайте адрес функционального блока Vent_dP – имитационная модель зависимости перепада давления от задания на преобразователь частоты вентилятора.
Задайте адреса для функционального блока read_vent и блока данных read_vent_DB, в которых будет вызываться блок Vent_dP (аналогично тому, как сделано в таблице 3.2 в работе №3).
Задайте имя блоку данных, где будут храниться переменные – переменные, соответствующие входам и выходам блока CONT_C и блока
Vent_dP.
Сохраните все изменения.
3. Создание блока CONT_C
Скопируйте текст в блок FB:
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; |
//Время действия дифференциальной |
составляющей |
|
|
|
111
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 |
112
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; |
|
// Получили рассогласование между |
||||
заданием и входом |
|
|
|
|
|
|
113
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;
114
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;
115
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;
116
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
Создание функции scale
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
Создание функционального блока Vent_dP
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 := VR.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;
117
ELSE
cur := cur; END_IF;
dP := cur; END_FUNCTION_BLOCK
Чтение и запись
Вблоке OB32 вызов проводится по шаблону:
Reading_AI.Reading_AI_DB();
Вблоке OB35 вызов проводится по шаблону: read_vent.read_vent_db();
Проверка правильности работы
В отсутствии проекта визуализации проверку рационально проводить с помощью VAT-таблицы. Она создается в папке Blocks. После открытия таблицы необходимо заполнить ее необходимыми переменными в поле Symbol (символьные имена).
Для мониторинга переменных нужно нажать на кнопку |
. |
Для записи значений переменных в поле Modify Value |
вводится |
необходимое значение, затем записывается кнопкой |
. |
Задание на выполнение
1.Создайте два дополнительных FB, дайте им имя, а также создайте экземплярные блоки данных для каждого из них (см. работы 5-7). В одном из блоков нужно осуществить вызов блока CONT_C, в другом Vent_dP. Для объявления CONT_C и Vent_dP создайте соответствующие переменные в дополнительных FB в областях
VAR … END_VAR: VAR
PID_1 : CONT_C;
END_VAR
118
VAR
Vent_1 : Vent_dP;
END_VAR
2.Осуществите вызов функциональных блоков CONT_C и Vent_dP в дополнительных функциональных блоках. Для этого в области кода (после END_VAR и до END_Function_block) поставьте курсор и с помощью меню вызовите блок: Block call > …Затем в открывшемся окне выберите вместо Library > Project. После этого найдите свой проект, а затем раскройте его, нажимая на «+» до папке «Blocks». В этой папке найдите по очереди функциональные блоки CONT_C и Vent_dP по адресу. При выборе блока на свободном поле появятся входные и выходные переменные для вызова. Ниже приведен пример вызова системного FB «BRCV».
Замените при вызове сложное имя блока FB на то, что дано в области
VAR … END_VAR (п.1):
119
3.Справа от операторов присваивания «:=» в скобках, после имени переменной BRCV1 указываются конкретные входные переменные. После скобок, слева от оператора присваивания указываются те переменные, куда нужно записать результат работы FB.
4.Выберите любой управляемый сигнал из входных аналоговых сигналов по Вашему варианту. Этот сигнал необходимо отвязать от области входа, т.е. он будет записываться из программы, поскольку осуществляется моделирование работы объекта управления.
5.Необходимо подобрать (придумать, найти) по смыслу такой физический сигнал, который может быть управляющим воздействием для него (управляющий сигнал). При возникновении сложности с выбором обратитесь к преподавателю. Определите диапазон этого сигнала.
6.Выберите уставку для управляемого сигнала в пределах измеряемого диапазона не ближе чем в 30% к минимальной или максимальной границе диапазона измерения этого сигнала.
7.Замените один из выходных аналоговых сигналов на выбранный управляющий сигнал (алгоритмическое имя).
8.Считая модель Vent_dP общей для моделирования любого объекта, определите свой объект исходя из выбранного управляемого сигнала.
120
