// SystemTaskAbfrage fbGetCurTaskIdx(); udint_zclock := _TaskInfo[fbGetCurTaskIdx.index].CycleTime/10000; int_zclock:= UDINT_TO_INT(udint_zclock); real_zclock:= INT_TO_LREAL(int_zclock)*0.01; cycle_time := real_zclock; // Aktuele Temperatur (Klemme) actual_value := (Input_Istwert/10.0); // Änderung der aktuellen Temperatur - Zyklus aenderung_actual_value := actual_value - actual_value_old; actual_value_old := actual_value; // Regeldifferenz error := (GVL_VAR.control_value - actual_value); // P-Regler P_part := error * GVL_VAR.kP; // I-Regler IF GVL_VAR.kI > 0 THEN I_Part_Zw_Summe := ((((error * GVL_VAR.kP) + (delta_error_last_cycle * GVL_VAR.kP)) / 2.0) * (cycle_time / GVL_VAR.kI)); IF NOT limit_on_low AND (I_Part_Zw_Summe <0) THEN I_part := I_part + I_Part_Zw_Summe; ELSIF NOT limit_on_high AND (I_Part_Zw_Summe >0) THEN I_part := I_part + I_Part_Zw_Summe; END_IF; ELSIF GVL_VAR.kI <= 0.0 THEN I_part := 0.0; END_IF; // I-Regler zurück setzen - manuelles zurücksetzen des Integrators if I_Reset then I_part := 0.0; END_IF; // Regleroutput output_value := P_part + I_part; limit_on_low := FALSE; limit_on_high := FALSE; // Regleroutput zwischen den Werten 0-255 skallieren (wird benötigt für die 8-bit PWM) IF output_value > Out_max THEN output_value := Out_max; limit_on_high := TRUE; ELSIF output_value < Out_min THEN output_value := Out_min; limit_on_low := TRUE; END_IF; // Skalierter Regleroutput PID_out := output_value; //Regeldifferenz für nächsten Zyklus beschreiben delta_error_last_cycle := error; //######################################################################### //############################ NEU ######################################## //######################################################################### // Variablen: //error_overwrite_integral_on: Beschreibt die Differenz zum Sollwert, bei der der I - Anteil mit dem für den Betrieb am Arbeitspunkt notwendigen Wert überschrieben werden soll. Wenn das passiert, wird das überschreiben zunächst gesperrt. //error_overwrite_integral_off: Wenn die Temperatur um diesen Wert unterhalb vom sollwert ist, wird das Überschreiben des I-Anteils wieder freigegeben //integral_overwrite_done: "Merker", dass der I- Anteil überschrieben wurde --> wird zurückgesetzt, wenn die Temperatur erstmalig wieder unter einem gewissen Wert gelandet ist. //Bei erstmaliger Annäherung in Richtung Sollwert I - Anteil vorbelegen und danach Vorbelegung sperren. IF (actual_value > GVL_VAR.control_value - error_overwrite_integral_on) AND (NOT integral_overwrite_done) THEN integral_overwrite_done := true; //Merkerbit setzen I_part := 50 - P_part; //I-Anteil vorbelegen (50 ist der zu erwartende Stellwert des Reglers (beispielhaft) END_IF; //Sobald der Istwert wieder weiter abgefallen ist, Vorbelegung für nächsten Aufheizprozess wieder freigeben IF (actual_value < GVL_VAR.control_value - error_overwrite_integral_off) THEN integral_overwrite_done := false; END_IF;