bed_screws: Add a helper tool for leveling bed screws

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2019-02-14 13:00:18 -05:00
parent 9e8077009e
commit 80c8bd8b4d
5 changed files with 267 additions and 2 deletions

View File

@ -107,8 +107,8 @@
# is above the bed at the given nozzle coordinates. The default is # is above the bed at the given nozzle coordinates. The default is
# to not enable the command. # to not enable the command.
#speed: 50 #speed: 50
# The speed (in mm/s) of non-probing moves during the # The speed (in mm/s) of non-probing moves during the calibration.
# calibration. The default is 50. # The default is 50.
#horizontal_move_z: 5 #horizontal_move_z: 5
# The height (in mm) that the head should be commanded to move to # The height (in mm) that the head should be commanded to move to
# just prior to starting a probe operation. The default is 5. # just prior to starting a probe operation. The default is 5.
@ -226,6 +226,43 @@
# results in more curvature in the mesh. Default is .2. # results in more curvature in the mesh. Default is .2.
# Tool to help adjust bed leveling screws. One may define a
# [bed_screws] config section to enable a BED_SCREWS_ADJUST g-code
# command.
#[bed_screws]
#screw1: 100,100
# The X,Y coordinate of the first bed leveling screw. This is a
# position to command the nozzle to that is directly above the bed
# screw (or as close as possible while still being above the bed).
# This parameter must be provided.
#screw1_name: front screw
# An arbitrary name for the given screw. This name is displayed when
# the helper script runs. The default is to use a name based upon
# the screw XY location.
#screw1_fine_adjust:
# An X,Y coordinate to command the nozzle to so that one can fine
# tune the bed leveling screw. The default is to not perform fine
# adjustments on the bed screw.
#screw2:
#screw2_name:
#screw2_fine_adjust:
#...
# Additional bed leveling screws. At least three screws must be
# defined.
#horizontal_move_z: 5
# The height (in mm) that the head should be commanded to move to
# when moving from one screw location to the next. The default is 5.
#probe_height: 0
# The height of the probe (in mm) after adjusting for the thermal
# expansion of bed and nozzle. The default is zero.
#speed: 50
# The speed (in mm/s) of non-probing moves during the calibration.
# The default is 50.
#probe_speed: 5
# The speed (in mm/s) when moving from a horizontal_move_z position
# to a probe_height position. The default is 5.
# Multiple Z stepper tilt adjustment. This feature enables independent # Multiple Z stepper tilt adjustment. This feature enables independent
# adjustment of multiple z steppers (see stepper_z1 section below) to # adjustment of multiple z steppers (see stepper_z1 section below) to
# adjust for tilt. If this section is present then a Z_TILT_ADJUST # adjust for tilt. If this section is present then a Z_TILT_ADJUST

View File

@ -261,6 +261,16 @@ section is enabled:
REMOVE operations have been run the SAVE_CONFIG gcode must be run REMOVE operations have been run the SAVE_CONFIG gcode must be run
to make the changes to peristent memory permanent. to make the changes to peristent memory permanent.
## Bed Screws Helper
The following commands are available when the "bed_screws" config
section is enabled:
- `BED_SCREWS_ADJUST`: This command will invoke the bed screws
adjustment tool. It will command the nozzle to different locations
(as defined in the config file) and allow one to make adjustments to
the bed screws so that the bed is a constant distance from the
nozzle.
## Z Tilt ## Z Tilt
The following commands are available when the "z_tilt" config section The following commands are available when the "z_tilt" config section

119
klippy/extras/bed_screws.py Normal file
View File

@ -0,0 +1,119 @@
# Helper script to adjust bed screws
#
# Copyright (C) 2019 Kevin O'Connor <kevin@koconnor.net>
#
# This file may be distributed under the terms of the GNU GPLv3 license.
def parse_coord(config, param):
pair = config.get(param).strip().split(',', 1)
try:
return (float(pair[0]), float(pair[1]))
except:
raise config.error("%s:%s needs to be an x,y coordinate" % (
config.get_name(), param))
class BedScrews:
def __init__(self, config):
self.printer = config.get_printer()
self.state = None
self.current_screw = 0
self.adjust_again = False
# Read config
screws = []
fine_adjust = []
for i in range(99):
prefix = "screw%d" % (i + 1,)
if config.get(prefix, None) is None:
break
screw_coord = parse_coord(config, prefix)
screw_name = "screw at %.3f,%.3f" % screw_coord
screw_name = config.get(prefix + "_name", screw_name)
screws.append((screw_coord, screw_name))
if config.get(prefix + "_fine_adjust", None) is not None:
fine_coord = parse_coord(config, prefix + "_fine_adjust")
fine_adjust.append((fine_coord, screw_name))
if len(screws) < 3:
raise config.error("bed_screws: Must have at least three screws")
self.states = {'adjust': screws, 'fine': fine_adjust}
self.speed = config.getfloat('speed', 50., above=0.)
self.lift_speed = config.getfloat('probe_speed', 5., above=0.)
self.horizontal_move_z = config.getfloat('horizontal_move_z', 5.)
self.probe_z = config.getfloat('probe_height', 0.)
# Register command
self.gcode = self.printer.lookup_object('gcode')
self.gcode.register_command("BED_SCREWS_ADJUST",
self.cmd_BED_SCREWS_ADJUST,
desc=self.cmd_BED_SCREWS_ADJUST_help)
def move(self, coord, speed):
toolhead = self.printer.lookup_object('toolhead')
curpos = toolhead.get_position()
for i in range(len(coord)):
if coord[i] is not None:
curpos[i] = coord[i]
try:
toolhead.move(curpos, speed)
except homing.EndstopError as e:
raise self.gcode.error(str(e))
def move_to_screw(self, state, screw):
# Move up, over, and then down
self.move((None, None, self.horizontal_move_z), self.lift_speed)
coord, name = self.states[state][screw]
self.move((coord[0], coord[1], self.horizontal_move_z), self.speed)
self.move((coord[0], coord[1], self.probe_z), self.lift_speed)
# Update state
self.state = state
self.current_screw = screw
# Register commands
self.gcode.respond_info(
"Adjust %s. Then run ACCEPT, ADJUSTED, or ABORT\n"
"Use ADJUSTED if a significant screw adjustment is made" % (name,))
self.gcode.register_command('ACCEPT', self.cmd_ACCEPT,
desc=self.cmd_ACCEPT_help)
self.gcode.register_command('ADJUSTED', self.cmd_ADJUSTED,
desc=self.cmd_ADJUSTED_help)
self.gcode.register_command('ABORT', self.cmd_ABORT,
desc=self.cmd_ABORT_help)
def unregister_commands(self):
self.gcode.register_command('ACCEPT', None)
self.gcode.register_command('ADJUSTED', None)
self.gcode.register_command('ABORT', None)
cmd_BED_SCREWS_ADJUST_help = "Tool to help adjust bed leveling screws"
def cmd_BED_SCREWS_ADJUST(self, params):
if self.state is not None:
raise self.gcode.error(
"Already in bed_screws helper; use ABORT to exit")
self.adjust_again = False
self.move((None, None, self.horizontal_move_z), self.speed)
self.move_to_screw('adjust', 0)
cmd_ACCEPT_help = "Accept bed screw position"
def cmd_ACCEPT(self, params):
self.unregister_commands()
if self.current_screw + 1 < len(self.states[self.state]):
# Continue with next screw
self.move_to_screw(self.state, self.current_screw + 1)
return
if self.adjust_again:
# Retry coarse adjustments
self.adjust_again = False
self.move_to_screw('adjust', 0)
return
if self.state == 'adjust' and self.states['fine']:
# Perform fine screw adjustments
self.move_to_screw('fine', 0)
return
# Done
self.state = None
self.move((None, None, self.horizontal_move_z), self.lift_speed)
self.gcode.respond_info("Bed screws tool completed successfully")
cmd_ADJUSTED_help = "Accept bed screw position after notable adjustment"
def cmd_ADJUSTED(self, params):
self.unregister_commands()
self.adjust_again = True
self.cmd_ACCEPT(params)
cmd_ABORT_help = "Abort bed screws tool"
def cmd_ABORT(self, params):
self.unregister_commands()
self.state = None
def load_config(config):
return BedScrews(config)

View File

@ -0,0 +1,50 @@
# Test config for bed screws tool
[stepper_x]
step_pin: ar54
dir_pin: ar55
enable_pin: !ar38
step_distance: .0125
endstop_pin: ^ar3
position_endstop: 0
position_max: 200
homing_speed: 50
[stepper_y]
step_pin: ar60
dir_pin: !ar61
enable_pin: !ar56
step_distance: .0125
endstop_pin: ^ar14
position_endstop: 0
position_max: 200
homing_speed: 50
[stepper_z]
step_pin: ar46
dir_pin: ar48
enable_pin: !ar62
step_distance: .0025
endstop_pin: ^ar18
position_endstop: 0.5
position_max: 200
[bed_screws]
screw1: 100,50
screw1_name: Front right
screw1_fine_adjust: 200,50
screw2: 75,75
screw2_fine_adjust: 200,75
screw3: 75,75
screw3_name: Last
screw3_fine_adjust: 75,90
[mcu]
serial: /dev/ttyACM0
pin_map: arduino
[printer]
kinematics: cartesian
max_velocity: 300
max_accel: 3000
max_z_velocity: 5
max_z_accel: 100

View File

@ -0,0 +1,49 @@
# Test case for bed screws helper tool
CONFIG bed_screws.cfg
DICTIONARY atmega2560-16mhz.dict
# Start helper script and then abort it
G28
BED_SCREWS_ADJUST
ACCEPT
ACCEPT
ABORT
# Start helper script and run until success
BED_SCREWS_ADJUST
ACCEPT
ACCEPT
ACCEPT
ACCEPT
ACCEPT
ACCEPT
# Start helper script and run with two readjusts
BED_SCREWS_ADJUST
ACCEPT
ADJUSTED
ACCEPT
ACCEPT
ACCEPT
ACCEPT
ADJUSTED
ACCEPT
ACCEPT
ACCEPT
ACCEPT
ACCEPT
ACCEPT
ACCEPT
ACCEPT
# Start helper script and run with two readjusts
BED_SCREWS_ADJUST
ABORT