tmc: Track requested hold_current so SET_TMC_CURRENT doesn't reduce it

The code automatically reduces the hold_current so that it is no
greater than the run_current.  However, this could lead to confusing
behavior if one reduced and then increased the run_current via
SET_TMC_CURRENT commands.  To avoid that, this change adds support for
tracking the requested hold_current - thus changes to run_current
don't subtly alter the hold_current.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2021-10-24 20:03:42 -04:00
parent 627c1c5d2a
commit 86fee2d517
5 changed files with 20 additions and 17 deletions

View File

@ -2760,8 +2760,8 @@ run_current:
# during stepper movement. This parameter must be provided. # during stepper movement. This parameter must be provided.
#hold_current: #hold_current:
# The amount of current (in amps RMS) to configure the driver to use # The amount of current (in amps RMS) to configure the driver to use
# when the stepper is not moving. The default is to use the same # when the stepper is not moving. The default is to not reduce the
# value as run_current. # current.
#sense_resistor: 0.110 #sense_resistor: 0.110
# The resistance (in ohms) of the motor sense resistor. The default # The resistance (in ohms) of the motor sense resistor. The default
# is 0.110 ohms. # is 0.110 ohms.

View File

@ -261,26 +261,25 @@ class TMCCommandHelper:
cmd_SET_TMC_CURRENT_help = "Set the current of a TMC driver" cmd_SET_TMC_CURRENT_help = "Set the current of a TMC driver"
def cmd_SET_TMC_CURRENT(self, gcmd): def cmd_SET_TMC_CURRENT(self, gcmd):
ch = self.current_helper ch = self.current_helper
prev_run_current, prev_hold_current, max_current = ch.get_current() prev_cur, prev_hold_cur, req_hold_cur, max_cur = ch.get_current()
run_current = gcmd.get_float('CURRENT', None, run_current = gcmd.get_float('CURRENT', None, minval=0., maxval=max_cur)
minval=0., maxval=max_current)
hold_current = gcmd.get_float('HOLDCURRENT', None, hold_current = gcmd.get_float('HOLDCURRENT', None,
above=0., maxval=max_current) above=0., maxval=max_cur)
if run_current is not None or hold_current is not None: if run_current is not None or hold_current is not None:
if run_current is None: if run_current is None:
run_current = prev_run_current run_current = prev_cur
if hold_current is None: if hold_current is None:
hold_current = prev_hold_current hold_current = req_hold_cur
toolhead = self.printer.lookup_object('toolhead') toolhead = self.printer.lookup_object('toolhead')
print_time = toolhead.get_last_move_time() print_time = toolhead.get_last_move_time()
ch.set_current(run_current, hold_current, print_time) ch.set_current(run_current, hold_current, print_time)
prev_run_current, prev_hold_current, max_current = ch.get_current() prev_cur, prev_hold_cur, req_hold_cur, max_cur = ch.get_current()
# Report values # Report values
if prev_hold_current is None: if prev_hold_cur is None:
gcmd.respond_info("Run Current: %0.2fA" % (prev_run_current,)) gcmd.respond_info("Run Current: %0.2fA" % (prev_cur,))
else: else:
gcmd.respond_info("Run Current: %0.2fA Hold Current: %0.2fA" gcmd.respond_info("Run Current: %0.2fA Hold Current: %0.2fA"
% (prev_run_current, prev_hold_current)) % (prev_cur, prev_hold_cur))
# Stepper phase tracking # Stepper phase tracking
def _get_phases(self): def _get_phases(self):
return (256 >> self.fields.get_field("mres")) * 4 return (256 >> self.fields.get_field("mres")) * 4

View File

@ -103,8 +103,9 @@ class TMCCurrentHelper:
self.fields = mcu_tmc.get_fields() self.fields = mcu_tmc.get_fields()
run_current = config.getfloat('run_current', run_current = config.getfloat('run_current',
above=0., maxval=MAX_CURRENT) above=0., maxval=MAX_CURRENT)
hold_current = config.getfloat('hold_current', run_current, hold_current = config.getfloat('hold_current', MAX_CURRENT,
above=0., maxval=MAX_CURRENT) above=0., maxval=MAX_CURRENT)
self.req_hold_current = hold_current
self.sense_resistor = config.getfloat('sense_resistor', 0.110, above=0.) self.sense_resistor = config.getfloat('sense_resistor', 0.110, above=0.)
vsense, irun, ihold = self._calc_current(run_current, hold_current) vsense, irun, ihold = self._calc_current(run_current, hold_current)
self.fields.set_field("vsense", vsense) self.fields.set_field("vsense", vsense)
@ -139,8 +140,9 @@ class TMCCurrentHelper:
def get_current(self): def get_current(self):
run_current = self._calc_current_from_field("irun") run_current = self._calc_current_from_field("irun")
hold_current = self._calc_current_from_field("ihold") hold_current = self._calc_current_from_field("ihold")
return run_current, hold_current, MAX_CURRENT return run_current, hold_current, self.req_hold_current, MAX_CURRENT
def set_current(self, run_current, hold_current, print_time): 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) vsense, irun, ihold = self._calc_current(run_current, hold_current)
if vsense != self.fields.get_field("vsense"): if vsense != self.fields.get_field("vsense"):
val = self.fields.set_field("vsense", vsense) val = self.fields.set_field("vsense", vsense)

View File

@ -169,7 +169,7 @@ class TMC2660CurrentHelper:
self.mcu_tmc.set_register("DRVCONF", val, print_time) self.mcu_tmc.set_register("DRVCONF", val, print_time)
def get_current(self): def get_current(self):
return self.current, None, MAX_CURRENT return self.current, None, None, MAX_CURRENT
def set_current(self, run_current, hold_current, print_time): def set_current(self, run_current, hold_current, print_time):
self.current = run_current self.current = run_current

View File

@ -235,8 +235,9 @@ class TMC5160CurrentHelper:
self.fields = mcu_tmc.get_fields() self.fields = mcu_tmc.get_fields()
run_current = config.getfloat('run_current', run_current = config.getfloat('run_current',
above=0., maxval=MAX_CURRENT) above=0., maxval=MAX_CURRENT)
hold_current = config.getfloat('hold_current', run_current, hold_current = config.getfloat('hold_current', MAX_CURRENT,
above=0., maxval=MAX_CURRENT) above=0., maxval=MAX_CURRENT)
self.req_hold_current = hold_current
self.sense_resistor = config.getfloat('sense_resistor', 0.075, above=0.) self.sense_resistor = config.getfloat('sense_resistor', 0.075, above=0.)
self._set_globalscaler(run_current) self._set_globalscaler(run_current)
irun, ihold = self._calc_current(run_current, hold_current) irun, ihold = self._calc_current(run_current, hold_current)
@ -271,8 +272,9 @@ class TMC5160CurrentHelper:
def get_current(self): def get_current(self):
run_current = self._calc_current_from_field("irun") run_current = self._calc_current_from_field("irun")
hold_current = self._calc_current_from_field("ihold") hold_current = self._calc_current_from_field("ihold")
return run_current, hold_current, MAX_CURRENT return run_current, hold_current, self.req_hold_current, MAX_CURRENT
def set_current(self, run_current, hold_current, print_time): def set_current(self, run_current, hold_current, print_time):
self.req_hold_current = hold_current
irun, ihold = self._calc_current(run_current, hold_current) irun, ihold = self._calc_current(run_current, hold_current)
self.fields.set_field("ihold", ihold) self.fields.set_field("ihold", ihold)
val = self.fields.set_field("irun", irun) val = self.fields.set_field("irun", irun)