diff --git a/controller/Controller.h b/controller/Controller.h index 611b0fd..497bec5 100755 --- a/controller/Controller.h +++ b/controller/Controller.h @@ -1,3 +1,14 @@ +/* +File: Controller.h +Description: This is a C++ source file containing implementation code for a program or library component. +Rev: 0.1 +Created: nn.03.2026 +Author: [Your Name] +Copyright: Binder GmbH TUT 2026 +Purpose: [Briefly describe the file's functionality, e.g., "Implements a class for managing user data."] +Notes: [Any relevant details, such as dependencies, usage examples, or known issues.] +*/ + #pragma once #ifdef BUILD_TARGET_SOM @@ -16,45 +27,19 @@ #include #include #include -#include -#include -#include + +//UJ: not yet needed, future use +// #include +// #include +// #include + +#include + +#include "datamodel.h" +#include "util.h" const double PI_CONST = 3.14159265358979323846; -#define MAX std::max -#define MIN std::min - -namespace UTILITY_FUNCTIONS { - -inline double limit(double x, double lo, double hi) { - return (x < lo) ? lo : (x > hi) ? hi : x; -} - -inline double max3(double a, double b, double c) { - return std::max(a, std::max(b, c)); -} -inline double min3(double a, double b, double c) { - return std::min(a, std::min(b, c)); -} - -inline bool is_valid(double x) { return std::isfinite(x); } - -// ST: REAL_TO_INT(x) i.d.R. trunc Richtung 0. Bei Siemens oft ROUND? Du nutzt -// häufig +0.5. -inline int real_to_int(double x) { return static_cast(x); } - -// Platzhalter für GET_VALUE_* (kommt vermutlich aus Parameter-/Recipe-System) -inline std::int32_t GET_VALUE_DINT(int /*a*/, int /*b*/, int /*c*/, int /*d*/) { - // TODO: an dein Parameter-System anbinden - return 0; -} -inline double GET_VALUE_REAL(int /*a*/, int /*b*/, int /*c*/, int /*d*/) { - // TODO: an dein Parameter-System anbinden - return 0.0; -} - -} // namespace UTILITY_FUNCTIONS // ------------------------- // Regelkern (ST -> C++) @@ -125,6 +110,8 @@ private: double Zyklus_MIN = 0.0; }; + + class ClimateAlgorithm { public: struct BinInputs { @@ -233,1727 +220,2050 @@ public: ClimateAlgorithm() = default; - void Step(void) { - using UTILITY_FUNCTIONS::is_valid; - using UTILITY_FUNCTIONS::limit; - // --------------------------- - // Eingangswerte (ST Zuweisungen) - // --------------------------- - Sammelalarm_quittiert = binInput.Sammelalarm_quittiert; - Tuer_offen = binInput.Tuer_offen; - Sollwert_Feuchte_aktiv = true; - Steuerkontakt_Standby = false; - Steuerkontakt_Befeuchtung_aus = false; - Steuerkontakt_Entfeuchtung_aus = false; - Entleerbehaelter_Oben = binInput.Entleerbehaelter_Oben; - bool Wasserkanister_leer = false; - Entleerbehaelter_Unten = binInput.Entleerbehaelter_Unten; - Sammelalarm = false; - Istwert_Temperatur = analogInput.Istwert_Temperatur; - Istwert_Ueberwachungsregler = Istwert_Temperatur; - Sollwert_Temperatur = analogInput.Sollwert_Temperatur; - Istwert_Feuchte = analogInput.Istwert_Feuchte; - Sollwert_Feuchte = analogInput.Sollwert_Feuchte; - // uj - not needed double Sollwert_Luefter = analogInput.Sollwert_Luefter; - Istwert_Temperatur_Tuer = analogInput.Istwert_Temperatur_Tuer; - double Istwert_Temperatur_Verdampferausgang = analogInput.Istwert_Temperatur_Verdampferausgang; - Temperatur_Feuchtemodul = analogInput.Temperatur_Feuchtemodul; - double Betauungsschutz = 50.0; - double Feuchteband = 10; - double Temperaturband = 5; - bool reset_flag = binInput.reset_flag; +void Step(void) +{ + using UTILITY_FUNCTIONS::is_valid; + using UTILITY_FUNCTIONS::limit; - // Zähler reset_flag - // ----------------- - if (reset_flag) { - Counter_reset_flag = 0; - } else { - Counter_reset_flag += 1; - } - Startup_finished = - (Counter_reset_flag > static_cast(10 * 4)); + bool Wasserkanister_leer = false; + double Istwert_Temperatur_Verdampferausgang = analogInput.Istwert_Temperatur_Verdampferausgang; + double Betauungsschutz = 50.0; + double Feuchteband = 10; + double Temperaturband = 5; + bool reset_flag = binInput.reset_flag; - // ------------------------------------------ - // Verzögerte Abschaltung Regelung bei Türöffnung - // ------------------------------------------ - // f_PostDoorOpeningCutOffDelaed(...) - if (Tuer_offen || Steuerkontakt_Standby) { - Counter_Regelung_AUS += sampling_time; - } else { - Counter_Regelung_AUS = 0.0; - } - Regelung_AUS = (Counter_Regelung_AUS > 60.0); + // --------------------------- + // Eingangswerte (ST Zuweisungen) + // --------------------------- + Sammelalarm_quittiert = binInput.Sammelalarm_quittiert; + Tuer_offen = binInput.Tuer_offen; + Sollwert_Feuchte_aktiv = true; + Steuerkontakt_Standby = false; + Steuerkontakt_Befeuchtung_aus = false; + Steuerkontakt_Entfeuchtung_aus = false; + Entleerbehaelter_Oben = binInput.Entleerbehaelter_Oben; + Entleerbehaelter_Unten = binInput.Entleerbehaelter_Unten; + Sammelalarm = false; + Istwert_Temperatur = analogInput.Istwert_Temperatur; + Istwert_Ueberwachungsregler = Istwert_Temperatur; + Sollwert_Temperatur = analogInput.Sollwert_Temperatur; + Istwert_Feuchte = analogInput.Istwert_Feuchte; + Sollwert_Feuchte = analogInput.Sollwert_Feuchte; + // uj - not yet needed - silence compiler +// double Sollwert_Luefter = analogInput.Sollwert_Luefter; + Temperatur_Feuchtemodul = analogInput.Temperatur_Feuchtemodul; + Istwert_Temperatur_Tuer = analogInput.Istwert_Temperatur_Tuer; - // ------------------- - // Nachlauf Türöffnung - // ------------------- - // f_PostDoorOpening(..) - if (!Startup_finished) { - Counter_Tuer_offen = 0.0; - Counter_Tuer_geschlossen = 600.0; - } else if (Tuer_offen) { - Counter_Tuer_offen += sampling_time; - Counter_Tuer_geschlossen = 0.0; - } else { - Counter_Tuer_offen = 0.0; - Counter_Tuer_geschlossen += sampling_time; - } - - Sollwert_Temperatur_MIN = -5.0; - Sollwert_Temperatur_MAX = 100.0; - - // ------------------------------------------ - // Sollwert Feuchte (Limit-Kennfeld) - // ------------------------------------------ - // f_HumiditySetValueByVector(...) - Index_Sollwert_Feuchte_Limit = 1; - while (Kennfeld_Sollwert_Feuchte_Limit[0][Index_Sollwert_Feuchte_Limit] < - Sollwert_Temperatur && - Index_Sollwert_Feuchte_Limit < 10) { - Index_Sollwert_Feuchte_Limit++; - } - - Interpolation_Sollwert_Feuchte_Limit = limit( - (Kennfeld_Sollwert_Feuchte_Limit[0][Index_Sollwert_Feuchte_Limit - 1] - - Sollwert_Temperatur) / - (Kennfeld_Sollwert_Feuchte_Limit[0] - [Index_Sollwert_Feuchte_Limit - 1] - - Kennfeld_Sollwert_Feuchte_Limit[0][Index_Sollwert_Feuchte_Limit]), - 0.0, 1.0); - - Sollwert_Feuchte_Max = - Kennfeld_Sollwert_Feuchte_Limit[1][Index_Sollwert_Feuchte_Limit] * - Interpolation_Sollwert_Feuchte_Limit + - Kennfeld_Sollwert_Feuchte_Limit[1][Index_Sollwert_Feuchte_Limit - 1] * - (1.0 - Interpolation_Sollwert_Feuchte_Limit); - - Sollwert_Feuchte_Min = - Kennfeld_Sollwert_Feuchte_Limit[2][Index_Sollwert_Feuchte_Limit] * - Interpolation_Sollwert_Feuchte_Limit + - Kennfeld_Sollwert_Feuchte_Limit[2][Index_Sollwert_Feuchte_Limit - 1] * - (1.0 - Interpolation_Sollwert_Feuchte_Limit); - - Sollwert_Feuchte = - limit(Sollwert_Feuchte, Sollwert_Feuchte_Min, Sollwert_Feuchte_Max); + ///////////////////////////////////////////////////////////////////////////// + // Ende Zuweisungen aus ST-Code Zeilen 1 ... 355 + ///////////////////////////////////////////////////////////////////////////// + // Zähler reset_flag + // ----------------- + if (reset_flag) { + Counter_reset_flag = 0; + } + else { + Counter_reset_flag += 1; + } + Startup_finished = (Counter_reset_flag > static_cast(10 * 4)); - // Abschaltung Feuchteregelung - // f_CutOffHumidityControl(...) - Befeuchtung_aus = - (!Sollwert_Feuchte_aktiv) || Steuerkontakt_Befeuchtung_aus || - (Sollwert_Temperatur > 95.0) || (Sollwert_Temperatur < 5.0); - Entfeuchtung_aus = - (!Sollwert_Feuchte_aktiv) || Steuerkontakt_Entfeuchtung_aus || - (Sollwert_Temperatur > 95.0) || (Sollwert_Temperatur < 5.0); + /* ------------------------------------------------------------------------------- + * Selbsttest + * Entfällt hier, da anderer Kontext und Maschine: Findet an anderer Stelle statt! + * Gilt evtl. auch für die Zeilen oben : 'Zähler reset_flag' + */ - // (p_H2Omax, Taupunkt etc.) - p_H2Omax_Sollwert = 6.112 * std::exp(17.62 * Sollwert_Temperatur / - (243.12 + Sollwert_Temperatur)); - p_H2Omax_Istwert = 6.112 * std::exp(17.62 * Istwert_Temperatur / - (243.12 + Istwert_Temperatur)); + /* Quittierung Sammelalarm */ + // F_TRIG01(Sammelalarm_quittiert); UJ: todo - kären ! - Taupunkt_Istwert = - (241.2 * std::log(std::max(Istwert_Feuchte, 0.001) / 100.0) + - (4222.03716 * Istwert_Temperatur) / (241.2 + Istwert_Temperatur)) / - (17.5043 - std::log(std::max(Istwert_Feuchte, 0.001) / 100.0) - - (17.5043 * Istwert_Temperatur) / (241.2 + Istwert_Temperatur)); + // ------------------------------------------ + // Verzögerte Abschaltung Regelung bei Türöffnung + // ------------------------------------------ +#if 1 + // f_PostDoorOpeningCutOffDelaed(...) + if (Tuer_offen || Steuerkontakt_Standby) + { + Counter_Regelung_AUS += sampling_time; + } + else + { + Counter_Regelung_AUS = 0.0; + } + Regelung_AUS = (Counter_Regelung_AUS > 60.0); +#else + // Original ST Code + // UJ: todo Ist das wirklich äquivalent ? + (* Verzögerte Abschaltung Regelung bei Türöffnung *) + TON01(Tuer_offen OR Steuerkontakt_Standby, 60, 2); + Regelung_AUS := TON01.Q; +#endif - if (Temperatursprung) { - Sollwert_Feuchte_Absolut = - limit(Sollwert_Feuchte * p_H2Omax_Sollwert / p_H2Omax_Istwert, 0.0, - Sollwert_Feuchte); - } else { - Sollwert_Feuchte_Absolut = Sollwert_Feuchte; - } - if (!is_valid(Sollwert_Feuchte_Absolut)) { - Sollwert_Feuchte_Absolut = Sollwert_Feuchte; - } +#if 1 + // todo: insert C++ code here +#else + // UJ: Enfällt dieser ST Code ? + (* ------------------------------- *) + (* Erkennung Typ Befeuchtungsmodul *) + (* ------------------------------- *) - // ------------------ - // Überwachungsregler - // ------------------ - // f_SuperVisor + IF NOT is_valid(Counter_Typ_Feuchtemodul) THEN + Counter_Typ_Feuchtemodul := 0.0; + ELSIF Entleerbehaelter_Unten OR Entleerbehaelter_Oben THEN + Counter_Typ_Feuchtemodul := MIN(Counter_Typ_Feuchtemodul + sampling_time, 10.0); + ELSE + Counter_Typ_Feuchtemodul := MAX(Counter_Typ_Feuchtemodul - sampling_time, -10.0); + END_IF; + BDR_Feuchtemodul := Counter_Typ_Feuchtemodul > 5.0; + BDR_300W_Feuchtemodul := Counter_Typ_Feuchtemodul < -5.0; +#endif - /* - Modus_Ueberwachungsregler = - static_cast(UTILITY_FUNCTIONS::GET_VALUE_DINT(71,0,3,0)); - Grenzwert_Uebertemperatur = UTILITY_FUNCTIONS::GET_VALUE_REAL(71,0,4,0); - Offset_Ueberwachungsregler = UTILITY_FUNCTIONS::GET_VALUE_REAL(71,0,5,0); - if (Modus_Ueberwachungsregler > 0) { - Schaltwert_Uebertemperatur = limit(Sollwert_Temperatur + - Offset_Ueberwachungsregler, -30.0, 110.0); Schaltwert_Untertemperatur = - limit(Sollwert_Temperatur - Offset_Ueberwachungsregler, -30.0, 110.0); } - else { Schaltwert_Uebertemperatur = Grenzwert_Uebertemperatur; - Schaltwert_Untertemperatur = Grenzwert_Untertemperatur; + // ------------------- + // Nachlauf Türöffnung + // ------------------- + // f_PostDoorOpening(..) + if (!Startup_finished) + { + Counter_Tuer_offen = 0.0; + Counter_Tuer_geschlossen = 600.0; + } + else if (Tuer_offen) + { + Counter_Tuer_offen += sampling_time; + Counter_Tuer_geschlossen = 0.0; + } + else + { + Counter_Tuer_offen = 0.0; + Counter_Tuer_geschlossen += sampling_time; } - const double maxUeberw = std::max(Istwert_Ueberwachungsregler, - Istwert_Temperatur); const double minUeberw = - std::min(Istwert_Ueberwachungsregler, Istwert_Temperatur); + /////////////////////////////////////////////////////////////////////////////// + /// UJ: Warum fehlt folgender ST-Code ? + /////////////////////////////////////////////////////////////////////////////// + /* - if ( (maxUeberw > Schaltwert_Uebertemperatur) || - (Status_Uebertemperatur && (maxUeberw > Schaltwert_Uebertemperatur - - 1.0)) || (StatusQuittierung_Uebertemperatur && (Klasse_Ueberwachungsregler - < 3.0)) ) { Counter_Status_Uebertemperatur += 1; } else { - Counter_Status_Uebertemperatur = 0; + (* -------------------- *) + (* LQC Lichtintegration *) + (* -------------------- *) + + R_TRIG08(get_second(rtc.cdt) > 0); + IF (R_TRIG08.Q AND Lichtintegral_AN) THEN + IF (Istwert_UVA > 0.0 AND Istwert_UVA < 100.0) THEN + Integral_UVA := LIMIT(Integral_UVA + Istwert_UVA / 60.0, 0.0, 99999.0) ; + END_IF; + IF (Istwert_VIS > 0.0 AND Istwert_VIS < 100.0) THEN + Integral_VIS := LIMIT(Integral_VIS + Istwert_VIS / (1000.0 * 60.0), 0.0, 99999.0); + END_IF; + END_IF; + + TON07(Lichtintegral_RESET_UVA, 5, 2); + TOF06(NOT Lichtintegral_RESET_UVA, 6, 2); + TOF05(reset_flag, 8, 2); + IF TON07.Q AND TOF06.Q AND NOT TOF05.Q THEN + Integral_UVA := 0.0; + END_IF; + + TON08(Lichtintegral_RESET_VIS, 5, 2); + TOF08(NOT Lichtintegral_RESET_VIS, 6, 2); + TOF07(reset_flag, 8, 2); + IF TON08.Q AND TOF08.Q AND NOT TOF07.Q THEN + Integral_VIS := 0.0; + END_IF; + + UVA_Dosis_erreicht := Integral_UVA >= Grenzwert_UVA AND Lichtintegral_AN; + VIS_Dosis_erreicht := Integral_VIS >= Grenzwert_VIS AND Lichtintegral_AN; + + (* Steuerung Lichtkassetten *) + IF (Steuerkontakt_Standby) THEN + Beleuchtung_UVA := FALSE; + Beleuchtung_VIS := FALSE; + ELSE + Beleuchtung_UVA := (Integral_UVA < Grenzwert_UVA AND Lichtintegral_AN) OR Steuerkontakt_Beleuchtung_UVA; + Beleuchtung_VIS := (Integral_VIS < Grenzwert_VIS AND Lichtintegral_AN) OR Steuerkontakt_Beleuchtung_VIS; + END_IF; + + (* Fehler UVA-Sensor *) + IF NOT Startup_finished OR NOT is_valid (Counter_Alarm_Lichtsensor_UVA) OR (is_valid(Istwert_UVA) AND Lichtsensor_UVA) OR NOT Lichtintegral_AN THEN + Counter_Alarm_Lichtsensor_UVA := 0.0; + ELSE + Counter_Alarm_Lichtsensor_UVA := Counter_Alarm_Lichtsensor_UVA + sampling_time; + END_IF; + + (* Fehler VIS-Sensor *) + IF NOT Startup_finished OR NOT is_valid (Counter_Alarm_Lichtsensor_VIS) OR (is_valid(Istwert_VIS) AND Lichtsensor_VIS) OR NOT Lichtintegral_AN THEN + Counter_Alarm_Lichtsensor_VIS := 0.0; + ELSE + Counter_Alarm_Lichtsensor_VIS := Counter_Alarm_Lichtsensor_VIS + sampling_time; + END_IF; + + (* Sollwertbegrenzung Temperatur *) + IF Lichtbox OR Lichtsensor_UVA OR is_valid(Istwert_UVA) OR Lichtsensor_VIS OR is_valid(Istwert_VIS) OR Steuerkontakt_Beleuchtung_UVA OR Steuerkontakt_Beleuchtung_VIS THEN + Sollwert_Temperatur_MIN := 5.0; + Sollwert_Temperatur_MAX := 60.0; + ELSE + + */ + /////////////////////////////////////////////////////////////////////////////// + + /* + (* Sollwertbegrenzung Temperatur *) + */ + Sollwert_Temperatur_MIN = -5.0; + Sollwert_Temperatur_MAX = 100.0; + + + /////////////////////////////////////////////////////////////////////////////// + /// UJ: Warum fehlt folgender ST-Code ? + /////////////////////////////////////////////////////////////////////////////// + /* + + (* ---------- *) + (* CO2-Regler *) + (* ---------- *) + + (* Überprüfung ob Sensor gesteckt oder defekt *) + IF Istwert_CO2 < -3.75 OR NOT is_valid(Istwert_CO2) THEN (* < 1mA *) + CO2_Sensor_gesteckt := FALSE; + CO2_Sensor_defekt := FALSE; + Istwert_CO2 := 3.0e37; + ELSIF Istwert_CO2 >= -3.75 AND Istwert_CO2 < -1.25 THEN (* >=1mA && < 3mA *) + CO2_Sensor_gesteckt := TRUE; + CO2_Sensor_defekt := TRUE; + Istwert_CO2 := 3.0e37; + ELSE + CO2_Sensor_gesteckt := TRUE; + CO2_Sensor_defekt := FALSE; + END_IF; + + (* Korrektur CO2-Istwert *) + (* Als quadratische Funktion gefittete Internationale Höhenformel + p = 1013.25*(1-(0.0065*h)/288.15).^5.255; + maximaler Fehler: +/- 0.053 im Bereich von 0..2000m*) + Luftdruck_NHN := LIMIT(5.3532e-06 * Hoehe_NHN * Hoehe_NHN - 0.11979 * Hoehe_NHN + 1013.2, 702.0088, 1013.2); (* mbar *) + + (* Korrekturformel *) + (* Korrektur auf Referenzwert bei 0m (1013.25mbar) und 37°C *) + (* Formel laut Vaisala PDF: W:\FuE_Projekte\2016\16-031_PDP_Entwicklung C170-E7\A12 Elektrokonstruktion, MSR\Wie misst man CO2.pdf *) + IF is_valid(Istwert_CO2) THEN + Istwert_CO2 := LIMIT(Istwert_CO2 * 1013.25 / Luftdruck_NHN * (273.15 + Istwert_Temperatur) / (273.15 + 37.0), 0.0, 20.0); (* Vol.% *) + END_IF; + + Regler_CO2_Xp := F_Xp_CO2; + + IF Steuerkontakt_Messbereich_0bis1 THEN + Istwert_CO2 := Istwert_CO2 * 1.0 / 20.0; + Sollwert_CO2 := MIN(Sollwert_CO2, 1.0); + Regler_CO2_Xp := F_Xp_CO2 * 1.0 / 20.0; + END_IF; + + (*Regelabweichung*) + IF NOT Tuer_offen OR ABS(Regelabweichung_CO2) > ABS(Sollwert_CO2 - Istwert_CO2) OR NOT is_valid(Regelabweichung_CO2) THEN + Regelabweichung_CO2 := Sollwert_CO2 - Istwert_CO2; + END_IF; + (* P-Anteil *) + IF NOT is_valid(Regelabweichung_CO2) THEN + P_Anteil_CO2 := 0.0; + ELSE + P_Anteil_CO2 := 100.0 / Regler_CO2_Xp * Regelabweichung_CO2; + END_IF; + (* I-Anteil *) + (* Anti-wind-up über dynamisches Integrator Clamping *) + IF NOT Startup_finished OR NOT is_valid(I_Anteil_CO2) THEN + I_Anteil_CO2 := 0.0; + ELSIF is_valid(Regelabweichung_CO2) THEN + I_Anteil_CO2 := LIMIT(I_Anteil_CO2 + 100.0 / Regler_CO2_Xp / Regler_CO2_Tn * sampling_time * Regelabweichung_CO2, Regler_CO2_I_Anteil_MIN, MAX(Regler_CO2_I_Anteil_MAX - P_Anteil_CO2, Regler_CO2_I_Anteil_MIN)); + END_IF; + (* D-Anteil *) + IF NOT Startup_finished OR NOT is_valid(D_Anteil_CO2) THEN + D_Anteil_CO2 := 0.0; + ELSIF is_valid(Regelabweichung_CO2) AND is_valid(Regelabweichung_CO2_alt) THEN + D_Anteil_CO2 := D_Anteil_CO2 + (100.0 / Regler_CO2_Xp * Regler_CO2_Tv * (Regelabweichung_CO2 - Regelabweichung_CO2_alt) / sampling_time - D_Anteil_CO2) / (Tau_CO2_Tv / sampling_time); + END_IF; + (* Berechnung Stellgrad *) + IF Tuer_offen OR Regelung_AUS OR NOT Startup_finished OR NOT Sollwert_CO2_aktiv OR NOT is_valid(Regelabweichung_CO2) THEN + Stellgrad_CO2 := 0.0; + ELSE + Stellgrad_CO2 := LIMIT(P_Anteil_CO2 + I_Anteil_CO2 + D_Anteil_CO2, Regler_CO2_MIN, Regler_CO2_MAX); + END_IF; + + IF Steuerkontakt_Messbereich_0bis1 THEN + Stellgrad_CO2 := Stellgrad_CO2 / 20.0; + END_IF; + + (* Fehler CO2-Sensor *) + IF NOT Startup_finished OR NOT is_valid (Counter_Fehler_Sensor_CO2) OR NOT Sollwert_CO2_aktiv OR NOT CO2_Sensor_defekt THEN + Counter_Fehler_Sensor_CO2 := 0.0; + ELSE + Counter_Fehler_Sensor_CO2 := Counter_Fehler_Sensor_CO2 + sampling_time; + END_IF; + + + (* -------------------- *) + (* Heißluftdesinfektion *) + (* -------------------- *) + + IF Automatikbetrieb AND Programmnummer < 1.5 AND Programmabschnitt < 1.5 THEN + Desinfektion_aktiv := TRUE; + Sollwert_Temperatur_Offset := Sollwert_Temperatur_MAX; + Signal_Programm_Stopp := Istwert_Temperatur < Sollwert_Temperatur_Geber - 1.0; + ELSIF Automatikbetrieb AND Programmnummer < 1.5 AND Programmabschnitt > 1.5 THEN + Desinfektion_aktiv := TRUE; + Sollwert_Temperatur_Offset := GET_VALUE_REAL(82,0,0,0); + Signal_Programm_Stopp := Istwert_Temperatur > Sollwert_Temperatur_Offset + 1.0;; + ELSIF Programmendesignal AND Programmnummer < 1.5 THEN + Desinfektion_aktiv := FALSE; + Sollwert_Temperatur_Offset := GET_VALUE_REAL(82,0,0,0); + Signal_Programm_Stopp := FALSE; + ELSE + Desinfektion_aktiv := FALSE; + Sollwert_Temperatur_Offset := 0.0; + Signal_Programm_Stopp := FALSE; + END_IF; + + + (* -------------- *) + (* Kaskadenregler *) + (* -------------- *) + + (* Begrenzung der Sensitivität *) + Sensitivitaet_Kaskade := MAX(Sensitivitaet_Kaskade, 1.0); + + (* Regelabweichung *) + Regelabweichung_Kaskade := Sollwert_Temperatur_Geber - Istwert_Objekttemperatur; + + (* Gradient Regelabweichung Temperatur *) + IF NOT Startup_finished OR NOT IS_VALID(Regelabweichung_Kaskade_Gradient) THEN + Regelabweichung_Kaskade_Gradient := 0.0; + ELSIF IS_VALID(Regelabweichung_Kaskade) AND IS_VALID(Regelabweichung_Kaskade_alt) THEN + Regelabweichung_Kaskade_Gradient := LIMIT(Regelabweichung_Kaskade_Gradient + ((Regelabweichung_Kaskade - Regelabweichung_Kaskade_alt) * 60.0 / sampling_time - Regelabweichung_Kaskade_Gradient) / (60.0 * 100.0 / Sensitivitaet_Kaskade) * sampling_time, -1.0 * Sensitivitaet_Kaskade / 100.0, 1.0 * Sensitivitaet_Kaskade / 100.0); + END_IF; + + (* Xp, Tn und Tv Berechnung *) + Regler_Kaskade_Xp := F_Xp_Kaskade; + IF Regelabweichung_Kaskade > 0.0 THEN + Regler_Kaskade_Tn := 300.0 * 100.0 / Sensitivitaet_Kaskade * LIMIT(Regelabweichung_Kaskade_Gradient / (-0.05 * Sensitivitaet_Kaskade / 100.0), 1.0, 100.0); + ELSE + Regler_Kaskade_Tn := 300.0 * 100.0 / Sensitivitaet_Kaskade * LIMIT(Regelabweichung_Kaskade_Gradient / (0.05 * Sensitivitaet_Kaskade / 100.0), 1.0, 100.0); + END_IF; + Regler_Kaskade_Tv := 60.0 * 100.0 / Sensitivitaet_Kaskade; + + (* Anti-wind-up über dynamisches Clamping *) + Regler_Kaskade_MIN := -Korrektur_Temperatur_MAX; + Regler_Kaskade_MAX := Korrektur_Temperatur_MAX; + Regler_Kaskade_I_Anteil_MIN := LIMIT(Regler_Kaskade_MIN - Regler_Kaskade_MIN * Regelabweichung_Kaskade_Gradient / (1.0 * Sensitivitaet_Kaskade / 100.0) - P_Anteil_Kaskade, Regler_Kaskade_MIN, 0.0); + Regler_Kaskade_I_Anteil_MAX := LIMIT(Regler_Kaskade_MAX - Regler_Kaskade_MAX * Regelabweichung_Kaskade_Gradient / (-1.0 * Sensitivitaet_Kaskade / 100.0) - P_Anteil_Kaskade, 0.0, Regler_Kaskade_MAX); + + (* P-Anteil *) + IF NOT is_valid(Regelabweichung_Kaskade) THEN + P_Anteil_Kaskade := 0.0; + ELSE + P_Anteil_Kaskade := LIMIT(Korrektur_Temperatur_MAX / Regler_Kaskade_Xp * Regelabweichung_Kaskade, -100.0, 100.0); + END_IF; + (* I-Anteil *) + IF NOT Startup_finished OR NOT is_valid(I_Anteil_Kaskade) THEN + I_Anteil_Kaskade := 0.0; + ELSIF is_valid(Regelabweichung_Kaskade) AND Counter_Tuer_geschlossen > 300.0 AND NOT Temperatursprung THEN + I_Anteil_Kaskade := LIMIT(I_Anteil_Kaskade + (D_Anteil_Kaskade + Korrektur_Temperatur_MAX / Regler_Kaskade_Xp * Regelabweichung_Kaskade) / Regler_Kaskade_Tn * sampling_time, Regler_Kaskade_I_Anteil_MIN, Regler_Kaskade_I_Anteil_MAX); + END_IF; + (* D-Anteil *) + IF NOT Startup_finished OR NOT is_valid(D_Anteil_Kaskade) THEN + D_Anteil_Kaskade := 0.0; + ELSIF is_valid(Regelabweichung_Kaskade) AND is_valid(Regelabweichung_Kaskade_alt) AND Counter_Tuer_geschlossen > 60.0 THEN + D_Anteil_Kaskade := D_Anteil_Kaskade + (Korrektur_Temperatur_MAX / Regler_Kaskade_Xp * Regler_Kaskade_Tv * (Regelabweichung_Kaskade - Regelabweichung_Kaskade_alt) / sampling_time - D_Anteil_Kaskade) / (Tau_Kaskade_Tv / sampling_time); + END_IF; + (* Berechnung Stellgrad *) + IF Regelung_AUS OR NOT Startup_finished OR NOT Steuerkontakt_Kaskade OR NOT is_valid(Regelabweichung_Kaskade) THEN + Stellgrad_Kaskade := 0.0; + ELSE + Stellgrad_Kaskade := LIMIT(P_Anteil_Kaskade + I_Anteil_Kaskade + D_Anteil_Kaskade, Regler_Kaskade_MIN, Regler_Kaskade_MAX); + END_IF; + + (* Objektfeuchte *) + p_H2O_MAX_Objekttemperatur := 6.112 * EXP(17.62 * Istwert_Objekttemperatur / (243.12 + Istwert_Objekttemperatur)); + p_H2O_MAX_Temperatur := 6.112 * EXP(17.62 * Istwert_Temperatur / (243.12 + Istwert_Temperatur)); + + IF NOT Startup_finished OR NOT is_valid(Stellgrad_Kaskade_Feuchte) OR NOT Steuerkontakt_Kaskade THEN + Istwert_Objektfeuchte := Istwert_Feuchte; + Stellgrad_Kaskade_Feuchte := 0.0; + ELSIF IS_VALID(p_H2O_MAX_Objekttemperatur) AND IS_VALID(p_H2O_MAX_Temperatur) THEN + Istwert_Objektfeuchte := Istwert_Feuchte * p_H2O_MAX_Temperatur / p_H2O_MAX_Objekttemperatur; + Stellgrad_Kaskade_Feuchte := LIMIT(Stellgrad_Kaskade_Feuchte + ((Istwert_Feuchte - Istwert_Objektfeuchte) - Stellgrad_Kaskade_Feuchte) / (600.0 / sampling_time), -Korrektur_Feuchte_MAX, Korrektur_Feuchte_MAX); + END_IF; + + (* Sollwerte für Temperatur und Feuchteregelung im Seitenteil *) + Sollwert_Temperatur := LIMIT(Sollwert_Temperatur_Geber + Stellgrad_Kaskade, Sollwert_Temperatur_MIN, Sollwert_Temperatur_MAX); + Sollwert_Feuchte := Sollwert_Feuchte_Geber + Stellgrad_Kaskade_Feuchte ; + + + */ + + // ------------------------------------------ + // (* Sollwert Feuchteregelung (absolut/relativ) *) + // Sollwert Feuchte (Limit-Kennfeld) + // ------------------------------------------ + // (* Begrenzung Feuchtesollwert*) + Index_Sollwert_Feuchte_Limit = 1; + while ((Kennfeld_Sollwert_Feuchte_Limit[0][Index_Sollwert_Feuchte_Limit] < Sollwert_Temperatur) && + (Index_Sollwert_Feuchte_Limit < 10)) + { + Index_Sollwert_Feuchte_Limit++; } - Status_Uebertemperatur = (Counter_Status_Uebertemperatur >= - static_cast(10 * 4)); StatusQuittierung_Uebertemperatur = - (Status_Uebertemperatur && Counter_Status_Uebertemperatur < - static_cast(11 * 4)) || (StatusQuittierung_Uebertemperatur && - Sammelalarm_quittiert); + Interpolation_Sollwert_Feuchte_Limit = + limit((Kennfeld_Sollwert_Feuchte_Limit[0][Index_Sollwert_Feuchte_Limit - 1] - Sollwert_Temperatur) / + (Kennfeld_Sollwert_Feuchte_Limit[0][Index_Sollwert_Feuchte_Limit - 1] - Kennfeld_Sollwert_Feuchte_Limit[0][Index_Sollwert_Feuchte_Limit]), + 0.0, + 1.0); - if ( ((minUeberw < Schaltwert_Untertemperatur) || - (Status_Untertemperatur && (minUeberw < Schaltwert_Untertemperatur - + 1.0))) && (Klasse_Ueberwachungsregler >= 3.0) ) { - Counter_Status_Untertemperatur += 1; + Sollwert_Feuchte_Max = + Kennfeld_Sollwert_Feuchte_Limit[1][Index_Sollwert_Feuchte_Limit] * Interpolation_Sollwert_Feuchte_Limit + + Kennfeld_Sollwert_Feuchte_Limit[1][Index_Sollwert_Feuchte_Limit - 1] * (1.0 - Interpolation_Sollwert_Feuchte_Limit); + + Sollwert_Feuchte_Min = + Kennfeld_Sollwert_Feuchte_Limit[2][Index_Sollwert_Feuchte_Limit] * Interpolation_Sollwert_Feuchte_Limit + + Kennfeld_Sollwert_Feuchte_Limit[2][Index_Sollwert_Feuchte_Limit - 1] * (1.0 - Interpolation_Sollwert_Feuchte_Limit); + + Sollwert_Feuchte = limit(Sollwert_Feuchte, Sollwert_Feuchte_Min, Sollwert_Feuchte_Max); + + + + // Abschaltung Feuchteregelung + // f_CutOffHumidityControl(...) + Befeuchtung_aus = !Sollwert_Feuchte_aktiv || Steuerkontakt_Befeuchtung_aus || + (Sollwert_Temperatur > 95.0) || (Sollwert_Temperatur < 5.0); + Entfeuchtung_aus = !Sollwert_Feuchte_aktiv || Steuerkontakt_Entfeuchtung_aus || + (Sollwert_Temperatur > 95.0) || (Sollwert_Temperatur < 5.0); + + // (p_H2Omax, Taupunkt etc.) + p_H2Omax_Sollwert = 6.112 * std::exp(17.62 * Sollwert_Temperatur / (243.12 + Sollwert_Temperatur)); + p_H2Omax_Istwert = 6.112 * std::exp(17.62 * Istwert_Temperatur / (243.12 + Istwert_Temperatur)); + + Taupunkt_Istwert = (241.2 * std::log(std::max(Istwert_Feuchte, 0.001) / 100.0) + + (4222.03716 * Istwert_Temperatur) / (241.2 + Istwert_Temperatur)) / (17.5043 - std::log(std::max(Istwert_Feuchte, 0.001) / 100.0) - + (17.5043 * Istwert_Temperatur) / (241.2 + Istwert_Temperatur)); + + if (Temperatursprung) + { + Sollwert_Feuchte_Absolut = limit(Sollwert_Feuchte * p_H2Omax_Sollwert / p_H2Omax_Istwert, 0.0, Sollwert_Feuchte); + } + else + { + Sollwert_Feuchte_Absolut = Sollwert_Feuchte; + } + + if (!is_valid(Sollwert_Feuchte_Absolut)) + { + Sollwert_Feuchte_Absolut = Sollwert_Feuchte; + } + + // ------------------ + // Überwachungsregler + // ------------------ + Modus_Ueberwachungsregler = static_cast(UTILITY_FUNCTIONS::GET_VALUE_DINT(71,0,3,0)); + Grenzwert_Uebertemperatur = UTILITY_FUNCTIONS::GET_VALUE_REAL(71,0,4,0); + Offset_Ueberwachungsregler = UTILITY_FUNCTIONS::GET_VALUE_REAL(71,0,5,0); + + /////////////////////////////////////////////////////////////////////////////// + /// UJ: Warum fehlt folgender ST-Code ? + /////////////////////////////////////////////////////////////////////////////// + /* + IF Desinfektion_aktiv THEN + Schaltwert_Uebertemperatur := 110.0; + Schaltwert_Untertemperatur := -30.0; + ~~ ELSIF Modus_Ueberwachungsregler > 0 THEN + */ + + if (Modus_Ueberwachungsregler > 0) + { + Schaltwert_Uebertemperatur = limit(Sollwert_Temperatur + Offset_Ueberwachungsregler, -30.0, 110.0); + Schaltwert_Untertemperatur = limit(Sollwert_Temperatur - Offset_Ueberwachungsregler, -30.0, 110.0); + } + else + { + Schaltwert_Uebertemperatur = Grenzwert_Uebertemperatur; + Schaltwert_Untertemperatur = Grenzwert_Untertemperatur; + } + + const double maxUeberw = std::max(Istwert_Ueberwachungsregler, Istwert_Temperatur); + const double minUeberw = std::min(Istwert_Ueberwachungsregler, Istwert_Temperatur); + + if ( (maxUeberw > Schaltwert_Uebertemperatur) || (Status_Uebertemperatur && (maxUeberw > Schaltwert_Uebertemperatur - 1.0)) || + (StatusQuittierung_Uebertemperatur && (Klasse_Ueberwachungsregler < 3.0)) ) + { + Counter_Status_Uebertemperatur += 1; + } + else + { + Counter_Status_Uebertemperatur = 0; + } + + Status_Uebertemperatur = (Counter_Status_Uebertemperatur >= static_cast(10 * 4)); + StatusQuittierung_Uebertemperatur = (Status_Uebertemperatur && Counter_Status_Uebertemperatur < static_cast(11 * 4)) || + (StatusQuittierung_Uebertemperatur && Sammelalarm_quittiert); + + if ( ((minUeberw < Schaltwert_Untertemperatur) || (Status_Untertemperatur && (minUeberw < Schaltwert_Untertemperatur + 1.0))) && + (Klasse_Ueberwachungsregler >= 3.0) ) + { + Counter_Status_Untertemperatur += 1; + } + else + { + Counter_Status_Untertemperatur = 0; + } + + Status_Untertemperatur = (Counter_Status_Untertemperatur >= static_cast(10 * 4)); + StatusQuittierung_Untertemperatur = Status_Untertemperatur && ( Counter_Status_Untertemperatur < static_cast(11 * 4)) || + (StatusQuittierung_Untertemperatur && Sammelalarm_quittiert); + + if (Status_Untertemperatur || StatusQuittierung_Untertemperatur) + { + Sollwert_Temperatur = std::max(Sollwert_Temperatur, Schaltwert_Untertemperatur); + } + + if (Status_Uebertemperatur || StatusQuittierung_Uebertemperatur) + { + Sollwert_Temperatur = std::min(Sollwert_Temperatur, + Schaltwert_Uebertemperatur); + } + + // ------------------------ + // Parametersatzumschaltung + // ------------------------ + // (* Parametersatzumschaltung über Kennfeld *) + Index_Feuchte = static_cast( 8 - UTILITY_FUNCTIONS::real_to_int(limit((Sollwert_Feuchte - 10.0) / + (90.0 - 10.0) * 8.0, 0.0, 8.0) + 0.5)); + Index_Temperatur = static_cast( UTILITY_FUNCTIONS::real_to_int(limit((Sollwert_Temperatur - 10.0) / + (90.0 - 10.0) * 8.0, 0.0, 8.0) + 0.5)); + Index_Temperatur_ohne_Feuchte = static_cast(UTILITY_FUNCTIONS::real_to_int( limit((Sollwert_Temperatur - (-20.0)) / + (100.0 - (-20.0)) * 12.0, 0.0, 12.0) + 0.5)); + + // (* Zuweisung der Regelparameter *) + Regler_Heizung_Xp = F_Xp_Heizung * Kennfeld_Regler_Heizung_Xp[Index_Temperatur_ohne_Feuchte]; + Regler_Kuehlung_Xp = F_Xp_Kuehlung * Kennfeld_Regler_Kuehlung_Xp[Index_Temperatur_ohne_Feuchte]; + /* + * UJ : Warum fehlt das? + IF BDR_Feuchtemodul THEN + Regler_Befeuchtung_Xp := F_Xp_Befeuchtung_BDR * Kennfeld_Regler_Befeuchtung_Xp[Index_Feuchte, Index_Temperatur]; + ELSIF BDR_300W_Feuchtemodul THEN + Regler_Befeuchtung_Xp := F_Xp_Befeuchtung_BDR_300W * Kennfeld_Regler_Befeuchtung_Xp[Index_Feuchte, Index_Temperatur]; + END_IF; + */ + Regler_Befeuchtung_Xp = F_Xp_Befeuchtung_BINDER * Kennfeld_Regler_Befeuchtung_Xp[Index_Feuchte][Index_Temperatur]; + Regler_Entfeuchtung_Xp = F_Xp_Entfeuchtung * Kennfeld_Regler_Entfeuchtung_Xp[Index_Feuchte][Index_Temperatur]; + Regler_Tuer_Xp = F_Xp_Tuer; // * Kennfeld_Regler_Tuer_Xp[Index_Temperatur_ohne_Feuchte]; UJ : Warum fehlt das? + + // --------------------- + // PID Regler Temperatur + // --------------------- + // (* Regelabweichung *) + Regelabweichung_Temperatur = Sollwert_Temperatur - Istwert_Temperatur; + + // Zykluszeit Regelabweichung Temperatur + // (* Berechnung Regelabweichung Temperatur Mittelwert *) + if (!Startup_finished || !is_valid(Standardregelabweichung_Temperatur) || + !is_valid(Standardgradient_Regelabweichung_Temperatur) || + Standardgradient_Regelabweichung_Temperatur <= 0.0) + { + Zykluszeit_Regelabweichung_Temperatur = 600.0; + } + else + { + Zykluszeit_Regelabweichung_Temperatur = limit( 2.0 * 3.1415 * Standardregelabweichung_Temperatur / Standardgradient_Regelabweichung_Temperatur * 60.0, + 120.0, + 1200.0); + } + Zykluszeit_Regelabweichung_Heizung = std::min(Zykluszeit_Regelabweichung_Temperatur, 300.0); + Zykluszeit_Regelabweichung_Kuehlung = std::max(Zykluszeit_Regelabweichung_Temperatur, 600.0); + Amplitude_Regelabweichung_Temperatur = 1.4142 * Standardregelabweichung_Temperatur; + + // Mittelwert Regelabweichung Temperatur + if (!Startup_finished || !is_valid(Regelabweichung_Temperatur_Mittelwert) || Temperatursprung) + { + Regelabweichung_Temperatur_Mittelwert = 0.0; + } + else if (is_valid(Regelabweichung_Temperatur)) + { + const double alpha = (Zykluszeit_Regelabweichung_Temperatur / sampling_time); + Regelabweichung_Temperatur_Mittelwert = limit( Regelabweichung_Temperatur_Mittelwert + (Regelabweichung_Temperatur - Regelabweichung_Temperatur_Mittelwert) / alpha, + Regelabweichung_Temperatur - 1.0, + Regelabweichung_Temperatur + 1.0); + } + + // Standardregelabweichung Temperatur + if (!Startup_finished || !is_valid(Standardregelabweichung_Temperatur) || Temperatursprung) + { + Standardregelabweichung_Temperatur = 0.0; + } + else if (is_valid(Regelabweichung_Temperatur)) + { + const double n = (Zykluszeit_Regelabweichung_Temperatur / sampling_time); + Standardregelabweichung_Temperatur = std::min( std::sqrt(((Regelabweichung_Temperatur - Regelabweichung_Temperatur_Mittelwert) * + (Regelabweichung_Temperatur - Regelabweichung_Temperatur_Mittelwert) + + Standardregelabweichung_Temperatur * Standardregelabweichung_Temperatur * (n - 1.0)) / n), + 1.0); + } + + // Gradient Regelabweichung Temperatur + // f_PID_Temperaure.GradientDifference(...) + if (!Startup_finished || !is_valid(Regelabweichung_Temperatur_Gradient)) + { + Regelabweichung_Temperatur_Gradient = 0.0; + } + else if (is_valid(Regelabweichung_Temperatur) && is_valid(Regelabweichung_Temperatur_alt)) + { + Regelabweichung_Temperatur_Gradient = limit(Regelabweichung_Temperatur_Gradient + ((Regelabweichung_Temperatur - Regelabweichung_Temperatur_alt) * + (60.0 / sampling_time) - Regelabweichung_Temperatur_Gradient) / (10.0 / sampling_time), + -4.0, + 2.0); + } + + // Standardgradient Temperatur + // f_PID_Temperaure.StandardGradient(...) + if (!Startup_finished || !is_valid(Standardgradient_Regelabweichung_Temperatur) || Temperatursprung) + { + Standardgradient_Regelabweichung_Temperatur = 0.0; + } + else if (is_valid(Regelabweichung_Temperatur)) + { + const double n = (Zykluszeit_Regelabweichung_Temperatur / sampling_time); + Standardgradient_Regelabweichung_Temperatur = limit(std::sqrt((Regelabweichung_Temperatur_Gradient * Regelabweichung_Temperatur_Gradient + + Standardgradient_Regelabweichung_Temperatur * + Standardgradient_Regelabweichung_Temperatur * (n - 1.0)) / n), + 0.01, + 1.0); + } + + // Temperatursprung + // f_TemperatureJumpHandler(...) + if (!Startup_finished) + { + Counter_Temperatursprung = 0.0; + } + else if (((Sollwert_Temperatur != Sollwert_Temperatur_alt) && (std::abs(Regelabweichung_Temperatur) > 1.0)) || Tuer_offen) + { + Counter_Temperatursprung = std::max(Counter_Temperatursprung + sampling_time, 0.0); + } + else if (Regelabweichung_Temperatur < std::max(0.2, Amplitude_Regelabweichung_Temperatur) && + Regelabweichung_Temperatur > -std::max(0.2, Amplitude_Regelabweichung_Temperatur)) + { + Counter_Temperatursprung = std::min(Counter_Temperatursprung - sampling_time, 0.0); + } + else if (Regelabweichung_Temperatur > std::max(0.5, 2.0 * Amplitude_Regelabweichung_Temperatur) || + Regelabweichung_Temperatur < -std::max(0.5, 2.0 * Amplitude_Regelabweichung_Temperatur)) + { + Counter_Temperatursprung = std::max(Counter_Temperatursprung + sampling_time, -120.0); + } + Temperatursprung = (Counter_Temperatursprung > 0.0) || (Temperatursprung && Counter_Temperatursprung > -60.0); + + // Anti-wind-up Heizung (dynamisches Clamping) + // ------ F_PID_Temperatuer.AntiWindUpHeater(...) + if ((Counter_Tuer_geschlossen < 180.0) || (Counter_Tuer_offen > 0.0)) + { + Regler_Heizung_MIN = 0.0; + Regler_Heizung_I_Anteil_MIN = 0.0; + Regler_Heizung_MAX = 100.0; + Regler_Heizung_I_Anteil_MAX = limit(100.0 - P_Anteil_Heizung, Regler_Heizung_I_Anteil_MIN, Stellgrad_Heizung_Mittelwert); + } + else + { + Regler_Heizung_MIN = 0.0; + Regler_Heizung_I_Anteil_MIN = 0.0; + Regler_Heizung_MAX = 100.0; + if (Temperatursprung) + { + Regler_Heizung_I_Anteil_MAX = limit(100.0 - P_Anteil_Heizung, Regler_Heizung_I_Anteil_MIN, Regler_Heizung_MAX); + } + else + { + Regler_Heizung_I_Anteil_MAX = 100.0; + } +} + //---------------------- + + // Anpassung Xp Heizung + // // ------------F_PID_Temperatuer.AdaptXp(...) + if (Regelabweichung_Temperatur > Amplitude_Regelabweichung_Temperatur && + Regelabweichung_Temperatur_Mittelwert > 0.05 && + !Temperatursprung) + { + Regler_Heizung_Xp /= 2.0; + } + // Achtung: du referenzierst hier Zykluszeit_Regelabweichung_Feuchte später + // – steht unten. Wir setzen default, falls noch uninitialisiert: + if (!is_valid(Zykluszeit_Regelabweichung_Feuchte) || Zykluszeit_Regelabweichung_Feuchte <= 0.0) + { + Zykluszeit_Regelabweichung_Feuchte = 600.0; + } + + Regler_Heizung_Xp = Regler_Heizung_Xp * limit(Zykluszeit_Regelabweichung_Feuchte / 300.0, 1.0, 2.0) * + limit(1.0 + Amplitude_Regelabweichung_Temperatur / 0.5 + Stellgrad_Kuehlung_Mittelwert / -100.0, + 1.0, + 2.0); + + // P/I/D Heizung + //----------------- F_PID_Temperature.step(...) + if (!Startup_finished || !is_valid(Regelabweichung_Temperatur)) { + P_Anteil_Heizung = 0.0; } else { - Counter_Status_Untertemperatur = 0; + P_Anteil_Heizung = 100.0 / Regler_Heizung_Xp * Regelabweichung_Temperatur; } - Status_Untertemperatur = (Counter_Status_Untertemperatur >= - static_cast(10 * 4)); StatusQuittierung_Untertemperatur = - (Status_Untertemperatur && Counter_Status_Untertemperatur < - static_cast(11 * 4)) || (StatusQuittierung_Untertemperatur && - Sammelalarm_quittiert); - - if (Status_Untertemperatur || StatusQuittierung_Untertemperatur) { - Sollwert_Temperatur = std::max(Sollwert_Temperatur, - Schaltwert_Untertemperatur); + if (!Startup_finished || !is_valid(I_Anteil_Heizung)) { + I_Anteil_Heizung = 0.0; + } else if (!Regelung_AUS && is_valid(Regelabweichung_Temperatur) && + Counter_Tuer_geschlossen > 60.0) { + I_Anteil_Heizung = limit( + I_Anteil_Heizung + 100.0 / Regler_Heizung_Xp / + (1.0 * Zykluszeit_Regelabweichung_Heizung) * + sampling_time * Regelabweichung_Temperatur, + Regler_Heizung_I_Anteil_MIN, Regler_Heizung_I_Anteil_MAX); } - if (Status_Uebertemperatur || StatusQuittierung_Uebertemperatur) { - Sollwert_Temperatur = std::min(Sollwert_Temperatur, - Schaltwert_Uebertemperatur); - }*/ - // ------------------------ - // Parametersatzumschaltung - // ------------------------ - // f_SwitchParameterSet(...) - Index_Feuchte = static_cast( - 8 - - UTILITY_FUNCTIONS::real_to_int( - limit((Sollwert_Feuchte - 10.0) / (90.0 - 10.0) * 8.0, 0.0, 8.0) + - 0.5)); - Index_Temperatur = - static_cast(UTILITY_FUNCTIONS::real_to_int( - limit((Sollwert_Temperatur - 10.0) / (90.0 - 10.0) * 8.0, 0.0, - 8.0) + - 0.5)); - Index_Temperatur_ohne_Feuchte = - static_cast(UTILITY_FUNCTIONS::real_to_int( - limit((Sollwert_Temperatur - (-20.0)) / (100.0 - (-20.0)) * 12.0, - 0.0, 12.0) + - 0.5)); + if (!Startup_finished || !is_valid(D_Anteil_Heizung)) + { + D_Anteil_Heizung = 0.0; + } + else if (is_valid(Regelabweichung_Temperatur) && + is_valid(Regelabweichung_Temperatur_alt) && + Counter_Tuer_geschlossen > 0.0) + { + D_Anteil_Heizung = D_Anteil_Heizung + (100.0 / Regler_Heizung_Xp * (0.1 * Zykluszeit_Regelabweichung_Heizung) * + (Regelabweichung_Temperatur - Regelabweichung_Temperatur_alt) / sampling_time - + D_Anteil_Heizung) / (Tau_Heizung_Tv / sampling_time); + } - Regler_Heizung_Xp = F_Xp_Heizung * Kennfeld_Regler_Heizung_Xp[Index_Temperatur_ohne_Feuchte]; - Regler_Kuehlung_Xp = F_Xp_Kuehlung * - Kennfeld_Regler_Kuehlung_Xp[Index_Temperatur_ohne_Feuchte]; - Regler_Befeuchtung_Xp = - F_Xp_Befeuchtung_BINDER * - Kennfeld_Regler_Befeuchtung_Xp[Index_Feuchte][Index_Temperatur]; - Regler_Entfeuchtung_Xp = - F_Xp_Entfeuchtung * - Kennfeld_Regler_Entfeuchtung_Xp[Index_Feuchte][Index_Temperatur]; - Regler_Tuer_Xp = F_Xp_Tuer; + if (Counter_Tuer_offen > 60.0 || Regelung_AUS || !Startup_finished) + { + Stellgrad_Heizung = 0.0; + } + else + { + Stellgrad_Heizung = limit(P_Anteil_Heizung + I_Anteil_Heizung + D_Anteil_Heizung, + Regler_Heizung_MIN, + Regler_Heizung_MAX); + } - // --------------------- - // PID Regler Temperatur - // --------------------- - // F_PID PID_Temperature(...) - Regelabweichung_Temperatur = Sollwert_Temperatur - Istwert_Temperatur; - - // Zykluszeit Regelabweichung Temperatur - if (!Startup_finished || !is_valid(Standardregelabweichung_Temperatur) || - !is_valid(Standardgradient_Regelabweichung_Temperatur) || - Standardgradient_Regelabweichung_Temperatur <= 0.0) { - Zykluszeit_Regelabweichung_Temperatur = 600.0; - } else { - Zykluszeit_Regelabweichung_Temperatur = - limit(2.0 * 3.1415 * Standardregelabweichung_Temperatur / - Standardgradient_Regelabweichung_Temperatur * 60.0, - 120.0, 1200.0); - } - Zykluszeit_Regelabweichung_Heizung = - std::min(Zykluszeit_Regelabweichung_Temperatur, 300.0); - Zykluszeit_Regelabweichung_Kuehlung = - std::max(Zykluszeit_Regelabweichung_Temperatur, 600.0); - - Amplitude_Regelabweichung_Temperatur = - 1.4142 * Standardregelabweichung_Temperatur; - - // Mittelwert Regelabweichung Temperatur - if (!Startup_finished || !is_valid(Regelabweichung_Temperatur_Mittelwert) || - Temperatursprung) { - Regelabweichung_Temperatur_Mittelwert = 0.0; - } else if (is_valid(Regelabweichung_Temperatur)) { - const double alpha = - (Zykluszeit_Regelabweichung_Temperatur / sampling_time); - Regelabweichung_Temperatur_Mittelwert = limit( - Regelabweichung_Temperatur_Mittelwert + - (Regelabweichung_Temperatur - - Regelabweichung_Temperatur_Mittelwert) / - alpha, - Regelabweichung_Temperatur - 1.0, Regelabweichung_Temperatur + 1.0); - } - - // Standardregelabweichung Temperatur - if (!Startup_finished || !is_valid(Standardregelabweichung_Temperatur) || - Temperatursprung) { - Standardregelabweichung_Temperatur = 0.0; - } else if (is_valid(Regelabweichung_Temperatur)) { - const double n = (Zykluszeit_Regelabweichung_Temperatur / sampling_time); - Standardregelabweichung_Temperatur = std::min( - std::sqrt(((Regelabweichung_Temperatur - - Regelabweichung_Temperatur_Mittelwert) * - (Regelabweichung_Temperatur - - Regelabweichung_Temperatur_Mittelwert) + - Standardregelabweichung_Temperatur * - Standardregelabweichung_Temperatur * (n - 1.0)) / - n), - 1.0); - } - - // Gradient Regelabweichung Temperatur - // f_PID_Temperaure.GradientDifference(...) - if (!Startup_finished || !is_valid(Regelabweichung_Temperatur_Gradient)) { - Regelabweichung_Temperatur_Gradient = 0.0; - } else if (is_valid(Regelabweichung_Temperatur) && - is_valid(Regelabweichung_Temperatur_alt)) { - Regelabweichung_Temperatur_Gradient = limit( - Regelabweichung_Temperatur_Gradient + - ((Regelabweichung_Temperatur - Regelabweichung_Temperatur_alt) * - (60.0 / sampling_time) - - Regelabweichung_Temperatur_Gradient) / - (10.0 / sampling_time), - -4.0, 2.0); - } - - // Standardgradient Temperatur - // f_PID_Temperaure.StandardGradient(...) - if (!Startup_finished || - !is_valid(Standardgradient_Regelabweichung_Temperatur) || - Temperatursprung) { - Standardgradient_Regelabweichung_Temperatur = 0.0; - } else if (is_valid(Regelabweichung_Temperatur)) { - const double n = (Zykluszeit_Regelabweichung_Temperatur / sampling_time); - Standardgradient_Regelabweichung_Temperatur = - limit(std::sqrt((Regelabweichung_Temperatur_Gradient * - Regelabweichung_Temperatur_Gradient + - Standardgradient_Regelabweichung_Temperatur * - Standardgradient_Regelabweichung_Temperatur * - (n - 1.0)) / - n), - 0.01, 1.0); - } - - // Temperatursprung - // f_TemperatureJumpHandler(...) - if (!Startup_finished) { - Counter_Temperatursprung = 0.0; - } else if (((Sollwert_Temperatur != Sollwert_Temperatur_alt) && - (std::abs(Regelabweichung_Temperatur) > 1.0)) || - Tuer_offen) { - Counter_Temperatursprung = - std::max(Counter_Temperatursprung + sampling_time, 0.0); - } else if (Regelabweichung_Temperatur < - std::max(0.2, Amplitude_Regelabweichung_Temperatur) && - Regelabweichung_Temperatur > - -std::max(0.2, Amplitude_Regelabweichung_Temperatur)) { - Counter_Temperatursprung = - std::min(Counter_Temperatursprung - sampling_time, 0.0); - } else if (Regelabweichung_Temperatur > - std::max(0.5, 2.0 * Amplitude_Regelabweichung_Temperatur) || - Regelabweichung_Temperatur < - -std::max(0.5, 2.0 * Amplitude_Regelabweichung_Temperatur)) { - Counter_Temperatursprung = - std::max(Counter_Temperatursprung + sampling_time, -120.0); - } - Temperatursprung = (Counter_Temperatursprung > 0.0) || - (Temperatursprung && Counter_Temperatursprung > -60.0); - - // Anti-wind-up Heizung (dynamisches Clamping) - // ------ F_PID_Temperatuer.AntiWindUpHeater(...) - if ((Counter_Tuer_geschlossen < 180.0) || (Counter_Tuer_offen > 0.0)) { - Regler_Heizung_MIN = 0.0; - Regler_Heizung_I_Anteil_MIN = 0.0; - Regler_Heizung_MAX = 100.0; - Regler_Heizung_I_Anteil_MAX = - limit(100.0 - P_Anteil_Heizung, Regler_Heizung_I_Anteil_MIN, - Stellgrad_Heizung_Mittelwert); - } else { - Regler_Heizung_MIN = 0.0; - Regler_Heizung_I_Anteil_MIN = 0.0; - Regler_Heizung_MAX = 100.0; - if (Temperatursprung) { - Regler_Heizung_I_Anteil_MAX = - limit(100.0 - P_Anteil_Heizung, Regler_Heizung_I_Anteil_MIN, - Regler_Heizung_MAX); - } else { - Regler_Heizung_I_Anteil_MAX = 100.0; - } - } - //---------------------- - - // Anpassung Xp Heizung - // // ------------F_PID_Temperatuer.AdaptXp(...) - if (Regelabweichung_Temperatur > Amplitude_Regelabweichung_Temperatur && - Regelabweichung_Temperatur_Mittelwert > 0.05 && !Temperatursprung) { - Regler_Heizung_Xp /= 2.0; - } - // Achtung: du referenzierst hier Zykluszeit_Regelabweichung_Feuchte später - // – steht unten. Wir setzen default, falls noch uninitialisiert: - if (!is_valid(Zykluszeit_Regelabweichung_Feuchte) || - Zykluszeit_Regelabweichung_Feuchte <= 0.0) { - Zykluszeit_Regelabweichung_Feuchte = 600.0; - } - - Regler_Heizung_Xp = - Regler_Heizung_Xp * - limit(Zykluszeit_Regelabweichung_Feuchte / 300.0, 1.0, 2.0) * - limit(1.0 + Amplitude_Regelabweichung_Temperatur / 0.5 + - Stellgrad_Kuehlung_Mittelwert / -100.0, - 1.0, 2.0); - //-----------// ------------F_PID_Temperatuer.AdaptXp(...)--------------------------------------------------- - - // P/I/D Heizung - //----------------- F_PID_Temperature.step(...) - if (!Startup_finished || !is_valid(Regelabweichung_Temperatur)) { - P_Anteil_Heizung = 0.0; - } else { - P_Anteil_Heizung = 100.0 / Regler_Heizung_Xp * Regelabweichung_Temperatur; - } - - if (!Startup_finished || !is_valid(I_Anteil_Heizung)) { - I_Anteil_Heizung = 0.0; - } else if (!Regelung_AUS && is_valid(Regelabweichung_Temperatur) && - Counter_Tuer_geschlossen > 60.0) { - I_Anteil_Heizung = limit( - I_Anteil_Heizung + 100.0 / Regler_Heizung_Xp / - (1.0 * Zykluszeit_Regelabweichung_Heizung) * - sampling_time * Regelabweichung_Temperatur, - Regler_Heizung_I_Anteil_MIN, Regler_Heizung_I_Anteil_MAX); - } - - if (!Startup_finished || !is_valid(D_Anteil_Heizung)) { - D_Anteil_Heizung = 0.0; - } else if (is_valid(Regelabweichung_Temperatur) && - is_valid(Regelabweichung_Temperatur_alt) && - Counter_Tuer_geschlossen > 0.0) { - D_Anteil_Heizung = - D_Anteil_Heizung + - (100.0 / Regler_Heizung_Xp * - (0.1 * Zykluszeit_Regelabweichung_Heizung) * - (Regelabweichung_Temperatur - Regelabweichung_Temperatur_alt) / - sampling_time - - D_Anteil_Heizung) / - (Tau_Heizung_Tv / sampling_time); - } - - if (Counter_Tuer_offen > 60.0 || Regelung_AUS || !Startup_finished) { - Stellgrad_Heizung = 0.0; - } else { - Stellgrad_Heizung = - limit(P_Anteil_Heizung + I_Anteil_Heizung + D_Anteil_Heizung, - Regler_Heizung_MIN, Regler_Heizung_MAX); - } - - if (!Startup_finished || !is_valid(Stellgrad_Heizung_Mittelwert)) { - Stellgrad_Heizung_Mittelwert = 0.0; - } else if (Temperatursprung) { - Stellgrad_Heizung_Mittelwert = Stellgrad_Heizung; - } else if (is_valid(Stellgrad_Heizung)) { - Stellgrad_Heizung_Mittelwert = - Stellgrad_Heizung_Mittelwert + - (Stellgrad_Heizung - Stellgrad_Heizung_Mittelwert) / - (Zykluszeit_Regelabweichung_Temperatur / sampling_time); - } + if (!Startup_finished || !is_valid(Stellgrad_Heizung_Mittelwert)) + { + Stellgrad_Heizung_Mittelwert = 0.0; + } + else if (Temperatursprung) + { + Stellgrad_Heizung_Mittelwert = Stellgrad_Heizung; + } + else if (is_valid(Stellgrad_Heizung)) + { + Stellgrad_Heizung_Mittelwert = Stellgrad_Heizung_Mittelwert + + (Stellgrad_Heizung - Stellgrad_Heizung_Mittelwert) / (Zykluszeit_Regelabweichung_Temperatur / sampling_time); + } // ------------ F_PID_Temperature.step(...) !!!!! todo uj umbenennen in Heizung !!!!!!!!!!!!!!!!!!! - // ---------------------------------------------------- - // Ab hier: Kühlung + Feuchte-PIDs + Tür-PID + Aktorlogik - // ---------------------------------------------------- - // => in gleicher Art übersetzen (Muster ist identisch). - // - // Für dieses Snippet: wir übernehmen für die Outputs zumindest die Werte, - // die schon berechnet sind, und lassen Stellgrade der restlichen Aktoren, - // falls nicht berechnet, auf gültigen Default stehen. + // ---------------------------------------------------- + // Ab hier: Kühlung + Feuchte-PIDs + Tür-PID + Aktorlogik + // ---------------------------------------------------- + // => in gleicher Art übersetzen (Muster ist identisch). + // + // Für dieses Snippet: wir übernehmen für die Outputs zumindest die Werte, + // die schon berechnet sind, und lassen Stellgrade der restlichen Aktoren, + // falls nicht berechnet, auf gültigen Default stehen. - // Regelabweichung Kühlung - // F_ PID PID_Cooling() - double Regelabweichung_Kuehlung = Regelabweichung_Temperatur; + // Regelabweichung Kühlung + // F_ PID PID_Cooling() + double Regelabweichung_Kuehlung = Regelabweichung_Temperatur; - // Gradient Regelabweichgun Kuehlung + // Gradient Regelabweichgun Kuehlung - if (!Startup_finished) { - Regelabweichung_Kuehlung_Gradient = 0.0; + if (!Startup_finished) + { + Regelabweichung_Kuehlung_Gradient = 0.0; - } else { - Regelabweichung_Kuehlung_Gradient = - limit((Regelabweichung_Kuehlung - Regelabweichung_Kuehlung_alt) * - 60.0 / sampling_time - - Regelabweichung_Kuehlung_Gradient, - -4.0, 2.0); + } + else + { + Regelabweichung_Kuehlung_Gradient = limit((Regelabweichung_Kuehlung - Regelabweichung_Kuehlung_alt) * 60.0 / sampling_time - Regelabweichung_Kuehlung_Gradient, + -4.0, + 2.0); + } + + // Faktor Kuehlung + + if (!Startup_finished || Temperatursprung) + { + Faktor_Kuehlung = 5.0; + } + else if (Regelabweichung_Kuehlung < -0.1) + { + Faktor_Kuehlung = std::min(Faktor_Kuehlung + sampling_time, 5.0); + } + else + { + Faktor_Kuehlung = std::max(Faktor_Kuehlung - sampling_time / 60.0, 0.2); + } + + // --------------------------- Gegenheizen Band !!! Überwacher !!!!! + double Regelabweichung_Entfeuchtung = Regelabweichung_Feuchte; + if (!Startup_finished || Temperatursprung || (Counter_Temperatursprung > -600.0 && Faktor_Gegenheizen_Band == 10.0)) + { + Faktor_Gegenheizen_Band = 10.0; + } + else if (Stellgrad_Heizung_Mittelwert - Sollwert_Gegenheizen < -1.0) + { + if (Regelabweichung_Entfeuchtung > 0.5) + { + Faktor_Gegenheizen_Band = std::max(Faktor_Gegenheizen_Band - sampling_time / 10.0, 0.0); + } else + { + Faktor_Gegenheizen_Band = std::min(Faktor_Gegenheizen_Band + sampling_time / 60.0, 10.0); } - // Faktor Kuehlung + } else if (Stellgrad_Heizung_Mittelwert - Sollwert_Gegenheizen > 1.0 && Stellgrad_Kuehlung_Mittelwert < -5.0) + { + if (Regelabweichung_Entfeuchtung < -0.5) + { + Faktor_Gegenheizen_Band = std::max(Faktor_Gegenheizen_Band - sampling_time / 10.0, 0.0); + } + else + { + Faktor_Gegenheizen_Band = std::min(Faktor_Gegenheizen_Band + sampling_time / 600.0, 5.0); + } + } + else + { + Faktor_Gegenheizen_Band = std::max(Faktor_Gegenheizen_Band - sampling_time / 60.0, 0.1); + } + // --------------------------- Gegenheizen Band - if (!Startup_finished || Temperatursprung) { - Faktor_Kuehlung = 5.0; - } else if (Regelabweichung_Kuehlung < -0.1) { - Faktor_Kuehlung = std::min(Faktor_Kuehlung + sampling_time, 5.0); - } else { - Faktor_Kuehlung = std::max(Faktor_Kuehlung - sampling_time / 60.0, 0.2); + // -----------------------Sollwert Gegenheizen für I-Anteilverschiebung + + double Faktor_Entfeuchtung_Kuehlung = 0.0; + double Offset_Kuehlung = Faktor_Entfeuchtung_Kuehlung; + Offset_Kuehlung = Faktor_Entfeuchtung_Kuehlung * Stellgrad_Entfeuchtung_Mittelwert * + std::max((50.0 - Stellgrad_Heizung_Mittelwert) / (50 - 0.0), 0.0) * (8.0 - Stellgrad_Befeuchtung_Standby) / (8.0 - 2.0); + + // P-Anteil Kühlung + double P_Anteil_Kuehlung = 0.0; + if (!Startup_finished) + { + P_Anteil_Kuehlung = 0.0; + } + else + { + P_Anteil_Kuehlung = 100.0 / Regler_Kuehlung_Xp * Faktor_Kuehlung * Regelabweichung_Kuehlung; + } + + // Begrenzung I-Anteil Kühlung bei Türöffnung + double Regler_Kuehlung_MAX = 0; + double Regler_Kuehlung_MIN = 0; + double Regler_Kuehlung_I_Anteil_MAX = 0; + double Regler_Kuehlung_I_Anteil_MIN = 0; + + if ((Counter_Tuer_geschlossen < 180.0) || (Counter_Tuer_offen > 0.0)) + { + Regler_Kuehlung_MAX = I_Anteil_Kuehlung; + Regler_Kuehlung_MIN = -100.0; + Regler_Kuehlung_I_Anteil_MAX = I_Anteil_Kuehlung; + Regler_Kuehlung_I_Anteil_MIN = limit( -100.0 - P_Anteil_Kuehlung, Regler_Kuehlung_MIN, Regler_Kuehlung_MAX); + } + else + { + Regler_Kuehlung_MAX = 0.0; + Regler_Kuehlung_MIN = -100.0; + Regler_Kuehlung_I_Anteil_MAX = 0.1 / Regler_Kuehlung_Xp * 100.0; + Regler_Kuehlung_I_Anteil_MIN = limit( -100.0 - P_Anteil_Kuehlung + Regelabweichung_Kuehlung_Gradient / 0.5 * 100.0, + Regler_Kuehlung_MIN, + Regler_Kuehlung_MAX); + } + + // f_PID_Cooling.Step(...) + // I Anteil Kühlung + if (!Startup_finished) + { + I_Anteil_Kuehlung = 0.0; + } + else if (Counter_Tuer_geschlossen > 60.0) + { + I_Anteil_Kuehlung = limit(I_Anteil_Kuehlung + 100.0 / Regler_Kuehlung_Tn * sampling_time * + (Regelabweichung_Kuehlung + (Stellgrad_Heizung - Sollwert_Gegenheizen) / 100.0 * + Regler_Heizung_Xp * Theta_I_Kuehlung * Faktor_Gegenheizen_Band), + Regler_Kuehlung_I_Anteil_MIN, + Regler_Kuehlung_I_Anteil_MAX); + } + + // D-Anteil Kühlung + + if (!Startup_finished) + { + D_Anteil_Kuehlung = 0.0; + } + else if (Counter_Tuer_geschlossen > 0.0) + { + D_Anteil_Kuehlung += (100.0 / Regler_Kuehlung_Xp * Regler_Kuehlung_Tv * (Regelabweichung_Kuehlung - + Regelabweichung_Kuehlung_alt) / sampling_time - + D_Anteil_Kuehlung) / (Tau_Kuehlung_Tv / sampling_time); + } + + // Berechnung Stellgrad Kühlung + // f_ + if (Counter_Tuer_offen > 60.0 || !Startup_finished) + { + Stellgrad_Kuehlung = 0.0; + } + else + { + Stellgrad_Kuehlung = limit(P_Anteil_Kuehlung + I_Anteil_Kuehlung + D_Anteil_Kuehlung + Offset_Kuehlung, + Regler_Kuehlung_MIN, + Regler_Kuehlung_MAX); + } + + // Berechnung Stellgrad Mittelwert + + if (!Startup_finished) + { + Stellgrad_Kuehlung_Mittelwert = 0.0; + } + else + { + Stellgrad_Kuehlung_Mittelwert = limit(Stellgrad_Kuehlung_Mittelwert + (Stellgrad_Kuehlung - Stellgrad_Kuehlung_Mittelwert) / (600.0 / sampling_time), + Stellgrad_Kuehlung - 0.5 * 100.0 * Regler_Kuehlung_Xp, + Stellgrad_Kuehlung + 0.5 * 100.0 / Regler_Kuehlung_Xp); + } + // ------------------- F_ PID PID_Cooling() + + + // PID Regler Feuchte + // f_PID_Humidiy + Regelabweichung_Feuchte = Sollwert_Feuchte_Absolut - Istwert_Feuchte; + + // Berechnung Regelabweichung Feuchte Mittelwert + if (!Startup_finished) + { + Regelabweichung_Feuchte_Mittelwert = 0.0; + } + else + { + Regelabweichung_Feuchte_Mittelwert = limit(Regelabweichung_Feuchte_Mittelwert + (Regelabweichung_Feuchte - Regelabweichung_Feuchte_Mittelwert) / (60.0 / sampling_time), + Regelabweichung_Feuchte - 10.0, + Regelabweichung_Feuchte + 10.0); + } + + // Feuchtesprung + // f_PID_Hunidity.HandleJump(...) + if (!Startup_finished) + { + Counter_Feuchtesprung = 0.0; + } + else if (Sollwert_Feuchte != Sollwert_Feuchte_alt && std::abs(Regelabweichung_Feuchte) > 2.0) + { + Counter_Feuchtesprung = std::max(Counter_Feuchtesprung + sampling_time, 0.0); + } + else if (std::abs(Regelabweichung_Feuchte) < 2.0 || std::abs(Regelabweichung_Feuchte_Mittelwert) < 2.0) + { + Counter_Feuchtesprung = std::min(Counter_Feuchtesprung - sampling_time, 0.0); + } else if (std::abs(Regelabweichung_Feuchte_Mittelwert) > 5.0) + { + Counter_Feuchtesprung = std::max(Counter_Feuchtesprung + sampling_time, -120.0); + } + + Feuchtesprung = (Counter_Feuchtesprung > 0.0 || (Feuchtesprung && Counter_Feuchtesprung > -120.0)); + + // Regelabweichung Befeuchtung + + double Regelabweichung_Befeuchtung = Regelabweichung_Feuchte; + + // Gradient regelabweichung Feuchte + + if (!Startup_finished) + { + Regelabweichung_Befeuchtung_Gradient = 0.0; + } + else + { + Regelabweichung_Befeuchtung_Gradient = limit(Regelabweichung_Befeuchtung_Gradient + + ((Regelabweichung_Befeuchtung - Regelabweichung_Befeuchtung_alt) * 60.0 / sampling_time - + Regelabweichung_Befeuchtung_Gradient) / 60.0 * sampling_time, + -20.0, + 5.0); + } + + // Begrenzung I-Anteil bei Türöffnung + double Regler_Befeuchtung_MIN = 0.0; + double Regler_Befeuchtung_MAX = 0.0; + double Regler_Befeuchtung_I_Anteil_MIN = 0.0; + double Regler_Befeuchtung_I_Anteil_MAX = 0.0; + + if ((Counter_Tuer_geschlossen < 180.0) || (Counter_Tuer_offen > 0.0)) + { + Regler_Befeuchtung_MIN = std::max(Stellgrad_Befeuchtung_Standby - 2.0, Standby_Feuchtemodul); + Regler_Befeuchtung_MAX = std::min(100.0, Stellgrad_Feuchtemodul_MAX); + Regler_Befeuchtung_I_Anteil_MIN = 0.0; + Regler_Befeuchtung_I_Anteil_MAX = limit(100.0 - P_Anteil_Befeuchtung, + Regler_Befeuchtung_I_Anteil_MIN, + Stellgrad_Befeuchtung_Mittelwert); + } else + { + if (Feuchtesprung) + { + Regler_Befeuchtung_MIN = std::max(Stellgrad_Befeuchtung_Standby - 2.0, Standby_Feuchtemodul); + } + else + { + Regler_Befeuchtung_MIN = std::max(std::min(Stellgrad_Befeuchtung_Standby + 0.25 * P_Anteil_Befeuchtung + D_Anteil_Befeuchtung + Z_Anteil_Befeuchtung, + Stellgrad_Befeuchtung_Standby + 2.0), + std::max(Stellgrad_Befeuchtung_Standby - 1.0, + Standby_Feuchtemodul)); + } + Regler_Befeuchtung_MAX = std::min(100.0, Stellgrad_Feuchtemodul_MAX); + Regler_Befeuchtung_I_Anteil_MIN = 0.0; + Regler_Befeuchtung_I_Anteil_MAX = limit(100.0, Regler_Befeuchtung_I_Anteil_MIN, Stellgrad_Befeuchtung_Mittelwert); + } + + // Anteil P-Anteil Befeuchtung bei Feuchtesprung und Türöffnung + + if (Counter_Tuer_geschlossen < 180.0 && Feuchtesprung) + { + Regler_Befeuchtung_Xp = Regler_Befeuchtung_Xp * 2.0; + } + else if (Counter_Tuer_geschlossen > 300.0 && Feuchtesprung) + { + Regler_Befeuchtung_Xp = Regler_Befeuchtung_Xp / 2.0; + } + else + { + Regler_Befeuchtung_Xp = Regler_Befeuchtung_Xp * (1.0 + Stellgrad_Entfeuchtung_Mittelwert / -100.0); + } + + // P-Anteil Befeuchtung + + if (!Startup_finished) + { + P_Anteil_Befeuchtung = 0.0; + } + else + { + P_Anteil_Befeuchtung = 100.0 / Regler_Befeuchtung_Xp * Regelabweichung_Befeuchtung; + } + + // I-Anteil Befeuchtung + + if (!Startup_finished) + { + I_Anteil_Befeuchtung = 0.0; + } + else if (Counter_Tuer_geschlossen > 60.0) + { + I_Anteil_Befeuchtung = limit(I_Anteil_Befeuchtung + 100.0 / Regler_Befeuchtung_Xp / Regler_Befeuchtung_Tn * sampling_time * Regelabweichung_Befeuchtung, + Regler_Befeuchtung_I_Anteil_MIN, + Regler_Befeuchtung_I_Anteil_MAX); + } + + // D-Anteil Befeuchtung + if (!Startup_finished) + { + D_Anteil_Befeuchtung = 0.0; + } + else if (Counter_Tuer_geschlossen) + { + D_Anteil_Befeuchtung += (100.0 / Regler_Befeuchtung_Xp * Regler_Befeuchtung_Tv * (Regelabweichung_Befeuchtung - Regelabweichung_Befeuchtung_alt) / sampling_time - + D_Anteil_Befeuchtung) / (Tau_Befeuchtung_Tv / sampling_time); + } + + // Z-Anteil Befeuchtung + + if (!Startup_finished || Feuchtesprung) + { + Z_Anteil_Befeuchtung = 0.0; + } + else if (Counter_Tuer_geschlossen > 0.0) + { + Z_Anteil_Befeuchtung += (100.0 / Regler_Befeuchtung_Xp * Regler_Befeuchtung_Tz * ((Regelabweichung_Befeuchtung -Regelabweichung_Befeuchtung_alt) - + (Regelabweichung_Befeuchtung_alt - + Regelabweichung_Befeuchtung_alt_alt)) / sampling_time - + Z_Anteil_Befeuchtung) / (Tau_Befeuchtung_Tz / sampling_time); + } + // Regler_Befeuchtung_MAX = 10.0; + // Berechnung Stellgrad Befeuchtung + if (Counter_Tuer_offen > 60.0 || !Startup_finished) + { + Stellgrad_Befeuchtung = 0.0; + } + else + { + Stellgrad_Befeuchtung = limit(P_Anteil_Befeuchtung + I_Anteil_Befeuchtung + D_Anteil_Befeuchtung + Z_Anteil_Befeuchtung, + Regler_Befeuchtung_MIN, + Regler_Befeuchtung_MAX); + } + + // Berechnung Stellgrad befeuchtung Mittelwert + + if (!Startup_finished) + { + Stellgrad_Befeuchtung_Mittelwert = 0.0; + } + else + { + Stellgrad_Befeuchtung_Mittelwert = limit(Stellgrad_Befeuchtung_Mittelwert + (Stellgrad_Befeuchtung - Stellgrad_Befeuchtung_Mittelwert) / (600.0 / sampling_time), + Stellgrad_Befeuchtung - 5.0 * 100.0 / Regler_Befeuchtung_Xp, + Stellgrad_Befeuchtung + 5.0 * 100.0 / Regler_Befeuchtung_Xp); + } + + if (!Startup_finished) + { + Stellgrad_Befeuchtung_Standby = 4.0; + } + else if (!(Feuchtesprung && Counter_Feuchtesprung < 300.0)) + { + Stellgrad_Befeuchtung_Standby = limit(Stellgrad_Befeuchtung_Standby + (Stellgrad_Befeuchtung - Stellgrad_Befeuchtung_Standby) / (600.0 / sampling_time), + 2.0, + 8.0); + } + + // Regelabweichung Entfeuchtung + + Regelabweichung_Entfeuchtung = Regelabweichung_Feuchte; + + // Gradient Regelabweichung Entfeuchtung + + if (!Startup_finished) + { + Regelabweichung_Entfeuchtung_Gradient = 0.0; + } + else + { + Regelabweichung_Entfeuchtung_Gradient = limit(Regelabweichung_Entfeuchtung_Gradient + + ((Regelabweichung_Entfeuchtung - Regelabweichung_Entfeuchtung_alt) * 60.0 / sampling_time - + Regelabweichung_Entfeuchtung_Gradient) / 60.0 * sampling_time, + -20.0, + 5.0); + } + + // Faktor Entfeuchtung + + if (!Startup_finished) + { + Faktor_Entfeuchtung = 5.0; + } + else if (Regelabweichung_Entfeuchtung < -0.5) + { + Faktor_Entfeuchtung = std::min(Faktor_Entfeuchtung + sampling_time / 60.0, 5.0); + } + else + { + Faktor_Entfeuchtung = std::max(Faktor_Entfeuchtung - sampling_time, 0.2); + } + + // Gegenbefeuchten Band + + if (!Startup_finished || Feuchtesprung || (Counter_Feuchtesprung > -600.0 && + Faktor_Gegenbefeuchten_Band == 5.0)) + { + Faktor_Gegenbefeuchten_Band = 5.0; + } + else if (Stellgrad_Befeuchtung_Mittelwert - Sollwert_Gegenbefeuchten < -1.0) + { + if (Regelabweichung_Kuehlung > 0.05) + { + Faktor_Gegenbefeuchten_Band = std::max(Faktor_Gegenbefeuchten_Band - sampling_time / 10.0, 0.0); + } + else + { + Faktor_Gegenbefeuchten_Band = std::min(Faktor_Gegenbefeuchten_Band + sampling_time / 60.0, 5.0); } - // --------------------------- Gegenheizen Band !!! Überwacher !!!!! - double Regelabweichung_Entfeuchtung = Regelabweichung_Feuchte; - if (!Startup_finished || Temperatursprung || - (Counter_Temperatursprung > -600.0 && - Faktor_Gegenheizen_Band == 10.0)) { - Faktor_Gegenheizen_Band = 10.0; - - } else if (Stellgrad_Heizung_Mittelwert - Sollwert_Gegenheizen < -1.0) { - if (Regelabweichung_Entfeuchtung > 0.5) { - Faktor_Gegenheizen_Band = - std::max(Faktor_Gegenheizen_Band - sampling_time / 10.0, 0.0); - } else { - Faktor_Gegenheizen_Band = - std::min(Faktor_Gegenheizen_Band + sampling_time / 60.0, 10.0); - } - - } else if (Stellgrad_Heizung_Mittelwert - Sollwert_Gegenheizen > 1.0 && - Stellgrad_Kuehlung_Mittelwert < -5.0) { - if (Regelabweichung_Entfeuchtung < -0.5) { - Faktor_Gegenheizen_Band = - std::max(Faktor_Gegenheizen_Band - sampling_time / 10.0, 0.0); - } else { - Faktor_Gegenheizen_Band = - std::min(Faktor_Gegenheizen_Band + sampling_time / 600.0, 5.0); - } + } + else if (Stellgrad_Befeuchtung_Mittelwert - Sollwert_Gegenbefeuchten > 1.0 && Stellgrad_Entfeuchtung_Mittelwert < -10.0) + { + if (Regelabweichung_Kuehlung < -0.05) + { + Faktor_Gegenbefeuchten_Band = std::max(Faktor_Gegenbefeuchten_Band - sampling_time / 10.0, 0.0); } - else { - Faktor_Gegenheizen_Band = - std::max(Faktor_Gegenheizen_Band - sampling_time / 60.0, 0.1); + else + { + Faktor_Gegenbefeuchten_Band = std::min(Faktor_Gegenbefeuchten_Band + sampling_time / 600.0, 2.0); } - // --------------------------- Gegenheizen Band - - // -----------------------Sollwert Gegenheizen für I-Anteilverschiebung - - double Faktor_Entfeuchtung_Kuehlung = 0.0; - double Offset_Kuehlung = Faktor_Entfeuchtung_Kuehlung; - Offset_Kuehlung = - Faktor_Entfeuchtung_Kuehlung * Stellgrad_Entfeuchtung_Mittelwert * - std::max((50.0 - Stellgrad_Heizung_Mittelwert) / (50 - 0.0), 0.0) * - (8.0 - Stellgrad_Befeuchtung_Standby) / (8.0 - 2.0); - //------------------------------------------------------------ - - - // P-Anteil Kühlung - // f_PID_Cooling.SetP - double P_Anteil_Kuehlung = 0.0; - if (!Startup_finished) { - P_Anteil_Kuehlung = 0.0; - } else { - P_Anteil_Kuehlung = 100.0 / Regler_Kuehlung_Xp * Faktor_Kuehlung * - Regelabweichung_Kuehlung; - } - - // Begrenzung I-Anteil Kühlung bei Türöffnung - // f_PID_Cooling.Limit_I_PostDoorOpening(...) - double Regler_Kuehlung_MAX = 0; - double Regler_Kuehlung_MIN = 0; - double Regler_Kuehlung_I_Anteil_MAX = 0; - double Regler_Kuehlung_I_Anteil_MIN = 0; - - if ((Counter_Tuer_geschlossen < 180.0) || (Counter_Tuer_offen > 0.0)) { - Regler_Kuehlung_MAX = I_Anteil_Kuehlung; - Regler_Kuehlung_MIN = -100.0; - Regler_Kuehlung_I_Anteil_MAX = I_Anteil_Kuehlung; - Regler_Kuehlung_I_Anteil_MIN = limit( -100.0 - P_Anteil_Kuehlung, Regler_Kuehlung_MIN, Regler_Kuehlung_MAX); - } else { - Regler_Kuehlung_MAX = 0.0; - Regler_Kuehlung_MIN = -100.0; - Regler_Kuehlung_I_Anteil_MAX = 0.1 / Regler_Kuehlung_Xp * 100.0; - Regler_Kuehlung_I_Anteil_MIN = limit( -100.0 - P_Anteil_Kuehlung + Regelabweichung_Kuehlung_Gradient / 0.5 * 100.0, - Regler_Kuehlung_MIN, - Regler_Kuehlung_MAX); - } - - // f_PID_Cooling.Step(...) - // I Anteil Kühlung - if (!Startup_finished) { - I_Anteil_Kuehlung = 0.0; - } else if (Counter_Tuer_geschlossen > 60.0) { - I_Anteil_Kuehlung = - limit(I_Anteil_Kuehlung + - 100.0 / Regler_Kuehlung_Tn * sampling_time * - (Regelabweichung_Kuehlung + - (Stellgrad_Heizung - Sollwert_Gegenheizen) / 100.0 * - Regler_Heizung_Xp * Theta_I_Kuehlung * - Faktor_Gegenheizen_Band), - Regler_Kuehlung_I_Anteil_MIN, Regler_Kuehlung_I_Anteil_MAX); - } - - // D-Anteil Kühlung - - if (!Startup_finished) { - D_Anteil_Kuehlung = 0.0; - } else if (Counter_Tuer_geschlossen > 0.0) { - D_Anteil_Kuehlung += - (100.0 / Regler_Kuehlung_Xp * Regler_Kuehlung_Tv * - (Regelabweichung_Kuehlung - Regelabweichung_Kuehlung_alt) / - sampling_time - - D_Anteil_Kuehlung) / - (Tau_Kuehlung_Tv / sampling_time); - } - - // Berechnung Stellgrad Kühlung - // f_ - if (Counter_Tuer_offen > 60.0 || !Startup_finished) { - Stellgrad_Kuehlung = 0.0; - } else { - Stellgrad_Kuehlung = limit(P_Anteil_Kuehlung + I_Anteil_Kuehlung + - D_Anteil_Kuehlung + Offset_Kuehlung, - Regler_Kuehlung_MIN, Regler_Kuehlung_MAX); - } - - // Berechnung Stellgrad Mittelwert - - if (!Startup_finished) { - Stellgrad_Kuehlung_Mittelwert = 0.0; - } else { - Stellgrad_Kuehlung_Mittelwert = - limit(Stellgrad_Kuehlung_Mittelwert + - (Stellgrad_Kuehlung - Stellgrad_Kuehlung_Mittelwert) / - (600.0 / sampling_time), - Stellgrad_Kuehlung - 0.5 * 100.0 * Regler_Kuehlung_Xp, - Stellgrad_Kuehlung + 0.5 * 100.0 / Regler_Kuehlung_Xp); - } - // ------------------- F_ PID PID_Cooling() - - - // PID Regler Feuchte - // f_PID_Humidiy - Regelabweichung_Feuchte = Sollwert_Feuchte_Absolut - Istwert_Feuchte; - - // Berechnung Regelabweichung Feuchte Mittelwert - if (!Startup_finished) { - Regelabweichung_Feuchte_Mittelwert = 0.0; - } else { - Regelabweichung_Feuchte_Mittelwert = limit( - Regelabweichung_Feuchte_Mittelwert + - (Regelabweichung_Feuchte - Regelabweichung_Feuchte_Mittelwert) / - (60.0 / sampling_time), - Regelabweichung_Feuchte - 10.0, Regelabweichung_Feuchte + 10.0); - } - - // Feuchtesprung - // f_PID_Hunidity.HandleJump(...) - if (!Startup_finished) { - Counter_Feuchtesprung = 0.0; - } else if (Sollwert_Feuchte != Sollwert_Feuchte_alt && - std::abs(Regelabweichung_Feuchte) > 2.0) { - Counter_Feuchtesprung = - std::max(Counter_Feuchtesprung + sampling_time, 0.0); - } else if (std::abs(Regelabweichung_Feuchte) < 2.0 || - std::abs(Regelabweichung_Feuchte_Mittelwert) < 2.0) { - Counter_Feuchtesprung = - std::min(Counter_Feuchtesprung - sampling_time, 0.0); - } else if (std::abs(Regelabweichung_Feuchte_Mittelwert) > 5.0) { - Counter_Feuchtesprung = - std::max(Counter_Feuchtesprung + sampling_time, -120.0); - } - - Feuchtesprung = (Counter_Feuchtesprung > 0.0 || - (Feuchtesprung && Counter_Feuchtesprung > -120.0)); - - // Regelabweichung Befeuchtung - - double Regelabweichung_Befeuchtung = Regelabweichung_Feuchte; - - // Gradient regelabweichung Feuchte - - if (!Startup_finished) { - Regelabweichung_Befeuchtung_Gradient = 0.0; - } else { - Regelabweichung_Befeuchtung_Gradient = limit( - Regelabweichung_Befeuchtung_Gradient + - ((Regelabweichung_Befeuchtung - Regelabweichung_Befeuchtung_alt) * - 60.0 / sampling_time - - Regelabweichung_Befeuchtung_Gradient) / - 60.0 * sampling_time, - -20.0, 5.0); - } - - // Begrenzung I-Anteil bei Türöffnung - double Regler_Befeuchtung_MIN = 0.0; - double Regler_Befeuchtung_MAX = 0.0; - double Regler_Befeuchtung_I_Anteil_MIN = 0.0; - double Regler_Befeuchtung_I_Anteil_MAX = 0.0; - - if ((Counter_Tuer_geschlossen < 180.0) || (Counter_Tuer_offen > 0.0)) { - Regler_Befeuchtung_MIN = - std::max(Stellgrad_Befeuchtung_Standby - 2.0, Standby_Feuchtemodul); - Regler_Befeuchtung_MAX = std::min(100.0, Stellgrad_Feuchtemodul_MAX); - Regler_Befeuchtung_I_Anteil_MIN = 0.0; - Regler_Befeuchtung_I_Anteil_MAX = - limit(100.0 - P_Anteil_Befeuchtung, Regler_Befeuchtung_I_Anteil_MIN, - Stellgrad_Befeuchtung_Mittelwert); - } else { - if (Feuchtesprung) { - Regler_Befeuchtung_MIN = - std::max(Stellgrad_Befeuchtung_Standby - 2.0, Standby_Feuchtemodul); - } else { - Regler_Befeuchtung_MIN = - std::max(std::min(Stellgrad_Befeuchtung_Standby + - 0.25 * P_Anteil_Befeuchtung + - D_Anteil_Befeuchtung + Z_Anteil_Befeuchtung, - Stellgrad_Befeuchtung_Standby + 2.0), - std::max(Stellgrad_Befeuchtung_Standby - 1.0, - Standby_Feuchtemodul)); - } - Regler_Befeuchtung_MAX = std::min(100.0, Stellgrad_Feuchtemodul_MAX); - Regler_Befeuchtung_I_Anteil_MIN = 0.0; - Regler_Befeuchtung_I_Anteil_MAX = - limit(100.0, Regler_Befeuchtung_I_Anteil_MIN, - Stellgrad_Befeuchtung_Mittelwert); - } - - // Anteil P-Anteil Befeuchtung bei Feuchtesprung und Türöffnung - - if (Counter_Tuer_geschlossen < 180.0 && Feuchtesprung) { - Regler_Befeuchtung_Xp = Regler_Befeuchtung_Xp * 2.0; - } else if (Counter_Tuer_geschlossen > 300.0 && Feuchtesprung) { - Regler_Befeuchtung_Xp = Regler_Befeuchtung_Xp / 2.0; - } else { - Regler_Befeuchtung_Xp = - Regler_Befeuchtung_Xp * - (1.0 + Stellgrad_Entfeuchtung_Mittelwert / -100.0); - } - - // P-Anteil Befeuchtung - - if (!Startup_finished) { - P_Anteil_Befeuchtung = 0.0; - } - - else { - P_Anteil_Befeuchtung = - 100.0 / Regler_Befeuchtung_Xp * Regelabweichung_Befeuchtung; - } - - // I-Anteil Befeuchtung - - if (!Startup_finished) { - I_Anteil_Befeuchtung = 0.0; - } else if (Counter_Tuer_geschlossen > 60.0) { - I_Anteil_Befeuchtung = limit( - I_Anteil_Befeuchtung + 100.0 / Regler_Befeuchtung_Xp / - Regler_Befeuchtung_Tn * sampling_time * - Regelabweichung_Befeuchtung, - Regler_Befeuchtung_I_Anteil_MIN, Regler_Befeuchtung_I_Anteil_MAX); - } - - // D-Anteil Befeuchtung - if (!Startup_finished) { - D_Anteil_Befeuchtung = 0.0; - } else if (Counter_Tuer_geschlossen) { - D_Anteil_Befeuchtung += - (100.0 / Regler_Befeuchtung_Xp * Regler_Befeuchtung_Tv * - (Regelabweichung_Befeuchtung - Regelabweichung_Befeuchtung_alt) / - sampling_time - - D_Anteil_Befeuchtung) / - (Tau_Befeuchtung_Tv / sampling_time); - } - - // Z-Anteil Befeuchtung - - if (!Startup_finished || Feuchtesprung) { - Z_Anteil_Befeuchtung = 0.0; - } else if (Counter_Tuer_geschlossen > 0.0) { - Z_Anteil_Befeuchtung += - (100.0 / Regler_Befeuchtung_Xp * Regler_Befeuchtung_Tz * - ((Regelabweichung_Befeuchtung - - Regelabweichung_Befeuchtung_alt) - - (Regelabweichung_Befeuchtung_alt - - Regelabweichung_Befeuchtung_alt_alt)) / - sampling_time - - Z_Anteil_Befeuchtung) / - (Tau_Befeuchtung_Tz / sampling_time); - } - // Regler_Befeuchtung_MAX = 10.0; - // Berechnung Stellgrad Befeuchtung - if (Counter_Tuer_offen > 60.0 || !Startup_finished) { - Stellgrad_Befeuchtung = 0.0; - } else { - Stellgrad_Befeuchtung = - limit(P_Anteil_Befeuchtung + I_Anteil_Befeuchtung + - D_Anteil_Befeuchtung + Z_Anteil_Befeuchtung, - Regler_Befeuchtung_MIN, Regler_Befeuchtung_MAX); - } - - // Berechnung Stellgrad befeuchtung Mittelwert - - if (!Startup_finished) { - Stellgrad_Befeuchtung_Mittelwert = 0.0; - } else { - Stellgrad_Befeuchtung_Mittelwert = - limit(Stellgrad_Befeuchtung_Mittelwert + - (Stellgrad_Befeuchtung - Stellgrad_Befeuchtung_Mittelwert) / - (600.0 / sampling_time), - Stellgrad_Befeuchtung - 5.0 * 100.0 / Regler_Befeuchtung_Xp, - Stellgrad_Befeuchtung + 5.0 * 100.0 / Regler_Befeuchtung_Xp); - } - - if (!Startup_finished) { - Stellgrad_Befeuchtung_Standby = 4.0; - } else if (!(Feuchtesprung && Counter_Feuchtesprung < 300.0)) { - Stellgrad_Befeuchtung_Standby = - limit(Stellgrad_Befeuchtung_Standby + - (Stellgrad_Befeuchtung - Stellgrad_Befeuchtung_Standby) / - (600.0 / sampling_time), - 2.0, 8.0); - } - - // Regelabweichung Entfeuchtung - - Regelabweichung_Entfeuchtung = Regelabweichung_Feuchte; - - // Gradient Regelabweichung Entfeuchtung - - if (!Startup_finished) { - Regelabweichung_Entfeuchtung_Gradient = 0.0; - } - - else { - Regelabweichung_Entfeuchtung_Gradient = - limit(Regelabweichung_Entfeuchtung_Gradient + - ((Regelabweichung_Entfeuchtung - - Regelabweichung_Entfeuchtung_alt) * - 60.0 / sampling_time - - Regelabweichung_Entfeuchtung_Gradient) / - 60.0 * sampling_time, - -20.0, 5.0); - } - - // Faktor Entfeuchtung - - if (!Startup_finished) { - Faktor_Entfeuchtung = 5.0; - } else if (Regelabweichung_Entfeuchtung < -0.5) { - Faktor_Entfeuchtung = - std::min(Faktor_Entfeuchtung + sampling_time / 60.0, 5.0); - } else { - Faktor_Entfeuchtung = std::max(Faktor_Entfeuchtung - sampling_time, 0.2); - } - - // Gegenbefeuchten Band - - if (!Startup_finished || Feuchtesprung || - (Counter_Feuchtesprung > -600.0 && - Faktor_Gegenbefeuchten_Band == 5.0)) { - Faktor_Gegenbefeuchten_Band = 5.0; - } else if (Stellgrad_Befeuchtung_Mittelwert - Sollwert_Gegenbefeuchten < - -1.0) { - if (Regelabweichung_Kuehlung > 0.05) { - Faktor_Gegenbefeuchten_Band = - std::max(Faktor_Gegenbefeuchten_Band - sampling_time / 10.0, 0.0); - } else { - Faktor_Gegenbefeuchten_Band = - std::min(Faktor_Gegenbefeuchten_Band + sampling_time / 60.0, 5.0); - } - - } else if (Stellgrad_Befeuchtung_Mittelwert - Sollwert_Gegenbefeuchten > - 1.0 && - Stellgrad_Entfeuchtung_Mittelwert < -10.0) { - if (Regelabweichung_Kuehlung < -0.05) { - Faktor_Gegenbefeuchten_Band = - std::max(Faktor_Gegenbefeuchten_Band - sampling_time / 10.0, 0.0); - } else { - Faktor_Gegenbefeuchten_Band = - std::min(Faktor_Gegenbefeuchten_Band + sampling_time / 600.0, 2.0); - } - } else { - Faktor_Gegenbefeuchten_Band = - std::max(Faktor_Gegenbefeuchten_Band - sampling_time / 60.0, 0.2); - } - - // Sollwert Gegenbefeuchten für I-Anteilverschiebung - - Sollwert_Gegenbefeuchten = - 6.0 - 4.0 * (-Stellgrad_Entfeuchtung_Mittelwert / 100.0); - double Offset_Entfeuchtung = 0.0 * Stellgrad_Kuehlung_Mittelwert; - - //(* P-Anteil Entfeuchtung *) - - double P_Anteil_Entfeuchtung = 0.0; - if (!Startup_finished) { - P_Anteil_Entfeuchtung = 0.0; - } else { - P_Anteil_Entfeuchtung = 100.0 / Regler_Entfeuchtung_Xp * - Faktor_Entfeuchtung * - Regelabweichung_Entfeuchtung; - } - // I-Anteil Entfeuchtung - if (!Startup_finished) { - I_Anteil_Entfeuchtung = 0.0; - } else if (Counter_Tuer_geschlossen > 60.0) { - I_Anteil_Entfeuchtung = limit( - I_Anteil_Entfeuchtung + - 100.0 / Regler_Entfeuchtung_Xp / Regler_Entfeuchtung_Tn * - sampling_time * - (Regelabweichung_Entfeuchtung + - (Stellgrad_Befeuchtung - Sollwert_Gegenbefeuchten) / 100.0 * - Regler_Befeuchtung_Xp * Theta_I_Entfeuchtung * - Faktor_Gegenbefeuchten_Band), - Regler_Entfeuchtung_I_Anteil_MIN, Regler_Entfeuchtung_I_Anteil_MAX); - } - // D-Anteil Entfeuchtung - if (!Startup_finished) { - D_Anteil_Entfeuchtung = 0.0; - } else if (Counter_Tuer_geschlossen > 0.0) { - D_Anteil_Entfeuchtung = - D_Anteil_Entfeuchtung + - (100.0 / Regler_Entfeuchtung_Xp * Regler_Entfeuchtung_Tv * - (Regelabweichung_Entfeuchtung - - Regelabweichung_Entfeuchtung_alt) / - sampling_time - - D_Anteil_Entfeuchtung) / - (Tau_Entfeuchtung_Tv / sampling_time); - } - - // Begrenzung Stellgrad und I-Anteil - - if ((Counter_Tuer_geschlossen < 180.0) || (Counter_Tuer_offen > 0.0)) { - Regler_Entfeuchtung_MAX = I_Anteil_Entfeuchtung; - Regler_Entfeuchtung_MIN = -100.0; - Regler_Entfeuchtung_I_Anteil_MAX = I_Anteil_Entfeuchtung; - Regler_Entfeuchtung_I_Anteil_MIN = - limit(-100.0 - P_Anteil_Entfeuchtung, Regler_Entfeuchtung_MIN, - Regler_Entfeuchtung_I_Anteil_MAX); - } else { - Regler_Entfeuchtung_MAX = 0.0; - Regler_Entfeuchtung_MIN = -100.0; - Regler_Entfeuchtung_I_Anteil_MAX = 1.5 / Regler_Entfeuchtung_Xp * 100.0; - Regler_Entfeuchtung_I_Anteil_MIN = - limit(-100.0 - P_Anteil_Entfeuchtung + - Regelabweichung_Entfeuchtung_Gradient / 20.0 * 100.0, - Regler_Entfeuchtung_MIN, Regler_Entfeuchtung_I_Anteil_MAX); - } - - // Berechnung Stellgrad Entfeuchtung - - if (Counter_Tuer_offen > 60.0 || !Startup_finished) { - Stellgrad_Entfeuchtung = 0.0; - } else { - Stellgrad_Entfeuchtung = - limit(P_Anteil_Entfeuchtung + I_Anteil_Entfeuchtung + - Offset_Entfeuchtung + D_Anteil_Entfeuchtung, - Regler_Entfeuchtung_MIN, Regler_Entfeuchtung_MAX); - } - - // Berechnung Stellgrad entfeuchtung Mittelwert - - if (!Startup_finished) { - Stellgrad_Entfeuchtung_Mittelwert = 0.0; - } else { - Stellgrad_Entfeuchtung_Mittelwert = limit( - Stellgrad_Entfeuchtung_Mittelwert + - (Stellgrad_Entfeuchtung - Stellgrad_Entfeuchtung_Mittelwert) / - (600.0 / sampling_time), - Stellgrad_Entfeuchtung - 5.0 * 100.0 / Regler_Entfeuchtung_Xp, - Stellgrad_Entfeuchtung + 5.0 * 100.0 / Regler_Entfeuchtung_Xp); - } - - // PID Regler Tür - // f_PID_Door(...) - double Offset_Temperatur_Tuer; - if (Feuchtesprung) { - Offset_Temperatur_Tuer = 0.0; - } else { - Offset_Temperatur_Tuer = - 2.0 * Betauungsschutz / 100.0 * - limit((90.0 + Stellgrad_Kuehlung_Mittelwert) / (90.0 - 80.0), 0.0, - 1.0); - } - - // Regelabweichung - if (!Tuer_offen || - std::abs(Regelabweichung_Tuer) > - std::abs(Sollwert_Temperatur + Offset_Temperatur_Tuer - - Istwert_Temperatur_Tuer)) { - Regelabweichung_Tuer = Sollwert_Temperatur + Offset_Temperatur_Tuer - - Istwert_Temperatur_Tuer; - } - - // P-Anteil - - // Anti-Windup über dynamisches Integrator Clamping - - double Regler_Tuer_MAX = limit( - (100.0 + Stellgrad_Kuehlung) / (100.0 - 80.0) * 100.0, 0.0, 100.0); - double Regler_Tuer_MIN = 0.0; - double Regler_Tuer_I_Anteil_MAX = - limit(100.0 - P_Anteil_Tuer, 0.0, Regler_Tuer_MAX); - double Regler_Tuer_I_Anteil_MIN = 0.0; - - if (!Startup_finished) { - P_Anteil_Tuer = 0.0; - } else { - P_Anteil_Tuer = 100.0 / Regler_Tuer_Xp * Regelabweichung_Tuer; - } - - // I-Anteil - if (!Startup_finished) { - I_Anteil_Tuer = 0.0; - } else if (Temperatursprung && Regelabweichung_Tuer > 0.0) { - I_Anteil_Tuer = limit(I_Anteil_Tuer, Regler_Tuer_I_Anteil_MIN, - Regler_Tuer_I_Anteil_MAX); - } else if (!Tuer_offen) { - I_Anteil_Tuer = - limit(I_Anteil_Tuer + 100.0 / Regler_Tuer_Xp / Regler_Tuer_Tn * - sampling_time * Regelabweichung_Tuer, - Regler_Tuer_I_Anteil_MIN, Regler_Tuer_I_Anteil_MAX); - } - // D-Anteil - - if (!Startup_finished) { - D_Anteil_Tuer = 0.0; - } else { - D_Anteil_Tuer = D_Anteil_Tuer + - (100.0 / Regler_Tuer_Xp * Regler_Tuer_Tv * - (Regelabweichung_Tuer - Regelabweichung_Tuer_alt) / - sampling_time - - D_Anteil_Tuer) / - (Tau_Tuer_Tv / sampling_time); - } - - double Stellgrad_Tuer; - // Berechnung Stellgrad Tür - if (Tuer_offen || !Startup_finished) { - Stellgrad_Tuer = limit(P_Anteil_Tuer + I_Anteil_Tuer + D_Anteil_Tuer, - Regler_Tuer_MIN, Regler_Tuer_MAX); - } - - // Kennfelder Kühlung/Entfeuchtung - - int Index_Ueberhitzung = 1; - while (Kennfeld_Ueberhitzung[0][Index_Ueberhitzung] < Istwert_Temperatur && - Index_Ueberhitzung < 12) { - Index_Ueberhitzung++; - } - double Interpolation_Ueberhitzung = limit((Kennfeld_Ueberhitzung[0][Index_Ueberhitzung - 1] - Istwert_Temperatur) / - (Kennfeld_Ueberhitzung[0][Index_Ueberhitzung - 1] - Kennfeld_Ueberhitzung[0][Index_Ueberhitzung]), - 0.0, 1.0); - double Skalierung_Ueberhitzung_Kennfeld_Min = Kennfeld_Ueberhitzung[1][Index_Ueberhitzung] * - (Interpolation_Ueberhitzung + Kennfeld_Ueberhitzung[1][Index_Ueberhitzung - 1]) * - (1.0 - Interpolation_Ueberhitzung); - double Skalierung_Ueberhitzung_Kennfeld_Max = Kennfeld_Ueberhitzung[2][Index_Ueberhitzung] * - (Interpolation_Ueberhitzung + Kennfeld_Ueberhitzung[2][Index_Ueberhitzung - 1]) * - (1.0 - Interpolation_Ueberhitzung); - double Sollwert_Ueberhitzung = Kennfeld_Ueberhitzung[3][Index_Ueberhitzung] * - (Interpolation_Ueberhitzung + Kennfeld_Ueberhitzung[3][Index_Ueberhitzung - 1]) * - (1.0 - Interpolation_Ueberhitzung); - - //(* Entfeuchtung und Abtauung aus Kennfeld *) - int Index_Entfeuchtung = 1; // todo uj - warum nicht mit 0 starten? - while ((Kennfeld_Entfeuchtung[0][Index_Entfeuchtung] < Istwert_Temperatur) && (Index_Ueberhitzung < 12)) { - Index_Entfeuchtung++; - } - double Interpolation_Entfeuchtung = limit((Kennfeld_Entfeuchtung[0][Index_Entfeuchtung - 1] - - (Istwert_Temperatur) / (Kennfeld_Entfeuchtung[0][Index_Entfeuchtung - 1] ) - - Kennfeld_Entfeuchtung[0][Index_Entfeuchtung]), - 0.0, 1.0); - double Skalierung_Entfeuchtungsventil = Kennfeld_Entfeuchtung[1][Index_Entfeuchtung] * - Interpolation_Entfeuchtung + - Kennfeld_Entfeuchtung[1][Index_Entfeuchtung - 1] * - (1.0 - Interpolation_Entfeuchtung); - double Abtauzyklus_Pause = - Kennfeld_Entfeuchtung[2][Index_Entfeuchtung] * - Interpolation_Entfeuchtung + - Kennfeld_Entfeuchtung[2][Index_Entfeuchtung - 1] * - (1.0 - Interpolation_Entfeuchtung); - double Abtauzyklus_Dauer = - Kennfeld_Entfeuchtung[3][Index_Entfeuchtung] * - Interpolation_Entfeuchtung + - Kennfeld_Entfeuchtung[3][Index_Entfeuchtung - 1] * - (1.0 - Interpolation_Entfeuchtung); - - // Ende - f_PID_Door(...) - - // Überhitzungsregelung - - // Temperatur Verdampferausgang PT1 - // f_PT1.Vapourize(...) - if (!Startup_finished) { - Istwert_Temperatur_Verdampferausgang_PT1 = - Istwert_Temperatur_Verdampferausgang; - } else { - Istwert_Temperatur_Verdampferausgang_PT1 += - (Istwert_Temperatur_Verdampferausgang - - Istwert_Temperatur_Verdampferausgang_PT1) / - (60.0 * 4.0); - } - - // Skalierung Überhitzung - if (Istwert_Temperatur_Verdampferausgang < - (Istwert_Temperatur + Sollwert_Ueberhitzung)) { - Counter_Durchzug = MIN(Counter_Durchzug + sampling_time, 10.0); - } else { - // uj-todo; template for MAX - // Counter_Durchzug = MAX(MAX(Counter_Durchzug-sampling_time,-10),0); - } - if (Counter_Durchzug >= 10.0) { - Durchzug = true; - } else if (Counter_Durchzug <= -10.0) { - Durchzug = false; - } - - double Skalierung_Ueberhitzung_PT1 = Skalierung_Ueberhitzung_Kennfeld_Max; - - // Magnetventil Kühlung - - // Stellgrad Kühlung - - if (Counter_Verdichter_aus > 60.0 && Counter_Verdichter_aus < 600.0) { - Stellgrad_Kuehlventil = 1.0; - } else if (Istwert_Temperatur > 120.0 || Counter_Kuehlung_Freigabe <= 0.0) { - Stellgrad_Kuehlventil = 0.0; - } else { - Stellgrad_Kuehlventil = MAX(-Stellgrad_Kuehlung, 0.0) * - Skalierung_Ueberhitzung_PT1 * - Counter_Kuehlung_Freigabe; - } - - // Ende - f_PT1.Vapourize(...) - - // PWM Generierung Kuehlventil - // bool step(double Stellgrad,double sampling_time){ - - // f_PWMCoolingValve.Step(...) - Kuehlventil = PWM_Kuehlventil.step(Stellgrad_Kuehlventil, sampling_time); - - // Magnetventil Entfeuchtung - double T_Entfeuchtung; - if (!Startup_finished) { - T_Entfeuchtung = Istwert_Temperatur; - } else if (Entfeuchtungsventil) { - T_Entfeuchtung = - limit(T_Entfeuchtung + - ((Istwert_Temperatur - T_Entfeuchtung) * U_Entfeuchtung - - P_Entfeuchtung) / - (4.0 * C_Entfeuchtung), - -30.0, Istwert_Temperatur); - } else { - T_Entfeuchtung = - limit(T_Entfeuchtung + - ((Istwert_Temperatur - T_Entfeuchtung) * U_Entfeuchtung) / - (4.0 * C_Entfeuchtung), - -30.0, Istwert_Temperatur); - } - // Stellgrad Entfeuchtung - - if (Istwert_Temperatur > 120.0 || Counter_Entfeuchtung_Freigabe <= 0.0) { - Stellgrad_Entfeuchtungsventil = 0.0; - } else { - Stellgrad_Entfeuchtungsventil = MAX(-Stellgrad_Entfeuchtung, 0.0) * + } + else + { + Faktor_Gegenbefeuchten_Band = std::max(Faktor_Gegenbefeuchten_Band - sampling_time / 60.0, 0.2); + } + + // Sollwert Gegenbefeuchten für I-Anteilverschiebung + + Sollwert_Gegenbefeuchten = 6.0 - 4.0 * (-Stellgrad_Entfeuchtung_Mittelwert / 100.0); + double Offset_Entfeuchtung = 0.0 * Stellgrad_Kuehlung_Mittelwert; + + //(* P-Anteil Entfeuchtung *) + + double P_Anteil_Entfeuchtung = 0.0; + if (!Startup_finished) + { + P_Anteil_Entfeuchtung = 0.0; + } + else + { + P_Anteil_Entfeuchtung = 100.0 / Regler_Entfeuchtung_Xp * Faktor_Entfeuchtung * Regelabweichung_Entfeuchtung; + } + // I-Anteil Entfeuchtung + if (!Startup_finished) + { + I_Anteil_Entfeuchtung = 0.0; + } + else if (Counter_Tuer_geschlossen > 60.0) + { + I_Anteil_Entfeuchtung = limit(I_Anteil_Entfeuchtung + 100.0 / Regler_Entfeuchtung_Xp / Regler_Entfeuchtung_Tn * sampling_time * (Regelabweichung_Entfeuchtung + + (Stellgrad_Befeuchtung - Sollwert_Gegenbefeuchten) / 100.0 * Regler_Befeuchtung_Xp * Theta_I_Entfeuchtung * Faktor_Gegenbefeuchten_Band), + Regler_Entfeuchtung_I_Anteil_MIN, + Regler_Entfeuchtung_I_Anteil_MAX); + } + // D-Anteil Entfeuchtung + if (!Startup_finished) + { + D_Anteil_Entfeuchtung = 0.0; + } + else if (Counter_Tuer_geschlossen > 0.0) + { + D_Anteil_Entfeuchtung = D_Anteil_Entfeuchtung + (100.0 / Regler_Entfeuchtung_Xp * Regler_Entfeuchtung_Tv * + (Regelabweichung_Entfeuchtung - Regelabweichung_Entfeuchtung_alt) / sampling_time - + D_Anteil_Entfeuchtung) / (Tau_Entfeuchtung_Tv / sampling_time); + } + + // Begrenzung Stellgrad und I-Anteil + + if ((Counter_Tuer_geschlossen < 180.0) || (Counter_Tuer_offen > 0.0)) + { + Regler_Entfeuchtung_MAX = I_Anteil_Entfeuchtung; + Regler_Entfeuchtung_MIN = -100.0; + Regler_Entfeuchtung_I_Anteil_MAX = I_Anteil_Entfeuchtung; + Regler_Entfeuchtung_I_Anteil_MIN = limit(-100.0 - P_Anteil_Entfeuchtung, + Regler_Entfeuchtung_MIN, + Regler_Entfeuchtung_I_Anteil_MAX); + } + else + { + Regler_Entfeuchtung_MAX = 0.0; + Regler_Entfeuchtung_MIN = -100.0; + Regler_Entfeuchtung_I_Anteil_MAX = 1.5 / Regler_Entfeuchtung_Xp * 100.0; + Regler_Entfeuchtung_I_Anteil_MIN = limit(-100.0 - P_Anteil_Entfeuchtung + Regelabweichung_Entfeuchtung_Gradient / 20.0 * 100.0, + Regler_Entfeuchtung_MIN, + Regler_Entfeuchtung_I_Anteil_MAX); + } + + // Berechnung Stellgrad Entfeuchtung + + if (Counter_Tuer_offen > 60.0 || !Startup_finished) + { + Stellgrad_Entfeuchtung = 0.0; + } + else + { + Stellgrad_Entfeuchtung = limit(P_Anteil_Entfeuchtung + I_Anteil_Entfeuchtung + Offset_Entfeuchtung + D_Anteil_Entfeuchtung, + Regler_Entfeuchtung_MIN, + Regler_Entfeuchtung_MAX); + } + + // Berechnung Stellgrad entfeuchtung Mittelwert + + if (!Startup_finished) + { + Stellgrad_Entfeuchtung_Mittelwert = 0.0; + } + else + { + Stellgrad_Entfeuchtung_Mittelwert = limit((Stellgrad_Entfeuchtung - Stellgrad_Entfeuchtung_Mittelwert) / (600.0 / sampling_time), + Stellgrad_Entfeuchtung - 5.0 * 100.0 / Regler_Entfeuchtung_Xp, + Stellgrad_Entfeuchtung + 5.0 * 100.0 / Regler_Entfeuchtung_Xp); + } + + // PID Regler Tür + // f_PID_Door(...) + double Offset_Temperatur_Tuer; + if (Feuchtesprung) + { + Offset_Temperatur_Tuer = 0.0; + } + else + { + Offset_Temperatur_Tuer = 2.0 * Betauungsschutz / 100.0 * limit((90.0 + Stellgrad_Kuehlung_Mittelwert) / (90.0 - 80.0), + 0.0, + 1.0); + } + + // Regelabweichung + if (!Tuer_offen || std::abs(Regelabweichung_Tuer) > std::abs(Sollwert_Temperatur + Offset_Temperatur_Tuer - Istwert_Temperatur_Tuer)) + { + Regelabweichung_Tuer = Sollwert_Temperatur + Offset_Temperatur_Tuer - Istwert_Temperatur_Tuer; + } + + // P-Anteil + + // Anti-Windup über dynamisches Integrator Clamping + + double Regler_Tuer_MAX = limit( (100.0 + Stellgrad_Kuehlung) / (100.0 - 80.0) * 100.0, 0.0, 100.0); + double Regler_Tuer_MIN = 0.0; + double Regler_Tuer_I_Anteil_MAX = limit(100.0 - P_Anteil_Tuer, 0.0, Regler_Tuer_MAX); + double Regler_Tuer_I_Anteil_MIN = 0.0; + + if (!Startup_finished) + { + P_Anteil_Tuer = 0.0; + } + else + { + P_Anteil_Tuer = 100.0 / Regler_Tuer_Xp * Regelabweichung_Tuer; + } + + // I-Anteil + if (!Startup_finished) + { + I_Anteil_Tuer = 0.0; + } else if (Temperatursprung && Regelabweichung_Tuer > 0.0) + { + I_Anteil_Tuer = limit(I_Anteil_Tuer, + Regler_Tuer_I_Anteil_MIN, + Regler_Tuer_I_Anteil_MAX); + } + else if (!Tuer_offen) + { + I_Anteil_Tuer = limit(I_Anteil_Tuer + 100.0 / Regler_Tuer_Xp / Regler_Tuer_Tn * sampling_time * Regelabweichung_Tuer, + Regler_Tuer_I_Anteil_MIN, + Regler_Tuer_I_Anteil_MAX); + } + // D-Anteil + + if (!Startup_finished) + { + D_Anteil_Tuer = 0.0; + } + else + { + D_Anteil_Tuer = D_Anteil_Tuer + (100.0 / Regler_Tuer_Xp * Regler_Tuer_Tv * (Regelabweichung_Tuer - Regelabweichung_Tuer_alt) / sampling_time - + D_Anteil_Tuer) / (Tau_Tuer_Tv / sampling_time); + } + + double Stellgrad_Tuer; + // Berechnung Stellgrad Tür + if (Tuer_offen || !Startup_finished) + { + Stellgrad_Tuer = limit(P_Anteil_Tuer + I_Anteil_Tuer + D_Anteil_Tuer, + Regler_Tuer_MIN, + Regler_Tuer_MAX); + } + + // Kennfelder Kühlung/Entfeuchtung + + int Index_Ueberhitzung = 1; + while (Kennfeld_Ueberhitzung[0][Index_Ueberhitzung] < Istwert_Temperatur && Index_Ueberhitzung < 12) + { + Index_Ueberhitzung++; + } + double Interpolation_Ueberhitzung = limit((Kennfeld_Ueberhitzung[0][Index_Ueberhitzung - 1] - Istwert_Temperatur) / (Kennfeld_Ueberhitzung[0][Index_Ueberhitzung - 1] - Kennfeld_Ueberhitzung[0][Index_Ueberhitzung]), + 0.0, + 1.0); + double Skalierung_Ueberhitzung_Kennfeld_Min = Kennfeld_Ueberhitzung[1][Index_Ueberhitzung] * + (Interpolation_Ueberhitzung + Kennfeld_Ueberhitzung[1][Index_Ueberhitzung - 1]) * + (1.0 - Interpolation_Ueberhitzung); + double Skalierung_Ueberhitzung_Kennfeld_Max = Kennfeld_Ueberhitzung[2][Index_Ueberhitzung] * + (Interpolation_Ueberhitzung + Kennfeld_Ueberhitzung[2][Index_Ueberhitzung - 1]) * + (1.0 - Interpolation_Ueberhitzung); + double Sollwert_Ueberhitzung = Kennfeld_Ueberhitzung[3][Index_Ueberhitzung] * + (Interpolation_Ueberhitzung + Kennfeld_Ueberhitzung[3][Index_Ueberhitzung - 1]) * + (1.0 - Interpolation_Ueberhitzung); + + //(* Entfeuchtung und Abtauung aus Kennfeld *) + int Index_Entfeuchtung = 1; // todo uj - warum nicht mit 0 starten? + while ((Kennfeld_Entfeuchtung[0][Index_Entfeuchtung] < Istwert_Temperatur) && (Index_Ueberhitzung < 12)) + { + Index_Entfeuchtung++; + } + double Interpolation_Entfeuchtung = limit((Kennfeld_Entfeuchtung[0][Index_Entfeuchtung - 1] - + (Istwert_Temperatur) / (Kennfeld_Entfeuchtung[0][Index_Entfeuchtung - 1] ) - + Kennfeld_Entfeuchtung[0][Index_Entfeuchtung]), + 0.0, + 1.0); + double Skalierung_Entfeuchtungsventil = Kennfeld_Entfeuchtung[1][Index_Entfeuchtung] * Interpolation_Entfeuchtung + + Kennfeld_Entfeuchtung[1][Index_Entfeuchtung - 1] * (1.0 - Interpolation_Entfeuchtung); + + double Abtauzyklus_Pause = Kennfeld_Entfeuchtung[2][Index_Entfeuchtung] * Interpolation_Entfeuchtung + + Kennfeld_Entfeuchtung[2][Index_Entfeuchtung - 1] * (1.0 - Interpolation_Entfeuchtung); + + double Abtauzyklus_Dauer = Kennfeld_Entfeuchtung[3][Index_Entfeuchtung] * Interpolation_Entfeuchtung + + Kennfeld_Entfeuchtung[3][Index_Entfeuchtung - 1] * (1.0 - Interpolation_Entfeuchtung); + + // Ende - f_PID_Door(...) + + // Überhitzungsregelung + + // Temperatur Verdampferausgang PT1 + // f_PT1.Vapourize(...) + if (!Startup_finished) + { + Istwert_Temperatur_Verdampferausgang_PT1 = Istwert_Temperatur_Verdampferausgang; + } + else + { + Istwert_Temperatur_Verdampferausgang_PT1 += (Istwert_Temperatur_Verdampferausgang - + Istwert_Temperatur_Verdampferausgang_PT1) / (60.0 * 4.0); + } + + // Skalierung Überhitzung + if (Istwert_Temperatur_Verdampferausgang < (Istwert_Temperatur + Sollwert_Ueberhitzung)) + { + Counter_Durchzug = MIN(Counter_Durchzug + sampling_time, 10.0); + } + else + { + // uj-todo; template for MAX + // Counter_Durchzug = MAX(MAX(Counter_Durchzug-sampling_time,-10),0); + } + if (Counter_Durchzug >= 10.0) + { + Durchzug = true; + } + else if (Counter_Durchzug <= -10.0) + { + Durchzug = false; + } + + double Skalierung_Ueberhitzung_PT1 = Skalierung_Ueberhitzung_Kennfeld_Max; + + // Magnetventil Kühlung + + // Stellgrad Kühlung + + if (Counter_Verdichter_aus > 60.0 && Counter_Verdichter_aus < 600.0) + { + Stellgrad_Kuehlventil = 1.0; + } + else if (Istwert_Temperatur > 120.0 || Counter_Kuehlung_Freigabe <= 0.0) + { + Stellgrad_Kuehlventil = 0.0; + } + else + { + Stellgrad_Kuehlventil = MAX(-Stellgrad_Kuehlung, 0.0) * Skalierung_Ueberhitzung_PT1 * Counter_Kuehlung_Freigabe; + } + + // Ende - f_PT1.Vapourize(...) + + // PWM Generierung Kuehlventil + // bool step(double Stellgrad,double sampling_time){ + + // f_PWMCoolingValve.Step(...) + Kuehlventil = PWM_Kuehlventil.step(Stellgrad_Kuehlventil, sampling_time); + + // Magnetventil Entfeuchtung + double T_Entfeuchtung; + + if (!Startup_finished) + { + T_Entfeuchtung = Istwert_Temperatur; + } + else if (Entfeuchtungsventil) + { + T_Entfeuchtung = limit(T_Entfeuchtung + ((Istwert_Temperatur - T_Entfeuchtung) * U_Entfeuchtung - + P_Entfeuchtung) / (4.0 * C_Entfeuchtung), + -30.0, + Istwert_Temperatur); + } + else + { + T_Entfeuchtung = limit(T_Entfeuchtung + ((Istwert_Temperatur - T_Entfeuchtung) * U_Entfeuchtung) / (4.0 * C_Entfeuchtung), + -30.0, + Istwert_Temperatur); + } + // Stellgrad Entfeuchtung + + if (Istwert_Temperatur > 120.0 || Counter_Entfeuchtung_Freigabe <= 0.0) + { + Stellgrad_Entfeuchtungsventil = 0.0; + } else + { + Stellgrad_Entfeuchtungsventil = MAX(-Stellgrad_Entfeuchtung, 0.0) * Skalierung_Entfeuchtungsventil * Counter_Entfeuchtung_Freigabe; - } + } - // Abtauzyklus - bool Freigabe_Abtauzyklus = - Istwert_Feuchte > Sollwert_Feuchte_Absolut + 2.5; - if (!Freigabe_Abtauzyklus) { - Counter_Freigabe_Abtauzyklus = 0.0; - } else { - Counter_Freigabe_Abtauzyklus += sampling_time; - } - double Skalierung_Abtauzyklus_Dauer = 0.0; - ; - if (Abtauzyklus_Pause > 0.0 && Abtauzyklus_Dauer > 0.0) { - Skalierung_Abtauzyklus_Dauer = - limit(Counter_Freigabe_Abtauzyklus / - (10.0 * (Abtauzyklus_Pause + Abtauzyklus_Dauer) * 60.0), - 1.0, 5.0); - } - if (Counter_Abtauzyklus > - (Abtauzyklus_Pause + Abtauzyklus_Dauer * Skalierung_Abtauzyklus_Dauer) * - 60.0) { - Counter_Abtauzyklus = 0.0; - } else if ((T_Entfeuchtung < 0.0 && Freigabe_Abtauzyklus) || Abtauzyklus) { - Counter_Abtauzyklus += sampling_time; - } + // Abtauzyklus + bool Freigabe_Abtauzyklus = Istwert_Feuchte > Sollwert_Feuchte_Absolut + 2.5; + if (!Freigabe_Abtauzyklus) + { + Counter_Freigabe_Abtauzyklus = 0.0; + } else + { + Counter_Freigabe_Abtauzyklus += sampling_time; + } + double Skalierung_Abtauzyklus_Dauer = 0.0; + ; + if (Abtauzyklus_Pause > 0.0 && Abtauzyklus_Dauer > 0.0) + { + Skalierung_Abtauzyklus_Dauer = limit(Counter_Freigabe_Abtauzyklus / (10.0 * (Abtauzyklus_Pause + Abtauzyklus_Dauer) * 60.0), + 1.0, + 5.0); + } + if (Counter_Abtauzyklus > (Abtauzyklus_Pause + Abtauzyklus_Dauer * Skalierung_Abtauzyklus_Dauer) * 60.0) + { + Counter_Abtauzyklus = 0.0; + } + else if ((T_Entfeuchtung < 0.0 && Freigabe_Abtauzyklus) || Abtauzyklus) + { + Counter_Abtauzyklus += sampling_time; + } + else + { + Counter_Abtauzyklus = MAX(Counter_Abtauzyklus - sampling_time, 0.0); + } + Abtauzyklus = Counter_Abtauzyklus > Abtauzyklus_Pause * 60.0 && Abtauzyklus_Pause > 0.0; - else { - Counter_Abtauzyklus = MAX(Counter_Abtauzyklus - sampling_time, 0.0); - } - Abtauzyklus = Counter_Abtauzyklus > Abtauzyklus_Pause * 60.0 && - Abtauzyklus_Pause > 0.0; - - if (Abtauzyklus) { - Stellgrad_Entfeuchtungsventil = 0.0; - } - // Ende -f_PWMCoolingValve.Step(...) + if (Abtauzyklus) + { + Stellgrad_Entfeuchtungsventil = 0.0; + } + // Ende -f_PWMCoolingValve.Step(...) - // PWM Entfeuchtungsventil - // f_PWMDeHumizeValve.Step(...) - Entfeuchtungsventil = PWM_Entfeuchtungsventil.step( - Stellgrad_Entfeuchtungsventil, sampling_time); + // PWM Entfeuchtungsventil + // f_PWMDeHumizeValve.Step(...) + Entfeuchtungsventil = PWM_Entfeuchtungsventil.step(Stellgrad_Entfeuchtungsventil, sampling_time); - // Druckausgleich vor Start Verdichter - if (!Verdichter && Counter_Entfeuchtung_Freigabe > 5.0) { - Entfeuchtungsventil = true; - } + // Druckausgleich vor Start Verdichter + if (!Verdichter && Counter_Entfeuchtung_Freigabe > 5.0) + { + Entfeuchtungsventil = true; + } - // Heizung Kessel + // Heizung Kessel - if (Freigabe_Heizung) { - Stellgrad_HeizungKessel = - MAX(Stellgrad_Heizung * Counter_Heizung_Freigabe, 0.0); - } else { - Stellgrad_HeizungKessel = 0.0; - } + if (Freigabe_Heizung) + { + Stellgrad_HeizungKessel = MAX(Stellgrad_Heizung * Counter_Heizung_Freigabe, 0.0); + } + else + { + Stellgrad_HeizungKessel = 0.0; + } - // PWM Heizung Kessel - HeizungKessel = PWM_Heizung_Kessel.step(Stellgrad_HeizungKessel, 0.25); + // PWM Heizung Kessel + HeizungKessel = PWM_Heizung_Kessel.step(Stellgrad_HeizungKessel, 0.25); - // Betauungsschutz + // Betauungsschutz - double Stellgrad_Betauungsschutz_MAX = limit( - (90.0 + Stellgrad_Kuehlung_Mittelwert) / (90.0 - 80.0) * 100.0, 0.0, - limit((Sollwert_Temperatur - 25.0) / (-20.0 - 25.0) * Betauungsschutz, - 0.0, Betauungsschutz)); + double Stellgrad_Betauungsschutz_MAX = limit( (90.0 + Stellgrad_Kuehlung_Mittelwert) / (90.0 - 80.0) * 100.0, + 0.0, + limit((Sollwert_Temperatur - 25.0) / (-20.0 - 25.0) * Betauungsschutz, + 0.0, + Betauungsschutz)); - if (!Startup_finished) { - Stellgrad_Betauungsschutz = 0.0; - } + if (!Startup_finished) + { + Stellgrad_Betauungsschutz = 0.0; + } - // Tuerheizung - Stellgrad_HeizungTuer = - limit(Stellgrad_Tuer + Stellgrad_Betauungsschutz / 10.0, 0.0, 100.0); + // Tuerheizung + Stellgrad_HeizungTuer = limit(Stellgrad_Tuer + Stellgrad_Betauungsschutz / 10.0, 0.0, 100.0); - HeizungTuer = PWM_Heizung_Tuer.step(Stellgrad_HeizungTuer, 0.25); + HeizungTuer = PWM_Heizung_Tuer.step(Stellgrad_HeizungTuer, 0.25); - // Heizung Kesselrand + // Heizung Kesselrand - Stellgrad_HeizungKesselrand = - limit(Stellgrad_Tuer * - limit(1.0 + Betauungsschutz / 100.0 * 2.0 * - (90.0 + Stellgrad_Kuehlung_Mittelwert) / - (90.0 - 80.0), - 1.0, 2.0) + - Stellgrad_Betauungsschutz, - 0.0, 100.0); + Stellgrad_HeizungKesselrand = limit(Stellgrad_Tuer * limit(1.0 + Betauungsschutz / 100.0 * 2.0 * (90.0 + Stellgrad_Kuehlung_Mittelwert) / (90.0 - 80.0), + 1.0, + 2.0) + Stellgrad_Betauungsschutz, + 0.0, + 100.0); - // Ende - f_PWMDeHumizeValve.Step(...) + // Ende - f_PWMDeHumizeValve.Step(...) - // PWM Kesselrand - // Ende - f_PWMKesselRand.Step(...) - HeizungKesselrand = PWM_Heizung_Kesselrand.step(Stellgrad_HeizungKesselrand, 0.25); - // Ende - f_PWMKesselRand.Step(...) + // PWM Kesselrand + // Ende - f_PWMKesselRand.Step(...) + HeizungKesselrand = PWM_Heizung_Kesselrand.step(Stellgrad_HeizungKesselrand, 0.25); + // Ende - f_PWMKesselRand.Step(...) + { + // Binder Feuchtemodul + + // Sperrsignal Feuchtemodul + + bool Sperrsignal_Feuchte = false; + + // Gradient Feuchtemodul + + if (!Startup_finished) + { + Temperatur_Feuchtemodul_Gradient = 0; + } + else + { + Temperatur_Feuchtemodul_Gradient += ((Temperatur_Feuchtemodul - Temperatur_Feuchtemodul_alt) * 60.0 * 4.0 - + Temperatur_Feuchtemodul_Gradient) / (4.0 * 10.0); + } + + Sollwert_Temperatur_Feuchtemodul = Sollwert_Temperatur_Feuchtemodul_MIN + Stellgrad_Feuchtemodul_Mittelwert / 100.0 * + (Sollwert_Temperatur_Feuchtemodul_MAX - Sollwert_Temperatur_Feuchtemodul_MIN); + + // Offset Stellgrad Feuchtemodul + + double Temperatur_Feuchtemodul_Standby = Sollwert_Temperatur_Feuchtemodul - (Stellgrad_Entfeuchtung_Mittelwert - 0.0) / (-100.0 - 0.0) * 60.0; + double Standby_Feuchtemodul = limit((Temperatur_Feuchtemodul_Standby - Temperatur_Feuchtemodul) / 10.0 * 5.0, + 0.0, + 5.0); + + // Stellgrad Feuchtemodul + Stellgrad_Feuchtemodul = limit(Stellgrad_Befeuchtung + 2.0 * limit(Stellgrad_Befeuchtung - Stellgrad_Feuchtemodul_PT1, + -2.0, + 2.0) + Stellgrad_Feuchtemodul_Nachfuellen, + 0.0, + 100.0); + + // Begrenzung Temperatur Feuchtemodul über Temperatur + double Stellgrad_Feuchtemodul_MAX_Temperatur = limit((Temperatur_Feuchtemodul_MAX - Temperatur_Feuchtemodul) / 40.0 * 100.0, + 0.0, + 100.0); + + double Temperatur_Feuchtemodul_Gradient_MAX = 10.0; + if (Temperatur_Feuchtemodul < 90.0) + { + Temperatur_Feuchtemodul_Gradient_MAX = 10.0; + } + else + { + Temperatur_Feuchtemodul_Gradient_MAX = limit(20.0 - (Temperatur_Feuchtemodul - (Temperatur_Feuchtemodul_MAX - 60.0)) / 60.0 * 20.0 - Stellgrad_Feuchtemodul_MAX / 100.0 * 10.0, + 5.0, + 20.0); + } + + double Stellgrad_Feuchtemodul_MAX_adaptiv = 10.0; + if (!Startup_finished) + { + Stellgrad_Feuchtemodul_MAX_adaptiv = 10.0; + } + else if (Temperatur_Feuchtemodul < 80.0) + { + Stellgrad_Feuchtemodul_MAX_adaptiv = 10.0; + } + else if (Stellgrad_Feuchtemodul + 20.0 > Stellgrad_Feuchtemodul_MAX_adaptiv && + Stellgrad_Feuchtemodul_MAX_adaptiv < Stellgrad_Feuchtemodul_MAX_Temperatur && + Temperatur_Feuchtemodul_Gradient < 2.0 * Temperatur_Feuchtemodul_Gradient_MAX && + !Sperrsignal_Feuchte) + { + Stellgrad_Feuchtemodul_MAX_adaptiv = limit(Stellgrad_Feuchtemodul_MAX_adaptiv + 20.0 * limit((Temperatur_Feuchtemodul_Gradient_MAX - + Temperatur_Feuchtemodul_Gradient) / Temperatur_Feuchtemodul_Gradient_MAX, + -2.0, + 1.0) / (60.0 * 4.0), + 0.0, + Stellgrad_Feuchtemodul_MAX_Temperatur); + } + else + { + Stellgrad_Feuchtemodul_MAX_adaptiv = limit(Stellgrad_Feuchtemodul_MAX_adaptiv - 5.0 / (60.0 * 4.0), + 10.0, + Stellgrad_Feuchtemodul_MAX_Temperatur); + } + + // Begrenzung Stellgrad_Feuchtemodul + + Stellgrad_Feuchtemodul_MAX = MIN(Stellgrad_Feuchtemodul_MAX_Temperatur - 5.0, + Stellgrad_Feuchtemodul_MAX_adaptiv + Stellgrad_Feuchtemodul_Boost); + + Stellgrad_Feuchtemodul = MIN(Stellgrad_Feuchtemodul, Stellgrad_Feuchtemodul_MAX); + + // Stellgrad Feuchtemodul Boost + + if (!Startup_finished || Temperatur_Feuchtemodul < 80.0) + { + Stellgrad_Feuchtemodul_Boost = 0.0; + } + else if (Stellgrad_Feuchtemodul < Stellgrad_Feuchtemodul_MAX_adaptiv - 10.0) + { + Stellgrad_Feuchtemodul_Boost = MIN(Stellgrad_Feuchtemodul_Boost + 10.0 / 60.0 * sampling_time, + 2.0 * Stellgrad_Feuchtemodul_MAX_Temperatur); + } else { + Stellgrad_Feuchtemodul_Boost = MAX(Stellgrad_Feuchtemodul_Boost - (Stellgrad_Feuchtemodul + 10.0 - + Stellgrad_Feuchtemodul_MAX_adaptiv) / 60.0 * sampling_time, + 0.0); + } + if (!Startup_finished) + { + Stellgrad_Feuchtemodul_PT1 = Stellgrad_Feuchtemodul; + } + else if (is_valid(Stellgrad_Feuchtemodul_PT1)) + { + Stellgrad_Feuchtemodul_PT1 = 0.0; + } + else + { + Stellgrad_Feuchtemodul_PT1 = Stellgrad_Feuchtemodul_PT1 + + (Stellgrad_Feuchtemodul - Stellgrad_Feuchtemodul_PT1) / (4.0 * 30.0); + } + + // Nachfüllen Befeuchtungsmodul + + double Stellgrad_Nachfuellen_Temperatur = 0.0; + double Skalierung_Nachfuellen_Temperatur_P_Anteil = 0.0; + double Skalierung_Nachfuellen_Temperatur_D_Anteil = 0.0; + + if (!Startup_finished) + { + Stellgrad_Nachfuellen_Temperatur = 0.0; + Skalierung_Nachfuellen_Temperatur_D_Anteil = 0.0; + Skalierung_Nachfuellen_Temperatur_D_Anteil = 0.0; + Skalierung_Nachfuellen_Temperatur_I_Anteil = 0.0; + } + else + { + Stellgrad_Nachfuellen_Temperatur = limit(MAX(Temperatur_Feuchtemodul - Sollwert_Temperatur_Feuchtemodul, 0.0) * 2.0 + + MIN(Temperatur_Feuchtemodul - Sollwert_Temperatur_Feuchtemodul, 0.0) * 1.0, + -20.0, + 50.0); + Skalierung_Nachfuellen_Temperatur_P_Anteil = limit(MAX(Temperatur_Feuchtemodul - Sollwert_Temperatur_Feuchtemodul, 0.0) / 20.0 + + MIN(Temperatur_Feuchtemodul - Sollwert_Temperatur_Feuchtemodul, 0.0) / 40.0, + -0.2, + 5.0); + Skalierung_Nachfuellen_Temperatur_D_Anteil = limit(Temperatur_Feuchtemodul_Gradient / 10.0, -5.0, 5.0); + Skalierung_Nachfuellen_Temperatur_I_Anteil = limit(Skalierung_Nachfuellen_Temperatur_I_Anteil + limit(Skalierung_Nachfuellen_Temperatur_P_Anteil + + Skalierung_Nachfuellen_Temperatur_D_Anteil, + -0.2, + 25.0) * + sampling_time / 1200.0, + 0.0, + 5.0); + } + double Stellgrad_Nachfuellen = 0.0; + Stellgrad_Feuchtemodul_Nachfuellen = 0.0; + + if (Temperatur_Feuchtemodul > Temperatur_Feuchtemodul_MAX && Temperatur_Feuchtemodul_Gradient > 0.0) + { + Stellgrad_Nachfuellen = 20.0; + Stellgrad_Feuchtemodul_Nachfuellen = 0.0; + } + else + { + Stellgrad_Nachfuellen = limit(((Stellgrad_Feuchtemodul_PT1 - Stellgrad_Feuchtemodul_Nachfuellen) * + (MAX(Skalierung_Nachfuellen_Temperatur_P_Anteil + Skalierung_Nachfuellen_Temperatur_D_Anteil, + 0.0) + Skalierung_Nachfuellen_Temperatur_I_Anteil) + Stellgrad_Nachfuellen_Temperatur) * 2.0 * 7.9681 / Durchflussmenge_Einlassventil_Feuchtemodul, + 0.0, + 100.0); + Stellgrad_Feuchtemodul_Nachfuellen = 0.5 * Stellgrad_Nachfuellen * Durchflussmenge_Einlassventil_Feuchtemodul / 60.0 * 4.19 * 75.0 / 600.0; + } + + //(* Entleeren des Kessels *) + bool Entleeren_Kessel = false; + if (Startup_finished && Temperatur_Feuchtemodul < 70.0) { + Entleeren_Kessel = Counter_Entleeren_Kessel < 60.0; + Counter_Entleeren_Kessel += sampling_time; + } else { + Counter_Entleeren_Kessel = 0.0; + Entleeren_Kessel = false; + } + + //(* Abschlämmen des Kessels *) + Abschlaemmintegral = Abschlaemmintegral + 0.1 * Durchflussmenge_Einlassventil_Feuchtemodul / Durchflussmenge_Abschlaemmventil_Feuchtemodul * + Stellgrad_Nachfuellen / 100.0 * sampling_time; + + if (Entleeren_Kessel) + { + Abschlaemmventil = true; + Stellgrad_Abschlaemmventil_zyklisch = 100.0; + } + else + { + Counter_Zyklus_Abschlaemmventil += sampling_time; + if (Abschlaemmintegral > 0.25 && Temperatur_Feuchtemodul_Gradient < 0.0) { - // Binder Feuchtemodul - - // Sperrsignal Feuchtemodul - - bool Sperrsignal_Feuchte = false; - - // Gradient Feuchtemodul - - if (!Startup_finished) { - Temperatur_Feuchtemodul_Gradient = 0; - } else { - Temperatur_Feuchtemodul_Gradient += - ((Temperatur_Feuchtemodul - Temperatur_Feuchtemodul_alt) * 60.0 * - 4.0 - - Temperatur_Feuchtemodul_Gradient) / - (4.0 * 10.0); + Abschlaemmventil = true; + Stellgrad_Abschlaemmventil_zyklisch = 2.5; + Counter_Zyklus_Abschlaemmventil = 0.0; + Abschlaemmintegral -= 0.25; + } + else + { + Abschlaemmventil = false; + if (Counter_Zyklus_Abschlaemmventil >= 10.0) + { + Stellgrad_Abschlaemmventil_zyklisch = 0.0; } + } + } - Sollwert_Temperatur_Feuchtemodul = - Sollwert_Temperatur_Feuchtemodul_MIN + - Stellgrad_Feuchtemodul_Mittelwert / 100.0 * - (Sollwert_Temperatur_Feuchtemodul_MAX - - Sollwert_Temperatur_Feuchtemodul_MIN); + // Stellgrad_Feuchtemodul = 2.0; - // Offset Stellgrad Feuchtemodul + // PWM Befeuchtungsmodul + HeizungFeuchtemodul = PWM_Heizung_Feuchtemodul.step(Stellgrad_Feuchtemodul, 0.25); + // PWM Nachfüllen + Nachfuellen = PWM_Nachfuellen.step(Stellgrad_Nachfuellen, 0.25); - double Temperatur_Feuchtemodul_Standby = - Sollwert_Temperatur_Feuchtemodul - - (Stellgrad_Entfeuchtung_Mittelwert - 0.0) / (-100.0 - 0.0) * 60.0; - double Standby_Feuchtemodul = - limit((Temperatur_Feuchtemodul_Standby - Temperatur_Feuchtemodul) / - 10.0 * 5.0, - 0.0, 5.0); + // Abwassermanagement + if (!Entleerbehaelter_Unten || !Entleerbehaelter_Oben || Entleeren_Kessel) + { + Counter_Nachlauf_Entleeren = 10.0; + Counter_Pause_Entleeren += sampling_time; + if (Counter_Pause_Entleeren > 30.0) + { + Counter_Pause_Entleeren = 0.0; + } - // Stellgrad Feuchtemodul - Stellgrad_Feuchtemodul = limit( - Stellgrad_Befeuchtung + - 2.0 * limit(Stellgrad_Befeuchtung - Stellgrad_Feuchtemodul_PT1, - -2.0, 2.0) + - Stellgrad_Feuchtemodul_Nachfuellen, - 0.0, 100.0); + } + else + { + Counter_Nachlauf_Entleeren = MAX(Counter_Nachlauf_Entleeren - sampling_time, 0.0); + Counter_Pause_Entleeren = 0.0; + } - // Begrenzung Temperatur Feuchtemodul über Temperatur - double Stellgrad_Feuchtemodul_MAX_Temperatur = limit( - (Temperatur_Feuchtemodul_MAX - Temperatur_Feuchtemodul) / 40.0 * 100.0, - 0.0, 100.0); + bool Entleeren_Pause = false; + Entleeren = Counter_Nachlauf_Entleeren > 0.0; + Entleeren_Pause = Counter_Pause_Entleeren > 27.0; + Entleerpumpe = Entleeren && !Entleeren_Pause; - double Temperatur_Feuchtemodul_Gradient_MAX = 10.0; - if (Temperatur_Feuchtemodul < 90.0) { - Temperatur_Feuchtemodul_Gradient_MAX = 10.0; - } else { - Temperatur_Feuchtemodul_Gradient_MAX = limit( - 20.0 - - (Temperatur_Feuchtemodul - (Temperatur_Feuchtemodul_MAX - 60.0)) / - 60.0 * 20.0 - - Stellgrad_Feuchtemodul_MAX / 100.0 * 10.0, - 5.0, 20.0); - } + if (!Startup_finished) + { + Zyklus_Entleeren_Mittelwert = 600.0; + } + else if (Entleeren && !Entleeren_alt) + { + Zyklus_Entleeren_Mittelwert = limit(Zyklus_Entleeren_Mittelwert + (Counter_Zyklus_Entleeren - Zyklus_Entleeren_Mittelwert) / 10.0, + 10.0, + 3600.0); + Counter_Zyklus_Entleeren = 0.0; + } + else + { + Counter_Zyklus_Entleeren += sampling_time; + } - double Stellgrad_Feuchtemodul_MAX_adaptiv = 10.0; - if (!Startup_finished) { - Stellgrad_Feuchtemodul_MAX_adaptiv = 10.0; - } else if (Temperatur_Feuchtemodul < 80.0) { - Stellgrad_Feuchtemodul_MAX_adaptiv = 10.0; - } else if (Stellgrad_Feuchtemodul + 20.0 > - Stellgrad_Feuchtemodul_MAX_adaptiv && - Stellgrad_Feuchtemodul_MAX_adaptiv < - Stellgrad_Feuchtemodul_MAX_Temperatur && - Temperatur_Feuchtemodul_Gradient < - 2.0 * Temperatur_Feuchtemodul_Gradient_MAX && - !Sperrsignal_Feuchte) { - Stellgrad_Feuchtemodul_MAX_adaptiv = - limit(Stellgrad_Feuchtemodul_MAX_adaptiv + - 20.0 * - limit((Temperatur_Feuchtemodul_Gradient_MAX - - Temperatur_Feuchtemodul_Gradient) / - Temperatur_Feuchtemodul_Gradient_MAX, - -2.0, 1.0) / - (60.0 * 4.0), - 0.0, Stellgrad_Feuchtemodul_MAX_Temperatur); - } else { - Stellgrad_Feuchtemodul_MAX_adaptiv = - limit(Stellgrad_Feuchtemodul_MAX_adaptiv - 5.0 / (60.0 * 4.0), 10.0, - Stellgrad_Feuchtemodul_MAX_Temperatur); - } + if (Steuerkontakt_Standby || Istwert_Temperatur > 110.0) + { + Counter_Kuehlung_Freigabe = 0.0; + } else + { + if (Stellgrad_Kuehlung < 0.0 || Stellgrad_Heizung < 2.0 || Counter_Tuer_geschlossen < 300.0) + { + Counter_Kuehlung_Freigabe = MIN(Counter_Kuehlung_Freigabe + sampling_time / 10.0, 1.0); + } + else + { + Counter_Kuehlung_Freigabe = MAX(Counter_Kuehlung_Freigabe - sampling_time / 300.0, 0.0); + } + } + Freigabe_Kuehlung = Counter_Kuehlung_Freigabe >= 1.0 || (Freigabe_Kuehlung && Counter_Kuehlung_Freigabe > 0.0); + // * Freigabe Kühlung *) - // Begrenzung Stellgrad_Feuchtemodul + // (* Freigabe Entfeuchtung *) + if (Steuerkontakt_Standby || Istwert_Temperatur > 110.0) + { + Counter_Entfeuchtung_Freigabe = 0.0; + } + else + { + if (Stellgrad_Entfeuchtung < 0.0 || Stellgrad_Befeuchtung < 2.0 || Counter_Tuer_geschlossen < 300.0) { + Counter_Entfeuchtung_Freigabe = MIN(Counter_Entfeuchtung_Freigabe + sampling_time / 10.0, 10.0); + } + else + { + Counter_Entfeuchtung_Freigabe = MAX(Counter_Entfeuchtung_Freigabe - sampling_time / 300.0, 0.0); + } + } + Freigabe_Entfeuchtung = Counter_Entfeuchtung_Freigabe >= 1.0 || (Freigabe_Entfeuchtung && Counter_Entfeuchtung_Freigabe > 0.0); - Stellgrad_Feuchtemodul_MAX = - MIN(Stellgrad_Feuchtemodul_MAX_Temperatur - 5.0, - Stellgrad_Feuchtemodul_MAX_adaptiv + Stellgrad_Feuchtemodul_Boost); + // (* Freigabe Heizung *) + if (Steuerkontakt_Standby || Istwert_Temperatur > 110.0) + { + Counter_Heizung_Freigabe = 0.0; + } + else + { + if (Stellgrad_Heizung < 0.0 || Stellgrad_Kuehlung > -2.0 || Counter_Tuer_geschlossen < 300.0) + { + Counter_Heizung_Freigabe = MIN(Counter_Heizung_Freigabe + sampling_time / 10.0, 10.0); + } + else + { + Counter_Heizung_Freigabe = MAX(Counter_Heizung_Freigabe - sampling_time / 300.0, 0.0); + } + } + Freigabe_Heizung = Counter_Heizung_Freigabe >= 1.0 || (Freigabe_Heizung && Counter_Heizung_Freigabe > 0.0); + // (* Freigabe Befeuchtung *) + if (Steuerkontakt_Standby || Istwert_Temperatur > 110.0) + { + Counter_Befeuchtung_Freigabe = 0.0; + } + else + { + if (Stellgrad_Befeuchtung < 0.0 || Stellgrad_Entfeuchtung > -2.0 || Counter_Tuer_geschlossen < 300.0) + { + Counter_Befeuchtung_Freigabe = MIN(Counter_Befeuchtung_Freigabe + sampling_time / 10.0, 10.0); + } + else + { + Counter_Befeuchtung_Freigabe = MAX(Counter_Befeuchtung_Freigabe - sampling_time / 300.0, 0.0); + } + } + Freigabe_Befeuchtung = Counter_Befeuchtung_Freigabe >= 1.0 || (Freigabe_Befeuchtung && Counter_Befeuchtung_Freigabe > 0.0); - Stellgrad_Feuchtemodul = - MIN(Stellgrad_Feuchtemodul, Stellgrad_Feuchtemodul_MAX); + // Verdichterabscaltung - // Stellgrad Feuchtemodul Boost + if (!Startup_finished) + { + Drehzahl_Verdichter_adaptiv = Drehzahl_Verdichter_MAX; + } + else if (Temperatursprung) + { + Drehzahl_Verdichter_adaptiv = MAX(Drehzahl_Verdichter_Kuehlung, Drehzahl_Verdichter_Entfeuchtung); + } + else if (is_valid(Stellgrad_Kuehlung)) + { + Drehzahl_Verdichter_adaptiv = limit(Drehzahl_Verdichter_adaptiv + (-Stellgrad_Kuehlung - 25.0) / 100.0 * (Drehzahl_Verdichter_MAX - Drehzahl_Verdichter_MIN) / (4.0 * 600.0), + Drehzahl_Verdichter_MIN, + Drehzahl_Verdichter_MAX); + } - if (!Startup_finished || Temperatur_Feuchtemodul < 80.0) { - Stellgrad_Feuchtemodul_Boost = 0.0; - } else if (Stellgrad_Feuchtemodul < - Stellgrad_Feuchtemodul_MAX_adaptiv - 10.0) { - Stellgrad_Feuchtemodul_Boost = - MIN(Stellgrad_Feuchtemodul_Boost + 10.0 / 60.0 * sampling_time, - 2.0 * Stellgrad_Feuchtemodul_MAX_Temperatur); - } else { - Stellgrad_Feuchtemodul_Boost = MAX( - Stellgrad_Feuchtemodul_Boost - (Stellgrad_Feuchtemodul + 10.0 - - Stellgrad_Feuchtemodul_MAX_adaptiv) / - 60.0 * sampling_time, - 0.0); - } - if (!Startup_finished) { - Stellgrad_Feuchtemodul_PT1 = Stellgrad_Feuchtemodul; - } else if (is_valid(Stellgrad_Feuchtemodul_PT1)) { - Stellgrad_Feuchtemodul_PT1 = 0.0; - } else { - Stellgrad_Feuchtemodul_PT1 = - Stellgrad_Feuchtemodul_PT1 + - (Stellgrad_Feuchtemodul - Stellgrad_Feuchtemodul_PT1) / (4.0 * 30.0); - } + Drehzahl_Verdichter_Kuehlung = Drehzahl_Verdichter_MIN + (MAX(-Stellgrad_Kuehlung_Mittelwert, -Stellgrad_Kuehlung) - 30.0) / (90.0 - 30.0) * (Drehzahl_Verdichter_MAX - Drehzahl_Verdichter_MIN); + Drehzahl_Verdichter_Entfeuchtung = Drehzahl_Verdichter_MIN + 0.5 * (MAX(-Stellgrad_Entfeuchtung_Mittelwert, -Stellgrad_Entfeuchtung) - + 50.0) / (90.0 - 50.0) * (Drehzahl_Verdichter_MAX - Drehzahl_Verdichter_MIN); - // Nachfüllen Befeuchtungsmodul + if (Verdichter) + { + Drehzahl_Verdichter = limit(MAX(Drehzahl_Verdichter_Kuehlung, MAX(Drehzahl_Verdichter_Entfeuchtung, Drehzahl_Verdichter_adaptiv)), + Drehzahl_Verdichter_MIN, + Drehzahl_Verdichter_MAX); + } + else + { + Drehzahl_Verdichter = 1000.0; + } - double Stellgrad_Nachfuellen_Temperatur = 0.0; - double Skalierung_Nachfuellen_Temperatur_P_Anteil = 0.0; - double Skalierung_Nachfuellen_Temperatur_D_Anteil = 0.0; - - if (!Startup_finished) { - Stellgrad_Nachfuellen_Temperatur = 0.0; - Skalierung_Nachfuellen_Temperatur_D_Anteil = 0.0; - Skalierung_Nachfuellen_Temperatur_D_Anteil = 0.0; - Skalierung_Nachfuellen_Temperatur_I_Anteil = 0.0; - } else { - Stellgrad_Nachfuellen_Temperatur = limit( - MAX(Temperatur_Feuchtemodul - Sollwert_Temperatur_Feuchtemodul, 0.0) * - 2.0 + - MIN(Temperatur_Feuchtemodul - Sollwert_Temperatur_Feuchtemodul, - 0.0) * - 1.0, - -20.0, 50.0); - Skalierung_Nachfuellen_Temperatur_P_Anteil = limit( - MAX(Temperatur_Feuchtemodul - Sollwert_Temperatur_Feuchtemodul, 0.0) / - 20.0 + - MIN(Temperatur_Feuchtemodul - Sollwert_Temperatur_Feuchtemodul, - 0.0) / - 40.0, - -0.2, 5.0); - Skalierung_Nachfuellen_Temperatur_D_Anteil = - limit(Temperatur_Feuchtemodul_Gradient / 10.0, -5.0, 5.0); - Skalierung_Nachfuellen_Temperatur_I_Anteil = - limit(Skalierung_Nachfuellen_Temperatur_I_Anteil + - limit(Skalierung_Nachfuellen_Temperatur_P_Anteil + - Skalierung_Nachfuellen_Temperatur_D_Anteil, - -0.2, 25.0) * - sampling_time / 1200.0, - 0.0, 5.0); - } - double Stellgrad_Nachfuellen = 0.0; - Stellgrad_Feuchtemodul_Nachfuellen = 0.0; - - if (Temperatur_Feuchtemodul > Temperatur_Feuchtemodul_MAX && - Temperatur_Feuchtemodul_Gradient > 0.0) { - Stellgrad_Nachfuellen = 20.0; - Stellgrad_Feuchtemodul_Nachfuellen = 0.0; - } else { - Stellgrad_Nachfuellen = limit( - ((Stellgrad_Feuchtemodul_PT1 - Stellgrad_Feuchtemodul_Nachfuellen) * - (MAX(Skalierung_Nachfuellen_Temperatur_P_Anteil + - Skalierung_Nachfuellen_Temperatur_D_Anteil, - 0.0) + - Skalierung_Nachfuellen_Temperatur_I_Anteil) + - Stellgrad_Nachfuellen_Temperatur) * - 2.0 * 7.9681 / Durchflussmenge_Einlassventil_Feuchtemodul, - 0.0, 100.0); - Stellgrad_Feuchtemodul_Nachfuellen = - 0.5 * Stellgrad_Nachfuellen * - Durchflussmenge_Einlassventil_Feuchtemodul / 60.0 * 4.19 * 75.0 / - 600.0; - } - //(* Entleeren des Kessels *) - bool Entleeren_Kessel = false; - if (Startup_finished && Temperatur_Feuchtemodul < 70.0) { - Entleeren_Kessel = Counter_Entleeren_Kessel < 60.0; - Counter_Entleeren_Kessel += sampling_time; - } else { - Counter_Entleeren_Kessel = 0.0; - Entleeren_Kessel = false; - } - - //(* Abschlämmen des Kessels *) - Abschlaemmintegral = - Abschlaemmintegral + 0.1 * Durchflussmenge_Einlassventil_Feuchtemodul / - Durchflussmenge_Abschlaemmventil_Feuchtemodul * - Stellgrad_Nachfuellen / 100.0 * sampling_time; - - if (Entleeren_Kessel) { - Abschlaemmventil = true; - Stellgrad_Abschlaemmventil_zyklisch = 100.0; - } else { - Counter_Zyklus_Abschlaemmventil += sampling_time; - if (Abschlaemmintegral > 0.25 && Temperatur_Feuchtemodul_Gradient < 0.0) { - Abschlaemmventil = true; - Stellgrad_Abschlaemmventil_zyklisch = 2.5; - Counter_Zyklus_Abschlaemmventil = 0.0; - Abschlaemmintegral -= 0.25; - } else { - Abschlaemmventil = false; - if (Counter_Zyklus_Abschlaemmventil >= 10.0) { - Stellgrad_Abschlaemmventil_zyklisch = 0.0; - } - } - } - - // Stellgrad_Feuchtemodul = 2.0; - - // PWM Befeuchtungsmodul - HeizungFeuchtemodul = - PWM_Heizung_Feuchtemodul.step(Stellgrad_Feuchtemodul, 0.25); - // PWM Nachfüllen - Nachfuellen = PWM_Nachfuellen.step(Stellgrad_Nachfuellen, 0.25); - - // Abwassermanagement - if (!Entleerbehaelter_Unten || !Entleerbehaelter_Oben || Entleeren_Kessel) { - Counter_Nachlauf_Entleeren = 10.0; - Counter_Pause_Entleeren += sampling_time; - if (Counter_Pause_Entleeren > 30.0) { - Counter_Pause_Entleeren = 0.0; - } - - } else { - Counter_Nachlauf_Entleeren = - MAX(Counter_Nachlauf_Entleeren - sampling_time, 0.0); - Counter_Pause_Entleeren = 0.0; - } - bool Entleeren_Pause = false; - Entleeren = Counter_Nachlauf_Entleeren > 0.0; - Entleeren_Pause = Counter_Pause_Entleeren > 27.0; - Entleerpumpe = Entleeren && !Entleeren_Pause; - - if (!Startup_finished) { - Zyklus_Entleeren_Mittelwert = 600.0; - } else if (Entleeren && !Entleeren_alt) { - Zyklus_Entleeren_Mittelwert = limit( - Zyklus_Entleeren_Mittelwert + - (Counter_Zyklus_Entleeren - Zyklus_Entleeren_Mittelwert) / 10.0, - 10.0, 3600.0); - Counter_Zyklus_Entleeren = 0.0; - } else { - Counter_Zyklus_Entleeren += sampling_time; - } - - if (Steuerkontakt_Standby || Istwert_Temperatur > 110.0) { - Counter_Kuehlung_Freigabe = 0.0; - } else { - if (Stellgrad_Kuehlung < 0.0 || Stellgrad_Heizung < 2.0 || - Counter_Tuer_geschlossen < 300.0) { - Counter_Kuehlung_Freigabe = - MIN(Counter_Kuehlung_Freigabe + sampling_time / 10.0, 1.0); - } else { - Counter_Kuehlung_Freigabe = - MAX(Counter_Kuehlung_Freigabe - sampling_time / 300.0, 0.0); - } - } - Freigabe_Kuehlung = Counter_Kuehlung_Freigabe >= 1.0 || - (Freigabe_Kuehlung && Counter_Kuehlung_Freigabe > 0.0); - // * Freigabe Kühlung *) - - // (* Freigabe Entfeuchtung *) - if (Steuerkontakt_Standby || Istwert_Temperatur > 110.0) { - Counter_Entfeuchtung_Freigabe = 0.0; - } else { - if (Stellgrad_Entfeuchtung < 0.0 || Stellgrad_Befeuchtung < 2.0 || - Counter_Tuer_geschlossen < 300.0) { - Counter_Entfeuchtung_Freigabe = - MIN(Counter_Entfeuchtung_Freigabe + sampling_time / 10.0, 10.0); - } else { - Counter_Entfeuchtung_Freigabe = - MAX(Counter_Entfeuchtung_Freigabe - sampling_time / 300.0, 0.0); - } - } - Freigabe_Entfeuchtung = - Counter_Entfeuchtung_Freigabe >= 1.0 || - (Freigabe_Entfeuchtung && Counter_Entfeuchtung_Freigabe > 0.0); - - // (* Freigabe Heizung *) - if (Steuerkontakt_Standby || Istwert_Temperatur > 110.0) { - Counter_Heizung_Freigabe = 0.0; - } else { - if (Stellgrad_Heizung < 0.0 || Stellgrad_Kuehlung > -2.0 || - Counter_Tuer_geschlossen < 300.0) { - Counter_Heizung_Freigabe = - MIN(Counter_Heizung_Freigabe + sampling_time / 10.0, 10.0); - } else { - Counter_Heizung_Freigabe = - MAX(Counter_Heizung_Freigabe - sampling_time / 300.0, 0.0); - } - } - Freigabe_Heizung = Counter_Heizung_Freigabe >= 1.0 || - (Freigabe_Heizung && Counter_Heizung_Freigabe > 0.0); - // (* Freigabe Befeuchtung *) - if (Steuerkontakt_Standby || Istwert_Temperatur > 110.0) { - Counter_Befeuchtung_Freigabe = 0.0; - } else { - if (Stellgrad_Befeuchtung < 0.0 || Stellgrad_Entfeuchtung > -2.0 || - Counter_Tuer_geschlossen < 300.0) { - Counter_Befeuchtung_Freigabe = - MIN(Counter_Befeuchtung_Freigabe + sampling_time / 10.0, 10.0); - } else { - Counter_Befeuchtung_Freigabe = - MAX(Counter_Befeuchtung_Freigabe - sampling_time / 300.0, 0.0); - } - } - Freigabe_Befeuchtung = - Counter_Befeuchtung_Freigabe >= 1.0 || - (Freigabe_Befeuchtung && Counter_Befeuchtung_Freigabe > 0.0); - - // Verdichterabscaltung - - if (!Startup_finished) { - Drehzahl_Verdichter_adaptiv = Drehzahl_Verdichter_MAX; - } else if (Temperatursprung) { - Drehzahl_Verdichter_adaptiv = - MAX(Drehzahl_Verdichter_Kuehlung, Drehzahl_Verdichter_Entfeuchtung); - } else if (is_valid(Stellgrad_Kuehlung)) { - Drehzahl_Verdichter_adaptiv = - limit(Drehzahl_Verdichter_adaptiv + - (-Stellgrad_Kuehlung - 25.0) / 100.0 * - (Drehzahl_Verdichter_MAX - Drehzahl_Verdichter_MIN) / - (4.0 * 600.0), - Drehzahl_Verdichter_MIN, Drehzahl_Verdichter_MAX); - } - - Drehzahl_Verdichter_Kuehlung = - Drehzahl_Verdichter_MIN + - (MAX(-Stellgrad_Kuehlung_Mittelwert, -Stellgrad_Kuehlung) - 30.0) / - (90.0 - 30.0) * (Drehzahl_Verdichter_MAX - Drehzahl_Verdichter_MIN); - Drehzahl_Verdichter_Entfeuchtung = - Drehzahl_Verdichter_MIN + - 0.5 * - (MAX(-Stellgrad_Entfeuchtung_Mittelwert, -Stellgrad_Entfeuchtung) - - 50.0) / - (90.0 - 50.0) * (Drehzahl_Verdichter_MAX - Drehzahl_Verdichter_MIN); - - if (Verdichter) { - Drehzahl_Verdichter = - limit(MAX(Drehzahl_Verdichter_Kuehlung, - MAX(Drehzahl_Verdichter_Entfeuchtung, - Drehzahl_Verdichter_adaptiv)), - Drehzahl_Verdichter_MIN, Drehzahl_Verdichter_MAX); - } else { - Drehzahl_Verdichter = 1000.0; - } - - Stellgrad_Verdichter = - Drehzahl_Verdichter / Drehzahl_Verdichter_MAX * 100.0 * (160.0 / 200.0); - /* + Stellgrad_Verdichter = Drehzahl_Verdichter / Drehzahl_Verdichter_MAX * 100.0 * (160.0 / 200.0); + /* (* -------------------- *) (* Verflüssigerregelung *) (* -------------------- *) */ - Verfluessiger = Verfluessiger && - ((Drehzahl_Verdichter_adaptiv - Drehzahl_Verdichter_MIN) / ((Drehzahl_Verdichter_MAX - Drehzahl_Verdichter_MIN) < 0.30) && - (-Stellgrad_Kuehlung_Mittelwert < 30.0) && - (-Stellgrad_Entfeuchtung_Mittelwert < 60.0) || ((Drehzahl_Verdichter_adaptiv - Drehzahl_Verdichter_MIN) / (Drehzahl_Verdichter_MAX - Drehzahl_Verdichter_MIN) < 0.20) && - (-Stellgrad_Kuehlung_Mittelwert < 20.0) && - -Stellgrad_Entfeuchtung_Mittelwert < 50.0); + Verfluessiger = Verfluessiger && ((Drehzahl_Verdichter_adaptiv - Drehzahl_Verdichter_MIN) / ((Drehzahl_Verdichter_MAX - Drehzahl_Verdichter_MIN) < 0.30) && + (-Stellgrad_Kuehlung_Mittelwert < 30.0) && + (-Stellgrad_Entfeuchtung_Mittelwert < 60.0) || ((Drehzahl_Verdichter_adaptiv - Drehzahl_Verdichter_MIN) / (Drehzahl_Verdichter_MAX - Drehzahl_Verdichter_MIN) < 0.20) && + (-Stellgrad_Kuehlung_Mittelwert < 20.0) && + -Stellgrad_Entfeuchtung_Mittelwert < 50.0); - }// Ende Feuchtemodul + }// Ende Feuchtemodul - // ---------------------------------------- - // Werte die auf Veränderung geprüft werden - // ---------------------------------------- - Sammelalarm_quittiert_alt = Sammelalarm_quittiert; - Istwert_Temperatur_alt = Istwert_Temperatur; - Regelabweichung_Temperatur_alt = Regelabweichung_Temperatur; - Sollwert_Temperatur_alt = Sollwert_Temperatur; - Istwert_Feuchte_alt = Istwert_Feuchte; - Regelabweichung_Feuchte_alt_alt = Regelabweichung_Feuchte_alt; - Regelabweichung_Feuchte_alt = Regelabweichung_Feuchte; - Sollwert_Feuchte_alt = Sollwert_Feuchte; - Durchzug_alt = Durchzug; - Regelabweichung_Tuer_alt = Regelabweichung_Tuer; - HeizungFeuchtemodul_alt = HeizungFeuchtemodul; - Regelabweichung_Befeuchtung_alt_alt = Regelabweichung_Befeuchtung_alt; - Regelabweichung_Entfeuchtung_alt = Regelabweichung_Entfeuchtung; + // ---------------------------------------- + // Werte die auf Veränderung geprüft werden + // ---------------------------------------- + Sammelalarm_quittiert_alt = Sammelalarm_quittiert; + Istwert_Temperatur_alt = Istwert_Temperatur; + Regelabweichung_Temperatur_alt = Regelabweichung_Temperatur; + Sollwert_Temperatur_alt = Sollwert_Temperatur; + Istwert_Feuchte_alt = Istwert_Feuchte; + Regelabweichung_Feuchte_alt_alt = Regelabweichung_Feuchte_alt; + Regelabweichung_Feuchte_alt = Regelabweichung_Feuchte; + Sollwert_Feuchte_alt = Sollwert_Feuchte; + Durchzug_alt = Durchzug; + Regelabweichung_Tuer_alt = Regelabweichung_Tuer; + HeizungFeuchtemodul_alt = HeizungFeuchtemodul; + Regelabweichung_Befeuchtung_alt_alt = Regelabweichung_Befeuchtung_alt; + Regelabweichung_Entfeuchtung_alt = Regelabweichung_Entfeuchtung; - // ---------------- - // Rückgabewerte - // ---------------- - // F_Outputs out{}; + // ---------------- + // Rückgabewerte + // ---------------- + // F_Outputs out{}; - binOut.bool_out01 = (std::abs((Sollwert_Temperatur - Istwert_Temperatur)) > Temperaturband); // du nutzt Temperaturband-Alarm - // separat; hier nur Beispiel - binOut.bool_out02 = (std::abs((Sollwert_Feuchte - Istwert_Feuchte)) > Feuchteband) && - (!Befeuchtung_aus) && (!Entfeuchtung_aus); - binOut.bool_out03 = Befeuchtung_aus || Entfeuchtung_aus; - binOut.bool_out07 = (!Status_Uebertemperatur) && - (!(std::abs(Istwert_Ueberwachungsregler - Istwert_Temperatur) > 20.0)); - alarmOut.Startup = Startup_finished; + binOut.bool_out01 = (std::abs((Sollwert_Temperatur - Istwert_Temperatur)) > Temperaturband); // du nutzt Temperaturband-Alarm + // separat; hier nur Beispiel + binOut.bool_out02 = (std::abs((Sollwert_Feuchte - Istwert_Feuchte)) > Feuchteband) && + (!Befeuchtung_aus) && (!Entfeuchtung_aus); + binOut.bool_out03 = Befeuchtung_aus || Entfeuchtung_aus; + binOut.bool_out07 = (!Status_Uebertemperatur) && + (!(std::abs(Istwert_Ueberwachungsregler - Istwert_Temperatur) > 20.0)); + alarmOut.Startup = Startup_finished; - binOut.bool_out09 = HeizungKessel; - binOut.bool_out11 = HeizungTuer; - binOut.bool_out12 = HeizungKesselrand; - binOut.bool_out13 = Verfluessiger; - binOut.bool_out14 = Nachfuellen; - binOut.bool_out16 = Entleerpumpe; - binOut.bool_out17 = HeizungFeuchtemodul; - binOut.bool_out20 = Abschlaemmventil; - binOut.bool_out18 = Kuehlventil; - binOut.bool_out19 = Entfeuchtungsventil; - binOut.bool_out21 = Verdichter; - binOut.bool_out23 = !Sammelalarm_quittiert; + binOut.bool_out09 = HeizungKessel; + binOut.bool_out11 = HeizungTuer; + binOut.bool_out12 = HeizungKesselrand; + binOut.bool_out13 = Verfluessiger; + binOut.bool_out14 = Nachfuellen; + binOut.bool_out16 = Entleerpumpe; + binOut.bool_out17 = HeizungFeuchtemodul; + binOut.bool_out20 = Abschlaemmventil; + binOut.bool_out18 = Kuehlventil; + binOut.bool_out19 = Entfeuchtungsventil; + binOut.bool_out21 = Verdichter; + binOut.bool_out23 = !Sammelalarm_quittiert; - analogOut.real_out01 = Istwert_Temperatur; - analogOut.real_out02 = Istwert_Temperatur; - analogOut.real_out04 = Istwert_Temperatur; - analogOut.real_out05 = limit(Istwert_Feuchte, 0.0, 100.0); - analogOut.real_out06 = limit(Istwert_Feuchte, 0.0, 100.0); - analogOut.real_out07 = Sollwert_Feuchte; - analogOut.real_out08 = limit(Istwert_Feuchte, 0.0, 100.0); - analogOut.real_out09 = Stellgrad_HeizungKessel; - analogOut.real_out10 = Stellgrad_Pumpe; - analogOut.real_out11 = Stellgrad_HeizungTuer; - analogOut.real_out12 = Stellgrad_HeizungKesselrand; - analogOut.real_out13 = Stellgrad_Feuchtemodul; - analogOut.real_out14 = Stellgrad_Abschlaemmventil_zyklisch; - analogOut.real_out16 = Temperatur_Feuchtemodul; - analogOut.Stellgrad_Feuchtemodul = Stellgrad_Feuchtemodul; - analogOut.real_out18 = Stellgrad_Kuehlventil; - analogOut.real_out19 = Stellgrad_Entfeuchtungsventil; - analogOut.real_out20 = Stellgrad_Luefter; - analogOut.real_out21 = Stellgrad_Verdichter; - analogOut.real_out25 = Schaltwert_Uebertemperatur; - analogOut.real_out26 = Schaltwert_Untertemperatur; - analogOut.Stellgrad_Heizung = Stellgrad_Heizung; - analogOut.Stellgrad_Kuehlung = Stellgrad_Kuehlung; - analogOut.Stellgrad_Befeuchtung = Stellgrad_Befeuchtung; - analogOut.Stellgrad_Entfeuchtung = Stellgrad_Entfeuchtung; - analogOut.Counter_Tuer = Counter_Tuer_offen; + analogOut.real_out01 = Istwert_Temperatur; + analogOut.real_out02 = Istwert_Temperatur; + analogOut.real_out04 = Istwert_Temperatur; + analogOut.real_out05 = limit(Istwert_Feuchte, 0.0, 100.0); + analogOut.real_out06 = limit(Istwert_Feuchte, 0.0, 100.0); + analogOut.real_out07 = Sollwert_Feuchte; + analogOut.real_out08 = limit(Istwert_Feuchte, 0.0, 100.0); + analogOut.real_out09 = Stellgrad_HeizungKessel; + analogOut.real_out10 = Stellgrad_Pumpe; + analogOut.real_out11 = Stellgrad_HeizungTuer; + analogOut.real_out12 = Stellgrad_HeizungKesselrand; + analogOut.real_out13 = Stellgrad_Feuchtemodul; + analogOut.real_out14 = Stellgrad_Abschlaemmventil_zyklisch; + analogOut.real_out16 = Temperatur_Feuchtemodul; + analogOut.Stellgrad_Feuchtemodul = Stellgrad_Feuchtemodul; + analogOut.real_out18 = Stellgrad_Kuehlventil; + analogOut.real_out19 = Stellgrad_Entfeuchtungsventil; + analogOut.real_out20 = Stellgrad_Luefter; + analogOut.real_out21 = Stellgrad_Verdichter; + analogOut.real_out25 = Schaltwert_Uebertemperatur; + analogOut.real_out26 = Schaltwert_Untertemperatur; + analogOut.Stellgrad_Heizung = Stellgrad_Heizung; + analogOut.Stellgrad_Kuehlung = Stellgrad_Kuehlung; + analogOut.Stellgrad_Befeuchtung = Stellgrad_Befeuchtung; + analogOut.Stellgrad_Entfeuchtung = Stellgrad_Entfeuchtung; + analogOut.Counter_Tuer = Counter_Tuer_offen; - // alarms (wie ST) - alarmOut.alarm_01 = Bandalarm_Temperatur; - alarmOut.alarm_02 = Bandalarm_Feuchte; - alarmOut.alarm_03 = Tueralarm; - alarmOut.alarm_04 = false; - alarmOut.alarm_05 = false; - alarmOut.alarm_06 = Alarm_Wasser_Befeuchtungsmodul && !Befeuchtung_aus; - alarmOut.alarm_07 = Alarm_Abwasser_Befeuchtungsmodul; - alarmOut.alarm_08 = (Alarm_Heizung_Befeuchtungsmodul || Alarm_PT100_Befeuchtungsmodul) && - !Befeuchtung_aus; + // alarms (wie ST) + alarmOut.alarm_01 = Bandalarm_Temperatur; + alarmOut.alarm_02 = Bandalarm_Feuchte; + alarmOut.alarm_03 = Tueralarm; + alarmOut.alarm_04 = false; + alarmOut.alarm_05 = false; + alarmOut.alarm_06 = Alarm_Wasser_Befeuchtungsmodul && !Befeuchtung_aus; + alarmOut.alarm_07 = Alarm_Abwasser_Befeuchtungsmodul; + alarmOut.alarm_08 = (Alarm_Heizung_Befeuchtungsmodul || Alarm_PT100_Befeuchtungsmodul) && !Befeuchtung_aus; - // alarm_09..alarm_15 sind im ST mit Selbsthaltung/Quittierung etc.: - alarmOut.alarm_09 = (((Istwert_Temperatur_Tuer < -50.0) || (Istwert_Temperatur_Tuer > 120.0)) && - Startup_finished) ||(alarm_09 && Sammelalarm_quittiert); + // alarm_09..alarm_15 sind im ST mit Selbsthaltung/Quittierung etc.: + alarmOut.alarm_09 = (((Istwert_Temperatur_Tuer < -50.0) || (Istwert_Temperatur_Tuer > 120.0)) && + Startup_finished) ||(alarm_09 && Sammelalarm_quittiert); - alarmOut.alarm_10 = (std::abs(Istwert_Ueberwachungsregler - Istwert_Temperatur) > 20.0) || - ((((Istwert_Ueberwachungsregler < -50.0) || - (Istwert_Ueberwachungsregler > 120.0) && Startup_finished))) || - (alarm_10 && Sammelalarm_quittiert); + alarmOut.alarm_10 = (std::abs(Istwert_Ueberwachungsregler - Istwert_Temperatur) > 20.0) || + ((((Istwert_Ueberwachungsregler < -50.0) || + (Istwert_Ueberwachungsregler > 120.0) && Startup_finished))) || + (alarm_10 && Sammelalarm_quittiert); - alarmOut.alarm_11 = - Status_Uebertemperatur || StatusQuittierung_Uebertemperatur; - alarmOut.alarm_12 = - Status_Untertemperatur || StatusQuittierung_Untertemperatur; + alarmOut.alarm_11 = Status_Uebertemperatur || StatusQuittierung_Uebertemperatur; + alarmOut.alarm_12 = Status_Untertemperatur || StatusQuittierung_Untertemperatur; - alarmOut.alarm_13 = (((Istwert_Temperatur_Verdampferausgang < -50.0) || - (Istwert_Temperatur_Verdampferausgang > 120.0)) && - Startup_finished) || - (alarm_13 && Sammelalarm_quittiert); + alarmOut.alarm_13 = (((Istwert_Temperatur_Verdampferausgang < -50.0) || (Istwert_Temperatur_Verdampferausgang > 120.0)) && Startup_finished) || + (alarm_13 && Sammelalarm_quittiert); - alarmOut.alarm_14 = - (Counter_Wasserkanister_leer > 10.0 && Startup_finished) || - (alarm_14 && Sammelalarm_quittiert); + alarmOut.alarm_14 = (Counter_Wasserkanister_leer > 10.0 && Startup_finished) || (alarm_14 && Sammelalarm_quittiert); - alarmOut.alarm_15 = - ((analogInput.real_in11 > Sollwert_Feuchte_Max && !Befeuchtung_aus) || - (analogInput.real_in11 < Sollwert_Feuchte_Min && !Entfeuchtung_aus)) || - (alarm_15 && Sammelalarm_quittiert); + alarmOut.alarm_15 = ((analogInput.real_in11 > Sollwert_Feuchte_Max && !Befeuchtung_aus) || + (analogInput.real_in11 < Sollwert_Feuchte_Min && !Entfeuchtung_aus)) || + (alarm_15 && Sammelalarm_quittiert); - // Selbsthaltung der Alarm-Bits (wie ST-OR alarm_x ...) - alarm_09 = alarmOut.alarm_09; - alarm_10 = alarmOut.alarm_10; - alarm_13 = alarmOut.alarm_13; - alarm_14 = alarmOut.alarm_14; - alarm_15 = alarmOut.alarm_15; + // Selbsthaltung der Alarm-Bits (wie ST-OR alarm_x ...) + alarm_09 = alarmOut.alarm_09; + alarm_10 = alarmOut.alarm_10; + alarm_13 = alarmOut.alarm_13; + alarm_14 = alarmOut.alarm_14; + alarm_15 = alarmOut.alarm_15; - // return out; - } + // return out; +} private: // ===== ST: VAR CONSTANT ===== @@ -2014,24 +2324,15 @@ private: 0.02}}}; static constexpr std::array, 9> Kennfeld_Regler_Entfeuchtung_Xp{ - {std::array{1.00, 0.80, 0.60, 0.50, 0.40, 0.35, 0.30, 0.25, - 0.20}, - std::array{1.00, 0.80, 0.60, 0.50, 0.40, 0.35, 0.30, 0.25, - 0.20}, - std::array{1.00, 0.80, 0.60, 0.50, 0.40, 0.35, 0.30, 0.25, - 0.20}, - std::array{1.00, 0.80, 0.60, 0.50, 0.40, 0.35, 0.30, 0.25, - 0.20}, - std::array{1.00, 0.80, 0.60, 0.50, 0.40, 0.35, 0.30, 0.25, - 0.20}, - std::array{1.00, 0.80, 0.60, 0.50, 0.40, 0.35, 0.30, 0.25, - 0.20}, - std::array{1.00, 0.80, 0.60, 0.50, 0.40, 0.35, 0.30, 0.25, - 0.20}, - std::array{1.00, 0.80, 0.60, 0.50, 0.40, 0.35, 0.30, 0.25, - 0.20}, - std::array{1.00, 0.80, 0.60, 0.50, 0.40, 0.35, 0.30, 0.25, - 0.20}}}; + {std::array{1.00, 0.80, 0.60, 0.50, 0.40, 0.35, 0.30, 0.25, 0.20}, + std::array{1.00, 0.80, 0.60, 0.50, 0.40, 0.35, 0.30, 0.25, 0.20}, + std::array{1.00, 0.80, 0.60, 0.50, 0.40, 0.35, 0.30, 0.25, 0.20}, + std::array{1.00, 0.80, 0.60, 0.50, 0.40, 0.35, 0.30, 0.25, 0.20}, + std::array{1.00, 0.80, 0.60, 0.50, 0.40, 0.35, 0.30, 0.25, 0.20}, + std::array{1.00, 0.80, 0.60, 0.50, 0.40, 0.35, 0.30, 0.25, 0.20}, + std::array{1.00, 0.80, 0.60, 0.50, 0.40, 0.35, 0.30, 0.25, 0.20}, + std::array{1.00, 0.80, 0.60, 0.50, 0.40, 0.35, 0.30, 0.25, 0.20}, + std::array{1.00, 0.80, 0.60, 0.50, 0.40, 0.35, 0.30, 0.25, 0.20}}}; static constexpr std::array, 3> Kennfeld_Sollwert_Feuchte_Limit{ @@ -2461,13 +2762,27 @@ extern "C" BINDER_SIMULINK_API_EXPORT ControllerBase *create(); #else class Controller { - public: + Controller(){ + inputs=nullptr; + }; + ~Controller(){}; bool initialize(const char *configFilePath); - void step(); + bool initialize( QList* inputs); + bool initialize( DataModel* instance); + void step(void); void terminate(); + void PID_Temperature(void); private: + + DataModel* model; + QList* inputs; + + void stepSOM(void); + void stepDesk(void); + + #if 0 appengine::IAppLogic *appLogic_{nullptr};