aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config/example-extras.cfg41
-rw-r--r--docs/G-Codes.md10
-rw-r--r--klippy/extras/bed_screws.py119
-rw-r--r--test/klippy/bed_screws.cfg50
-rw-r--r--test/klippy/bed_screws.test49
5 files changed, 267 insertions, 2 deletions
diff --git a/config/example-extras.cfg b/config/example-extras.cfg
index 806b5f7d..d22311a3 100644
--- a/config/example-extras.cfg
+++ b/config/example-extras.cfg
@@ -107,8 +107,8 @@
# is above the bed at the given nozzle coordinates. The default is
# to not enable the command.
#speed: 50
-# The speed (in mm/s) of non-probing moves during the
-# calibration. The default is 50.
+# The speed (in mm/s) of non-probing moves during the calibration.
+# The default is 50.
#horizontal_move_z: 5
# The height (in mm) that the head should be commanded to move to
# 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.
+# 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
# adjustment of multiple z steppers (see stepper_z1 section below) to
# adjust for tilt. If this section is present then a Z_TILT_ADJUST
diff --git a/docs/G-Codes.md b/docs/G-Codes.md
index a39f2c30..8cbd34ba 100644
--- a/docs/G-Codes.md
+++ b/docs/G-Codes.md
@@ -261,6 +261,16 @@ section is enabled:
REMOVE operations have been run the SAVE_CONFIG gcode must be run
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
The following commands are available when the "z_tilt" config section
diff --git a/klippy/extras/bed_screws.py b/klippy/extras/bed_screws.py
new file mode 100644
index 00000000..ce6754da
--- /dev/null
+++ b/klippy/extras/bed_screws.py
@@ -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)
diff --git a/test/klippy/bed_screws.cfg b/test/klippy/bed_screws.cfg
new file mode 100644
index 00000000..5033e317
--- /dev/null
+++ b/test/klippy/bed_screws.cfg
@@ -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
diff --git a/test/klippy/bed_screws.test b/test/klippy/bed_screws.test
new file mode 100644
index 00000000..53fa2cb1
--- /dev/null
+++ b/test/klippy/bed_screws.test
@@ -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