aboutsummaryrefslogtreecommitdiffstats
path: root/klippy/extras/filament_motion_sensor.py
diff options
context:
space:
mode:
authorTheJoshW <46292721+TheJoshW@users.noreply.github.com>2021-03-15 12:36:19 +1100
committerGitHub <noreply@github.com>2021-03-14 21:36:19 -0400
commitbf8f7133b43cbb98b4a9515e43e1a1b7d71e04ea (patch)
treed1f778bb9736b70b18925a36b971c52e400898b9 /klippy/extras/filament_motion_sensor.py
parentd77928b17ba6b32189033b3d6decdb5bcc7c342c (diff)
downloadkutter-bf8f7133b43cbb98b4a9515e43e1a1b7d71e04ea.tar.gz
kutter-bf8f7133b43cbb98b4a9515e43e1a1b7d71e04ea.tar.xz
kutter-bf8f7133b43cbb98b4a9515e43e1a1b7d71e04ea.zip
filament_motion_sensor: Add filament_motion_sensor (#3857)
Add functionality to support a Filament Motion Sensor for detecting extruder jams as well as runouts. Works by an encoder toggling the switch_pin 0/1 as the filament is pulled through the sensor. Signed-off-by: Joshua Wherrett <thejoshw.code@gmail.com>
Diffstat (limited to 'klippy/extras/filament_motion_sensor.py')
-rw-r--r--klippy/extras/filament_motion_sensor.py76
1 files changed, 76 insertions, 0 deletions
diff --git a/klippy/extras/filament_motion_sensor.py b/klippy/extras/filament_motion_sensor.py
new file mode 100644
index 00000000..a3efa436
--- /dev/null
+++ b/klippy/extras/filament_motion_sensor.py
@@ -0,0 +1,76 @@
+# Filament Motion Sensor Module
+#
+# Copyright (C) 2021 Joshua Wherrett <thejoshw.code@gmail.com>
+#
+# This file may be distributed under the terms of the GNU GPLv3 license.
+import logging
+from . import filament_switch_sensor
+
+CHECK_RUNOUT_TIMEOUT = .250
+
+class EncoderSensor:
+ def __init__(self, config):
+ # Read config
+ self.printer = config.get_printer()
+ switch_pin = config.get('switch_pin')
+ self.extruder_name = config.get('extruder')
+ self.detection_length = config.getfloat(
+ 'detection_length', 7., above=0.)
+ # Configure pins
+ buttons = self.printer.load_object(config, 'buttons')
+ buttons.register_buttons([switch_pin], self.encoder_event)
+ # Get printer objects
+ self.reactor = self.printer.get_reactor()
+ self.runout_helper = filament_switch_sensor.RunoutHelper(config)
+ self.extruder = None
+ self.estimated_print_time = None
+ # Initialise internal state
+ self.filament_runout_pos = None
+ # Register commands and event handlers
+ self.printer.register_event_handler('klippy:ready',
+ self._handle_ready)
+ self.printer.register_event_handler('idle_timeout:printing',
+ self._handle_printing)
+ self.printer.register_event_handler('idle_timeout:ready',
+ self._handle_not_printing)
+ self.printer.register_event_handler('idle_timeout:idle',
+ self._handle_not_printing)
+ def _update_filament_runout_pos(self, eventtime=None):
+ if eventtime is None:
+ eventtime = self.reactor.monotonic()
+ self.filament_runout_pos = (
+ self._get_extruder_pos(eventtime) +
+ self.detection_length)
+ def _handle_ready(self):
+ self.extruder = self.printer.lookup_object(self.extruder_name)
+ self.estimated_print_time = (
+ self.printer.lookup_object('mcu').estimated_print_time)
+ self._update_filament_runout_pos()
+ self._extruder_pos_update_timer = self.reactor.register_timer(
+ self._extruder_pos_update_event)
+ def _handle_printing(self, print_time):
+ self.reactor.update_timer(self._extruder_pos_update_timer,
+ self.reactor.NOW)
+ def _handle_not_printing(self, print_time):
+ self.reactor.update_timer(self._extruder_pos_update_timer,
+ self.reactor.NEVER)
+ def _get_extruder_pos(self, eventtime=None):
+ if eventtime is None:
+ eventtime = self.reactor.monotonic()
+ print_time = self.estimated_print_time(eventtime)
+ return self.extruder.find_past_position(print_time)
+ def _extruder_pos_update_event(self, eventtime):
+ extruder_pos = self._get_extruder_pos(eventtime)
+ # Check for filament runout
+ self.runout_helper.note_filament_present(
+ extruder_pos < self.filament_runout_pos)
+ return eventtime + CHECK_RUNOUT_TIMEOUT
+ def encoder_event(self, eventtime, state):
+ if self.extruder is not None:
+ self._update_filament_runout_pos(eventtime)
+ # Check for filament insertion
+ # Filament is always assumed to be present on an encoder event
+ self.runout_helper.note_filament_present(True)
+
+def load_config_prefix(config):
+ return EncoderSensor(config)