screws_tilt_adjust: Add DIRECTION parameter to SCREWS_TILT_CALCULATE (#4357)

Signed-off-by: Matthew Lloyd <github@matthewlloyd.net>
This commit is contained in:
Matthew Lloyd 2021-06-22 15:18:05 -04:00 committed by GitHub
parent f1091a484b
commit c2907c998c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 59 additions and 27 deletions

View File

@ -456,12 +456,13 @@ The following commands are available when the
[screws_tilt_adjust config section](Config_Reference.md#screws_tilt_adjust) [screws_tilt_adjust config section](Config_Reference.md#screws_tilt_adjust)
is enabled (also see the is enabled (also see the
[manual level guide](Manual_Level.md#adjusting-bed-leveling-screws-using-the-bed-probe)): [manual level guide](Manual_Level.md#adjusting-bed-leveling-screws-using-the-bed-probe)):
- `SCREWS_TILT_CALCULATE [<probe_parameter>=<value>]`: This command - `SCREWS_TILT_CALCULATE [DIRECTION=CW|CCW] [<probe_parameter>=<value>]`:
will invoke the bed screws adjustment tool. It will command the This command will invoke the bed screws adjustment tool. It will command the
nozzle to different locations (as defined in the config file) nozzle to different locations (as defined in the config file)
probing the z height and calculate the number of knob turns to probing the z height and calculate the number of knob turns to
adjust the bed level. See the PROBE command for details on the adjust the bed level. If DIRECTION is specified, the knob turns will all
optional probe parameters. be in the same direction, clockwise (CW) or counterclockwise (CCW).
See the PROBE command for details on the optional probe parameters.
IMPORTANT: You MUST always do a G28 before using this command. IMPORTANT: You MUST always do a G28 before using this command.
## Z Tilt ## Z Tilt

View File

@ -163,17 +163,18 @@ screw_thread: CW-M3
``` ```
The screw1 is always the reference point for the others, so the system The screw1 is always the reference point for the others, so the system
assumes that screw1 is in the correct height. Always run `G28` first assumes that screw1 is at the correct height. Always run `G28` first
and then run `SCREWS_TILT_CALCULATE` - it should produce output and then run `SCREWS_TILT_CALCULATE` - it should produce output
similar to: similar to:
``` ```
Send: G28 Send: G28
Recv: ok Recv: ok
Send: SCREWS_TILT_CALCULATE Send: SCREWS_TILT_CALCULATE
Recv: // front left screw (Base): X -5.0, Y 30.0, Z 2.48750 Recv: // 01:20 means 1 full turn and 20 minutes, CW=clockwise, CCW=counter-clockwise
Recv: // front right screw : X 155.0, Y 30.0, Z 2.36000 : Adjust -> CW 01:15 Recv: // front left screw (base) : x=-5.0, y=30.0, z=2.48750
Recv: // rear right screw : X 155.0, Y 190.0, Z 2.71500 : Adjust -> CCW 00:50 Recv: // front right screw : x=155.0, y=30.0, z=2.36000 : adjust CW 01:15
Recv: // read left screw : X -5.0, Y 190.0, Z 2.47250 : Adjust -> CW 00:02 Recv: // rear right screw : y=155.0, y=190.0, z=2.71500 : adjust CCW 00:50
Recv: // read left screw : x=-5.0, y=190.0, z=2.47250 : adjust CW 00:02
Recv: ok Recv: ok
``` ```
This means that: This means that:
@ -198,3 +199,12 @@ the mesh was created. For example, `SCREWS_TILT_CALCULATE MAX_DEVIATION=0.01`
can be added to the custom start gcode of the slicer before the mesh is loaded. can be added to the custom start gcode of the slicer before the mesh is loaded.
It will abort the print if the configured limit is exceeded (0.01mm in this It will abort the print if the configured limit is exceeded (0.01mm in this
example), giving the user a chance to adjust the screws and restart the print. example), giving the user a chance to adjust the screws and restart the print.
The `DIRECTION` parameter is useful if you can turn your bed adjustment
screws in one direction only. For example, you might have screws that start
tightened in their lowest (or highest) possible position, which can only be
turned in a single direction, to raise (or lower) the bed. If you can only
turn the screws clockwise, run `SCREWS_TILT_CALCULATE DIRECTION=CW`. If you can
only turn them counter-clockwise, run `SCREWS_TILT_CALCULATE DIRECTION=CCW`.
A suitable reference point will be chosen such that the bed can be leveled
by turning all the screws in the given direction.

View File

@ -1,6 +1,7 @@
# Helper script to adjust bed screws tilt using Z probe # Helper script to adjust bed screws tilt using Z probe
# #
# Copyright (C) 2019 Rui Caridade <rui.mcbc@gmail.com> # Copyright (C) 2019 Rui Caridade <rui.mcbc@gmail.com>
# Copyright (C) 2021 Matthew Lloyd <github@matthewlloyd.net>
# #
# This file may be distributed under the terms of the GNU GPLv3 license. # This file may be distributed under the terms of the GNU GPLv3 license.
import math import math
@ -53,44 +54,64 @@ class ScrewsTiltAdjust:
def cmd_SCREWS_TILT_CALCULATE(self, gcmd): def cmd_SCREWS_TILT_CALCULATE(self, gcmd):
self.max_diff = gcmd.get_float("MAX_DEVIATION", None) self.max_diff = gcmd.get_float("MAX_DEVIATION", None)
# Option to force all turns to be in the given direction (CW or CCW)
direction = gcmd.get("DIRECTION", default=None)
if direction is not None:
direction = direction.upper()
if direction not in ('CW', 'CCW'):
raise gcmd.error(
"Error on '%s': DIRECTION must be either CW or CCW" % (
gcmd.get_commandline(),))
self.direction = direction
self.probe_helper.start_probe(gcmd) self.probe_helper.start_probe(gcmd)
def probe_finalize(self, offsets, positions): def probe_finalize(self, offsets, positions):
# Factors used for CW-M3, CCW-M3, CW-M4, CCW-M4, CW-M5 and CCW-M5 # Factors used for CW-M3, CCW-M3, CW-M4, CCW-M4, CW-M5 and CCW-M5
threads_factor = {0: 0.5, 1: 0.5, 2: 0.7, 3: 0.7, 4: 0.8, 5: 0.8} threads_factor = {0: 0.5, 1: 0.5, 2: 0.7, 3: 0.7, 4: 0.8, 5: 0.8}
is_clockwise_thread = (self.thread & 1) == 0
screw_diff = [] screw_diff = []
# Process the read Z values and # Process the read Z values
if self.direction is not None:
# Lowest or highest screw is the base position used for comparison
use_max = ((is_clockwise_thread and self.direction == 'CW')
or (not is_clockwise_thread and self.direction == 'CCW'))
min_or_max = max if use_max else min
i_base, z_base = min_or_max(
enumerate([pos[2] for pos in positions]), key=lambda (i, z): z)
else:
# First screw is the base position used for comparison
i_base, z_base = 0, positions[0][2]
# Provide the user some information on how to read the results
self.gcode.respond_info("01:20 means 1 full turn and 20 minutes, "
"CW=clockwise, CCW=counter-clockwise")
for i, screw in enumerate(self.screws): for i, screw in enumerate(self.screws):
if i == 0: z = positions[i][2]
# First screw is the base position used for comparison coord, name = screw
z_base = positions[i][2] if i == i_base:
coord_base, name_base = screw
# Show the results # Show the results
self.gcode.respond_info("%s (Base): X %.1f, Y %.1f, Z %.5f" % self.gcode.respond_info(
(name_base, coord_base[0], "%s : x=%.1f, y=%.1f, z=%.5f" %
coord_base[1], z_base)) (name + ' (base)', coord[0], coord[1], z))
else: else:
# Calculate how knob must me adjusted for other positions # Calculate how knob must be adjusted for other positions
z = positions[i][2]
coord, name = screw
diff = z_base - z diff = z_base - z
screw_diff.append(abs(diff)) screw_diff.append(abs(diff))
if abs(diff) < 0.001: if abs(diff) < 0.001:
adjust = 0 adjust = 0
else: else:
adjust = diff / threads_factor.get(self.thread, 0.5) adjust = diff / threads_factor.get(self.thread, 0.5)
if (self.thread & 1) == 1: if is_clockwise_thread:
sign = "CW" if adjust < 0 else "CCW" sign = "CW" if adjust >= 0 else "CCW"
else: else:
sign = "CCW" if adjust < 0 else "CW" sign = "CCW" if adjust >= 0 else "CW"
adjust = abs(adjust)
full_turns = math.trunc(adjust) full_turns = math.trunc(adjust)
decimal_part = adjust - full_turns decimal_part = adjust - full_turns
minutes = round(decimal_part * 60, 0) minutes = round(decimal_part * 60, 0)
# Show the results # Show the results
self.gcode.respond_info("%s : X %.1f, Y %.1f, Z %.5f : " self.gcode.respond_info(
"Adjust -> %s %02d:%02d" % "%s : x=%.1f, y=%.1f, z=%.5f : adjust %s %02d:%02d" %
(name, coord[0], coord[1], z, sign, (name, coord[0], coord[1], z, sign, full_turns, minutes))
abs(full_turns), abs(minutes)))
if self.max_diff and any((d > self.max_diff) for d in screw_diff): if self.max_diff and any((d > self.max_diff) for d in screw_diff):
raise self.gcode.error( raise self.gcode.error(
"bed level exceeds configured limits ({}mm)! " \ "bed level exceeds configured limits ({}mm)! " \