diff --git a/docs/Config_Reference.md b/docs/Config_Reference.md index 4ceaa46d5..8eb198ba7 100644 --- a/docs/Config_Reference.md +++ b/docs/Config_Reference.md @@ -3908,8 +3908,14 @@ run_current: # The amount of time (in seconds) to wait after changing homing current. # The default is 0.5 seconds. #sense_resistor: 0.110 -# The resistance (in ohms) of the motor sense resistor. The default -# is 0.110 ohms. +# The resistance (in ohms) of the motor sense resistor. Overwrites +# value defined by stepstick_type. The default is 0.110 ohms. +#stepstick_type: +# Here, you will input the name of your stepper driver. This is used +# to define a more accurate max current, and also the proper sense +# resistor value. sense_resistor config entry overwrites a sense +# resistor value defined by this entry. +# (See the Stepstick_Types.md document for more details on each driver) #stealthchop_threshold: 0 # The velocity (in mm/s) to set the "stealthChop" threshold to. When # set, "stealthChop" mode will be enabled if the stepper motor @@ -4019,8 +4025,14 @@ run_current: # The amount of time (in seconds) to wait after changing homing current. # The default is 0.5 seconds. #sense_resistor: 0.110 -# The resistance (in ohms) of the motor sense resistor. The default -# is 0.110 ohms. +# The resistance (in ohms) of the motor sense resistor. Overwrites +# value defined by stepstick_type. The default is 0.110 ohms. +#stepstick_type: +# Here, you will input the name of your stepper driver. This is used +# to define a more accurate max current, and also the proper sense +# resistor value. sense_resistor config entry overwrites a sense +# resistor value defined by this entry. +# (See the Stepstick_Types.md document for more details on each driver) #stealthchop_threshold: 0 # The velocity (in mm/s) to set the "stealthChop" threshold to. When # set, "stealthChop" mode will be enabled if the stepper motor @@ -4064,6 +4076,14 @@ run_current: #home_current: #current_change_dwell_time: #sense_resistor: 0.110 +# The resistance (in ohms) of the motor sense resistor. Overwrites +# value defined by stepstick_type. The default is 0.110 ohms. +#stepstick_type: +# Here, you will input the name of your stepper driver. This is used +# to define a more accurate max current, and also the proper sense +# resistor value. sense_resistor config entry overwrites a sense +# resistor value defined by this entry. +# (See the Stepstick_Types.md document for more details on each driver) #stealthchop_threshold: 0 # See the "tmc2208" section for the definition of these parameters. #coolstep_threshold: @@ -4145,8 +4165,14 @@ run_current: # The amount of time (in seconds) to wait after changing homing current. # The default is 0.5 seconds. #sense_resistor: -# The resistance (in ohms) of the motor sense resistor. This -# parameter must be provided. +# The resistance (in ohms) of the motor sense resistor. Overwrites +# value defined by stepstick_type. The default is 0.110 ohms. +#stepstick_type: +# Here, you will input the name of your stepper driver. This is used +# to define a more accurate max current, and also the proper sense +# resistor value. sense_resistor config entry overwrites a sense +# resistor value defined by this entry. +# (See the Stepstick_Types.md document for more details on each driver) #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 @@ -4370,8 +4396,14 @@ run_current: # The amount of time (in seconds) to wait after changing homing current. # The default is 0.5 seconds. #sense_resistor: 0.075 -# The resistance (in ohms) of the motor sense resistor. The default -# is 0.075 ohms. +# The resistance (in ohms) of the motor sense resistor. Overwrites +# value defined by stepstick_type. The default is 0.075 ohms. +#stepstick_type: +# Here, you will input the name of your stepper driver. This is used +# to define a more accurate max current, and also the proper sense +# resistor value. sense_resistor config entry overwrites a sense +# resistor value defined by this entry. +# (See the Stepstick_Types.md document for more details on each driver) #stealthchop_threshold: 0 # The velocity (in mm/s) to set the "stealthChop" threshold to. When # set, "stealthChop" mode will be enabled if the stepper motor @@ -5770,4 +5802,4 @@ via the `i2c_speed` parameter. All other Klipper micro-controllers use a # The Klipper implementation on most micro-controllers is hard-coded # to 100000 and changing this value has no effect. The default is # 100000. Linux, RP2040 and ATmega support 400000. -``` +``` \ No newline at end of file diff --git a/docs/Stepstick_Types.md b/docs/Stepstick_Types.md new file mode 100644 index 000000000..785fa2572 --- /dev/null +++ b/docs/Stepstick_Types.md @@ -0,0 +1,64 @@ +# Stepstick Type Definitions + +This page contains information to assist in defining the `stepstick_type` config entry. + +In stock Klipper behavior, selecting a driver automatically uses the TMC definitions' default sense resistor. While this is usually fine, it can cause issues with driver boards that have unconventional sense resistor sizes, leading to incorrect current values being set. + +The goal of these changes to DangerKlipper is to allow you to set custom sense resistor and max current values for your stepper drivers. This results in more accurate configurations for your setup and enhances safety. + + +## Use +In practice, you should set your driver using `stepstick_type`. If you need to override the default value, you can then use `sense_resistor`. Additionally, `stepstick_type` is not required to use `sense_resistor`. If neither `stepstick_type` or `sense_resistor` is set, the default +Klipper behavior of using the TMC default value will be used (i.e. 0.075 for 5160). + +> [!NOTE] +> Drivers with variable sense resistors (such as the FYSETC EXT2160) have not been defined and have been left out of the table intentionally. You must set sense resistor for them manually. + + +| Stepstick Type | Config Name | Sense Resistor | Max Current | +|-----------------------------------------|-------------------------|----------------|-------------| +| BTT Kraken S1-4 | KRAKEN_2160_8A | 0.022 | 8 | +| BTT Kraken S5-8 | KRAKEN_2160_3A | 0.022 | 3 | +| LDO Leviathan HV0,HV1 | REFERENCE_5160 | 0.075 | 3 | +| LDO Leviathan S0-4 | REFERENCE_2209 | 0.11 | 2 | +| BTT TMC2208 | REFERENCE_2209 | 0.11 | 2 | +| BTT TMC2209 | REFERENCE_2209 | 0.11 | 2 | +| BTT TMC2240 | BTT_2240 | 0.11 | 2 | +| BTT TMC5160T Pro | REFERENCE_5160 | 0.075 | 3 | +| BTT EZ2130 | REFERENCE_2209 | 0.11 | 2 | +| BTT EZ2208 | REFERENCE_2209 | 0.11 | 2 | +| BTT EZ2209 | REFERENCE_2209 | 0.11 | 2 | +| BTT EZ2225 | REFERENCE_2209 | 0.11 | 2 | +| BTT EZ2226 | REFERENCE_2209 | 0.11 | 2 | +| BTT EZ5160 Pro | BTT_EZ_5160_PRO | 0.075 | 2.5 | +| BTT EZ5160 RGB | BTT_EZ_5160_RGB | 0.05 | 4.7 | +| BTT EZ6609 | REFERENCE_2209 | 0.11 | 2 | +| BTT TMC5160T Plus | BTT_EXT_5160 | 0.022 | 10.6 | +| COREVUS TMC2209 | COREVUS_2209 | 0.1 | 3 | +| COREVUS TMC2160 OLD | COREVUS_2160_OLD | 0.03 | 3 | +| COREVUS TMC2160 5A | COREVUS_2160_5A | 0.03 | 5 | +| COREVUS TMC2160 | COREVUS_2160 | 0.05 | 3 | +| Watterott SilentStepStick TMC2100 | REFERENCE_WOTT | 0.11 | 1.2 | +| Watterott SilentStepStick TMC2130 | REFERENCE_WOTT | 0.11 | 1.2 | +| Watterott SilentStepStick TMC2208 | REFERENCE_WOTT | 0.11 | 1.2 | +| Watterott SilentStepStick TMC2209 | WOTT_2209 | 0.11 | 1.7 | +| Watterott SilentStepStick TMC5160 | REFERENCE_5160 | 0.075 | 3 | +| Watterott SilentStepStick TMC5160HV | REFERENCE_5160 | 0.075 | 3 | +| FYSETC TMC2100 | REFERENCE_WOTT | 0.11 | 1.2 | +| FYSETC TMC2130 | REFERENCE_WOTT | 0.11 | 1.2 | +| FYSETC TMC2208 | REFERENCE_WOTT | 0.11 | 1.2 | +| FYSETC TMC2209 | WOTT_2209 | 0.11 | 1.7 | +| FYSETC TMC2225 | FYSETC_2225 | 0.11 | 1.4 | +| FYSETC TMC2226 | REFERENCE_2209 | 0.11 | 2 | +| FYSETC HV5160 | REFERENCE_5160 | 0.075 | 3 | +| FYSETC QHV5160 | REFERENCE_5160 | 0.075 | 3 | +| FYSETC Silent5161 | FYSETC_5161 | 0.06 | 3.5 | +| MKS 2130 | REFERENCE_2209 | 0.11 | 2 | +| MKS 2208 | REFERENCE_2209 | 0.11 | 2 | +| MKS 2209 | REFERENCE_2209 | 0.11 | 2 | +| MKS 2225 | REFERENCE_2209 | 0.11 | 2 | +| MKS 2226 | MKS_2226 | 0.17 | 2.5 | +| MKS 2240 | REFERENCE_2209 | 0.11 | 2 | +| Mellow Fly 2209 | REFERENCE_2209 | 0.11 | 2 | +| Mellow Fly 5160 | MELLOW_FLY_5160 | 0.11 | 3 | +| Mellow Fly HV-TMC5160 Pro | MELLOW_FLY_HV_5160_Pro | 0.033 | 6 | diff --git a/klippy/extras/stepstick_defs.py b/klippy/extras/stepstick_defs.py new file mode 100644 index 000000000..2139d2c63 --- /dev/null +++ b/klippy/extras/stepstick_defs.py @@ -0,0 +1,22 @@ +STEPSTICK_DEFS = { + "REFERENCE_WOTT": (0.11, 1.2), + "REFERENCE_2209": (0.11, 2), + "REFERENCE_5160": (0.075, 3), + "KRAKEN_2160_8A": (0.022, 8), + "KRAKEN_2160_3A": (0.022, 3), + "BTT_2240": (0.11, 2.1), + "BTT_EZ_5160_PRO": (0.075, 2.5), + "BTT_EZ_5160_RGB": (0.05, 4.7), + "BTT_EZ_6609": (0.11, 2), + "BTT_5160T": (0.022, 10.6), + "WOTT_2209": (0.11, 1.7), + "COREVUS_2209": (0.1, 3), + "COREVUS_2160_OLD": (0.03, 3), + "COREVUS_2160_5A": (0.03, 5), + "COREVUS_2160": (0.05, 3), + "FYSETC_2225": (0.11, 1.4), + "FYSETC_5161": (0.06, 3.5), + "MKS_2226": (0.17, 2.5), + "MELLOW_FLY_5160": (0.11, 3), + "MELLOW_FLY_HV_5160_Pro": (0.033, 6), +} diff --git a/klippy/extras/tmc.py b/klippy/extras/tmc.py index 473ddcd42..93b5f64e8 100644 --- a/klippy/extras/tmc.py +++ b/klippy/extras/tmc.py @@ -5,6 +5,7 @@ # This file may be distributed under the terms of the GNU GPLv3 license. import logging, collections import stepper +from . import stepstick_defs ###################################################################### @@ -349,57 +350,44 @@ def cmd_SET_TMC_FIELD(self, gcmd): def cmd_SET_TMC_CURRENT(self, gcmd): ch = self.current_helper ( - prev_cur, - prev_hold_cur, - req_hold_cur, - max_cur, - prev_home_cur, + run_current, + hold_current, + req_hold_current, + home_current, ) = ch.get_current() - run_current = gcmd.get_float( - "CURRENT", None, minval=0.0, maxval=max_cur + max_current = ch.get_max_current() + cmd_run_current = gcmd.get_float( + "CURRENT", None, minval=0.0, maxval=max_current ) - hold_current = gcmd.get_float( - "HOLDCURRENT", None, above=0.0, maxval=max_cur + cmd_hold_current = gcmd.get_float( + "HOLDCURRENT", None, above=0.0, maxval=max_current ) - home_current = gcmd.get_float( - "HOMECURRENT", None, above=0.0, maxval=max_cur + cmd_home_current = gcmd.get_float( + "HOMECURRENT", None, above=0.0, maxval=max_current ) - if ( - run_current is not None - or hold_current is not None - or home_current is not None - ): - if run_current is not None: - ch.set_run_current(run_current) - else: - run_current = prev_cur - - if hold_current is None: - hold_current = req_hold_cur - - if home_current is not None: - ch.set_home_current(home_current) - - 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, - prev_home_cur, - ) = ch.get_current() + if cmd_run_current: + run_current = cmd_run_current + ch.set_run_current(run_current) + if cmd_hold_current: + hold_current = cmd_hold_current + ch.set_hold_current(hold_current) + if cmd_home_current: + home_current = cmd_home_current + ch.set_home_current(home_current) + + toolhead = self.printer.lookup_object("toolhead") + print_time = toolhead.get_last_move_time() + ch.apply_run_current(print_time) # Report values - if prev_hold_cur is None: + if hold_current is None: gcmd.respond_info( "Run Current: %0.2fA Home Current: %0.2fA" - % (prev_cur, prev_home_cur) + % (run_current, home_current) ) else: gcmd.respond_info( "Run Current: %0.2fA Hold Current: %0.2fA Home Current: %0.2fA" - % (prev_cur, prev_hold_cur, prev_home_cur) + % (run_current, hold_current, home_current) ) # Stepper phase tracking @@ -771,12 +759,43 @@ def TMCStealthchopHelper(config, mcu_tmc, tmc_freq): class BaseTMCCurrentHelper: - def __init__(self, config, mcu_tmc, max_current): + def __init__(self, config, mcu_tmc): self.printer = config.get_printer() + self.config_file = self.printer.lookup_object("configfile") self.name = config.get_name().split()[-1] self.mcu_tmc = mcu_tmc self.fields = mcu_tmc.get_fields() + stepper_driver_type = config.get("stepstick_type", None) + sense_resistor_from_driver, step_driver_max_current = ( + stepstick_defs.STEPSTICK_DEFS.get(stepper_driver_type, (None, None)) + ) + + override_sense_resistor = config.getfloat( + "sense_resistor", + None, + minval=0.0, + ) + if ( + override_sense_resistor is None + and sense_resistor_from_driver is None + ): + self.sense_resistor = self.DEFAULT_SENSE_RESISTOR + self.config_file.warn( + "config", + f"""Neither 'stepper_driver_type' or 'sense_resistor' is defined for [{self.name}]. + Using default value of {self.sense_resistor} ohm sense resistor. + If this is incorrect, your drivers or board may be damaged.""", + "sense_resistor", + ) + + else: + self.sense_resistor = ( + override_sense_resistor or sense_resistor_from_driver + ) + + max_current = step_driver_max_current or self.DEFAULT_MAX_CURRENT + # config_{run|hold|home}_current # represents an initial value set via config file self.config_run_current = config.getfloat( @@ -807,9 +826,11 @@ def __init__(self, config, mcu_tmc, max_current): # It fluctuates between req_run_current and req_home_current # during homing self.actual_current = self.req_run_current - self.max_current = max_current + def get_max_current(self): + return self.max_current + def needs_home_current_change(self): needs = self.actual_current != self.req_home_current logging.info(f"tmc {self.name}: needs_home_current_change {needs}") @@ -825,6 +846,13 @@ def needs_hold_current_change(self, hold_current): logging.info(f"tmc {self.name}: needs_hold_current_change {needs}") return needs + def apply_run_current(self, print_time): + if self.needs_current_changes( + self.req_run_current, self.req_hold_current + ): + self.set_actual_current(self.req_run_current) + self.apply_current(print_time) + def set_home_current(self, new_home_current): self.req_home_current = min(self.max_current, new_home_current) diff --git a/klippy/extras/tmc2130.py b/klippy/extras/tmc2130.py index 99c25fb8e..54f54d29c 100644 --- a/klippy/extras/tmc2130.py +++ b/klippy/extras/tmc2130.py @@ -5,7 +5,6 @@ # This file may be distributed under the terms of the GNU GPLv3 license. import math from . import bus, tmc -from configfile import PrinterConfig TMC_FREQUENCY = 13200000.0 @@ -195,29 +194,14 @@ # TMC stepper current config helper ###################################################################### -MAX_CURRENT = 2.000 - class TMC2130CurrentHelper(tmc.BaseTMCCurrentHelper): + DEFAULT_SENSE_RESISTOR = 0.110 + DEFAULT_MAX_CURRENT = 2.000 + def __init__(self, config, mcu_tmc): - super().__init__(config, mcu_tmc, MAX_CURRENT) - pconfig: PrinterConfig = self.printer.lookup_object("configfile") - - self.sense_resistor = config.get("sense_resistor", None) - if self.sense_resistor is None: - pconfig.warn( - "config", - f"""[{self.name}] sense_resistor not specified; using default = 0.110. - If this value is wrong, it might burn your house down. - This parameter will be mandatory in future versions. - Specify the parameter to resolve this warning""", - self.name, - "sense_resistor", - ) - - self.sense_resistor = config.getfloat( - "sense_resistor", 0.110, above=0.0 - ) + super().__init__(config, mcu_tmc) + vsense, irun, ihold = self._calc_current( self.req_run_current, self.req_hold_current ) @@ -267,7 +251,6 @@ def get_current(self): run_current, hold_current, self.req_hold_current, - MAX_CURRENT, self.req_home_current, ) diff --git a/klippy/extras/tmc2240.py b/klippy/extras/tmc2240.py index 3c8665a27..70b6f5c95 100644 --- a/klippy/extras/tmc2240.py +++ b/klippy/extras/tmc2240.py @@ -347,14 +347,12 @@ def _calc_current_from_field(self, field_name): return globalscaler * (bits + 1) * ifs_rms / (256.0 * 32.0) def get_current(self): - ifs_rms = self._get_ifs_rms() 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, self.req_home_current, ) diff --git a/klippy/extras/tmc2660.py b/klippy/extras/tmc2660.py index 7356c658d..e54a81d55 100644 --- a/klippy/extras/tmc2660.py +++ b/klippy/extras/tmc2660.py @@ -111,15 +111,18 @@ # TMC stepper current config helper ###################################################################### -MAX_CURRENT = 2.400 - class TMC2660CurrentHelper(tmc.BaseTMCCurrentHelper): + DEFAULT_MAX_CURRENT = 2.400 + def __init__(self, config, mcu_tmc): - super().__init__(config, mcu_tmc, MAX_CURRENT) + super().__init__(config, mcu_tmc) self.current = self.req_run_current - self.sense_resistor = config.getfloat("sense_resistor") + + if self.sense_resistor is None: + self.sense_resistor = config.getfloat("sense_resistor") + vsense, cs = self._calc_current(self.req_run_current) self.fields.set_field("cs", cs) self.fields.set_field("vsense", vsense) @@ -187,10 +190,12 @@ def get_current(self): self.req_run_current, None, None, - MAX_CURRENT, self.req_home_current, ) + def apply_current(self, print_time): + self._update_current(self.actual_current, print_time) + def set_current(self, run_current, hold_current, print_time, force=False): if run_current == self.current and not force: return diff --git a/klippy/extras/tmc5160.py b/klippy/extras/tmc5160.py index f1003f977..1139e8006 100644 --- a/klippy/extras/tmc5160.py +++ b/klippy/extras/tmc5160.py @@ -6,7 +6,6 @@ import math from . import tmc from . import tmc2130 -from configfile import PrinterConfig TMC_FREQUENCY = 12000000.0 @@ -249,29 +248,15 @@ ###################################################################### VREF = 0.325 -MAX_CURRENT = 10.000 # Maximum dependent on board, but 10 is safe sanity check class TMC5160CurrentHelper(tmc.BaseTMCCurrentHelper): - def __init__(self, config, mcu_tmc): - super().__init__(config, mcu_tmc, MAX_CURRENT) - pconfig: PrinterConfig = self.printer.lookup_object("configfile") + DEFAULT_SENSE_RESISTOR = 0.075 + DEFAULT_MAX_CURRENT = 10.000 - self.sense_resistor = config.get("sense_resistor", None) - if self.sense_resistor is None: - pconfig.warn( - "config", - f"""[{self.name}] sense_resistor not specified; using default = 0.075. - If this value is wrong, it might burn your house down. - This parameter will be mandatory in future versions. - Specify the parameter to resolve this warning""", - self.name, - "sense_resistor", - ) + def __init__(self, config, mcu_tmc): + super().__init__(config, mcu_tmc) - self.sense_resistor = config.getfloat( - "sense_resistor", 0.075, above=0.0 - ) gscaler, irun, ihold = self._calc_current( self.req_run_current, self.req_hold_current ) @@ -325,7 +310,6 @@ def get_current(self): run_current, hold_current, self.req_hold_current, - MAX_CURRENT, self.req_home_current, )