126 lines
4.2 KiB
Smalltalk
126 lines
4.2 KiB
Smalltalk
(*
|
||
===============================================================================
|
||
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
|