Регулирование задвижкой без датчика положения
Стандартные ПИД-регуляторы в средах разработки программ для контроллеров предназначены для управления исполнительными механизмами с аналоговым входом, такими как преобразователь частоты или задвижка с заданием степени открытия. Для подобного исполнительного механизма достаточно просто соединить его вход с выходом регулятора. Рассмотрим более простую версию ПИД-регулятора – ПИ-регулятор, дискретная формула которого имеет следующий вид:
Что же делать если у нашей задвижки нет датчика положения или он недостаточно надежен для регулирования и используется только для индикации? В этом случае следует управлять задвижкой в инкрементном режиме – сигналы «больше» и «меньше». Для этого воспользуемся формулой инкрементного ПИ-регулятора, которая получается путем дифференцирования предыдущей формулы:
Фактически это ПД-регулятор, сигнал с которого будет проинтегрирован самой инкрементной задвижкой и на выходе мы получим пропорционально-интегральный закон регулирования.
Выход регулятора для удобства выразим в процентах от −100% до +100%. Он является входным значением для широтно-импульсной модуляции (ШИМ). Для ШИМ необходимо задать период. Он должен быть значительно больше цикла программы. Выход регулятора устанавливает долю времени от периода ШИМ, в течение которого задвижка открывается или закрывается. Положительные значения соответствуют открытию задвижки, а отрицательные – закрытию.
PWM.png
Далее фрагмент реальной программы регулятора температуры пара на языке CoDeSys в среде программирования Schneider SoMachine.
Глобальные переменные
VAR_GLOBAL END_VAR VAR_GLOBAL // Длительность цикла - секунды Cycle: REAL := 0.05; // Температура перегретой воды - градусы T: REAL; // Отказ датчика температуры T_err: BOOL; // Значение выхода регулятора Y: REAL; // Автоматический режим регулятора активен Reg_auto: BOOL; // Применить новые значения параметров Set_parameters: BOOL; // Активна новая сигнализация New_Alarm: BOOL; // Флаг первого цикла программы First_Cycle: BOOL := true; END_VAR
Программа регулятора - описательная часть
PROGRAM Regulator VAR // Рассогласование E: REAL; // Рассогласование - старое значение E_old: REAL; // Температура - старое значение T_old: REAL; // Изменение рассогласования dE: REAL; // Изменение рассогласования - старое значение dE_old: REAL; // Точное время между соседними измерениями dt_izm: REAL; END_VAR VAR RETAIN // Задание периода между соседними измерениями, секунды Period_reg: REAL := 5.0; END_VAR VAR // Новое задание периода между соседними измерениями, секунды Period_reg_new: REAL; // Количество циклов, соответствующее времени между соседними измерениями Period_reg_cycles: INT; // Счетчик циклов i: INT; END_VAR VAR RETAIN // Коэффициент усиления регулятора Kp: REAL := 100.0; // Постоянная времени регулятора, секунды Tn: REAL := 300.0; END_VAR VAR // Температура перегретой воды - задание, градусы T_set: REAL := 140.0; // Коэффициент усиления регулятора - новое значение Kp_new: REAL; // Температура перегретой воды - задание, градусы - новое значение Tn_new: REAL; END_VAR VAR RETAIN // Зона нечувствительности, градусы Zona: REAL := 0.3; END_VAR VAR // Зона нечувствительности, градусы - новое значение Zona_new: REAL; END_VAR
Программа регулятора - исполнительная часть
// Установка новых коэффициентов регулятора IF GVL.Set_parameters THEN Kp := Kp_new; Tn := Tn_new; Period_reg := Period_reg_new; Zona := Zona_new; END_IF
// Если регулятор находится в автоматическом режиме IF GVL.Reg_auto THEN // Расчет количества циклов между соседними измерениями Period_reg_cycles := REAL_TO_INT(Period_reg / GVL.Cycle); // Точное время между соседними измерениями (после округления по количеству циклов) dt_izm := GVL.Cycle * Period_reg_cycles;
// Начало нового цикла регулятора IF i = 0 THEN // Рассогласование E := T_set - GVL.T; // Зона нечувствительности IF ABS(E) < Zona THEN E := 0; ELSE IF E > 0 THEN E := E - Zona; ELSE E := E + Zona; END_IF END_IF // Изменение рассогласования dE := E - E_old; // Выход регулятора, % GVL.Y := Kp * (dE / dt_izm + E / Tn); // Верхнее ограничение регулятора = 100% IF GVL.Y > 100 THEN GVL.Y := 100; END_IF // Нижнее ограничение регулятора = -100% IF GVL.Y < -100 THEN GVL.Y := -100; END_IF // Замена старых значений новыми E_old := E; dE_old := dE; T_old := GVL.T; END_IF // Счетчик циклов контроллера i := i + 1; // Определение конца цикла регулятора IF i >= Period_reg_cycles THEN i := 0; END_IF END_IF
Программа позиционера задвижки - описательная часть
PROGRAM Valve VAR // Счетчик циклов Count: INT; END_VAR VAR RETAIN // Период ШИМ, секунды Period_PWM: REAL := 5.0; END_VAR VAR // Период ШИМ - новое значение, секунды Period_PWM_new: REAL; // Период ШИМ, циклы Period_PWM_cycles: INT; // Значение ШИМ, циклы Value: INT; END_VAR VAR RETAIN // Минимальное время движения клапана, секунды Min_value: REAL := 0.15; END_VAR VAR // Минимальное время движения клапана - новое значение, секунды Min_value_new: REAL; // Минимальное время движения клапана, циклы Min_value_cycles: INT; // Открыть клапан - дискретный выход Open: BOOL; // Закрыть клапан - дискретный выход Close: BOOL; // Открыть клапан - команда оператора Open_manual: BOOL; // Закрыть клапан - команда оператора Close_manual: BOOL; // Открыть клапан полностью - команда оператора Open_manual_full: BOOL; // Закрыть клапан полностью - команда оператора Close_manual_full: BOOL; // Остановаить клапан - команда оператора Stop_manual: BOOL; // Клапан открыт Opened: BOOL; // Клапан открыт Closed: BOOL; // Открытие клапана Closing: BOOL; // Закрытие клапана Opening: BOOL; // Авария клапана Alarm: BOOL; RS1: RS; RS2: RS; END_VAR
Программа позиционера задвижки - исполнительная часть
// Применение новых настроек IF GVL.Set_parameters THEN Period_PWM := Period_PWM_new; Min_value := Min_value_new; END_IF;
// Расчет периода ШИМ в циклах Period_PWM_cycles := REAL_TO_INT(Period_PWM / GVL.Cycle);
// Расчет минимального времени движения клапана в циклах Min_value_cycles := REAL_TO_INT(Min_value / GVL.Cycle);
// Автоматический режим регулятора IF GVL.Reg_auto THEN // Значение ШИМ в циклах Value := REAL_TO_INT(GVL.Y / 100 * Period_PWM_cycles);
// Определение направления движения клапана IF (Value > 0) THEN Open := TRUE; ELSE Close := TRUE; END_IF;
// Если счетчик циклов меньше минимального значения или больше значения ШИМ, то остановить движение клапана IF ABS(Value) < Min_value OR ABS(Value) < Count THEN Open := FALSE; Close := FALSE; END_IF; // Счетчик циклов контроллера Count := Count + 1;
// Определение конца периода ШИМ IF Count > Period_PWM_cycles THEN Count := 0; END_IF;
// Конечный выключатель закрытого состояния IF GVL.T < 81 OR Closed THEN Close := FALSE; END_IF;
// Конечный выключатель открытого состояния IF GVL.T > 179 OR Opened THEN Open := FALSE; END_IF; // Ручной режим работы регулятора ELSE // Триггер полного открытия RS1(SET := Open_manual_full , RESET1 := (Opened OR Open_manual OR Close_manual OR Close_manual_full OR Stop_manual)); Opening := RS1.Q1 ; // Триггер полного закрытия RS2(SET := Close_manual_full , RESET1 := (Closed OR Open_manual OR Close_manual OR Open_manual_full OR Stop_manual)); Closing := RS2.Q1 ;
// Открыть IF (Open_manual OR Opening) AND NOT Opened THEN Open := TRUE; ELSE Open := FALSE; END_IF; // Закрыть IF (Close_manual OR Closing) AND NOT Closed THEN Close := TRUE; ELSE Close := FALSE; END_IF; END_IF;
Ссылки
Энциклопедия АСУТП. Дискретная форма регулятора
Википедия. ПИД-регулятор
Овен ТРМ12. Руководство по эксплуатации