extruder: Add a SET_EXTRUDER_ROTATION_DISTANCE command

Support altering the extruder distance using the higher-level
rotation_distance.  This is in preparation for removal of the
SET_EXTRUDER_STEP_DISTANCE command.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2022-01-29 14:13:26 -05:00
parent 6d7c03365a
commit 189188e3ca
5 changed files with 55 additions and 23 deletions

View File

@ -300,14 +300,23 @@ extruders this command is used to change the active extruder.
parameters. If EXTRUDER is not specified, it defaults to the active parameters. If EXTRUDER is not specified, it defaults to the active
extruder. extruder.
#### SET_EXTRUDER_ROTATION_DISTANCE
`SET_EXTRUDER_ROTATION_DISTANCE EXTRUDER=<config_name>
[DISTANCE=<distance>]`: Set a new value for the provided extruder's
"rotation distance". Value is not retained on Klipper reset. Use with
caution as small changes can result in excessive pressure between
extruder and hot end. Do proper calibration with filament before use.
If 'DISTANCE' value is not included command will return current
rotation distance.
#### SET_EXTRUDER_STEP_DISTANCE #### SET_EXTRUDER_STEP_DISTANCE
`SET_EXTRUDER_STEP_DISTANCE [EXTRUDER=<config_name>] `SET_EXTRUDER_STEP_DISTANCE EXTRUDER=<config_name>
[DISTANCE=<distance>]`: Set a new value for the provided extruder's [DISTANCE=<distance>]`: Set a new value for the provided extruder's
"step distance". The "step distance" is "step distance". The "step distance" is
`rotation_distance/(full_steps_per_rotation*microsteps)`. Value is not `rotation_distance/(full_steps_per_rotation*microsteps)`. Value is not
retained on Klipper reset. Use with caution, small changes can result retained on Klipper reset. Use with caution as small changes can
in excessive pressure between extruder and hot end. Do proper result in excessive pressure between extruder and hot end. Do proper
calibration steps with filament before use. If 'DISTANCE' value is not calibration with filament before use. If 'DISTANCE' value is not
included command will return current step distance. included command will return current step distance.
#### SYNC_STEPPER_TO_EXTRUDER #### SYNC_STEPPER_TO_EXTRUDER

View File

@ -54,7 +54,8 @@ class EndstopPhase:
self.name = config.get_name().split()[1] self.name = config.get_name().split()[1]
# Obtain step_distance and microsteps from stepper config section # Obtain step_distance and microsteps from stepper config section
sconfig = config.getsection(self.name) sconfig = config.getsection(self.name)
self.step_dist = stepper.parse_step_distance(sconfig) rotation_dist, steps_per_rotation = stepper.parse_step_distance(sconfig)
self.step_dist = rotation_dist / steps_per_rotation
self.phases = sconfig.getint("microsteps", note_valid=False) * 4 self.phases = sconfig.getint("microsteps", note_valid=False) * 4
self.phase_calc = PhaseCalc(self.printer, self.name, self.phases) self.phase_calc = PhaseCalc(self.printer, self.name, self.phases)
# Register event handlers # Register event handlers

View File

@ -520,8 +520,9 @@ def TMCStealthchopHelper(config, mcu_tmc, tmc_freq):
velocity = config.getfloat('stealthchop_threshold', 0., minval=0.) velocity = config.getfloat('stealthchop_threshold', 0., minval=0.)
if velocity: if velocity:
stepper_name = " ".join(config.get_name().split()[1:]) stepper_name = " ".join(config.get_name().split()[1:])
stepper_config = config.getsection(stepper_name) sconfig = config.getsection(stepper_name)
step_dist = stepper.parse_step_distance(stepper_config) rotation_dist, steps_per_rotation = stepper.parse_step_distance(sconfig)
step_dist = rotation_dist / steps_per_rotation
step_dist_256 = step_dist / (1 << fields.get_field("mres")) step_dist_256 = step_dist / (1 << fields.get_field("mres"))
threshold = int(tmc_freq * step_dist_256 / velocity + .5) threshold = int(tmc_freq * step_dist_256 / velocity + .5)
fields.set_field("tpwmthrs", max(0, min(0xfffff, threshold))) fields.set_field("tpwmthrs", max(0, min(0xfffff, threshold)))

View File

@ -28,6 +28,9 @@ class ExtruderStepper:
gcode.register_mux_command("SET_PRESSURE_ADVANCE", "EXTRUDER", gcode.register_mux_command("SET_PRESSURE_ADVANCE", "EXTRUDER",
self.name, self.cmd_SET_PRESSURE_ADVANCE, self.name, self.cmd_SET_PRESSURE_ADVANCE,
desc=self.cmd_SET_PRESSURE_ADVANCE_help) desc=self.cmd_SET_PRESSURE_ADVANCE_help)
gcode.register_mux_command("SET_EXTRUDER_ROTATION_DISTANCE", "EXTRUDER",
self.name, self.cmd_SET_E_ROTATION_DISTANCE,
desc=self.cmd_SET_E_ROTATION_DISTANCE_help)
gcode.register_mux_command("SET_EXTRUDER_STEP_DISTANCE", "EXTRUDER", gcode.register_mux_command("SET_EXTRUDER_STEP_DISTANCE", "EXTRUDER",
self.name, self.cmd_SET_E_STEP_DISTANCE, self.name, self.cmd_SET_E_STEP_DISTANCE,
desc=self.cmd_SET_E_STEP_DISTANCE_help) desc=self.cmd_SET_E_STEP_DISTANCE_help)
@ -86,19 +89,29 @@ class ExtruderStepper:
% (pressure_advance, smooth_time)) % (pressure_advance, smooth_time))
self.printer.set_rollover_info(self.name, "%s: %s" % (self.name, msg)) self.printer.set_rollover_info(self.name, "%s: %s" % (self.name, msg))
gcmd.respond_info(msg, log=False) gcmd.respond_info(msg, log=False)
cmd_SET_E_ROTATION_DISTANCE_help = "Set extruder rotation distance"
def cmd_SET_E_ROTATION_DISTANCE(self, gcmd):
rotation_dist = gcmd.get_float('DISTANCE', None, above=0.)
if rotation_dist is not None:
toolhead = self.printer.lookup_object('toolhead')
toolhead.flush_step_generation()
self.stepper.set_rotation_distance(rotation_dist)
else:
rotation_dist, spr = self.stepper.get_rotation_distance()
gcmd.respond_info("Extruder '%s' rotation distance set to %0.6f"
% (self.name, rotation_dist))
cmd_SET_E_STEP_DISTANCE_help = "Set extruder step distance" cmd_SET_E_STEP_DISTANCE_help = "Set extruder step distance"
def cmd_SET_E_STEP_DISTANCE(self, gcmd): def cmd_SET_E_STEP_DISTANCE(self, gcmd):
step_dist = gcmd.get_float('DISTANCE', None, above=0.)
if step_dist is not None:
toolhead = self.printer.lookup_object('toolhead') toolhead = self.printer.lookup_object('toolhead')
dist = gcmd.get_float('DISTANCE', None, above=0.)
if dist is None:
step_dist = self.stepper.get_step_dist()
gcmd.respond_info("Extruder '%s' step distance is %0.6f"
% (self.name, step_dist))
return
toolhead.flush_step_generation() toolhead.flush_step_generation()
self.stepper.set_step_dist(dist) rd, steps_per_rotation = self.stepper.get_rotation_distance()
self.stepper.set_rotation_distance(step_dist * steps_per_rotation)
else:
step_dist = self.stepper.get_step_dist()
gcmd.respond_info("Extruder '%s' step distance set to %0.6f" gcmd.respond_info("Extruder '%s' step distance set to %0.6f"
% (self.name, dist)) % (self.name, step_dist))
cmd_SYNC_STEPPER_TO_EXTRUDER_help = "Set extruder stepper" cmd_SYNC_STEPPER_TO_EXTRUDER_help = "Set extruder stepper"
def cmd_SYNC_STEPPER_TO_EXTRUDER(self, gcmd): def cmd_SYNC_STEPPER_TO_EXTRUDER(self, gcmd):
ename = gcmd.get('EXTRUDER') ename = gcmd.get('EXTRUDER')

View File

@ -18,12 +18,15 @@ MIN_BOTH_EDGE_DURATION = 0.000000200
# Interface to low-level mcu and chelper code # Interface to low-level mcu and chelper code
class MCU_stepper: class MCU_stepper:
def __init__(self, name, step_pin_params, dir_pin_params, step_dist, def __init__(self, name, step_pin_params, dir_pin_params,
rotation_dist, steps_per_rotation,
step_pulse_duration=None, units_in_radians=False): step_pulse_duration=None, units_in_radians=False):
self._name = name self._name = name
self._step_dist = step_dist self._rotation_dist = rotation_dist
self._steps_per_rotation = steps_per_rotation
self._step_pulse_duration = step_pulse_duration self._step_pulse_duration = step_pulse_duration
self._units_in_radians = units_in_radians self._units_in_radians = units_in_radians
self._step_dist = rotation_dist / steps_per_rotation
self._mcu = step_pin_params['chip'] self._mcu = step_pin_params['chip']
self._oid = oid = self._mcu.create_oid() self._oid = oid = self._mcu.create_oid()
self._mcu.register_config_callback(self._build_config) self._mcu.register_config_callback(self._build_config)
@ -103,9 +106,12 @@ class MCU_stepper:
return self._oid return self._oid
def get_step_dist(self): def get_step_dist(self):
return self._step_dist return self._step_dist
def set_step_dist(self, dist): def get_rotation_distance(self):
return self._rotation_dist, self._steps_per_rotation
def set_rotation_distance(self, rotation_dist):
mcu_pos = self.get_mcu_position() mcu_pos = self.get_mcu_position()
self._step_dist = dist self._rotation_dist = rotation_dist
self._step_dist = rotation_dist / self._steps_per_rotation
self.set_stepper_kinematics(self._stepper_kinematics) self.set_stepper_kinematics(self._stepper_kinematics)
self._set_mcu_position(mcu_pos) self._set_mcu_position(mcu_pos)
def is_dir_inverted(self): def is_dir_inverted(self):
@ -222,10 +228,12 @@ def PrinterStepper(config, units_in_radians=False):
step_pin_params = ppins.lookup_pin(step_pin, can_invert=True) step_pin_params = ppins.lookup_pin(step_pin, can_invert=True)
dir_pin = config.get('dir_pin') dir_pin = config.get('dir_pin')
dir_pin_params = ppins.lookup_pin(dir_pin, can_invert=True) dir_pin_params = ppins.lookup_pin(dir_pin, can_invert=True)
step_dist = parse_step_distance(config, units_in_radians, True) rotation_dist, steps_per_rotation = parse_step_distance(
config, units_in_radians, True)
step_pulse_duration = config.getfloat('step_pulse_duration', None, step_pulse_duration = config.getfloat('step_pulse_duration', None,
minval=0., maxval=.001) minval=0., maxval=.001)
mcu_stepper = MCU_stepper(name, step_pin_params, dir_pin_params, step_dist, mcu_stepper = MCU_stepper(name, step_pin_params, dir_pin_params,
rotation_dist, steps_per_rotation,
step_pulse_duration, units_in_radians) step_pulse_duration, units_in_radians)
# Register with helper modules # Register with helper modules
for mname in ['stepper_enable', 'force_move', 'motion_report']: for mname in ['stepper_enable', 'force_move', 'motion_report']:
@ -263,7 +271,7 @@ def parse_step_distance(config, units_in_radians=None, note_valid=False):
raise config.error("full_steps_per_rotation invalid in section '%s'" raise config.error("full_steps_per_rotation invalid in section '%s'"
% (config.get_name(),)) % (config.get_name(),))
gearing = parse_gear_ratio(config, note_valid) gearing = parse_gear_ratio(config, note_valid)
return rotation_dist / (full_steps * microsteps * gearing) return rotation_dist, full_steps * microsteps * gearing
###################################################################### ######################################################################