2531 lines
99 KiB
C++
Executable File
2531 lines
99 KiB
C++
Executable File
#pragma once
|
||
|
||
#ifdef BUILD_TARGET_SOM
|
||
|
||
#if defined(_WIN32)
|
||
#define BINDER_SIMULINK_API_EXPORT __declspec(dllexport)
|
||
#else
|
||
#define BINDER_SIMULINK_API_EXPORT __attribute__((visibility("default")))
|
||
#endif
|
||
#include "algorithm/ControllerBase.hpp"
|
||
#include "asio/SignalConnection.hpp"
|
||
|
||
#endif
|
||
|
||
#include <algorithm>
|
||
#include <array>
|
||
#include <cmath>
|
||
#include <cstdint>
|
||
#include <limits>
|
||
#include <memory>
|
||
#include <vector>
|
||
|
||
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<int>(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++)
|
||
// -------------------------
|
||
|
||
class PWM {
|
||
public:
|
||
PWM(double zyklus_min, double zyklus_max, double initial_zykluszeit = -1.0) {
|
||
Zykluszeit = 0.0;
|
||
Ausgabe = 0.0;
|
||
Zyklus_MAX = zyklus_max;
|
||
Zyklus_MIN = zyklus_min;
|
||
}
|
||
/*(* Puls Pause Generierung Kühlung *)
|
||
Zyklus_Kuehlventil := Zyklus_Kuehlventil + sampling_time;
|
||
|
||
IF Ausgabe_Kuehlventil > 0.0 THEN
|
||
Kuehlventil := NOT Status_Untertemperatur;
|
||
Ausgabe_Kuehlventil := Ausgabe_Kuehlventil - sampling_time;
|
||
IF Ausgabe_Kuehlventil < 0.0 THEN
|
||
Zykluszeit_Kuehlventil := Zykluszeit_Kuehlventil -
|
||
Ausgabe_Kuehlventil * 100.0 / MAX(Stellgrad_Kuehlventil, sampling_time /
|
||
Zykluszeit_Kuehlventil_MAX * 100.0); Ausgabe_Kuehlventil := 0.0; END_IF; ELSE
|
||
Kuehlventil := FALSE;
|
||
END_IF;
|
||
|
||
IF Stellgrad_Kuehlventil > sampling_time / Zykluszeit_Kuehlventil_MAX * 100.0
|
||
THEN IF Zyklus_Kuehlventil >= Zykluszeit_Kuehlventil OR Zyklus_Kuehlventil >=
|
||
MAX(2.0 * Zykluszeit_Kuehlventil_MIN, sampling_time * 100.0 /
|
||
Stellgrad_Kuehlventil) THEN Ausgabe_Kuehlventil := MIN(Ausgabe_Kuehlventil +
|
||
Stellgrad_Kuehlventil / 100.0 * Zykluszeit_Kuehlventil_MIN,
|
||
Zykluszeit_Kuehlventil); Zykluszeit_Kuehlventil := Zykluszeit_Kuehlventil_MIN;
|
||
Zyklus_Kuehlventil := 0.0;
|
||
END_IF;
|
||
END_IF;*/
|
||
|
||
bool step(double Stellgrad, double samplingTime) {
|
||
Zyklus += samplingTime;
|
||
bool output_bool;
|
||
if (Ausgabe > 0.0) {
|
||
output_bool = true;
|
||
Ausgabe -= samplingTime;
|
||
if (Ausgabe < 0.0) {
|
||
Zykluszeit -=
|
||
Ausgabe * 100 / MAX(Stellgrad, samplingTime / Zyklus_MAX * 100.0);
|
||
Ausgabe = 0.0;
|
||
}
|
||
|
||
} else {
|
||
output_bool = false;
|
||
}
|
||
if (Stellgrad > samplingTime / Zyklus_MAX * 100.0) {
|
||
if (Zyklus >= Zykluszeit ||
|
||
Zyklus >= MAX(2.0 * Zyklus_MIN, samplingTime * 100.0 / Stellgrad)) {
|
||
Ausgabe = MIN(Ausgabe + Stellgrad / 100.0 * Zyklus_MIN, Zyklus);
|
||
Zykluszeit = Zyklus_MIN;
|
||
Zyklus = 0.0;
|
||
}
|
||
}
|
||
return output_bool;
|
||
}
|
||
|
||
private:
|
||
double Zyklus = 0.0;
|
||
double Ausgabe = 0.0;
|
||
double Zykluszeit = 0.0;
|
||
double Zyklus_MAX = 0.0;
|
||
double Zyklus_MIN = 0.0;
|
||
};
|
||
|
||
class ClimateAlgorithm {
|
||
public:
|
||
struct BinInputs {
|
||
// Eingangswerte aus bool_inXX / real_inXX / reset_flag
|
||
bool reset_flag{};
|
||
bool Sammelalarm_quittiert{};
|
||
bool Tuer_offen{};
|
||
bool Sollwert_Feuchte_aktiv{};
|
||
bool Steuerkontakt_Standby{};
|
||
bool Steuerkontakt_Befeuchtung_aus{};
|
||
bool Steuerkontakt_Entfeuchtung_aus{};
|
||
bool Entleerbehaelter_Oben{};
|
||
bool Wasserkanister_leer{};
|
||
bool Entleerbehaelter_Unten{};
|
||
bool Sammelalarm{};
|
||
} binInput;
|
||
|
||
struct AnalogInputs {
|
||
double Istwert_Temperatur{};
|
||
double Sollwert_Temperatur{};
|
||
double Temperaturband{};
|
||
double Istwert_Ueberwachungsregler{};
|
||
double Klasse_Ueberwachungsregler{};
|
||
double Grenzwert_Untertemperatur{};
|
||
double Istwert_Feuchte{};
|
||
double Sollwert_Feuchte{};
|
||
double Feuchteband{};
|
||
double Sollwert_Luefter{};
|
||
double Istwert_Temperatur_Tuer{};
|
||
double Istwert_Temperatur_Verdampferausgang{};
|
||
double Temperatur_Feuchtemodul{};
|
||
double Bandalarm_nach{};
|
||
double Betauungsschutz{};
|
||
double real_in11{}; // du nutzt real_in11 später direkt in alarm_15
|
||
} analogInput;
|
||
|
||
struct BinOutputs {
|
||
// bool_outXX
|
||
bool bool_out01{};
|
||
bool bool_out02{};
|
||
bool bool_out03{};
|
||
bool bool_out07{};
|
||
bool bool_out09{};
|
||
bool bool_out11{};
|
||
bool bool_out12{};
|
||
bool bool_out13{};
|
||
bool bool_out14{};
|
||
bool bool_out16{};
|
||
bool bool_out17{};
|
||
bool bool_out18{};
|
||
bool bool_out19{};
|
||
bool bool_out20{};
|
||
bool bool_out21{};
|
||
bool bool_out23{};
|
||
} binOut;
|
||
|
||
struct AnalogOutputs {
|
||
// real_outXX (nur die, die du im ST setzt)
|
||
double real_out01{};
|
||
double real_out02{};
|
||
double real_out04{};
|
||
double real_out05{};
|
||
double real_out06{};
|
||
double real_out07{};
|
||
double real_out08{};
|
||
double real_out09{};
|
||
double real_out10{};
|
||
double real_out11{};
|
||
double real_out12{};
|
||
double real_out13{};
|
||
double real_out14{};
|
||
double real_out16{};
|
||
double Stellgrad_Feuchtemodul{}; // ...out17
|
||
double real_out18{};
|
||
double real_out19{};
|
||
double real_out20{};
|
||
double real_out21{};
|
||
double real_out25{};
|
||
double real_out26{};
|
||
double Stellgrad_Heizung{};
|
||
double Stellgrad_Kuehlung{};
|
||
double Stellgrad_Befeuchtung{};
|
||
double Stellgrad_Entfeuchtung{};
|
||
double Counter_Tuer{};
|
||
} analogOut;
|
||
|
||
struct Alarm {
|
||
// alarm_01..alarm_15
|
||
bool Startup{};
|
||
bool alarm_01{};
|
||
bool alarm_02{};
|
||
bool alarm_03{};
|
||
bool alarm_04{};
|
||
bool alarm_05{};
|
||
bool alarm_06{};
|
||
bool alarm_07{};
|
||
bool alarm_08{};
|
||
bool alarm_09{};
|
||
bool alarm_10{};
|
||
bool alarm_11{};
|
||
bool alarm_12{};
|
||
bool alarm_13{};
|
||
bool alarm_14{};
|
||
bool alarm_15{};
|
||
} alarmOut;
|
||
|
||
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;
|
||
|
||
// Zähler reset_flag
|
||
// -----------------
|
||
if (reset_flag) {
|
||
Counter_reset_flag = 0;
|
||
} else {
|
||
Counter_reset_flag += 1;
|
||
}
|
||
Startup_finished =
|
||
(Counter_reset_flag > static_cast<std::uint32_t>(10 * 4));
|
||
|
||
// ------------------------------------------
|
||
// 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);
|
||
|
||
// -------------------
|
||
// 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);
|
||
|
||
|
||
|
||
// 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
|
||
// ------------------
|
||
// f_SuperVisor
|
||
|
||
/*
|
||
Modus_Ueberwachungsregler =
|
||
static_cast<std::uint32_t>(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;
|
||
}
|
||
|
||
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<std::uint32_t>(10 * 4)); StatusQuittierung_Uebertemperatur =
|
||
(Status_Uebertemperatur && Counter_Status_Uebertemperatur <
|
||
static_cast<std::uint32_t>(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<std::uint32_t>(10 * 4)); StatusQuittierung_Untertemperatur =
|
||
(Status_Untertemperatur && Counter_Status_Untertemperatur <
|
||
static_cast<std::uint32_t>(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
|
||
// ------------------------
|
||
// f_SwitchParameterSet(...)
|
||
Index_Feuchte = static_cast<std::uint16_t>(
|
||
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<std::uint16_t>(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<std::uint16_t>(UTILITY_FUNCTIONS::real_to_int(
|
||
limit((Sollwert_Temperatur - (-20.0)) / (100.0 - (-20.0)) * 12.0,
|
||
0.0, 12.0) +
|
||
0.5));
|
||
|
||
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;
|
||
|
||
// ---------------------
|
||
// 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);
|
||
}
|
||
|
||
|
||
// ------------ 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.
|
||
|
||
// Regelabweichung Kühlung
|
||
// F_ PID PID_Cooling()
|
||
double Regelabweichung_Kuehlung = Regelabweichung_Temperatur;
|
||
|
||
// Gradient Regelabweichgun Kuehlung
|
||
|
||
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);
|
||
}
|
||
|
||
// 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);
|
||
}
|
||
|
||
} 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
|
||
|
||
// -----------------------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) *
|
||
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;
|
||
}
|
||
|
||
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(...)
|
||
|
||
|
||
// 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;
|
||
}
|
||
|
||
// Heizung Kessel
|
||
|
||
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);
|
||
|
||
// 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;
|
||
}
|
||
|
||
// Tuerheizung
|
||
Stellgrad_HeizungTuer =
|
||
limit(Stellgrad_Tuer + Stellgrad_Betauungsschutz / 10.0, 0.0, 100.0);
|
||
|
||
HeizungTuer = PWM_Heizung_Tuer.step(Stellgrad_HeizungTuer, 0.25);
|
||
|
||
// 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);
|
||
|
||
// Ende - f_PWMDeHumizeValve.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) {
|
||
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);
|
||
/*
|
||
(* -------------------- *)
|
||
(* 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);
|
||
|
||
}// 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;
|
||
|
||
|
||
|
||
// ----------------
|
||
// 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_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;
|
||
|
||
// 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);
|
||
|
||
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_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_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;
|
||
|
||
// return out;
|
||
}
|
||
|
||
private:
|
||
// ===== ST: VAR CONSTANT =====
|
||
static constexpr double sampling_time = 0.25;
|
||
|
||
static constexpr std::array<std::array<double, 13>, 4> Kennfeld_Ueberhitzung{
|
||
{// 0: Temperatur
|
||
std::array<double, 13>{-20.0, -10.0, 0.0, 10.0, 20.0, 30.0, 40.0, 50.0,
|
||
60.0, 70.0, 80.0, 90.0, 100.0},
|
||
// 1: Skalierung Min
|
||
std::array<double, 13>{0.01, 0.02, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7,
|
||
0.8, 0.9, 1.0, 1.0},
|
||
// 2: Skalierung Max
|
||
std::array<double, 13>{0.01, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0,
|
||
1.0, 1.0, 1.0},
|
||
// 3: Sollwert Überhitzung
|
||
std::array<double, 13>{-6.0, -8.0, -10.0, -8.0, -6.0, -8.0, -10.0, -12.0,
|
||
-16.0, -20.0, -24.0, -28.0, -32.0}}};
|
||
static constexpr std::array<std::array<double, 13>, 4> Kennfeld_Entfeuchtung{
|
||
{// 0: Temperatur
|
||
std::array<double, 13>{-20.0, -10.0, 0.0, 10.0, 20.0, 30.0, 40.0, 50.0,
|
||
60.0, 70.0, 80.0, 90.0, 100.0},
|
||
// 1: Skalierung Entfeuchtung
|
||
std::array<double, 13>{0.08, 0.08, 0.08, 0.10, 0.12, 0.14, 0.16, 0.18,
|
||
0.20, 0.22, 0.24, 0.26, 0.28},
|
||
// 2: Abtauzyklus Pause
|
||
std::array<double, 13>{120.0, 120.0, 120.0, 120.0, 120.0, 90.0, 60.0,
|
||
60.0, 60.0, 0.0, 0.0, 0.0, 0.0},
|
||
// 3: Abtauzyklus Dauer
|
||
std::array<double, 13>{60.0, 60.0, 60.0, 30.0, 20.0, 10.0, 8.0, 4.0, 2.0,
|
||
0.0, 0.0, 0.0, 0.0}}};
|
||
|
||
// Kennfelder (nur die, die oben genutzt werden; den Rest kannst du genauso
|
||
// hinzufügen)
|
||
static constexpr std::array<double, 13> Kennfeld_Regler_Heizung_Xp{
|
||
0.2, 0.5, 0.8, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0};
|
||
static constexpr std::array<double, 13> Kennfeld_Regler_Kuehlung_Xp{
|
||
0.1, 0.1, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.0};
|
||
static constexpr std::array<std::array<double, 9>, 9>
|
||
Kennfeld_Regler_Befeuchtung_Xp{
|
||
{std::array<double, 9>{1.00, 0.54, 0.31, 0.18, 0.11, 0.07, 0.05, 0.03,
|
||
0.02},
|
||
std::array<double, 9>{1.00, 0.54, 0.31, 0.18, 0.11, 0.07, 0.05, 0.03,
|
||
0.02},
|
||
std::array<double, 9>{1.00, 0.54, 0.31, 0.18, 0.11, 0.07, 0.05, 0.03,
|
||
0.02},
|
||
std::array<double, 9>{1.00, 0.54, 0.31, 0.18, 0.11, 0.07, 0.05, 0.03,
|
||
0.02},
|
||
std::array<double, 9>{1.00, 0.54, 0.31, 0.18, 0.11, 0.07, 0.05, 0.03,
|
||
0.02},
|
||
std::array<double, 9>{1.00, 0.54, 0.31, 0.18, 0.11, 0.07, 0.05, 0.03,
|
||
0.02},
|
||
std::array<double, 9>{1.00, 0.54, 0.31, 0.18, 0.11, 0.07, 0.05, 0.03,
|
||
0.02},
|
||
std::array<double, 9>{1.00, 0.54, 0.31, 0.18, 0.11, 0.07, 0.05, 0.03,
|
||
0.02},
|
||
std::array<double, 9>{1.00, 0.54, 0.31, 0.18, 0.11, 0.07, 0.05, 0.03,
|
||
0.02}}};
|
||
static constexpr std::array<std::array<double, 9>, 9>
|
||
Kennfeld_Regler_Entfeuchtung_Xp{
|
||
{std::array<double, 9>{1.00, 0.80, 0.60, 0.50, 0.40, 0.35, 0.30, 0.25,
|
||
0.20},
|
||
std::array<double, 9>{1.00, 0.80, 0.60, 0.50, 0.40, 0.35, 0.30, 0.25,
|
||
0.20},
|
||
std::array<double, 9>{1.00, 0.80, 0.60, 0.50, 0.40, 0.35, 0.30, 0.25,
|
||
0.20},
|
||
std::array<double, 9>{1.00, 0.80, 0.60, 0.50, 0.40, 0.35, 0.30, 0.25,
|
||
0.20},
|
||
std::array<double, 9>{1.00, 0.80, 0.60, 0.50, 0.40, 0.35, 0.30, 0.25,
|
||
0.20},
|
||
std::array<double, 9>{1.00, 0.80, 0.60, 0.50, 0.40, 0.35, 0.30, 0.25,
|
||
0.20},
|
||
std::array<double, 9>{1.00, 0.80, 0.60, 0.50, 0.40, 0.35, 0.30, 0.25,
|
||
0.20},
|
||
std::array<double, 9>{1.00, 0.80, 0.60, 0.50, 0.40, 0.35, 0.30, 0.25,
|
||
0.20},
|
||
std::array<double, 9>{1.00, 0.80, 0.60, 0.50, 0.40, 0.35, 0.30, 0.25,
|
||
0.20}}};
|
||
|
||
static constexpr std::array<std::array<double, 11>, 3>
|
||
Kennfeld_Sollwert_Feuchte_Limit{
|
||
{std::array<double, 11>{0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100},
|
||
std::array<double, 11>{80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80},
|
||
std::array<double, 11>{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}};
|
||
|
||
// Zeitkonstanten etc.
|
||
static constexpr double Tau_Heizung_Tv = 10.0;
|
||
|
||
// Faktoren
|
||
static constexpr double F_Xp_Heizung = 3.8;
|
||
static constexpr double F_Xp_Kuehlung = 33.6;
|
||
static constexpr double F_Xp_Befeuchtung_BINDER = 131.0;
|
||
static constexpr double F_Xp_Entfeuchtung = 100.0;
|
||
static constexpr double F_Xp_Tuer = 10.0;
|
||
|
||
// ===== ST: VAR (Zustände / Merker) =====
|
||
// (ich halte hier nur die, die im übersetzten Teil genutzt werden; den Rest
|
||
// kannst du 1:1 ergänzen)
|
||
double Istwert_Temperatur{};
|
||
double Istwert_Temperatur_alt{};
|
||
double Sollwert_Temperatur{};
|
||
double Sollwert_Temperatur_alt{};
|
||
double Sollwert_Gegenbefeuchten = 0.0;
|
||
double Regelabweichung_Befeuchtung_alt = 0.0;
|
||
double P_Anteil_Befeuchtung = 0.0;
|
||
double Counter_Entfeuchtung_Freigabe = 0.0;
|
||
bool Freigabe_Entfeuchtung = false;
|
||
double Counter_Heizung_Freigabe = 0.0;
|
||
bool Freigabe_Heizung = false;
|
||
double Counter_Befeuchtung_Freigabe = 0.0;
|
||
bool Freigabe_Befeuchtung = false;
|
||
bool Abtauzyklus = false;
|
||
double Counter_Zyklus_Entleeren = 0.0;
|
||
double Drehzahl_Verdichter_Kuehlung = 0.0;
|
||
double Drehzahl_Verdichter_Entfeuchtung = 0.0;
|
||
double Drehzahl_Verdichter = 0.0;
|
||
|
||
/*PWM(double zyklus_min, double zyklus_max, double initial_zykluszeit = -1.0)
|
||
noexcept : Zyklus(0.0), Ausgabe(0.0), Zykluszeit((initial_zykluszeit > 0.0) ?
|
||
initial_zykluszeit : zyklus_max), Zyklus_MIN(zyklus_min),
|
||
Zyklus_MAX(zyklus_max)
|
||
{}
|
||
|
||
bool step(double Stellgrad,double sampling_time,double Zyklus_MIN,double
|
||
Zyklus_MAX){*/
|
||
PWM PWM_Heizung_Kessel = {10.0, 600.0, 0.0};
|
||
PWM PWM_Heizung_Tuer = {10.0, 600.0, 0.0};
|
||
PWM PWM_Nachfuellen = {10.0, 600.0, 0.0};
|
||
PWM PWM_Heizung_Kesselrand = {10.0, 600.0, 0.0};
|
||
PWM PWM_Heizung_Feuchtemodul = {10.0, 600.0, 0.0};
|
||
PWM PWM_Kuehlventil = {10.0, 600.0, 0.0};
|
||
PWM PWM_Entfeuchtungsventil = {10.0, 600.0, 0.0};
|
||
|
||
double Istwert_Ueberwachungsregler{};
|
||
std::uint32_t Modus_Ueberwachungsregler{};
|
||
double Offset_Ueberwachungsregler{};
|
||
double Klasse_Ueberwachungsregler{};
|
||
bool Wasserkanister_leer{};
|
||
double Regler_Tuer_Tn = 700.0;
|
||
double Regler_Tuer_Tv = 60.0;
|
||
double Tau_Tuer_Tv = 60.0;
|
||
double Regler_Entfeuchtung_MAX = 0.0;
|
||
double Regler_Entfeuchtung_MIN = 0.0;
|
||
double Regler_Entfeuchtung_I_Anteil_MAX = 0.0;
|
||
double Regler_Entfeuchtung_I_Anteil_MIN = 0.0;
|
||
bool Freigabe_Kuehlung = false;
|
||
double Sollwert_Temperatur_Feuchtemodul_MIN = 110.0;
|
||
double Sollwert_Temperatur_Feuchtemodul_MAX = 130.0;
|
||
double Zyklus_Entleeren_Mittelwert = 600.0;
|
||
|
||
double Grenzwert_Uebertemperatur{};
|
||
double Schaltwert_Uebertemperatur{};
|
||
bool Status_Uebertemperatur{};
|
||
std::uint32_t Counter_Status_Uebertemperatur{};
|
||
bool StatusQuittierung_Uebertemperatur{};
|
||
|
||
double Grenzwert_Untertemperatur{};
|
||
double Schaltwert_Untertemperatur{};
|
||
bool Status_Untertemperatur{};
|
||
std::uint32_t Counter_Status_Untertemperatur{};
|
||
bool StatusQuittierung_Untertemperatur{};
|
||
|
||
double Istwert_Feuchte{};
|
||
double Istwert_Feuchte_alt{};
|
||
double Sollwert_Feuchte{};
|
||
double Sollwert_Feuchte_alt{};
|
||
double Counter_Entleeren_Kessel{};
|
||
|
||
bool Regelung_AUS{};
|
||
double Counter_Regelung_AUS{};
|
||
bool Steuerkontakt_Standby{};
|
||
bool Sammelalarm{};
|
||
bool Sammelalarm_quittiert{};
|
||
bool Sammelalarm_quittiert_alt{};
|
||
double Regler_Kuehlung_Tv = 5.0;
|
||
double Tau_Kuehlung_Tv = 30.0;
|
||
double Theta_I_Kuehlung = 1.0;
|
||
|
||
// Feuchte absolut
|
||
double p_H2Omax_Sollwert{};
|
||
double p_H2Omax_Istwert{};
|
||
double Taupunkt_Istwert{};
|
||
double Sollwert_Feuchte_Absolut{};
|
||
double Sollwert_Temperatur_Feuchtemodul{};
|
||
double Counter_Kuehlung_Freigabe = 0.0;
|
||
|
||
// Tür
|
||
bool Tuer_offen{};
|
||
double Counter_Tuer_offen{};
|
||
double Counter_Tuer_geschlossen{};
|
||
double Istwert_Temperatur_Tuer{};
|
||
double Regelabweichung_Tuer{};
|
||
double Regelabweichung_Tuer_alt{};
|
||
double Abschlaemmintegral = 0.0;
|
||
double Standby_Feuchtemodul = 0.0;
|
||
double Regelabweichung_Befeuchtung_alt_alt = 0.0;
|
||
double Regelabweichung_Entfeuchtung_alt = 0.0;
|
||
double Durchflussmenge_Einlassventil_Feuchtemodul = 400.0;
|
||
double Durchflussmenge_Abschlaemmventil_Feuchtemodul = 1500.0;
|
||
|
||
// Startup / reset
|
||
std::uint32_t Counter_reset_flag{};
|
||
bool Startup_finished{};
|
||
|
||
// Feuchte limit
|
||
std::uint16_t Index_Sollwert_Feuchte_Limit{};
|
||
double Interpolation_Sollwert_Feuchte_Limit{};
|
||
double Sollwert_Feuchte_Min{};
|
||
double Sollwert_Feuchte_Max{};
|
||
|
||
// Abschaltung Feuchte-Regler
|
||
bool Sollwert_Feuchte_aktiv{};
|
||
bool Steuerkontakt_Befeuchtung_aus{};
|
||
bool Steuerkontakt_Entfeuchtung_aus{};
|
||
bool Befeuchtung_aus{};
|
||
bool Entfeuchtung_aus{};
|
||
double Sollwert_Gegenheizen = 2.0;
|
||
// Parameter Indizes
|
||
std::uint16_t Index_Feuchte{};
|
||
std::uint16_t Index_Temperatur{};
|
||
std::uint16_t Index_Temperatur_ohne_Feuchte{};
|
||
|
||
// Reglerparameter
|
||
double Regler_Heizung_Xp{};
|
||
double Regler_Kuehlung_Xp{};
|
||
double Regler_Befeuchtung_Xp{};
|
||
double Regler_Entfeuchtung_Xp{};
|
||
double Regler_Tuer_Xp{};
|
||
double Regler_Befeuchtung_Tv = 30.0;
|
||
double Regler_Befeuchtung_Tn = 100.0;
|
||
double Regler_Befeuchtung_Tz = 1200.0;
|
||
double Tau_Befeuchtung_Tv = 10.0;
|
||
double Tau_Befeuchtung_Tz = 5.0;
|
||
|
||
// Regelkern Temperatur
|
||
double Sollwert_Temperatur_MIN{};
|
||
double Sollwert_Temperatur_MAX{};
|
||
|
||
double Regelabweichung_Temperatur{};
|
||
double Regelabweichung_Temperatur_alt{};
|
||
double Regelabweichung_Temperatur_Mittelwert{};
|
||
double Standardregelabweichung_Temperatur{};
|
||
double Regelabweichung_Temperatur_Gradient{};
|
||
double Standardgradient_Regelabweichung_Temperatur{};
|
||
double Zykluszeit_Regelabweichung_Temperatur{};
|
||
double Amplitude_Regelabweichung_Temperatur{};
|
||
double Zykluszeit_Regelabweichung_Heizung{};
|
||
double Zykluszeit_Regelabweichung_Kuehlung{};
|
||
double Regelabweichung_Kuehlung_Gradient{};
|
||
double Regelabweichung_Kuehlung_alt{};
|
||
double Faktor_Kuehlung{};
|
||
double Faktor_Gegenheizen_Band{};
|
||
double I_Anteil_Kuehlung{};
|
||
double D_Anteil_Kuehlung{};
|
||
double Regelabweichung_Befeuchtung_Gradient{};
|
||
double I_Anteil_Befeuchtung{};
|
||
double Istwert_Temperatur_Verdampferausgang_PT1 = 0.0;
|
||
double D_Anteil_Befeuchtung{};
|
||
bool Temperatursprung{};
|
||
double Counter_Temperatursprung{};
|
||
double Faktor_Entfeuchtung{};
|
||
double Faktor_Gegenbefeuchten_Band = 5.0;
|
||
double I_Anteil_Entfeuchtung = 0.0;
|
||
double D_Anteil_Entfeuchtung = 0.0;
|
||
double I_Anteil_Tuer = 0.0;
|
||
double P_Anteil_Tuer;
|
||
double Regler_Heizung_MIN{};
|
||
double Regler_Heizung_MAX{};
|
||
double Regler_Heizung_I_Anteil_MIN{};
|
||
double Regler_Heizung_I_Anteil_MAX{};
|
||
double P_Anteil_Heizung{};
|
||
double I_Anteil_Heizung{};
|
||
double D_Anteil_Heizung{};
|
||
double Stellgrad_Heizung{};
|
||
double Stellgrad_Heizung_Mittelwert{};
|
||
double Regelabweichung_Entfeuchtung_Gradient = 0.0;
|
||
double D_Anteil_Tuer = 0.0;
|
||
double Counter_Verdichter_aus = 0.0;
|
||
double Counter_Freigabe_Abtauzyklus = 0.0;
|
||
double Counter_Abtauzyklus;
|
||
double Stellgrad_Feuchtemodul_MAX{};
|
||
double Skalierung_Nachfuellen_Temperatur_I_Anteil{};
|
||
double Counter_Zyklus_Abschlaemmventil = 0.0;
|
||
const double Regler_Kuehlung_Tn = 200.0;
|
||
|
||
double Stellgrad_Feuchtemodul_Boost{};
|
||
const double Temperatur_Feuchtemodul_MAX = 200.0;
|
||
|
||
// Feuchte - nur Platzhalter (weil spätere Ausdrücke referenzieren)
|
||
double Regelabweichung_Feuchte{};
|
||
double Regelabweichung_Feuchte_alt{};
|
||
double Regelabweichung_Feuchte_alt_alt{};
|
||
double Regelabweichung_Feuchte_Mittelwert{};
|
||
double Standardregelabweichung_Feuchte{};
|
||
double Regelabweichung_Feuchte_Gradient{};
|
||
double Standardgradient_Regelabweichung_Feuchte{};
|
||
double Zykluszeit_Regelabweichung_Feuchte{};
|
||
double Amplitude_Regelabweichung_Feuchte{};
|
||
bool Feuchtesprung{};
|
||
double Counter_Feuchtesprung = 0.0;
|
||
double Offset_Regelabweichung_Befeuchtung{};
|
||
double Offset_Regelabweichung_Entfeuchtung{};
|
||
double Stellgrad_Kuehlung{};
|
||
double Stellgrad_Kuehlung_Mittelwert{};
|
||
double Stellgrad_Befeuchtung{};
|
||
double Stellgrad_Befeuchtung_Mittelwert{};
|
||
double Stellgrad_Befeuchtung_Standby{};
|
||
double Stellgrad_Entfeuchtung{};
|
||
double Stellgrad_Entfeuchtung_Mittelwert{};
|
||
double Z_Anteil_Befeuchtung{};
|
||
|
||
// Aktoren/Signale (Defaults, bis restliche Logik ergänzt ist)
|
||
bool HeizungKessel{};
|
||
double Stellgrad_HeizungKessel{};
|
||
bool HeizungTuer{};
|
||
double Stellgrad_HeizungTuer{};
|
||
bool HeizungKesselrand{};
|
||
double Stellgrad_HeizungKesselrand{};
|
||
bool Verfluessiger{};
|
||
bool Nachfuellen{};
|
||
bool Entleerpumpe{};
|
||
bool HeizungFeuchtemodul{};
|
||
bool HeizungFeuchtemodul_alt{};
|
||
bool Abschlaemmventil{};
|
||
double Stellgrad_Abschlaemmventil_zyklisch{};
|
||
bool Kuehlventil{};
|
||
double Stellgrad_Kuehlventil{};
|
||
bool Entfeuchtungsventil{};
|
||
double Stellgrad_Entfeuchtungsventil{};
|
||
bool Verdichter{};
|
||
double Stellgrad_Verdichter{};
|
||
double Stellgrad_Pumpe{};
|
||
double Stellgrad_Luefter{};
|
||
double Stellgrad_Betauungsschutz{};
|
||
double Temperatur_Feuchtemodul_Gradient = 0.0;
|
||
double Stellgrad_Feuchtemodul_MAX_adaptiv = 0.0;
|
||
double Counter_Nachlauf_Entleeren = 0.0;
|
||
double Counter_Pause_Entleeren = 0.0;
|
||
|
||
// “Durchzug” (wird später in Überhitzungslogik gesetzt)
|
||
bool Durchzug{};
|
||
bool Durchzug_alt{};
|
||
double Counter_Durchzug{};
|
||
|
||
// Befeuchtungsmodul Zustände (Platzhalter, damit “Werte die auf Veränderung
|
||
// geprüft werden” passt)
|
||
double Temperatur_Feuchtemodul{};
|
||
double Temperatur_Feuchtemodul_alt{};
|
||
double Stellgrad_Feuchtemodul{};
|
||
double Stellgrad_Feuchtemodul_Mittelwert{};
|
||
double Stellgrad_Feuchtemodul_PT1{};
|
||
double Stellgrad_Feuchtemodul_Nachfuellen{};
|
||
bool Entleeren{};
|
||
bool Entleeren_alt{};
|
||
bool Entleerbehaelter_Oben{};
|
||
bool Entleerbehaelter_Unten{};
|
||
double Counter_Wasserkanister_leer{};
|
||
double Regler_Entfeuchtung_Tv = 5.0;
|
||
double Regler_Entfeuchtung_Tn = 200.0;
|
||
double Tau_Entfeuchtung_Tv = 60.0;
|
||
double Theta_I_Entfeuchtung = 0.1;
|
||
double C_Entfeuchtung = 200.0;
|
||
double U_Entfeuchtung = 0.4;
|
||
double P_Entfeuchtung = 500.0;
|
||
double Regler_Entfeuchten_I_Anteil_MIN = 0.0;
|
||
double Drehzahl_Verdichter_MIN = 1800.0;
|
||
double Drehzahl_Verdichter_MAX = 4500.0;
|
||
double Drehzahl_Verdichter_adaptiv = 0.0;
|
||
|
||
// Alarmbits mit Selbsthaltung
|
||
bool alarm_09{};
|
||
bool alarm_10{};
|
||
bool alarm_13{};
|
||
bool alarm_14{};
|
||
bool alarm_15{};
|
||
bool Alarm_Wasser_Befeuchtungsmodul{};
|
||
bool Alarm_Abwasser_Befeuchtungsmodul{};
|
||
bool Alarm_PT100_Befeuchtungsmodul{};
|
||
bool Alarm_Heizung_Befeuchtungsmodul{};
|
||
bool Bandalarm_Temperatur{};
|
||
bool Bandalarm_Feuchte{};
|
||
bool Tueralarm{};
|
||
};
|
||
|
||
// namespace UTILITY_FUNCTIONS
|
||
|
||
// double PT100_ResistanceToTemperature_Linear(double R)
|
||
// {
|
||
// constexpr double R0 = 100.0;
|
||
// constexpr double alpha = 0.00385; // IEC-Näherung
|
||
|
||
// return (R - R0) / (R0 * alpha);
|
||
// }
|
||
|
||
class PT1 {
|
||
public:
|
||
PT1() = default;
|
||
void initialize(double fs, double t_cutoff) {
|
||
fs_ = fs;
|
||
ts_ = 1 / fs_;
|
||
double f_cutoff = 1. / t_cutoff;
|
||
tau_ = 1 / (2 * PI_CONST * f_cutoff);
|
||
lambda_ = 2 * tau_ / ts_;
|
||
b0_ = k_ / (1. + lambda_);
|
||
b1_ = k_ / (1. + lambda_);
|
||
a0_ = (1. - lambda_) / (1. + lambda_);
|
||
};
|
||
|
||
double step(double x) {
|
||
|
||
double y = b0_ * x + s1_;
|
||
// s1 = b1*x - a1*y
|
||
s1_ = b1_ * x - a0_ * y;
|
||
return y;
|
||
};
|
||
|
||
private:
|
||
double s1_ = 0.;
|
||
double fs_ = 1.;
|
||
double ts_ = 1.;
|
||
double tau_ = 1.;
|
||
double a0_ = 0.;
|
||
double b0_ = 0.;
|
||
double b1_ = 0.;
|
||
double k_ = 1.;
|
||
double lambda_ = 1.;
|
||
};
|
||
|
||
#ifdef BUILD_TARGET_SOM
|
||
namespace appengine::state {
|
||
class IStateVariable;
|
||
}
|
||
#endif
|
||
|
||
#ifdef BUILD_TARGET_SOM
|
||
class Controller : public ControllerBase {
|
||
public:
|
||
bool initialize(const char *configFilePath,
|
||
appengine::IAppLogic *appLogic) override;
|
||
void step() override;
|
||
void terminate() override;
|
||
|
||
private:
|
||
appengine::IAppLogic *appLogic_{nullptr};
|
||
|
||
// Beispiel: du wirst für diese ST-Logik sehr viele StateVars mappen;
|
||
// hier nur exemplarisch:
|
||
std::shared_ptr<appengine::state::IStateVariable> tempVariable_;
|
||
std::shared_ptr<appengine::state::IStateVariable> tempSetPointVariable_;
|
||
|
||
// TODO: bool_inXX / real_inXX / bool_outXX / real_outXX / alarm_XX als
|
||
// StateVariables holen (oder je nach AppEngine: arrays/IO mapping)
|
||
|
||
ClimateAlgorithm algo_{};
|
||
PT1 FILTERED_TEMP{};
|
||
PT1 FILTER_TUER{};
|
||
// Eingänge
|
||
std::shared_ptr<appengine::state::IStateVariable> const_duty_cycle_;
|
||
std::shared_ptr<appengine::state::IStateVariable> const_freq_;
|
||
std::shared_ptr<appengine::state::IStateVariable> Wasserstand_Oben_Config_;
|
||
std::shared_ptr<appengine::state::IStateVariable> Wasserstand_Unten_Config_;
|
||
std::shared_ptr<appengine::state::IStateVariable> Fuellstand_Config_;
|
||
std::shared_ptr<appengine::state::IStateVariable> SV_Tuer_Variable_;
|
||
std::shared_ptr<appengine::state::IStateVariable> SV_Verdampferausgang_;
|
||
std::shared_ptr<appengine::state::IStateVariable> SV_Befeuchtungsmodul_;
|
||
std::shared_ptr<appengine::state::IStateVariable> SV_Verdichter_on_;
|
||
std::shared_ptr<appengine::state::IStateVariable> Startup_;
|
||
std::shared_ptr<appengine::state::IStateVariable> CounterTuer_;
|
||
|
||
// ausgänge
|
||
std::vector<appengine::asio::SignalConnectionPtr> subscriptions_{};
|
||
std::shared_ptr<appengine::state::IStateVariable> Heizung_Bef_Config_;
|
||
std::shared_ptr<appengine::state::IStateVariable> MV_Kuehlung_Config_;
|
||
std::shared_ptr<appengine::state::IStateVariable> Abschlaemmen_Config_;
|
||
std::shared_ptr<appengine::state::IStateVariable> Entleerpumpe_Config_;
|
||
std::shared_ptr<appengine::state::IStateVariable> Heizung_Kesselrand_Config_;
|
||
std::shared_ptr<appengine::state::IStateVariable>
|
||
Freigabe_Verfluessigerluefter_Config_;
|
||
std::shared_ptr<appengine::state::IStateVariable> Heizung_Innenraum_Config_;
|
||
std::shared_ptr<appengine::state::IStateVariable> Heizung_Tuer_Config_;
|
||
std::shared_ptr<appengine::state::IStateVariable> Uebertemperatur_Config_;
|
||
std::shared_ptr<appengine::state::IStateVariable> MV_Entfeuchtung_Config_;
|
||
std::shared_ptr<appengine::state::IStateVariable> MV_Druckluft_Config_;
|
||
std::shared_ptr<appengine::state::IStateVariable>
|
||
Ansteuerung_Wassereinlass_Config_;
|
||
std::shared_ptr<appengine::state::IStateVariable>
|
||
Ansteuerung_Verdichter_Config_;
|
||
std::shared_ptr<appengine::state::IStateVariable> Verdichter_Duty_Config;
|
||
std::shared_ptr<appengine::state::IStateVariable> Luefter_Innenraum_Config_;
|
||
|
||
std::shared_ptr<appengine::state::IStateVariable> SV_Stellgrad_Heizung;
|
||
std::shared_ptr<appengine::state::IStateVariable> SV_Stellgrad_Kuehlung;
|
||
std::shared_ptr<appengine::state::IStateVariable> SV_Stellgrad_Befeuchtung;
|
||
std::shared_ptr<appengine::state::IStateVariable> SV_Stellgrad_Entfeuchtung;
|
||
// Regelgrößen
|
||
std::shared_ptr<appengine::state::IStateVariable> SV_Sollwert_Temperatur_;
|
||
std::shared_ptr<appengine::state::IStateVariable> SV_Temperatur_Variable_;
|
||
std::shared_ptr<appengine::state::IStateVariable> SV_Sollwert_Feuchte_;
|
||
std::shared_ptr<appengine::state::IStateVariable> SV_Feuchte_Variable_;
|
||
|
||
// std::vector<appengine::asio::SignalConnectionPtr> subscriptions_{};
|
||
};
|
||
|
||
extern "C" BINDER_SIMULINK_API_EXPORT ControllerBase *create();
|
||
|
||
#else
|
||
class Controller {
|
||
|
||
public:
|
||
bool initialize(const char *configFilePath);
|
||
void step();
|
||
void terminate();
|
||
|
||
private:
|
||
#if 0
|
||
appengine::IAppLogic *appLogic_{nullptr};
|
||
|
||
// Beispiel: du wirst für diese ST-Logik sehr viele StateVars mappen;
|
||
// hier nur exemplarisch:
|
||
std::shared_ptr<appengine::state::IStateVariable> tempVariable_;
|
||
std::shared_ptr<appengine::state::IStateVariable> tempSetPointVariable_;
|
||
|
||
// TODO: bool_inXX / real_inXX / bool_outXX / real_outXX / alarm_XX als StateVariables holen
|
||
// (oder je nach AppEngine: arrays/IO mapping)
|
||
|
||
ClimateAlgorithm algo_{};
|
||
PT1 FILTERED_TEMP{} ;
|
||
PT1 FILTER_TUER{};
|
||
// Eingänge
|
||
std::shared_ptr<appengine::state::IStateVariable> const_duty_cycle_;
|
||
std::shared_ptr<appengine::state::IStateVariable> const_freq_;
|
||
std::shared_ptr<appengine::state::IStateVariable> Wasserstand_Oben_Config_;
|
||
std::shared_ptr<appengine::state::IStateVariable> Wasserstand_Unten_Config_;
|
||
std::shared_ptr<appengine::state::IStateVariable> Fuellstand_Config_;
|
||
std::shared_ptr<appengine::state::IStateVariable> SV_Tuer_Variable_;
|
||
std::shared_ptr<appengine::state::IStateVariable> SV_Verdampferausgang_;
|
||
std::shared_ptr<appengine::state::IStateVariable> SV_Befeuchtungsmodul_;
|
||
std::shared_ptr<appengine::state::IStateVariable> SV_Verdichter_on_;
|
||
std::shared_ptr<appengine::state::IStateVariable> Startup_;
|
||
std::shared_ptr<appengine::state::IStateVariable> CounterTuer_;
|
||
|
||
// ausgänge
|
||
std::vector<appengine::asio::SignalConnectionPtr> subscriptions_{};
|
||
std::shared_ptr<appengine::state::IStateVariable> Heizung_Bef_Config_;
|
||
std::shared_ptr<appengine::state::IStateVariable> MV_Kuehlung_Config_;
|
||
std::shared_ptr<appengine::state::IStateVariable> Abschlaemmen_Config_;
|
||
std::shared_ptr<appengine::state::IStateVariable> Entleerpumpe_Config_;
|
||
std::shared_ptr<appengine::state::IStateVariable> Heizung_Kesselrand_Config_;
|
||
std::shared_ptr<appengine::state::IStateVariable> Freigabe_Verfluessigerluefter_Config_;
|
||
std::shared_ptr<appengine::state::IStateVariable> Heizung_Innenraum_Config_;
|
||
std::shared_ptr<appengine::state::IStateVariable> Heizung_Tuer_Config_;
|
||
std::shared_ptr<appengine::state::IStateVariable> Uebertemperatur_Config_;
|
||
std::shared_ptr<appengine::state::IStateVariable> MV_Entfeuchtung_Config_;
|
||
std::shared_ptr<appengine::state::IStateVariable> MV_Druckluft_Config_;
|
||
std::shared_ptr<appengine::state::IStateVariable> Ansteuerung_Wassereinlass_Config_;
|
||
std::shared_ptr<appengine::state::IStateVariable> Ansteuerung_Verdichter_Config_;
|
||
std::shared_ptr<appengine::state::IStateVariable> Verdichter_Duty_Config;
|
||
std::shared_ptr<appengine::state::IStateVariable> Luefter_Innenraum_Config_;
|
||
|
||
std::shared_ptr<appengine::state::IStateVariable> SV_Stellgrad_Heizung;
|
||
std::shared_ptr<appengine::state::IStateVariable> SV_Stellgrad_Kuehlung;
|
||
std::shared_ptr<appengine::state::IStateVariable> SV_Stellgrad_Befeuchtung;
|
||
std::shared_ptr<appengine::state::IStateVariable> SV_Stellgrad_Entfeuchtung;
|
||
// Regelgrößen
|
||
std::shared_ptr<appengine::state::IStateVariable> SV_Sollwert_Temperatur_;
|
||
std::shared_ptr<appengine::state::IStateVariable> SV_Temperatur_Variable_;
|
||
std::shared_ptr<appengine::state::IStateVariable> SV_Sollwert_Feuchte_;
|
||
std::shared_ptr<appengine::state::IStateVariable> SV_Feuchte_Variable_;
|
||
|
||
//std::vector<appengine::asio::SignalConnectionPtr> subscriptions_{};
|
||
#endif
|
||
};
|
||
|
||
#endif
|