From f86857c279db755110a62be13ff79f31fa2fee18 Mon Sep 17 00:00:00 2001 From: Yurii Date: Thu, 31 Oct 2024 05:22:41 +0300 Subject: [PATCH] feat: improved turbo mode - added turbo factor parameter - implemented turbo mode for PID --- src/RegulatorTask.h | 45 +++++++++++++++--------------------- src/Settings.h | 5 ++-- src/utils.h | 10 ++++++++ src_data/locales/en.json | 3 ++- src_data/locales/ru.json | 5 ++-- src_data/pages/settings.html | 20 +++++++++++----- 6 files changed, 51 insertions(+), 37 deletions(-) diff --git a/src/RegulatorTask.h b/src/RegulatorTask.h index 9a8d005..605640a 100644 --- a/src/RegulatorTask.h +++ b/src/RegulatorTask.h @@ -29,31 +29,9 @@ protected: #endif void loop() { - bool pidIntergralResetted = false; - if (fabs(pidRegulator.Kp - settings.pid.p_factor) >= 0.0001f) { - pidRegulator.Kp = settings.pid.p_factor; - pidRegulator.integral = 0; - pidIntergralResetted = true; - } - - if (fabs(pidRegulator.Ki - settings.pid.i_factor) >= 0.0001f) { - pidRegulator.Ki = settings.pid.i_factor; - pidRegulator.integral = 0; - pidIntergralResetted = true; - } - - if (fabs(pidRegulator.Kd - settings.pid.d_factor) >= 0.0001f) { - pidRegulator.Kd = settings.pid.d_factor; - pidRegulator.integral = 0; - pidIntergralResetted = true; - } - if (!settings.pid.enable && fabs(pidRegulator.integral) > 0.01f) { pidRegulator.integral = 0.0f; - pidIntergralResetted = true; - } - if (pidIntergralResetted) { Log.sinfoln(FPSTR(L_REGULATOR_PID), F("Integral sum has been reset")); } @@ -61,10 +39,10 @@ protected: if (!settings.heating.enable || vars.states.emergency) { settings.heating.turbo = false; - } else if (settings.pid.enable) { - settings.heating.turbo = false; // not implemented + } else if (!settings.pid.enable && !settings.equitherm.enable) { + settings.heating.turbo = false; - } else if (fabs(settings.heating.target - vars.temperatures.indoor) < 1.0f) { + } else if (fabs(settings.heating.target - vars.temperatures.indoor) <= 1.0f) { settings.heating.turbo = false; } @@ -125,7 +103,9 @@ protected: etRegulator.indoorTemp = 0; } else { - etRegulator.Kt = settings.heating.turbo ? 10.0f : settings.equitherm.t_factor; + etRegulator.Kt = settings.heating.turbo + ? settings.equitherm.t_factor * settings.heating.turboFactor + : settings.equitherm.t_factor; etRegulator.indoorTemp = indoorTemp; } @@ -155,11 +135,24 @@ protected: if (settings.pid.enable) { //if (vars.parameters.heatingEnabled) { if (settings.heating.enable && vars.sensors.indoor.connected) { + pidRegulator.Kp = settings.heating.turbo + ? settings.pid.p_factor * settings.heating.turboFactor + : settings.pid.p_factor; + pidRegulator.Kd = settings.pid.d_factor; + pidRegulator.setLimits(settings.pid.minTemp, settings.pid.maxTemp); pidRegulator.setDt(settings.pid.dt * 1000u); pidRegulator.input = vars.temperatures.indoor; pidRegulator.setpoint = settings.heating.target; + if (fabs(pidRegulator.Ki - settings.pid.i_factor) >= 0.0001f) { + pidRegulator.Ki = settings.pid.i_factor; + pidRegulator.integral = 0; + pidRegulator.getResultNow(); + + Log.sinfoln(FPSTR(L_REGULATOR_PID), F("Integral sum has been reset")); + } + float pidResult = pidRegulator.getResultTimer(); if (fabs(prevPidResult - pidResult) > 0.09f) { prevPidResult = pidResult; diff --git a/src/Settings.h b/src/Settings.h index f81e5d0..a520f4c 100644 --- a/src/Settings.h +++ b/src/Settings.h @@ -95,6 +95,7 @@ struct Settings { bool turbo = false; float target = DEFAULT_HEATING_TARGET_TEMP; float hysteresis = 0.5f; + float turboFactor = 3.0f; byte minTemp = DEFAULT_HEATING_MIN_TEMP; byte maxTemp = DEFAULT_HEATING_MAX_TEMP; } heating; @@ -108,9 +109,9 @@ struct Settings { struct { bool enable = false; - float p_factor = 2; + float p_factor = 2.0f; float i_factor = 0.0055f; - float d_factor = 0; + float d_factor = 0.0f; unsigned short dt = 180; short minTemp = 0; short maxTemp = DEFAULT_HEATING_MAX_TEMP; diff --git a/src/utils.h b/src/utils.h index 6e268b5..775e82b 100644 --- a/src/utils.h +++ b/src/utils.h @@ -394,6 +394,7 @@ void settingsToJson(const Settings& src, JsonVariant dst, bool safe = false) { dst["heating"]["turbo"] = src.heating.turbo; dst["heating"]["target"] = roundd(src.heating.target, 2); dst["heating"]["hysteresis"] = roundd(src.heating.hysteresis, 2); + dst["heating"]["turboFactor"] = roundd(src.heating.turboFactor, 2); dst["heating"]["minTemp"] = src.heating.minTemp; dst["heating"]["maxTemp"] = src.heating.maxTemp; @@ -1106,6 +1107,15 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } + if (!src["heating"]["turboFactor"].isNull()) { + float value = src["heating"]["turboFactor"].as(); + + if (value >= 1.5f && value <= 10.0f && fabs(value - dst.heating.turboFactor) > 0.0001f) { + dst.heating.turboFactor = roundd(value, 2); + changed = true; + } + } + if (!src["heating"]["minTemp"].isNull()) { unsigned char value = src["heating"]["minTemp"].as(); diff --git a/src_data/locales/en.json b/src_data/locales/en.json index 207da8f..988f1c9 100644 --- a/src_data/locales/en.json +++ b/src_data/locales/en.json @@ -220,7 +220,8 @@ }, "heating": { - "hyst": "Hysteresis (in degrees)" + "hyst": "Hysteresis (in degrees)", + "turboFactor": "Turbo mode coeff." }, "emergency": { diff --git a/src_data/locales/ru.json b/src_data/locales/ru.json index e6f9a00..4c34f21 100644 --- a/src_data/locales/ru.json +++ b/src_data/locales/ru.json @@ -220,11 +220,12 @@ }, "heating": { - "hyst": "Гистерезис (в градусах)" + "hyst": "Гистерезис (в градусах)", + "turboFactor": "Коэфф. турбо режима" }, "emergency": { - "desc": "Аварийный режим активируется автоматически, если «ПИД» или «ПЗА» не могут рассчитать уставку теплоносителя:
- если «ПЗА» включен и датчик наружной температуры отключен;
- если включен «ПИД» или OT опция «Передать управление отоплением котлу» и датчик температуры в помещении отключен.
Примечание: При сбое сети или MQTT датчики с типом «Вручную через MQTT/API» будут находиться в состоянии ОТКЛЮЧЕН.", + "desc": "Аварийный режим активируется автоматически, если «ПИД» или «ПЗА» не могут рассчитать уставку теплоносителя:
- если «ПЗА» включен и датчик наружной температуры отключен;
- если включен «ПИД» или OT опция «Передать управление отоплением котлу» и датчик внутренней температуры отключен.
Примечание: При сбое сети или MQTT датчики с типом «Вручную через MQTT/API» будут находиться в состоянии ОТКЛЮЧЕН.", "target": { "title": "Целевая температура", diff --git a/src_data/pages/settings.html b/src_data/pages/settings.html index 492ec01..9778efc 100644 --- a/src_data/pages/settings.html +++ b/src_data/pages/settings.html @@ -166,10 +166,17 @@ - +
+ + + +
@@ -283,7 +290,7 @@
@@ -904,6 +911,7 @@ "max": data.system.unitSystem == 0 ? 100 : 212 }); setInputValue('#heating-hysteresis', data.heating.hysteresis); + setInputValue('#heating-turbo-factor', data.heating.turboFactor); setBusy('#heating-settings-busy', '#heating-settings', false); // DHW