PID control for chamber temperature fan

Basic Information:

Printer Model: Voron2.4_350mm_Fluidd
MCU / Printerboard: BTT Octopus 1.1
klippy.log klippy.log (2.0 MB)

Describe your issue:

I have an additional chamber temperature sensor controlling temperature_fan if the temperature is above 35C or it can be also controlled adjusted using g-code. The problem with this setup is that the chamber is experiencing quick temperature changes that can affect the quality of print. I attempted to implement PID control but lack of coding knowledge makes the temperature_fan work as heater: if temperature is lower than target (35C) it turns on the fan. My goal is to reverse PID: if temperature is higher that the target => turn on (PID) the fan.
Can someone please tell me if it’s possible at all and if possible how to implement that?
Here is the part of the config:

[temperature_fan chamber]
pin: PD13
max_power: 1.0
shutdown_speed: 0.0
kick_start_time: 5.0
sensor_type: ATC Semitec 104GT-2
sensor_pin: PF5
min_temp: 0
max_temp: 70
target_temp: 35.0
control: watermark
#control: pid
#hardware_pwm: true
#pid_kp: 40.0
#pid_ki: 5.0
#pid_kd: 0.01
gcode_id: C

[gcode_macro M141]

Hi! Basically, it makes no sense to use a PID controler here. Much better would be a 2-point-controle (“zweipunktregler”, google & translate this!) sometimes known as “bang-bang” controle. Why?:

  • Temerature changes slowly in terms of controler frequence (rather in s than in ms)
  • You do not nedd at least the “D” Part of the PID (this is an extra impulse if temp would change some degr during a few controler loops e.g. ms not s!), so a PI controle is at max all you need*.

2-Point It is very simple:
If (act_temp >= max_temp) Turn_on_fan 100%
if (act_temp< max_temp) Turn_off_fan

you will se that this little code controls temp pretty good. What you could add is a “window” where the fan will work unless the temp is lower than max_temp, so the fan will not frequently start and stop

maxtemp = 35,0; //35 deg C
offset = 3; // Fan stops at maxtemp-offset if temp is falling.
if (acttemp < lasttemp){ // Temp is falling
if (acttemp < (maxtemp-offset)){
} else { // rising or same
if (acttemp>=maxtemp) {
lasttemp = acttemp; // you should add some damping here like a value of a small ring buffer
wait (1000); //wait 1 or …5 seconds
Story: Temp start rising. at 35 deg C, the fan start to work (full speed, you do not need 35% or so…). Temp overshoots a little (depends on the weight of your printer) and hopefully drops. Fan will work untill temp reaches 32deg C below this, it will stop. It will stay stopped, until temp reaches again 35 deg. By adjusting “offset”, you will get a nice controle within a decent corridor of temp, depening on the weight of your printer (better: of all material inside of the housing, including the housing) and the amount of air your fan(s) may bring in. For a Voron, you need some larger fans (12cm) to see any reaction…

A very big problem for you will be how to measure the “temperature” inside your housing. You can do this at one point in space, but is this “the temperature”???

*You may notice, that Klipper uses PID controle to work with bed and hotend. But you will also notice, that the D-Part is often very high (some hundrets) against other values. That turns out, that there is no need for the D. If you’d set KiD to zero, nothing will happen (since there is no quick change of temp during some few controle loops unless you cut a cable).

See my config (Voron 2.4r2@350mm), 650W table heater
## pid_kp = 39.759 // This is the constant amplification factor
# pid_ki = 1.710 // This is the time dependent amplification factor, needed to close the gap between real temp and const application factor.
#*# pid_kd = 231.096 // this is the gradient amplication factor and it is nonsense!

Example, where a D-Part could make sense: During a print, you open the cabinet and icy air comes in. But: what is the weight of air? Nothing (more or less), so your printer will not recognizes this and btw could not react on this either.

1 Like

Thank you for your help.
I will give it a try.