Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Реализация законов аналогового регулирования на контроллерах-МЭИ.doc
Скачиваний:
7
Добавлен:
01.07.2025
Размер:
7 Мб
Скачать
☆

Приложение н Фрагменты работы Быкова а.Ю.

Ниже приведена примерно пятая часть семестровой работы студента гр. АТП-07 филиала МЭИ в г. Волжском Быкова Артёма Юрьевича. Здесь отсутствуют программы по следующим темам: «Информационный обмен в промышленных контроллерах [96]», «Реализация алгоритмов сигнализации [23, 25]», «Реализация дискретных систем управления [25, 26, 27]».

Трёхканальный блок циклической индикации

Программная реализация такого блока на языке ST представлена ниже. В этом блоке имеется счётчик каналов (он же индицирует отображаемый в данный момент канал). Отображаемая величина берётся из канала, соответствующего текущему значению счётчика. Изменение значения счётчика происходит в момент времени, соответствующий смене каналов. Этот момент времени определяется с помощью таймера и триггера.

FUNCTION_BLOCK cycle_ind (*блок циклической индикации*)

VAR_INPUT

sig_1: REAL;

sig_2: REAL;

sig_3: REAL;

time_sm: TIME; (*время смены каналов*)

END_VAR

VAR_OUTPUT

out: REAL; (*величина сигнала отображаемого канала*)

num_chan: BYTE; (*номер отображаемого канала*)

END_VAR

VAR

tm: TON; (*таймер*)

t: TIME; (*прошедшее время от последней смены каналов*)

trig: F_TRIG; (*тригер заднего фрона для определения момента

смены каналов*)

END_VAR

(*отсчитываем время*)

tm(IN:=t<time_sm, PT:=time_sm+T#1s, ET=>t);

(*единичный импульс при необходимости смены каналов*)

trig(CLK:=t<time_sm);

IF trig.Q THEN (*если надо сменить канал индикации*)

IF num_chan<3 THEN (*если отображаемый канал не последний*)

num_chan:=num_chan+1;(*переходим на следующий канал*)

ELSE (*если отображается последний канал*)

num_chan:=1; (*переходим на первый канал*)

END_IF

END_IF

(*присвоение выходному значению значение величины требуемого канала*)

CASE num_chan OF

1: out:=sig_1;

2: out:=sig_2;

3: out:=sig_3;

END_CASE

Четырёхканальный блок циклической индикации

Даны две групп параметров, по 4 параметра в каждой группе. Для каждого параметра – своя шкала. Реализация этого блока аналогична реализации предыдущего блока, но в данном случае добавляется индивидуальное преобразование величин каждого параметра по своей шкале, и параметры группируются в 2 группы по 4 параметра в каждом. В один момент времени выводится 4 параметра одной группы. Группировка происходит следующим образом: параметры 1-4 попадают в первую группу, параметры 5-8 – во вторую.

Преобразование величин по шкалам производится с помощью блока LIN_TRAFO из библиотеки «Util», входящей в стандартный комплект поставки среды CodeSys. Описание этого блока доступно в справочной системе CodeSys.

FUNCTION_BLOCK cycle_ind_2 (*блок циклической индикации*)

VAR_INPUT

sig_1: REAL; (*величина сигнала на входе*)

sig_1_in_min: REAL := 0; (*минимальное значение сигнала на входе*)

sig_1_in_max: REAL := 100; (*максимальное значение сигнала на входе*)

sig_1_out_min: REAL := 0; (*минимальное значение сигнала на выходе*)

sig_1_out_max: REAL := 100; (*максимальное значение сигнала на выходе*)

sig_2: REAL;

sig_2_in_min: REAL := 0;

sig_2_in_max: REAL := 100;

sig_2_out_min: REAL := 0;

sig_2_out_max: REAL := 100;

sig_3: REAL;

sig_3_in_min: REAL := 0;

sig_3_in_max: REAL := 100;

sig_3_out_min: REAL := 0;

sig_3_out_max: REAL := 100;

sig_4: REAL;

sig_4_in_min: REAL := 0;

sig_4_in_max: REAL := 100;

sig_4_out_min: REAL := 0;

sig_4_out_max: REAL := 100;

sig_5: REAL;

sig_5_in_min: REAL := 0;

sig_5_in_max: REAL := 100;

sig_5_out_min: REAL := 0;

sig_5_out_max: REAL := 100;

sig_6: REAL;

sig_6_in_min: REAL := 0;

sig_6_in_max: REAL := 100;

sig_6_out_min: REAL := 0;

sig_6_out_max: REAL := 100;

sig_7: REAL;

sig_7_in_min: REAL := 0;

sig_7_in_max: REAL := 100;

sig_7_out_min: REAL := 0;

sig_7_out_max: REAL := 100;

sig_8: REAL;

sig_8_in_min: REAL := 0;

sig_8_in_max: REAL := 100;

sig_8_out_min: REAL := 0;

sig_8_out_max: REAL := 100;

time_sm: TIME; (*время смены каналов*)

END_VAR

VAR_OUTPUT

out_1: REAL; (*величина сигнала отображаемого канала*)

out_2: REAL;

out_3: REAL;

out_4: REAL;

num_chan: BYTE; (*номер отображаемого канала*)

END_VAR

VAR

tm: TON; (*таймер*)

t: TIME; (*прошедшее время от последней смены каналов*)

trig: F_TRIG; (*триггер заднего фронта для определения момента

смены каналов*)

lf1: LIN_TRAFO; (*пересчёт значений канала*)

END_VAR

(*отсчитываем время*)

tm(IN:=t<time_sm, PT:=time_sm+T#1s, ET=>t);

(*единичный импульс при необходимости смены каналов*)

trig(CLK:=t<time_sm);

IF trig.Q THEN (*если надо сменить канал индикации*)

IF num_chan<2 THEN (*если отображаемый канал не последний*)

num_chan:=num_chan+1; (*переход на следующий канал*)

ELSE (*если отображается последний канал*)

num_chan:=1; (*переход на первый канал*)

END_IF

END_IF

(*присвоение выходному значению значения сигнала с учётом шкалы*)

CASE num_chan OF

1: lf1(IN:=sig_1, IN_MIN:=sig_1_in_min, IN_MAX:=sig_1_in_max

,OUT_MIN:=sig_1_out_min, OUT_MAX:=sig_1_out_max, OUT=>out_1);

lf1(IN:=sig_2, IN_MIN:=sig_2_in_min, IN_MAX:=sig_2_in_max

,OUT_MIN:=sig_2_out_min, OUT_MAX:=sig_2_out_max, OUT=>out_2);

lf1(IN:=sig_3, IN_MIN:=sig_3_in_min, IN_MAX:=sig_3_in_max

,OUT_MIN:=sig_3_out_min, OUT_MAX:=sig_3_out_max, OUT=>out_3);

lf1(IN:=sig_4, IN_MIN:=sig_4_in_min, IN_MAX:=sig_4_in_max

,OUT_MIN:=sig_4_out_min, OUT_MAX:=sig_4_out_max, OUT=>out_4);

2: lf1(IN:=sig_5, IN_MIN:=sig_5_in_min, IN_MAX:=sig_5_in_max

,OUT_MIN:=sig_5_out_min, OUT_MAX:=sig_5_out_max, OUT=>out_1);

lf1(IN:=sig_6, IN_MIN:=sig_6_in_min, IN_MAX:=sig_6_in_max

,OUT_MIN:=sig_6_out_min, OUT_MAX:=sig_6_out_max, OUT=>out_2);

lf1(IN:=sig_7, IN_MIN:=sig_7_in_min, IN_MAX:=sig_7_in_max

,OUT_MIN:=sig_7_out_min, OUT_MAX:=sig_7_out_max, OUT=>out_3);

lf1(IN:=sig_8, IN_MIN:=sig_8_in_min, IN_MAX:=sig_8_in_max

,OUT_MIN:=sig_8_out_min, OUT_MAX:=sig_8_out_max, OUT=>out_4);

END_CASE

В результате применения БЦИ количество контролируемых на ЛП параметров увеличилось в десятки раз. При этом резко сокращается число нажатий клавиш оператором при просмотре значений параметров. Принцип работы блока циклической индикации является общим и может использоваться на других контроллерах.

Программный регулятор

Программный регулятор реализован с использованием библиотеки oscat (файл «oscat_basic__codesys2_321.lib»). Полное описание этой библиотеки находится в файле «oscat_basic_doc_332_en.pdf}».

Регулятор состоит из блока задания уставки (prg) по заданной программе (задаётся три уставки, время выдержки первых двух и время перехода между уставками), блока защиты уставки (protect_ust), блока ограничения скорости изменения уставки (org_speed_ust), блока защиты аналогового сигнала обратной связи (protect_input_sig), блока ПИД-регулятора (pid_reg1) и блока ограничения скорости изменения выходной величины регулятора (org_speed_out_reg). Кроме этого в программе имеются блок, имитирующий объект управления в виде апериодического звена первого порядка (ob), и блока, имитирующего реальный измерительный канал с некоторой погрешностью измерения и с возможностью имитации выброса, провала и обрыва в данном канале.

Программа регулятора вместе с описанными блоками:

PROGRAM p2

VAR

pid_reg1: pid_reg; (*регулятор*)

y: REAL; (*выходная величина объекта*)

i_reset: BOOL:=FALSE; (*сброс интегральной составляющей регулятора*)

i_enable: BOOL:=TRUE; (*включение интегральной составляющей регулятора*)

manual_enable: BOOL; (*включение ручного режима работы регулятора*)

var_manual: REAL; (*величина выходного сигнала регулятора в ручном режиме*)

ob: FT_PT1; (*модель объекта управления*)

kp: REAL:=2; (*коэффициент пропорциональности регулятора*)

ti: REAL:=16; (*постоянная времени интегрирования регулятора*)

td: REAL:=4; (*постоянная времени дифференцирования регулятора*)

protect_input_sig: mprotect_analog; (*защита входного аналогового сигнала*)

protect_ust: mprotect_ust; (*защита уставки*)

kanal: real_kan; (*модель канала измерения*)

org_speed_ust: FT_RMP; (*ограничение скорости изменения уставки*)

org_speed_out_reg: FT_RMP;(*ограничение скорости изменения выходного сигнала регулятора*)

prg: prog_ust; (*программа изменения уставки*)

b4: BOOL; (*разрешение работы блока prg*)

b5: BOOL; (*сброс блока prg*)

END_VAR

Рис. 99. Программа регулятора с изменением задания во времени

FUNCTION_BLOCK pid_reg

VAR_INPUT

ust: REAL:=0;

act: REAL:=0;

db: REAL:=0;

kp: REAL:=1;

ti: REAL:=1;

td: REAL:=1;

ien: BOOL:=TRUE;

irst: BOOL:=FALSE;

i_lim_l: REAL:=-100;

i_lim_h: REAL:=100;

out_lim_l: REAL:=-100;

out_lim_h: REAL:=100;

men: BOOL:=FALSE;

m: REAL:=0;

END_VAR

VAR_OUTPUT

out: REAL;

i_lim: BOOL;

out_lim: BOOL;

END_VAR

VAR

pid1: FT_PID;

out1: CTRL_OUT;

END_VAR

Рис. 100. Программа простого (стандартного ПИ-регулятора) регулятора

FUNCTION_BLOCK prog_ust (*программа для формирования задания (уставки)*)

VAR_INPUT

en: BOOL; (*разрешить работу блока*)

val_1: REAL; (*стартовое значение уставки*)

tm_1: TIME; (*время выдержки val_1*)

ptm_1: TIME; (*время перехода от val_1 к val_2*)

val_2: REAL; (*уставка 2*)

tm_2: TIME; (*время выдержки val_2*)

ptm_2: TIME; (*время перехода от val_2 к val_3*)

val_3: REAL; (*завершающая уставка*)

reset: BOOL; (*сброс*)

END_VAR

VAR_OUTPUT

ust: REAL;

END_VAR

VAR

tmr: TON; (*таймер*)

t: TIME; (*текущее время*)

lf: lin_trafo; (*линейное преобразование для плавного перехода с одного задания на другое(на другую уставку)*)

END_VAR

(*если работа блока разрешена*)

IF en THEN

(*выполняем отсчёт времени*)

tmr(IN:=NOT(reset), PT:=tm_1+ptm_1+tm_2+ptm_2+T#1s, ET=>t);

(*если не сброс блока и не завершение счёта таймера*)

IF NOT(reset) AND NOT(tmr.Q) THEN

(*если время уставки 1*)

IF t<=tm_1 THEN

ust:=val_1;

(*если время перехода с уставки 1 на уставку 2*)

ELSIF t>tm_1 AND t<=tm_1+ptm_1 THEN

lf(IN:=TIME_TO_REAL(t-tm_1), IN_MIN:=0, IN_MAX:=TIME_TO_REAL(ptm_1)

,OUT_MIN:=val_1, OUT_MAX:=val_2, OUT=>ust);

(*если время уставки 2*)

ELSIF t>tm_1+ptm_1 AND t<=tm_1+ptm_1+tm_2 THEN

ust:=val_2;

(*если время перехода с уставки 2 на уставку 3*)

ELSIF t>tm_1+ptm_1+tm_2 AND t<=tm_1+ptm_1+tm_2+ptm_2 THEN

lf(IN:=TIME_TO_REAL(t-tm_1-ptm_1-tm_2), IN_MIN:=0, IN_MAX:=TIME_TO_REAL(ptm_2)

,OUT_MIN:=val_2, OUT_MAX:=val_3, OUT=>ust);

(*если время уставки 3*)

ELSE

ust:=val_3;

END_IF

END_IF

END_IF

(*если сброс*)

IF reset THEN ust:=val_1; END_IF

FUNCTION_BLOCK real_kan

VAR_INPUT

sig_in:REAL;

vybros: BOOL;

proval: BOOL;

koeff: REAL;

obryv: BOOL;

obryv_val: REAL;

time_noise:TIME;

amplitude_noise: REAL;

offset_noise:REAL;

END_VAR

VAR_OUTPUT

sig_out: REAL;

END_VAR

VAR

gen_random: GEN_RDM;

END_VAR

gen_random(

PT:=time_noise

,AM:=amplitude_noise

,OS:=offset_noise);

IF obryv THEN

sig_out:=obryv_val;

ELSE

sig_out:=

sig_in

+gen_random.Out

+koeff*BOOL_TO_REAL(vybros)

-koeff*BOOL_TO_REAL(proval);

END_IF