temperature_fan: Fix. Temperature fan min speed should be used (#1405)
Signed-off-by: Douglas Hammond <wizhippo@gmail.com>
This commit is contained in:
parent
5913170b6b
commit
c105adc80b
|
@ -626,20 +626,20 @@
|
||||||
# The default is 1.0.
|
# The default is 1.0.
|
||||||
#min_speed: 0.3
|
#min_speed: 0.3
|
||||||
# The minimum fan speed (expressed as a value from 0.0 to 1.0) that
|
# The minimum fan speed (expressed as a value from 0.0 to 1.0) that
|
||||||
# the fan will be set to when the sensor temperature is the set
|
# the fan will be set to for PID temperature fans.
|
||||||
# value. The default is 0.3.
|
# The default is 0.3.
|
||||||
#control: watermark
|
#control: watermark
|
||||||
# Control algorithm (either watermark or pid). This parameter must
|
# Control algorithm (either watermark or pid). This parameter must
|
||||||
# be provided.
|
# be provided.
|
||||||
#pid_Kp: 40
|
#pid_Kp: 40
|
||||||
# Kp is the "proportional" constant for the pid. This parameter must
|
# Kp is the "proportional" constant for the pid. This parameter must
|
||||||
# be provided for PID heaters.
|
# be provided for PID temperature fans.
|
||||||
#pid_Ki: 0.2
|
#pid_Ki: 0.2
|
||||||
# Ki is the "integral" constant for the pid. This parameter must be
|
# Ki is the "integral" constant for the pid. This parameter must be
|
||||||
# provided for PID heaters.
|
# provided for PID temperature fans.
|
||||||
#pid_Kd: 0.1
|
#pid_Kd: 0.1
|
||||||
# Kd is the "derivative" constant for the pid. This parameter must
|
# Kd is the "derivative" constant for the pid. This parameter must
|
||||||
# be provided for PID heaters.
|
# be provided for PID temperature fans.
|
||||||
#pid_deriv_time: 2.0
|
#pid_deriv_time: 2.0
|
||||||
# A time value (in seconds) over which the derivative in the pid
|
# A time value (in seconds) over which the derivative in the pid
|
||||||
# will be smoothed to reduce the impact of measurement noise. The
|
# will be smoothed to reduce the impact of measurement noise. The
|
||||||
|
|
|
@ -6,6 +6,10 @@ All dates in this document are approximate.
|
||||||
|
|
||||||
# Changes
|
# Changes
|
||||||
|
|
||||||
|
20190328: The min_speed value in [temperature_fan] config
|
||||||
|
will now be respected and the fan will always run at this
|
||||||
|
speed or higher in PID mode.
|
||||||
|
|
||||||
20190322: The default value for "driver_HEND" in [tmc2660] config
|
20190322: The default value for "driver_HEND" in [tmc2660] config
|
||||||
sections was changed from 6 to 3. The "driver_VSENSE" field was
|
sections was changed from 6 to 3. The "driver_VSENSE" field was
|
||||||
removed (it is now automatically calculated from run_current).
|
removed (it is now automatically calculated from run_current).
|
||||||
|
|
|
@ -15,7 +15,6 @@ class TemperatureFan:
|
||||||
self.name = config.get_name().split()[1]
|
self.name = config.get_name().split()[1]
|
||||||
self.printer = config.get_printer()
|
self.printer = config.get_printer()
|
||||||
self.fan = fan.PrinterFan(config, default_shutdown_speed=1.)
|
self.fan = fan.PrinterFan(config, default_shutdown_speed=1.)
|
||||||
self.mcu = self.fan.mcu_fan.get_mcu()
|
|
||||||
self.min_temp = config.getfloat('min_temp', minval=KELVIN_TO_CELCIUS)
|
self.min_temp = config.getfloat('min_temp', minval=KELVIN_TO_CELCIUS)
|
||||||
self.max_temp = config.getfloat('max_temp', above=self.min_temp)
|
self.max_temp = config.getfloat('max_temp', above=self.min_temp)
|
||||||
self.sensor = self.printer.lookup_object('heater').setup_sensor(config)
|
self.sensor = self.printer.lookup_object('heater').setup_sensor(config)
|
||||||
|
@ -36,8 +35,10 @@ class TemperatureFan:
|
||||||
self.next_speed_time = 0.
|
self.next_speed_time = 0.
|
||||||
self.last_speed_value = 0.
|
self.last_speed_value = 0.
|
||||||
def set_speed(self, read_time, value):
|
def set_speed(self, read_time, value):
|
||||||
if value < self.min_speed:
|
if value <= 0.:
|
||||||
value = 0.
|
value = 0.
|
||||||
|
elif value < self.min_speed:
|
||||||
|
value = self.min_speed
|
||||||
if self.target_temp <= 0.:
|
if self.target_temp <= 0.:
|
||||||
value = 0.
|
value = 0.
|
||||||
if ((read_time < self.next_speed_time or not self.last_speed_value)
|
if ((read_time < self.next_speed_time or not self.last_speed_value)
|
||||||
|
@ -53,6 +54,10 @@ class TemperatureFan:
|
||||||
self.control.temperature_callback(read_time, temp)
|
self.control.temperature_callback(read_time, temp)
|
||||||
def get_temp(self, eventtime):
|
def get_temp(self, eventtime):
|
||||||
return self.last_temp, self.target_temp
|
return self.last_temp, self.target_temp
|
||||||
|
def get_min_speed(self):
|
||||||
|
return self.min_speed
|
||||||
|
def get_max_speed(self):
|
||||||
|
return self.max_speed
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
# Bang-bang control algo
|
# Bang-bang control algo
|
||||||
|
@ -64,17 +69,18 @@ class ControlBangBang:
|
||||||
self.max_delta = config.getfloat('max_delta', 2.0, above=0.)
|
self.max_delta = config.getfloat('max_delta', 2.0, above=0.)
|
||||||
self.heating = False
|
self.heating = False
|
||||||
def temperature_callback(self, read_time, temp):
|
def temperature_callback(self, read_time, temp):
|
||||||
|
current_temp, target_temp = self.temperature_fan.get_temp(read_time)
|
||||||
if (self.heating
|
if (self.heating
|
||||||
and temp >= self.temperature_fan.target_temp+self.max_delta):
|
and temp >= target_temp+self.max_delta):
|
||||||
self.heating = False
|
self.heating = False
|
||||||
elif (not self.heating
|
elif (not self.heating
|
||||||
and temp <= self.temperature_fan.target_temp-self.max_delta):
|
and temp <= target_temp-self.max_delta):
|
||||||
self.heating = True
|
self.heating = True
|
||||||
if self.heating:
|
if self.heating:
|
||||||
self.temperature_fan.set_speed(read_time, 0.)
|
self.temperature_fan.set_speed(read_time, 0.)
|
||||||
else:
|
else:
|
||||||
self.temperature_fan.set_speed(read_time,
|
self.temperature_fan.set_speed(read_time,
|
||||||
self.temperature_fan.max_speed)
|
self.temperature_fan.get_max_speed())
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
# Proportional Integral Derivative (PID) control algo
|
# Proportional Integral Derivative (PID) control algo
|
||||||
|
@ -90,14 +96,15 @@ class ControlPID:
|
||||||
self.Ki = config.getfloat('pid_Ki') / PID_PARAM_BASE
|
self.Ki = config.getfloat('pid_Ki') / PID_PARAM_BASE
|
||||||
self.Kd = config.getfloat('pid_Kd') / PID_PARAM_BASE
|
self.Kd = config.getfloat('pid_Kd') / PID_PARAM_BASE
|
||||||
self.min_deriv_time = config.getfloat('pid_deriv_time', 2., above=0.)
|
self.min_deriv_time = config.getfloat('pid_deriv_time', 2., above=0.)
|
||||||
imax = config.getfloat('pid_integral_max', temperature_fan.max_speed,
|
imax = config.getfloat('pid_integral_max',
|
||||||
minval=0.)
|
self.temperature_fan.get_max_speed(), minval=0.)
|
||||||
self.temp_integ_max = imax / self.Ki
|
self.temp_integ_max = imax / self.Ki
|
||||||
self.prev_temp = AMBIENT_TEMP
|
self.prev_temp = AMBIENT_TEMP
|
||||||
self.prev_temp_time = 0.
|
self.prev_temp_time = 0.
|
||||||
self.prev_temp_deriv = 0.
|
self.prev_temp_deriv = 0.
|
||||||
self.prev_temp_integ = 0.
|
self.prev_temp_integ = 0.
|
||||||
def temperature_callback(self, read_time, temp):
|
def temperature_callback(self, read_time, temp):
|
||||||
|
current_temp, target_temp = self.temperature_fan.get_temp(read_time)
|
||||||
time_diff = read_time - self.prev_temp_time
|
time_diff = read_time - self.prev_temp_time
|
||||||
# Calculate change of temperature
|
# Calculate change of temperature
|
||||||
temp_diff = temp - self.prev_temp
|
temp_diff = temp - self.prev_temp
|
||||||
|
@ -107,14 +114,15 @@ class ControlPID:
|
||||||
temp_deriv = (self.prev_temp_deriv * (self.min_deriv_time-time_diff)
|
temp_deriv = (self.prev_temp_deriv * (self.min_deriv_time-time_diff)
|
||||||
+ temp_diff) / self.min_deriv_time
|
+ temp_diff) / self.min_deriv_time
|
||||||
# Calculate accumulated temperature "error"
|
# Calculate accumulated temperature "error"
|
||||||
temp_err = self.temperature_fan.target_temp - temp
|
temp_err = target_temp - temp
|
||||||
temp_integ = self.prev_temp_integ + temp_err * time_diff
|
temp_integ = self.prev_temp_integ + temp_err * time_diff
|
||||||
temp_integ = max(0., min(self.temp_integ_max, temp_integ))
|
temp_integ = max(0., min(self.temp_integ_max, temp_integ))
|
||||||
# Calculate output
|
# Calculate output
|
||||||
co = self.Kp*temp_err + self.Ki*temp_integ - self.Kd*temp_deriv
|
co = self.Kp*temp_err + self.Ki*temp_integ - self.Kd*temp_deriv
|
||||||
bounded_co = max(0., min(self.temperature_fan.max_speed, co))
|
bounded_co = max(0., min(self.temperature_fan.get_max_speed(), co))
|
||||||
self.temperature_fan.set_speed(
|
self.temperature_fan.set_speed(
|
||||||
read_time, self.temperature_fan.max_speed - bounded_co)
|
read_time, max(self.temperature_fan.get_min_speed(),
|
||||||
|
self.temperature_fan.get_max_speed() - bounded_co))
|
||||||
# Store state for next measurement
|
# Store state for next measurement
|
||||||
self.prev_temp = temp
|
self.prev_temp = temp
|
||||||
self.prev_temp_time = read_time
|
self.prev_temp_time = read_time
|
||||||
|
|
Loading…
Reference in New Issue