Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

МУ_Проектирование распределенных систем управления 04.09.2023

.pdf
Скачиваний:
10
Добавлен:
18.10.2024
Размер:
5.05 Mб
Скачать

Задайте адреса для функционального блока 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