Поправил скрипт, поправил неточности в библиотеке
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
(*
|
||||
===============================================================================
|
||||
Project : PLC_Library
|
||||
Device : -
|
||||
Path : Общие
|
||||
Name : PIDcontrol
|
||||
Type : FUNCTION_BLOCK
|
||||
Exported : 2026-07-31 11:16:16
|
||||
===============================================================================
|
||||
*)
|
||||
|
||||
FUNCTION_BLOCK PIDcontrol (* ПИД-регулятор. *)
|
||||
VAR_INPUT
|
||||
ProcessVariable: REAL := 0.0; (* Измеренное значение параметра *)
|
||||
Setpoint: REAL := 0.0; (* Заданное значение *)
|
||||
Kp: REAL := 0.001; (* Пропорциональный коэффициент *)
|
||||
Ki: REAL := 0.001; (* Интегральный коэффициент *)
|
||||
Kd: REAL := 0.0; (* Дифференциальный коэффициент *)
|
||||
Kdf: REAL := 1.0; (* Коэффициент фильтрации (1/Tdf) *)
|
||||
DBmax: REAL := 0.01; (* Верхняя граница зоны нечувствительности *)
|
||||
DBmin: REAL := - 0.01; (* Нижняя граница зоны нечувствительности *)
|
||||
OutMax: REAL := 100.0; (* Максимальный выход *)
|
||||
OutMin: REAL := 0.0; (* Минимальный выход *)
|
||||
Ts: REAL := 0.1; (* Время дискретизации [с] *)
|
||||
Manual: REAL := 25.0; (* Значение в ручном режиме *)
|
||||
ManOn: BOOL := FALSE; (* Флаг ручного режима *)
|
||||
Reset: BOOL := FALSE; (* Сброс интегратора *)
|
||||
AntiWindup: BOOL := TRUE; (* Включить антивиндап *)
|
||||
END_VAR
|
||||
|
||||
VAR_OUTPUT
|
||||
Out: REAL := 0.0; (* Выходной сигнал *)
|
||||
Err: REAL := 0.0; (* Ошибка регулирования *)
|
||||
OutLimited: BOOL := FALSE; (* Флаг ограничения выхода *)
|
||||
END_VAR
|
||||
|
||||
VAR (* Внутренние переменные, сохраняемые. *)
|
||||
Er: REAL := 0.0; (* Текущая ошибка *)
|
||||
Ppart: REAL := 0.0; (* Пропорциональная часть *)
|
||||
Ipart: REAL := 0.0; (* Интегральная часть *)
|
||||
Dpart: REAL := 0.0; (* Дифференциальная часть *)
|
||||
PrevEr: REAL := 0.0; (* Ошибка на предыдущем шаге (для дифференциатора). *)
|
||||
FirstScan: BOOL := TRUE; (* Флаг первого сканирования. *)
|
||||
END_VAR
|
||||
|
||||
VAR_TEMP
|
||||
Auto: REAL; (* Выход ПИД *)
|
||||
Sw: REAL; (* Промежуточное значение *)
|
||||
END_VAR
|
||||
(*----- IMPLEMENTATION -----*)
|
||||
(* === ИНИЦИАЛИЗАЦИЯ И СБРОС === *)
|
||||
IF Reset OR FirstScan THEN
|
||||
Ipart := 0.0;
|
||||
Dpart := 0.0;
|
||||
PrevEr := 0.0;
|
||||
FirstScan := FALSE;
|
||||
END_IF;
|
||||
|
||||
(* === ПРОВЕРКА ВХОДНЫХ ПАРАМЕТРОВ === *)
|
||||
IF (OutMin >= OutMax) OR (DBmin >= DBmax) OR (Ts <= 0) THEN
|
||||
Out := 0.0;
|
||||
OutLimited := TRUE;
|
||||
RETURN;
|
||||
END_IF;
|
||||
|
||||
(* === РАСЧЕТ ОШИБКИ === *)
|
||||
Er := Setpoint - ProcessVariable;
|
||||
Err := Er;
|
||||
|
||||
(* ЗОНА НЕЧУВСТВИТЕЛЬНОСТИ *)
|
||||
IF (DBmin < Er) AND (Er < DBmax) THEN
|
||||
Er := 0.0;
|
||||
END_IF;
|
||||
|
||||
(* === ПРОПОРЦИОНАЛЬНАЯ ЧАСТЬ === *)
|
||||
Ppart := Kp * Er;
|
||||
|
||||
(* === ИНТЕГРАЛЬНАЯ ЧАСТЬ === *)
|
||||
IF Ki <> 0.0 THEN
|
||||
Ipart := Ipart + (Ki * Er * Ts);
|
||||
Ipart := LIMIT(OutMin, Ipart, OutMax);
|
||||
ELSE
|
||||
Ipart := 0.0;
|
||||
END_IF;
|
||||
|
||||
(* === ДИФФЕРЕНЦИАЛЬНАЯ ЧАСТЬ (фильтрованная) === *)
|
||||
IF Kd <> 0.0 THEN
|
||||
Dpart := Kd * Kdf * (Er - PrevEr) - Kdf * Dpart * Ts;
|
||||
PrevEr := Er; (* Сохраняем ошибку для следующего шага *)
|
||||
ELSE
|
||||
Dpart := 0.0;
|
||||
END_IF;
|
||||
|
||||
(* === ВЫЧИСЛЕНИЕ ВЫХОДА === *)
|
||||
Auto := Ppart + Ipart + Dpart;
|
||||
|
||||
(* === РЕЖИМ РУЧНОЙ/АВТОМАТИЧЕСКИЙ === *)
|
||||
IF ManOn THEN
|
||||
Sw := Manual;
|
||||
(* Сброс интегратора при переходе в ручной режим *)
|
||||
IF AntiWindup THEN
|
||||
Ipart := Sw - (Ppart + Dpart);
|
||||
END_IF;
|
||||
ELSE
|
||||
Sw := Auto;
|
||||
END_IF;
|
||||
|
||||
(* === ОГРАНИЧЕНИЕ ВЫХОДА И АНТИВИНДАП === *)
|
||||
IF Sw >= OutMax THEN
|
||||
Out := OutMax;
|
||||
OutLimited := TRUE;
|
||||
IF AntiWindup AND NOT ManOn THEN
|
||||
Ipart := OutMax - (Ppart + Dpart);
|
||||
END_IF;
|
||||
ELSIF Sw <= OutMin THEN
|
||||
Out := OutMin;
|
||||
OutLimited := TRUE;
|
||||
IF AntiWindup AND NOT ManOn THEN
|
||||
Ipart := OutMin - (Ppart + Dpart);
|
||||
END_IF;
|
||||
ELSE
|
||||
Out := Sw;
|
||||
OutLimited := FALSE;
|
||||
END_IF;
|
||||
END_FUNCTION_BLOCK
|
||||
Reference in New Issue
Block a user