//====================================================================
//==== GEORG Automation ==============================================
//====================================================================
//
// FUNKTION: PI controller
//--------------------------------------------------------------------
//
// Autor: S.R. Datum: 25.10.2005 Version: 1.0
//--------------------------------------------------------------------
// Updates:
// Datum ! Autor ! Grund
// 07.03.06 SR anderes PI-verhalten, I-part erst bei < 50% err
// 01.06.07 SR I-part limitieen
//====================================================================
FUNCTION PI_Control : VOID
TITLE = 'PI controller V2'
VAR_INPUT
Init : BOOL; // Initialisierung...initialize
X_want : REAL; // [X] Sollwert...command value
X_act : REAL; // [X] Istwert...act. value
TN : REAL; // [] n x Tcyc, Nachstellzeit...int. time constant
Kp : REAL; // [ ] Verst鋜kung...gain
Corr_Lim : REAL; // [X] Regler-Begrenzung...controller limit
END_VAR
VAR_TEMP
TI : REAL; // Integrations-Zeitkonstante
END_VAR
VAR_IN_OUT
I_Part : REAL; // [X] I-Anteil...I-part
END_VAR
VAR_OUTPUT
Corr_Max : BOOL; // Regler-Begrenzung aktiv...controller at limit
X_corr : REAL; // [X]Soll-Korrekturwert...correction of command value
X_err : REAL; // [X]akt. Differenz (Soll - Ist)...P-part
END_VAR
BEGIN
IF (Init) THEN
I_Part := 0.0;
X_corr := 0.0;
X_err := 0.0;
ELSE
Corr_Max := FALSE;
IF (TN > 0.0) THEN // TN > 0: mit I-Anteil
TI := 1.0 / TN;
ELSE // TN = 0: ohne I-Anteil
TI := 0.0;
END_IF;
IF (Kp > 0.0) THEN
X_err := X_want - X_act; // (Soll - Ist) Differenz
IF (TI > 0.0) AND (ABS (X_err) < (0.5*Corr_Lim)) THEN // I_Anteil
// I_part := (I_part + X_err);
I_part := I_part + (X_err * TI);
IF ABS(I_Part) > Corr_Lim THEN
I_part := Corr_Lim;
END_IF;
ELSE
I_Part := 0.0;
END_IF;
// X_corr := (X_err + (I_part * TI)) * Kp; // Sollwert-Korrektur
X_corr := (X_err * Kp) + I_part; // Sollwert-Korrektur
IF (X_corr > Corr_Lim) THEN
X_corr := Corr_Lim;
Corr_Max := TRUE;
ELSIF (X_corr < -Corr_Lim) THEN
X_corr := -Corr_Lim;
Corr_Max := TRUE;
END_IF;
ELSE
I_part := 0.0;
X_err := 0.0;
X_corr := 0.0;
END_IF;
END_IF;
END_FUNCTION