diff --git a/examples/calibrate-offsets.cfg b/examples/calibrate-offsets.cfg index 19416a8..41e879e 100644 --- a/examples/calibrate-offsets.cfg +++ b/examples/calibrate-offsets.cfg @@ -39,6 +39,21 @@ gcode: M104 S0 {% endfor %} +[gcode_macro CALIBRATE_STORE_TOOL_OFFSETS] +gcode: + T0 + CALIBRATE_MOVE_OVER_PROBE + M109 S150 # Heat up as much as possible without oozing to account for any thermal deformations + TOOL_LOCATE_SENSOR + M104 S0 + # Other tools + {% for tool in [1,2,3] %} + T{tool} + M109 S150 + TOOL_CALIBRATE_STORE_TOOL_OFFSET TOOL_NUMBER={tool} + M104 S0 + {% endfor %} + [gcode_macro CALIBRATE_NOZZLE_PROBE_OFFSET] gcode: CALIBRATE_MOVE_OVER_PROBE diff --git a/examples/tapchanger/toolchanger.cfg b/examples/tapchanger/toolchanger.cfg index 893708e..97c0c27 100644 --- a/examples/tapchanger/toolchanger.cfg +++ b/examples/tapchanger/toolchanger.cfg @@ -76,7 +76,12 @@ # Wait for temp before actually picking up the tool, while the nozzle is resting on it's pad. {% if tool.extruder %} - M109 T{tool.tool_number} S{printer[tool.extruder].target|int} + {% set deltaT = printer[tool.extruder].target-printer[tool.extruder].temperature|int %} + {% if deltaT > 10 %} + M109 T{tool.tool_number} S{printer[tool.extruder].target|int} + {% else %} + M104 T{tool.tool_number} S{printer[tool.extruder].target|int} + {% endif %} {% endif %} # Run the path in reverse {% for pos in path|reverse %} diff --git a/klipper/extras/tool_probe.py b/klipper/extras/tool_probe.py index 607858d..c6aa546 100644 --- a/klipper/extras/tool_probe.py +++ b/klipper/extras/tool_probe.py @@ -66,6 +66,8 @@ def __init__(self, config, mcu_probe): minval=0.) self.samples_retries = config.getint('samples_tolerance_retries', 0, minval=0) + # Settling sample support + self.settling_sample = config.getboolean('settling_sample', False) # Session state self.multi_probe_pending = False self.results = [] @@ -94,6 +96,15 @@ def end_probe_session(self): self.results = [] self.multi_probe_pending = False self.mcu_probe.multi_probe_end() + def _run_settling_probe(self, gcmd): + """Perform a settling probe before the main probe.""" + toolhead = self.printer.lookup_object('toolhead') + probexy = toolhead.get_position()[:2] + speed = gcmd.get_float("SETTLING_SPEED", self.speed, above=0.) + pos = self._probe(speed) + # Retract after settling + toolhead.manual_move(probexy + [pos[2] + self.sample_retract_dist], self.lift_speed) + gcmd.respond_info("Sample throwed") def get_probe_params(self, gcmd=None): if gcmd is None: gcmd = self.dummy_gcode_cmd @@ -139,6 +150,8 @@ def run_probe(self, gcmd): if not self.multi_probe_pending: self._probe_state_error() params = self.get_probe_params(gcmd) + if self.settling_sample: + self._run_settling_probe(gcmd) toolhead = self.printer.lookup_object('toolhead') probexy = toolhead.get_position()[:2] retries = 0 diff --git a/klipper/extras/tools_calibrate.py b/klipper/extras/tools_calibrate.py index 9cf2d1a..5056869 100644 --- a/klipper/extras/tools_calibrate.py +++ b/klipper/extras/tools_calibrate.py @@ -4,6 +4,7 @@ # Sourced from https://github.com/ben5459/Klipper_ToolChanger/blob/master/probe_multi_axis.py import logging +import os direction_types = {'x+': [0, +1], 'x-': [0, -1], 'y+': [1, +1], 'y-': [1, -1], 'z+': [2, +1], 'z-': [2, -1]} @@ -51,6 +52,9 @@ def __init__(self, config): self.gcode.register_command('TOOL_CALIBRATE_TOOL_OFFSET', self.cmd_TOOL_CALIBRATE_TOOL_OFFSET, desc=self.cmd_TOOL_CALIBRATE_TOOL_OFFSET_help) + self.gcode.register_command('TOOL_CALIBRATE_STORE_TOOL_OFFSET', + self.cmd_TOOL_CALIBRATE_STORE_TOOL_OFFSET, + desc=self.cmd_TOOL_CALIBRATE_STORE_TOOL_OFFSET_help) self.gcode.register_command('TOOL_CALIBRATE_SAVE_TOOL_OFFSET', self.cmd_TOOL_CALIBRATE_SAVE_TOOL_OFFSET, desc=self.cmd_TOOL_CALIBRATE_SAVE_TOOL_OFFSET_help) @@ -132,6 +136,31 @@ def cmd_TOOL_CALIBRATE_TOOL_OFFSET(self, gcmd): % (self.last_result[0], self.last_result[1], self.last_result[2])) + cmd_TOOL_CALIBRATE_STORE_TOOL_OFFSET_help = "Calibrate current tool offset relative to tool 0 and save results" + + def cmd_TOOL_CALIBRATE_STORE_TOOL_OFFSET(self, gcmd): + tool_number = gcmd.get_int('TOOL_NUMBER') + if not self.sensor_location: + raise gcmd.error("No recorded sensor location, please run TOOL_LOCATE_SENSOR first") + + location = self.locate_sensor(gcmd) + self.last_result = [loc - sensor_loc for loc, sensor_loc in zip(location, self.sensor_location)] + + tool_offset_info = "Tool offset for tool {} is {:.6f},{:.6f},{:.6f}".format( + tool_number, *self.last_result) + self.gcode.respond_info(tool_offset_info) + + home_dir = os.path.expanduser("~") + results_dir = os.path.join(home_dir, "printer_data/config/tools_calibrate_results") + + os.makedirs(results_dir, exist_ok=True) + + filename = os.path.join(results_dir, f"tool_{tool_number}_offset.txt") + + with open(filename, "a") as f: + f.write("Tool {} offset is {:.6f},{:.6f},{:.6f}\n".format( + tool_number, *self.last_result)) + cmd_TOOL_CALIBRATE_SAVE_TOOL_OFFSET_help = "Save tool offset calibration to config" def cmd_TOOL_CALIBRATE_SAVE_TOOL_OFFSET(self, gcmd):