mirror of
https://github.com/Klipper3d/klipper.git
synced 2026-02-08 01:01:06 -07:00
Merge 7260cca7c8 into ca7d90084c
This commit is contained in:
commit
35933a0a3f
7 changed files with 101 additions and 77 deletions
|
|
@ -98,7 +98,7 @@ cs_pin: PD14 # X_SPI_EN Required for communication
|
|||
spi_bus: usart1 # All TMC2660 drivers are connected to USART1
|
||||
run_current: 1.000
|
||||
sense_resistor: 0.051
|
||||
idle_current_percent: 20
|
||||
ready_current: 0.5
|
||||
|
||||
[stepper_y]
|
||||
step_pin: PD7
|
||||
|
|
@ -115,7 +115,7 @@ cs_pin: PC9
|
|||
spi_bus: usart1
|
||||
run_current: 1.000
|
||||
sense_resistor: 0.051
|
||||
idle_current_percent: 20
|
||||
ready_current: 0.5
|
||||
|
||||
[stepper_z]
|
||||
step_pin: PD8
|
||||
|
|
|
|||
|
|
@ -3755,6 +3755,9 @@ run_current:
|
|||
# when the stepper is not moving. Setting a hold_current is not
|
||||
# recommended (see TMC_Drivers.md for details). The default is to
|
||||
# not reduce the current.
|
||||
#ready_current:
|
||||
# The amount of current (in amps RMS) to configure the driver to use
|
||||
# when the printer is in ready state - between last move and [idle_timeout].
|
||||
#sense_resistor: 0.110
|
||||
# The resistance (in ohms) of the motor sense resistor. The default
|
||||
# is 0.110 ohms.
|
||||
|
|
@ -3870,6 +3873,9 @@ run_current:
|
|||
# when the stepper is not moving. Setting a hold_current is not
|
||||
# recommended (see TMC_Drivers.md for details). The default is to
|
||||
# not reduce the current.
|
||||
#ready_current:
|
||||
# The amount of current (in amps RMS) to configure the driver to use
|
||||
# when the printer is in ready state - between last move and [idle_timeout].
|
||||
#sense_resistor: 0.110
|
||||
# The resistance (in ohms) of the motor sense resistor. The default
|
||||
# is 0.110 ohms.
|
||||
|
|
@ -3915,6 +3921,7 @@ uart_pin:
|
|||
#interpolate: True
|
||||
run_current:
|
||||
#hold_current:
|
||||
#ready_current:
|
||||
#sense_resistor: 0.110
|
||||
#stealthchop_threshold: 0
|
||||
# See the "tmc2208" section for the definition of these parameters.
|
||||
|
|
@ -3999,10 +4006,10 @@ run_current:
|
|||
#sense_resistor:
|
||||
# The resistance (in ohms) of the motor sense resistor. This
|
||||
# parameter must be provided.
|
||||
#idle_current_percent: 100
|
||||
# The percentage of the run_current the stepper driver will be
|
||||
# lowered to when the idle timeout expires (you need to set up the
|
||||
# timeout using a [idle_timeout] config section). The current will
|
||||
#ready_current:
|
||||
# The amount of current (in amps RMS) to configure the driver to use
|
||||
# when the printer is in ready state - between last move and [idle_timeout].
|
||||
# Upon move, the current will
|
||||
# be raised again once the stepper has to move again. Make sure to
|
||||
# set this to a high enough value such that the steppers do not lose
|
||||
# their position. There is also small delay until the current is
|
||||
|
|
@ -4076,6 +4083,9 @@ run_current:
|
|||
# when the stepper is not moving. Setting a hold_current is not
|
||||
# recommended (see TMC_Drivers.md for details). The default is to
|
||||
# not reduce the current.
|
||||
#ready_current:
|
||||
# The amount of current (in amps RMS) to configure the driver to use
|
||||
# when the printer is in ready state - between last move and [idle_timeout].
|
||||
#rref: 12000
|
||||
# The resistance (in ohms) of the resistor between IREF and GND. The
|
||||
# default is 12000.
|
||||
|
|
@ -4211,6 +4221,9 @@ run_current:
|
|||
# when the stepper is not moving. Setting a hold_current is not
|
||||
# recommended (see TMC_Drivers.md for details). The default is to
|
||||
# not reduce the current.
|
||||
#ready_current:
|
||||
# The amount of current (in amps RMS) to configure the driver to use
|
||||
# when the printer is in ready state - between last move and [idle_timeout].
|
||||
#sense_resistor: 0.075
|
||||
# The resistance (in ohms) of the motor sense resistor. The default
|
||||
# is 0.075 ohms.
|
||||
|
|
|
|||
|
|
@ -322,7 +322,21 @@ class TMCCommandHelper:
|
|||
self.stepper_name = ' '.join(config.get_name().split()[1:])
|
||||
self.name = config.get_name().split()[-1]
|
||||
self.mcu_tmc = mcu_tmc
|
||||
# Handle current settings
|
||||
self.current_helper = current_helper
|
||||
_, hold_support, max_cur = self.current_helper.get_current()
|
||||
self.run_current = config.getfloat('run_current',
|
||||
above=0., maxval=max_cur)
|
||||
self.hold_current = None
|
||||
run_cur = self.run_current
|
||||
if hold_support:
|
||||
hold = config.getfloat('hold_current', run_cur,
|
||||
above=0., maxval=run_cur)
|
||||
self.hold_current = hold
|
||||
self.ready_current = config.getfloat('ready_current', run_cur,
|
||||
above=0., maxval=run_cur)
|
||||
self._restore_current = [self.run_current, self.hold_current]
|
||||
self._in_ready = False
|
||||
self.fields = mcu_tmc.get_fields()
|
||||
self.stepper = None
|
||||
# Stepper phase tracking
|
||||
|
|
@ -346,6 +360,8 @@ class TMCCommandHelper:
|
|||
self._handle_mcu_identify)
|
||||
self.printer.register_event_handler("klippy:connect",
|
||||
self._handle_connect)
|
||||
self.printer.register_event_handler("idle_timeout:ready",
|
||||
self._handle_ready)
|
||||
# Register commands
|
||||
gcode = self.printer.lookup_object("gcode")
|
||||
gcode.register_mux_command("SET_TMC_FIELD", "STEPPER", self.name,
|
||||
|
|
@ -389,25 +405,68 @@ class TMCCommandHelper:
|
|||
cmd_SET_TMC_CURRENT_help = "Set the current of a TMC driver"
|
||||
def cmd_SET_TMC_CURRENT(self, gcmd):
|
||||
ch = self.current_helper
|
||||
prev_cur, prev_hold_cur, req_hold_cur, max_cur = ch.get_current()
|
||||
run_current = gcmd.get_float('CURRENT', None, minval=0., maxval=max_cur)
|
||||
hold_current = gcmd.get_float('HOLDCURRENT', None,
|
||||
above=0., maxval=max_cur)
|
||||
prev_cur, prev_hold_cur, max_cur = ch.get_current()
|
||||
run_current = gcmd.get_float('CURRENT', None,
|
||||
minval=0., maxval=max_cur)
|
||||
hold_current = None
|
||||
if prev_hold_cur is not None:
|
||||
hold_current = gcmd.get_float('HOLDCURRENT', None,
|
||||
above=0., maxval=max_cur)
|
||||
ready_current = gcmd.get_float('READYCURRENT', None,
|
||||
above=0., maxval=max_cur)
|
||||
if run_current is not None or hold_current is not None:
|
||||
if run_current is None:
|
||||
run_current = prev_cur
|
||||
if hold_current is None:
|
||||
hold_current = req_hold_cur
|
||||
hold_current = prev_hold_cur
|
||||
toolhead = self.printer.lookup_object('toolhead')
|
||||
print_time = toolhead.get_last_move_time()
|
||||
ch.set_current(run_current, hold_current, print_time)
|
||||
prev_cur, prev_hold_cur, req_hold_cur, max_cur = ch.get_current()
|
||||
prev_cur, prev_hold_cur, max_cur = ch.get_current()
|
||||
if ready_current is not None:
|
||||
self.ready_current = ready_current
|
||||
# Don't silently miss user input to change ihold upon restore
|
||||
if self._in_ready and hold_current is not None:
|
||||
self._restore_current[1] = hold_current
|
||||
# Report values
|
||||
if prev_hold_cur is None:
|
||||
gcmd.respond_info("Run Current: %0.2fA" % (prev_cur,))
|
||||
gcmd.respond_info("Run Current: %0.2fA "
|
||||
"Ready Current: %0.2fA"
|
||||
% (prev_cur, self.ready_current))
|
||||
else:
|
||||
gcmd.respond_info("Run Current: %0.2fA Hold Current: %0.2fA"
|
||||
% (prev_cur, prev_hold_cur))
|
||||
gcmd.respond_info("Run Current: %0.2fA "
|
||||
"Hold Current: %0.2fA "
|
||||
"Ready Current: %0.2fA"
|
||||
% (prev_cur, prev_hold_cur, self.ready_current))
|
||||
# Handle printer ready state current reduction
|
||||
def _handle_ready(self, print_time):
|
||||
if self.ready_current >= self.run_current:
|
||||
return
|
||||
if self._in_ready:
|
||||
return
|
||||
ch = self.current_helper
|
||||
run, hold, max_cur = ch.get_current()
|
||||
self._restore_current = [run, hold]
|
||||
def callback(eventtime):
|
||||
if hold is not None:
|
||||
ch.set_current(run, self.ready_current, print_time)
|
||||
else:
|
||||
#TMC2660
|
||||
ch.set_current(self.ready_current, None, print_time)
|
||||
self.printer.get_reactor().register_callback(callback)
|
||||
self._in_ready = True
|
||||
force_move = self.printer.lookup_object("force_move")
|
||||
stepper = force_move.lookup_stepper(self.stepper_name)
|
||||
stepper.add_active_callback(self._restore)
|
||||
def _restore(self, flush_time):
|
||||
if not self._in_ready:
|
||||
return
|
||||
ch = self.current_helper
|
||||
run, hold = self._restore_current
|
||||
def callback(eventtime):
|
||||
ch.set_current(run, hold, flush_time)
|
||||
self.printer.get_reactor().register_callback(callback)
|
||||
self._in_ready = False
|
||||
# Stepper phase tracking
|
||||
def _get_phases(self):
|
||||
return (256 >> self.fields.get_field("mres")) * 4
|
||||
|
|
@ -500,6 +559,8 @@ class TMCCommandHelper:
|
|||
self.stepper_name)
|
||||
# Send init
|
||||
try:
|
||||
ch = self.current_helper
|
||||
ch.set_current(self.run_current, self.hold_current, None)
|
||||
self._init_registers()
|
||||
except self.printer.command_error as e:
|
||||
logging.info("TMC %s failed to init: %s", self.name, str(e))
|
||||
|
|
@ -512,7 +573,8 @@ class TMCCommandHelper:
|
|||
res = {'mcu_phase_offset': self.mcu_phase_offset,
|
||||
'phase_offset_position': cpos,
|
||||
'run_current': current[0],
|
||||
'hold_current': current[1]}
|
||||
'hold_current': current[1],
|
||||
'ready_current': self.ready_current}
|
||||
res.update(self.echeck_helper.get_status(eventtime))
|
||||
return res
|
||||
# DUMP_TMC support
|
||||
|
|
|
|||
|
|
@ -124,16 +124,7 @@ class TMCCurrentHelper:
|
|||
self.name = config.get_name().split()[-1]
|
||||
self.mcu_tmc = mcu_tmc
|
||||
self.fields = mcu_tmc.get_fields()
|
||||
run_current = config.getfloat('run_current',
|
||||
above=0., maxval=MAX_CURRENT)
|
||||
hold_current = config.getfloat('hold_current', MAX_CURRENT,
|
||||
above=0., maxval=MAX_CURRENT)
|
||||
self.req_hold_current = hold_current
|
||||
self.sense_resistor = config.getfloat('sense_resistor', 0.110, above=0.)
|
||||
vsense, irun, ihold = self._calc_current(run_current, hold_current)
|
||||
self.fields.set_field("vsense", vsense)
|
||||
self.fields.set_field("ihold", ihold)
|
||||
self.fields.set_field("irun", irun)
|
||||
def _calc_current_bits(self, current, vsense):
|
||||
sense_resistor = self.sense_resistor + 0.020
|
||||
vref = 0.32
|
||||
|
|
@ -166,9 +157,8 @@ class TMCCurrentHelper:
|
|||
vsense = self.fields.get_field("vsense")
|
||||
run_current = self._calc_current_from_bits(irun, vsense)
|
||||
hold_current = self._calc_current_from_bits(ihold, vsense)
|
||||
return run_current, hold_current, self.req_hold_current, MAX_CURRENT
|
||||
return (run_current, hold_current, MAX_CURRENT)
|
||||
def set_current(self, run_current, hold_current, print_time):
|
||||
self.req_hold_current = hold_current
|
||||
vsense, irun, ihold = self._calc_current(run_current, hold_current)
|
||||
if vsense != self.fields.get_field("vsense"):
|
||||
val = self.fields.set_field("vsense", vsense)
|
||||
|
|
|
|||
|
|
@ -280,17 +280,6 @@ class TMC2240CurrentHelper:
|
|||
self.fields = mcu_tmc.get_fields()
|
||||
self.Rref = config.getfloat('rref', 12000.,
|
||||
minval=12000., maxval=60000.)
|
||||
max_cur = self._get_ifs_rms(3)
|
||||
run_current = config.getfloat('run_current', above=0., maxval=max_cur)
|
||||
hold_current = config.getfloat('hold_current', max_cur,
|
||||
above=0., maxval=max_cur)
|
||||
self.req_hold_current = hold_current
|
||||
current_range = self._calc_current_range(run_current)
|
||||
self.fields.set_field("current_range", current_range)
|
||||
gscaler, irun, ihold = self._calc_current(run_current, hold_current)
|
||||
self.fields.set_field("globalscaler", gscaler)
|
||||
self.fields.set_field("ihold", ihold)
|
||||
self.fields.set_field("irun", irun)
|
||||
def _get_ifs_rms(self, current_range=None):
|
||||
if current_range is None:
|
||||
current_range = self.fields.get_field("current_range")
|
||||
|
|
@ -327,12 +316,15 @@ class TMC2240CurrentHelper:
|
|||
bits = self.fields.get_field(field_name)
|
||||
return globalscaler * (bits + 1) * ifs_rms / (256. * 32.)
|
||||
def get_current(self):
|
||||
ifs_rms = self._get_ifs_rms()
|
||||
ifs_rms = self._get_ifs_rms(3)
|
||||
run_current = self._calc_current_from_field("irun")
|
||||
hold_current = self._calc_current_from_field("ihold")
|
||||
return (run_current, hold_current, self.req_hold_current, ifs_rms)
|
||||
return (run_current, hold_current, ifs_rms)
|
||||
def set_current(self, run_current, hold_current, print_time):
|
||||
self.req_hold_current = hold_current
|
||||
current_range = self._calc_current_range(run_current)
|
||||
if current_range != self.fields.get_field("current_range"):
|
||||
val = self.fields.set_field("current_range", current_range)
|
||||
self.mcu_tmc.set_register("DRV_CONF", val, print_time)
|
||||
gscaler, irun, ihold = self._calc_current(run_current, hold_current)
|
||||
val = self.fields.set_field("globalscaler", gscaler)
|
||||
self.mcu_tmc.set_register("GLOBALSCALER", val, print_time)
|
||||
|
|
|
|||
|
|
@ -118,21 +118,8 @@ class TMC2660CurrentHelper:
|
|||
self.name = config.get_name().split()[-1]
|
||||
self.mcu_tmc = mcu_tmc
|
||||
self.fields = mcu_tmc.get_fields()
|
||||
self.current = config.getfloat('run_current', minval=0.1,
|
||||
maxval=MAX_CURRENT)
|
||||
self.sense_resistor = config.getfloat('sense_resistor')
|
||||
vsense, cs = self._calc_current(self.current)
|
||||
self.fields.set_field("cs", cs)
|
||||
self.fields.set_field("vsense", vsense)
|
||||
|
||||
# Register ready/printing handlers
|
||||
self.idle_current_percentage = config.getint(
|
||||
'idle_current_percent', default=100, minval=0, maxval=100)
|
||||
if self.idle_current_percentage < 100:
|
||||
self.printer.register_event_handler("idle_timeout:printing",
|
||||
self._handle_printing)
|
||||
self.printer.register_event_handler("idle_timeout:ready",
|
||||
self._handle_ready)
|
||||
self.current = .0
|
||||
|
||||
def _calc_current_bits(self, current, vsense):
|
||||
vref = 0.165 if vsense else 0.310
|
||||
|
|
@ -157,16 +144,6 @@ class TMC2660CurrentHelper:
|
|||
irun = irun2
|
||||
return vsense, irun
|
||||
|
||||
def _handle_printing(self, print_time):
|
||||
print_time -= 0.100 # Schedule slightly before deadline
|
||||
self.printer.get_reactor().register_callback(
|
||||
(lambda ev: self._update_current(self.current, print_time)))
|
||||
|
||||
def _handle_ready(self, print_time):
|
||||
current = self.current * float(self.idle_current_percentage) / 100.
|
||||
self.printer.get_reactor().register_callback(
|
||||
(lambda ev: self._update_current(current, print_time)))
|
||||
|
||||
def _update_current(self, current, print_time):
|
||||
vsense, cs = self._calc_current(current)
|
||||
val = self.fields.set_field("cs", cs)
|
||||
|
|
@ -177,7 +154,7 @@ class TMC2660CurrentHelper:
|
|||
self.mcu_tmc.set_register("DRVCONF", val, print_time)
|
||||
|
||||
def get_current(self):
|
||||
return self.current, None, None, MAX_CURRENT
|
||||
return (self.current, None, MAX_CURRENT)
|
||||
|
||||
def set_current(self, run_current, hold_current, print_time):
|
||||
self.current = run_current
|
||||
|
|
|
|||
|
|
@ -268,16 +268,7 @@ class TMC5160CurrentHelper:
|
|||
self.name = config.get_name().split()[-1]
|
||||
self.mcu_tmc = mcu_tmc
|
||||
self.fields = mcu_tmc.get_fields()
|
||||
run_current = config.getfloat('run_current',
|
||||
above=0., maxval=MAX_CURRENT)
|
||||
hold_current = config.getfloat('hold_current', MAX_CURRENT,
|
||||
above=0., maxval=MAX_CURRENT)
|
||||
self.req_hold_current = hold_current
|
||||
self.sense_resistor = config.getfloat('sense_resistor', 0.075, above=0.)
|
||||
gscaler, irun, ihold = self._calc_current(run_current, hold_current)
|
||||
self.fields.set_field("globalscaler", gscaler)
|
||||
self.fields.set_field("ihold", ihold)
|
||||
self.fields.set_field("irun", irun)
|
||||
def _calc_globalscaler(self, current):
|
||||
globalscaler = int((current * 256. * math.sqrt(2.)
|
||||
* self.sense_resistor / VREF) + .5)
|
||||
|
|
@ -307,9 +298,8 @@ class TMC5160CurrentHelper:
|
|||
def get_current(self):
|
||||
run_current = self._calc_current_from_field("irun")
|
||||
hold_current = self._calc_current_from_field("ihold")
|
||||
return run_current, hold_current, self.req_hold_current, MAX_CURRENT
|
||||
return (run_current, hold_current, MAX_CURRENT)
|
||||
def set_current(self, run_current, hold_current, print_time):
|
||||
self.req_hold_current = hold_current
|
||||
gscaler, irun, ihold = self._calc_current(run_current, hold_current)
|
||||
val = self.fields.set_field("globalscaler", gscaler)
|
||||
self.mcu_tmc.set_register("GLOBALSCALER", val, print_time)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue