extruder: Add support for reversing the direction of extruder stepper movement

Extend SET_EXTRUDER_ROTATION_DISTANCE to support reversing the
direction of extruder movement.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2022-01-29 19:13:31 -05:00
parent 189188e3ca
commit 9ec9742484
9 changed files with 60 additions and 19 deletions

View File

@ -303,11 +303,13 @@ extruder.
#### SET_EXTRUDER_ROTATION_DISTANCE #### SET_EXTRUDER_ROTATION_DISTANCE
`SET_EXTRUDER_ROTATION_DISTANCE EXTRUDER=<config_name> `SET_EXTRUDER_ROTATION_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
"rotation distance". Value is not retained on Klipper reset. Use with "rotation distance". If the rotation distance is a negative number
caution as small changes can result in excessive pressure between then the stepper motion will be inverted (relative to the stepper
extruder and hot end. Do proper calibration with filament before use. direction specified in the config file). Changed settings are not
If 'DISTANCE' value is not included command will return current retained on Klipper reset. Use with caution as small changes can
rotation distance. 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>

View File

@ -38,8 +38,9 @@ defs_stepcompress = """
struct stepcompress *stepcompress_alloc(uint32_t oid); struct stepcompress *stepcompress_alloc(uint32_t oid);
void stepcompress_fill(struct stepcompress *sc, uint32_t max_error void stepcompress_fill(struct stepcompress *sc, uint32_t max_error
, uint32_t invert_sdir, int32_t queue_step_msgtag , int32_t queue_step_msgtag, int32_t set_next_step_dir_msgtag);
, int32_t set_next_step_dir_msgtag); void stepcompress_set_invert_sdir(struct stepcompress *sc
, uint32_t invert_sdir);
void stepcompress_free(struct stepcompress *sc); void stepcompress_free(struct stepcompress *sc);
int stepcompress_reset(struct stepcompress *sc, uint64_t last_step_clock); int stepcompress_reset(struct stepcompress *sc, uint64_t last_step_clock);
int stepcompress_set_last_position(struct stepcompress *sc int stepcompress_set_last_position(struct stepcompress *sc

View File

@ -259,15 +259,25 @@ stepcompress_alloc(uint32_t oid)
// Fill message id information // Fill message id information
void __visible void __visible
stepcompress_fill(struct stepcompress *sc, uint32_t max_error stepcompress_fill(struct stepcompress *sc, uint32_t max_error
, uint32_t invert_sdir, int32_t queue_step_msgtag , int32_t queue_step_msgtag, int32_t set_next_step_dir_msgtag)
, int32_t set_next_step_dir_msgtag)
{ {
sc->max_error = max_error; sc->max_error = max_error;
sc->invert_sdir = !!invert_sdir;
sc->queue_step_msgtag = queue_step_msgtag; sc->queue_step_msgtag = queue_step_msgtag;
sc->set_next_step_dir_msgtag = set_next_step_dir_msgtag; sc->set_next_step_dir_msgtag = set_next_step_dir_msgtag;
} }
// Set the inverted stepper direction flag
void __visible
stepcompress_set_invert_sdir(struct stepcompress *sc, uint32_t invert_sdir)
{
invert_sdir = !!invert_sdir;
if (invert_sdir != sc->invert_sdir) {
sc->invert_sdir = invert_sdir;
if (sc->sdir >= 0)
sc->sdir ^= 1;
}
}
// Helper to free items from the history_list // Helper to free items from the history_list
static void static void
free_history(struct stepcompress *sc, uint64_t end_clock) free_history(struct stepcompress *sc, uint64_t end_clock)

View File

@ -13,8 +13,10 @@ struct pull_history_steps {
struct stepcompress *stepcompress_alloc(uint32_t oid); struct stepcompress *stepcompress_alloc(uint32_t oid);
void stepcompress_fill(struct stepcompress *sc, uint32_t max_error void stepcompress_fill(struct stepcompress *sc, uint32_t max_error
, uint32_t invert_sdir, int32_t queue_step_msgtag , int32_t queue_step_msgtag
, int32_t set_next_step_dir_msgtag); , int32_t set_next_step_dir_msgtag);
void stepcompress_set_invert_sdir(struct stepcompress *sc
, uint32_t invert_sdir);
void stepcompress_free(struct stepcompress *sc); void stepcompress_free(struct stepcompress *sc);
uint32_t stepcompress_get_oid(struct stepcompress *sc); uint32_t stepcompress_get_oid(struct stepcompress *sc);
int stepcompress_get_step_dir(struct stepcompress *sc); int stepcompress_get_step_dir(struct stepcompress *sc);

View File

@ -139,7 +139,7 @@ class DumpStepper:
mcu_pos = first.start_position mcu_pos = first.start_position
start_position = self.mcu_stepper.mcu_to_commanded_position(mcu_pos) start_position = self.mcu_stepper.mcu_to_commanded_position(mcu_pos)
step_dist = self.mcu_stepper.get_step_dist() step_dist = self.mcu_stepper.get_step_dist()
if self.mcu_stepper.is_dir_inverted(): if self.mcu_stepper.get_dir_inverted()[0]:
step_dist = -step_dist step_dist = -step_dist
d = [(s.interval, s.step_count, s.add) for s in data] d = [(s.interval, s.step_count, s.add) for s in data]
return {"data": d, "start_position": start_position, return {"data": d, "start_position": start_position,

View File

@ -224,6 +224,8 @@ class TMCCommandHelper:
self.stepper_enable = self.printer.load_object(config, "stepper_enable") self.stepper_enable = self.printer.load_object(config, "stepper_enable")
self.printer.register_event_handler("stepper:sync_mcu_position", self.printer.register_event_handler("stepper:sync_mcu_position",
self._handle_sync_mcu_pos) self._handle_sync_mcu_pos)
self.printer.register_event_handler("stepper:set_sdir_inverted",
self._handle_sync_mcu_pos)
self.printer.register_event_handler("klippy:mcu_identify", self.printer.register_event_handler("klippy:mcu_identify",
self._handle_mcu_identify) self._handle_mcu_identify)
self.printer.register_event_handler("klippy:connect", self.printer.register_event_handler("klippy:connect",
@ -306,7 +308,7 @@ class TMCCommandHelper:
if enable_line.is_motor_enabled(): if enable_line.is_motor_enabled():
raise raise
return return
if not stepper.is_dir_inverted(): if not stepper.get_dir_inverted()[0]:
driver_phase = 1023 - driver_phase driver_phase = 1023 - driver_phase
phases = self._get_phases() phases = self._get_phases()
phase = int(float(driver_phase) / 1024 * phases + .5) % phases phase = int(float(driver_phase) / 1024 * phases + .5) % phases

View File

@ -91,13 +91,24 @@ class ExtruderStepper:
gcmd.respond_info(msg, log=False) gcmd.respond_info(msg, log=False)
cmd_SET_E_ROTATION_DISTANCE_help = "Set extruder rotation distance" cmd_SET_E_ROTATION_DISTANCE_help = "Set extruder rotation distance"
def cmd_SET_E_ROTATION_DISTANCE(self, gcmd): def cmd_SET_E_ROTATION_DISTANCE(self, gcmd):
rotation_dist = gcmd.get_float('DISTANCE', None, above=0.) rotation_dist = gcmd.get_float('DISTANCE', None)
if rotation_dist is not None: if rotation_dist is not None:
if not rotation_dist:
raise gcmd.error("Rotation distance can not be zero")
invert_dir, orig_invert_dir = self.stepper.get_dir_inverted()
next_invert_dir = orig_invert_dir
if rotation_dist < 0.:
next_invert_dir = not orig_invert_dir
rotation_dist = -rotation_dist
toolhead = self.printer.lookup_object('toolhead') toolhead = self.printer.lookup_object('toolhead')
toolhead.flush_step_generation() toolhead.flush_step_generation()
self.stepper.set_rotation_distance(rotation_dist) self.stepper.set_rotation_distance(rotation_dist)
self.stepper.set_dir_inverted(next_invert_dir)
else: else:
rotation_dist, spr = self.stepper.get_rotation_distance() rotation_dist, spr = self.stepper.get_rotation_distance()
invert_dir, orig_invert_dir = self.stepper.get_dir_inverted()
if invert_dir != orig_invert_dir:
rotation_dist = -rotation_dist
gcmd.respond_info("Extruder '%s' rotation distance set to %0.6f" gcmd.respond_info("Extruder '%s' rotation distance set to %0.6f"
% (self.name, rotation_dist)) % (self.name, rotation_dist))
cmd_SET_E_STEP_DISTANCE_help = "Set extruder step distance" cmd_SET_E_STEP_DISTANCE_help = "Set extruder step distance"

View File

@ -36,7 +36,7 @@ class MCU_stepper:
raise self._mcu.get_printer().config_error( raise self._mcu.get_printer().config_error(
"Stepper dir pin must be on same mcu as step pin") "Stepper dir pin must be on same mcu as step pin")
self._dir_pin = dir_pin_params['pin'] self._dir_pin = dir_pin_params['pin']
self._invert_dir = dir_pin_params['invert'] self._invert_dir = self._orig_invert_dir = dir_pin_params['invert']
self._step_both_edge = self._req_step_both_edge = False self._step_both_edge = self._req_step_both_edge = False
self._mcu_position_offset = 0. self._mcu_position_offset = 0.
self._reset_cmd_tag = self._get_position_cmd = None self._reset_cmd_tag = self._get_position_cmd = None
@ -44,6 +44,7 @@ class MCU_stepper:
ffi_main, ffi_lib = chelper.get_ffi() ffi_main, ffi_lib = chelper.get_ffi()
self._stepqueue = ffi_main.gc(ffi_lib.stepcompress_alloc(oid), self._stepqueue = ffi_main.gc(ffi_lib.stepcompress_alloc(oid),
ffi_lib.stepcompress_free) ffi_lib.stepcompress_free)
ffi_lib.stepcompress_set_invert_sdir(self._stepqueue, self._invert_dir)
self._mcu.register_stepqueue(self._stepqueue) self._mcu.register_stepqueue(self._stepqueue)
self._stepper_kinematics = None self._stepper_kinematics = None
self._itersolve_generate_steps = ffi_lib.itersolve_generate_steps self._itersolve_generate_steps = ffi_lib.itersolve_generate_steps
@ -101,7 +102,7 @@ class MCU_stepper:
max_error_ticks = self._mcu.seconds_to_clock(max_error) max_error_ticks = self._mcu.seconds_to_clock(max_error)
ffi_main, ffi_lib = chelper.get_ffi() ffi_main, ffi_lib = chelper.get_ffi()
ffi_lib.stepcompress_fill(self._stepqueue, max_error_ticks, ffi_lib.stepcompress_fill(self._stepqueue, max_error_ticks,
self._invert_dir, step_cmd_tag, dir_cmd_tag) step_cmd_tag, dir_cmd_tag)
def get_oid(self): def get_oid(self):
return self._oid return self._oid
def get_step_dist(self): def get_step_dist(self):
@ -114,8 +115,16 @@ class MCU_stepper:
self._step_dist = rotation_dist / self._steps_per_rotation 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 get_dir_inverted(self):
return self._invert_dir return self._invert_dir, self._orig_invert_dir
def set_dir_inverted(self, invert_dir):
invert_dir = not not invert_dir
if invert_dir == self._invert_dir:
return
self._invert_dir = invert_dir
ffi_main, ffi_lib = chelper.get_ffi()
ffi_lib.stepcompress_set_invert_sdir(self._stepqueue, invert_dir)
self._mcu.get_printer().send_event("stepper:set_dir_inverted", self)
def calc_position_from_coord(self, coord): def calc_position_from_coord(self, coord):
ffi_main, ffi_lib = chelper.get_ffi() ffi_main, ffi_lib = chelper.get_ffi()
return ffi_lib.itersolve_calc_position_from_coord( return ffi_lib.itersolve_calc_position_from_coord(

View File

@ -13,9 +13,13 @@ G1 X20 Y20 Z1
G1 X25 Y25 E7.5 G1 X25 Y25 E7.5
# Update step_distance # Update step_distance
SET_EXTRUDER_STEP_DISTANCE EXTRUDER=extruder DISTANCE=.005 SET_EXTRUDER_ROTATION_DISTANCE EXTRUDER=extruder DISTANCE=33.2
G1 X30 Y30 E8.0 G1 X30 Y30 E8.0
# Reverse step_distance
SET_EXTRUDER_ROTATION_DISTANCE EXTRUDER=extruder DISTANCE=-33.1
G1 X30 Y30 E8.2
# Disable extruder stepper motor # Disable extruder stepper motor
SYNC_STEPPER_TO_EXTRUDER STEPPER=extruder EXTRUDER= SYNC_STEPPER_TO_EXTRUDER STEPPER=extruder EXTRUDER=
G1 X35 Y35 E8.5 G1 X35 Y35 E8.5