For some reason, on the working driver for the Heat pump, I get strange results for values between 10-12 and 30-32.
Sometimes I get power_stage 7 for pid_value from 10-12
Can anybody explain why?
But now, between each case there is no value for power_stage, and this is exactly where your problems happen. And you do not show what happens with the value when it isn’t defined.
I like to add deadband
If pid value is aroound switching point lets assuming pid is 11 i voud like to svitch to stage 2 when pid raise to 12
And switch down to stage 1 when pid drops below 10. And so on for every stage switch.
In that case there would be no quck switching between stages.
Hi
Thanks for your suggestion.
I did approach with this approach but not with filters I get strange behaviour with that.
I add code to my PID calculation.
I am sure that another way could do it but this way is simpler to understand for me.
So thanks for pointing me in the right direction.
- lambda: |-
static float I_integral = 0;
static float previous_odklon = 0;
static float previous_pid_value = 0; // Prejšnji PID izhod
int power_stage;
// Preveri, ali je toplotna črpalka vklopljena (VklopHP)
if ((id(HP_ON_OFF_fiz).state == HIGH || id(HP_ON_OFF_virt).state == HIGH) && id(Delov_hp_txt).state != "PowerOFF" && id(MV_TG_gipo).state == LOW) {
float Trenutna_temp_HP = id(TempHP).state;
// Preveri, da Trenutna_temp_HP ni NaN
if (isnan(Trenutna_temp_HP)) {
ESP_LOGE("PID", "TempHP je NaN, preskočam izračune.");
power_stage = 0;
return; // Izpusti ostalo kodo
}
float setpoint = id(NastavitevTempHp).state; // Preberi setpoint iz number entitete
// Preveri, da setpoint ni NaN
if (isnan(setpoint)) {
ESP_LOGE("PID", "Setpoint je NaN, preskočam izračune.");
return; // Izpusti ostalo kodo
}
float odklon = setpoint - Trenutna_temp_HP;
// Preberi vrednosti P, I, D komponent iz number entitet
float kp = id(kp_value).state;
float ki = id(ki_value).state;
float kd = id(kd_value).state;
// P komponenta
float P_proportional = odklon * kp;
// I komponenta
I_integral += odklon * ki;
if (I_integral > 100) I_integral = 100; // Omejitev I_integrala
if (I_integral < -10) I_integral = -10;
// D komponenta
float D_derivative = (odklon - previous_odklon) * kd;
previous_odklon = odklon;
// Končni izračun PID
float pid_value = P_proportional + I_integral + D_derivative;
// Omeji vrednosti PID (med 0 in 100)
if (pid_value > 100) pid_value = 100;
if (pid_value < 0) pid_value = 0;
// Pretvorba PID vrednosti v 8 stopenj moči
// Posodobi PID vrednost samo, če se spremeni za več kot 1
if (fabs(pid_value - previous_pid_value) > 0.5) {
previous_pid_value = pid_value; // Posodobi prejšnji PID izhod
} else {
pid_value = previous_pid_value; // Ohrani prejšnji PID izhod
}
int power_stage = 0;
if (pid_value >= 90) {
power_stage = 7; // 100%
} else if (pid_value >= 70) {
power_stage = 6; // 90%
} else if (pid_value >= 60) {
power_stage = 5; // 70%
} else if (pid_value >= 50) {
power_stage = 4; // 60%
} else if (pid_value >= 40) {
power_stage = 3; // 50%
} else if (pid_value >= 30) {
power_stage = 2; // 40%
} else if (pid_value >= 10) {
power_stage = 1; // 30%
} else {
power_stage = 0; // 0% (izklop)
}