diff --git a/docs/Config_Reference.md b/docs/Config_Reference.md index d247a9ecc..c1a70bc66 100644 --- a/docs/Config_Reference.md +++ b/docs/Config_Reference.md @@ -5114,6 +5114,10 @@ adc2: #enable: False # Sensor enabled or disabled after power on. The default is to # disable. +#enable_flow_compensation: True +# Flow compensation enabled or disabled. If set to False, the sensor +# will not modify the extrusion multiplier and will only trigger +# runout events. The default is True. #measurement_interval: 10 # The approximate distance (in mm) between sensor readings. The # default is 10mm. diff --git a/docs/G-Codes.md b/docs/G-Codes.md index 1afaa2bb8..19185ca9e 100644 --- a/docs/G-Codes.md +++ b/docs/G-Codes.md @@ -780,19 +780,22 @@ is enabled (also see [TSLl401CL Filament Width Sensor](TSL1401CL_Filament_Width_ and [Hall Filament Width Sensor](Hall_Filament_Width_Sensor.md)): #### QUERY_FILAMENT_WIDTH -`QUERY_FILAMENT_WIDTH`: Return the current measured filament width. +`QUERY_FILAMENT_WIDTH`: Return the current measured filament width, the +state of the width sensor, the state of the filament sensor and the state +of flow compensation. #### RESET_FILAMENT_WIDTH_SENSOR `RESET_FILAMENT_WIDTH_SENSOR`: Clear all sensor readings. Helpful -after filament change. +after filament change. Resets flow rate to 100%. #### DISABLE_FILAMENT_WIDTH_SENSOR `DISABLE_FILAMENT_WIDTH_SENSOR`: Turn off the filament width sensor -and stop using it for flow control. +and stop using it for flow compensation. Resets flow rate to 100%. #### ENABLE_FILAMENT_WIDTH_SENSOR -`ENABLE_FILAMENT_WIDTH_SENSOR`: Turn on the filament width sensor and -start using it for flow control. +`ENABLE_FILAMENT_WIDTH_SENSOR [FLOW_COMPENSATION=[0|1]`: Turn on the filament +width sensor and enable or disable flow compensation. If `FLOW_COMPENSATION` +is not specified, the current flow compensation state is preserved. #### QUERY_RAW_FILAMENT_WIDTH `QUERY_RAW_FILAMENT_WIDTH`: Return the current ADC channel readings diff --git a/docs/Hall_Filament_Width_Sensor.md b/docs/Hall_Filament_Width_Sensor.md index 9992ef730..f51a6aa94 100644 --- a/docs/Hall_Filament_Width_Sensor.md +++ b/docs/Hall_Filament_Width_Sensor.md @@ -56,6 +56,27 @@ By default, the sensor is disabled at power-on. To enable the sensor, issue **ENABLE_FILAMENT_WIDTH_SENSOR** command or set the `enable` parameter to `true`. +## Use as a runout switch only + +By default, the sensor measures filament diameter and adjusts the extrusion multiplier +to compensate for variations. + +If you want to use the sensor as a runout switch only, set the `enable_flow_compensation` +config parameter to `false`. In this mode, the sensor will only trigger runout +events when filament is not detected, it will not modify the extrusion multiplier. + +This is useful for printers where the filament sensor is not accurate enough for +flow compensation but can reliably detect filament runout, or when printing with +flexible filaments which have unstable diameter characteristics. + +Issue **ENABLE_FILAMENT_WIDTH_SENSOR FLOW_COMPENSATION=1** to enable flow compensation +or **ENABLE_FILAMENT_WIDTH_SENSOR FLOW_COMPENSATION=0** to disable it. + +Note that disabling filament width compensation automatically resets the extrusion +multiplier to 100%. + +**QUERY_FILAMENT_WIDTH** includes the current state of flow compensation in its output. + ## Logging By default, diameter logging is disabled at power-on. diff --git a/docs/Status_Reference.md b/docs/Status_Reference.md index 1f6704acc..913bf10a8 100644 --- a/docs/Status_Reference.md +++ b/docs/Status_Reference.md @@ -248,6 +248,7 @@ object: - all items from [filament_switch_sensor](Status_Reference.md#filament_switch_sensor) - `is_active`: Returns True if the sensor is currently active. +- `flow_compensation_enabled`: Returns True if flow compensation is enabled. - `Diameter`: The last reading from the sensor in mm. - `Raw`: The last raw ADC reading from the sensor. diff --git a/klippy/extras/hall_filament_width_sensor.py b/klippy/extras/hall_filament_width_sensor.py index 6c981303b..f391b2f77 100644 --- a/klippy/extras/hall_filament_width_sensor.py +++ b/klippy/extras/hall_filament_width_sensor.py @@ -33,6 +33,8 @@ class HallFilamentWidthSensor: self.runout_dia_min=config.getfloat('min_diameter', 1.0) self.runout_dia_max=config.getfloat('max_diameter', self.max_diameter) self.is_log =config.getboolean('logging', False) + self.enable_flow_compensation = config.getboolean( + 'enable_flow_compensation', True) # Use the current diameter instead of nominal while the first # measurement isn't in place self.use_current_dia_while_delay = config.getboolean( @@ -147,15 +149,17 @@ class HallFilamentWidthSensor: self.filament_width = self.diameter elif self.firstExtruderUpdatePosition == pending_position: self.filament_width = self.nominal_filament_dia - if ((self.filament_width <= self.max_diameter) - and (self.filament_width >= self.min_diameter)): - percentage = round(self.nominal_filament_dia**2 - / self.filament_width**2 * 100) - self.gcode.run_script("M221 S" + str(percentage)) - else: - self.gcode.run_script("M221 S100") + if self.enable_flow_compensation: + if ((self.filament_width <= self.max_diameter) + and (self.filament_width >= self.min_diameter)): + percentage = round(self.nominal_filament_dia**2 + / self.filament_width**2 * 100) + self.gcode.run_script("M221 S" + str(percentage)) + else: + self.gcode.run_script("M221 S100") else: - self.gcode.run_script("M221 S100") + if self.enable_flow_compensation: + self.gcode.run_script("M221 S100") self.filament_array = [] if self.is_active: @@ -164,12 +168,23 @@ class HallFilamentWidthSensor: return self.reactor.NEVER def cmd_M407(self, gcmd): - response = "" - if self.diameter > 0: - response += ("Filament dia (measured mm): " - + str(self.diameter)) + response = "Filament diameter: " + if self.is_active: + response += "%.3f mm" % (self.diameter) else: - response += "Filament NOT present" + response += "sensor disabled" + response += "\nFilament state:" + if self.is_active: + if self.runout_helper.filament_present: + response += " present" + else: + response += " not present" + else: + response += " sensor disabled" + response += ("\nWidth sensor:" + + (" ON" if self.is_active else " OFF")) + response += ("\nFlow compensation:" + + (" ON" if self.enable_flow_compensation else " OFF")) gcmd.respond_info(response) def cmd_ClearFilamentArray(self, gcmd): @@ -179,53 +194,58 @@ class HallFilamentWidthSensor: self.gcode.run_script_from_command("M221 S100") def cmd_M405(self, gcmd): - response = "Filament width sensor Turned On" - if self.is_active: - response = "Filament width sensor is already On" - else: - self.is_active = True - # Start extrude factor update timer + flow_comp = gcmd.get_int("FLOW_COMPENSATION", None, minval=0, maxval=1) + if flow_comp is not None: + self.enable_flow_compensation = flow_comp + if not flow_comp: + self.gcode.run_script_from_command("M221 S100") + + was_active = self.is_active + self.is_active = True + response = ("Filament width sensor: ON" + + "\nFlow compensation: " + + ("ON" if self.enable_flow_compensation else "OFF")) + + # Only start/restart timer if sensor was previously inactive + if not was_active: self.reactor.update_timer(self.extrude_factor_update_timer, - self.reactor.NOW) + self.reactor.NOW) gcmd.respond_info(response) def cmd_M406(self, gcmd): - response = "Filament width sensor Turned Off" - if not self.is_active: - response = "Filament width sensor is already Off" - else: - self.is_active = False - # Stop extrude factor update timer - self.reactor.update_timer(self.extrude_factor_update_timer, - self.reactor.NEVER) - # Clear filament array - self.filament_array = [] - # Set extrude multiplier to 100% - self.gcode.run_script_from_command("M221 S100") + response = "Filament width sensor: OFF" + self.is_active = False + # Stop extrude factor update timer + self.reactor.update_timer(self.extrude_factor_update_timer, + self.reactor.NEVER) + # Clear filament array + self.filament_array = [] + # Set extrude multiplier to 100% + self.gcode.run_script_from_command("M221 S100") gcmd.respond_info(response) def cmd_Get_Raw_Values(self, gcmd): - response = "ADC1=" - response += (" "+str(self.lastFilamentWidthReading)) - response += (" ADC2="+str(self.lastFilamentWidthReading2)) - response += (" RAW="+ - str(self.lastFilamentWidthReading - +self.lastFilamentWidthReading2)) + response = ("ADC1="+str(self.lastFilamentWidthReading)) + response += (" ADC2="+str(self.lastFilamentWidthReading2)) + response += (" RAW="+ + str(self.lastFilamentWidthReading + +self.lastFilamentWidthReading2)) gcmd.respond_info(response) def get_status(self, eventtime): status = self.runout_helper.get_status(eventtime) status.update({'Diameter': self.diameter, 'Raw':(self.lastFilamentWidthReading+ self.lastFilamentWidthReading2), - 'is_active':self.is_active}) + 'is_active':self.is_active, + 'flow_compensation_enabled':self.enable_flow_compensation}) return status def cmd_log_enable(self, gcmd): self.is_log = True - gcmd.respond_info("Filament width logging Turned On") + gcmd.respond_info("Filament width logging: ON") def cmd_log_disable(self, gcmd): self.is_log = False - gcmd.respond_info("Filament width logging Turned Off") + gcmd.respond_info("Filament width logging: OFF") def load_config(config): return HallFilamentWidthSensor(config)