PID controller erweitert

Begonnen von hugo, 04. Januar 2007, 12:21:11

Vorheriges Thema - Nächstes Thema

0 Mitglieder und 1 Gast betrachten dieses Thema.

hugo

der pid regler hat nun eine strukturumschaltung erhalten. der anwender kann nun festlegen wann der integrator aktiv wird.
PID regler sind grundsätzlich schlecht geeignet wenn der sollwert sprunghaft verstellt wird, der uintegrator läuft dabei von anfang an und kann schnell an die oberen oder unteren limits gelangen, was längere ausregelzeiten und über bzw unterschwingen bedeutet.

mit einem zusätzlichen eingang int_band kann nun festgelegt werden das der integrator nur nahe dem sollwert funktioniert und bei großen regelabweichungen abgeschaltet wird.

FUNCTION_BLOCK FT_PID
VAR_INPUT
   actual, set_point, offset, manual_in : REAL;
   Manual : BOOL;
   rst : BOOL := FALSE;
   int_band : REAL := 100;
END_VAR
VAR_INPUT
   KP, TN, TV, limit_L, limit_H : REAL;
END_VAR
VAR_OUTPUT
   Y : REAL;
   LIM, overflow : BOOL;
END_VAR
VAR
   integ : FT_INT;
   deriv : FT_deriv;
   diff: REAL;
END_VAR

(*
version 1.2   3 jan 2007
programmer    hugo
tested by      tobias

FT_PID is a pid controller with manual functionality.
The PID controller works according to the fomula Y = KP * ( e + 1/TN * INTEG(e) + TV *DERIV(e)) + offset, while e = set_point - actual.
a rst will reset all internal data, while a switch to manual will cause the controller to follow the function Y = manual_in + offset.
limit_h and Limit_l set the possible output range of Y.
the output flags lim will signal that the output limits are active and overflow will signal that the integrator has reached the max or min limit. 

since rev 1.1 the "trapezregel is used for more accuracy.
rev 1.2 added selective integratin which means the integrative component is only active within a small range of the target value
this avoids the integrator to go to limits while an input setpoint change happened and is only causing overshoots.
the int_band is by default 100 which means the int is active all the time and if set to for example to 0.1 the integrator is only active
while the input is between 0.9 and 1.1 of the set_point value.
*)


IF rst OR KP = 0 THEN
   y := offset;
   integ(rst := 1);
   integ.rst := 0;
ELSIF manual THEN
   Y := manual_in + offset;
   integ(rst := 1);
   integ.rst := 0;
ELSE
   (* calcualtion of the actual PID values *)
   diff := set_point - actual;

   (* integrator is only called if TN > 0 and input is within int_band othewrwise it is disabled *)
   IF TN > 0 AND actual > set_point - int_band AND actual < set_point + int_band THEN
      integ(in := diff, K := 1/TN, out_min := (limit_L - offset) / KP, out_max := (limit_H - offset) / KP);
   ELSE
      integ(rst := 1);
      integ.rst := 0;
   END_IF;
   deriv(in := diff, K := TV);

   (* check if integrator has reached the allowed limits and set overflow if necessary *)
   IF integ.Out >= (limit_H - offset) / KP THEN
      Y := limit_H;
      overflow := TRUE;
   ELSIF integ.Out <= (limit_L - offset) / KP THEN
      Y := limit_L;
      overflow := TRUE;
   ELSE
      Y := KP * (integ.Out + deriv.out + diff) + offset;
      overflow := FALSE;
   END_IF;

   (* this portion limits the output to limit_H and limit_L and set the lim flag if limits are exceeded *)
   IF Y > limit_H THEN
      Y := limit_H;
      Lim := TRUE;
   ELSIF Y < limit_L THEN
      Y := limit_L;
      lim := TRUE;
   ELSE
      lim := FALSE;
   END_IF;
END_IF;

(* revision history

hm 1.12.2006 rev 1.1
   changed algorithm to trapezregel for higher accuracy

hm 3.1.2007   rev 1.2
   added integ_band to select when the integrator is active.

*)