Skip to content

Commit

Permalink
.
Browse files Browse the repository at this point in the history
  • Loading branch information
Zeanon committed Dec 2, 2023
1 parent 9a06f86 commit 01883b8
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 0 deletions.
6 changes: 6 additions & 0 deletions docs/Config_Reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -2906,6 +2906,12 @@ a shutdown_speed equal to max_power.
# The fan speed (expressed as a value from 0.0 to 1.0) that the fan
# will be set to when its associated heater is enabled. The default
# is 1.0
#min_rpm: 0
# The minimum expected fan speed in RPM. Klipper shuts down if the
# fan is enabled but fan RPM reading from the tachometer is below
# this value. This parameter is optional but tachometer_pin must
# be specified for this parameter to be valid.
```
```
### [controller_fan]
Expand Down
31 changes: 31 additions & 0 deletions klippy/extras/heater_fan.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
# Copyright (C) 2016-2020 Kevin O'Connor <[email protected]>
#
# This file may be distributed under the terms of the GNU GPLv3 license.
import logging
from . import fan

PIN_MIN_TIME = 0.100
SAFETY_CHECK_INIT_TIME = 3.

class PrinterHeaterFan:
def __init__(self, config):
Expand All @@ -22,6 +24,13 @@ def __init__(self, config):
self.fan_speed = config.getfloat("fan_speed", 1., minval=0., maxval=1.)
self.last_speed = 0.
self.enabled = 1
self.name = config.get_name().split()[-1]
self.num_err = 0
self.max_err = 3
self.min_rpm = config.getint("min_rpm", 0, minval=0)
if self.min_rpm > 0 and self.fan.tachometer._freq_counter is None:
raise config.error(
"'tachometer_pin' must be specified before enabling `min_rpm`")
gcode = self.printer.lookup_object('gcode')
gcode.register_mux_command(
"SET_HEATER_FAN", "HEATER_FAN", self.name,
Expand All @@ -32,6 +41,9 @@ def handle_ready(self):
self.heaters = [pheaters.lookup_heater(n) for n in self.heater_names]
reactor = self.printer.get_reactor()
reactor.register_timer(self.callback, reactor.monotonic()+PIN_MIN_TIME)
if self.min_rpm > 0:
reactor.register_timer(
self.fan_check, reactor.monotonic()+SAFETY_CHECK_INIT_TIME)
def get_status(self, eventtime):
return self.fan.get_status(eventtime)
def callback(self, eventtime):
Expand All @@ -58,6 +70,25 @@ def cmd_SET_HEATER_FAN(self, gcmd):
curtime = self.printer.get_reactor().monotonic()
print_time = self.fan.get_mcu().estimated_print_time(curtime)
self.fan.set_speed(print_time + PIN_MIN_TIME, 0.0)
def fan_check(self, eventtime):
rpm = self.fan.tachometer.get_status(eventtime)['rpm']
has_err = False
if rpm is not None:
for heater in self.heaters:
current_temp, target_temp = heater.get_temp(eventtime)
if current_temp > self.heater_temp and rpm < self.min_rpm:
has_err = True
if has_err:
self.num_err += 1
if self.num_err > self.max_err:
msg = "'%s' spinning below minimum safe speed of %d rev/min" % (
self.name, self.min_rpm)
logging.error(msg)
self.printer.invoke_shutdown(msg)
return self.printer.get_reactor().NEVER
else:
self.num_err = 0
return eventtime + 1.5

def load_config_prefix(config):
return PrinterHeaterFan(config)

0 comments on commit 01883b8

Please sign in to comment.