diff --git a/docs/Config_Reference.md b/docs/Config_Reference.md index d0f17269a..de7854e30 100644 --- a/docs/Config_Reference.md +++ b/docs/Config_Reference.md @@ -5071,15 +5071,16 @@ adc2: # 1.50 for cal_dia1 and 2.00 for cal_dia2. #raw_dia1: 9500 #raw_dia2: 10500 -# The raw calibration values for the sensors. The default is 9500 -# for raw_dia1 and 10500 for raw_dia2. +# The raw calibration values for the sensors. Both values must not be +# the same. The default is 9500 for raw_dia1 and 10500 for raw_dia2. #default_nominal_filament_diameter: 1.75 # The nominal filament diameter. This parameter must be provided. #max_difference: 0.200 # Maximum allowed filament diameter difference in millimeters (mm). # If difference between nominal filament diameter and sensor output # is more than +- max_difference, extrusion multiplier is set back -# to %100. The default is 0.200. +# to %100. Must be less than default_nominal_filament_diameter. +# The default is 0.200. #measurement_delay: 70 # The distance from sensor to the melting chamber/hot-end in # millimeters (mm). The filament between the sensor and the hot-end @@ -5090,6 +5091,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 9b876a059..0e56a8aae 100644 --- a/docs/G-Codes.md +++ b/docs/G-Codes.md @@ -784,11 +784,11 @@ and [Hall Filament Width Sensor](Hall_Filament_Width_Sensor.md)): #### 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 control. Resets flow rate to 100%. #### ENABLE_FILAMENT_WIDTH_SENSOR `ENABLE_FILAMENT_WIDTH_SENSOR`: Turn on the filament width sensor and @@ -804,6 +804,19 @@ and RAW sensor value for calibration points. #### DISABLE_FILAMENT_WIDTH_LOG `DISABLE_FILAMENT_WIDTH_LOG`: Turn off diameter logging. +#### ENABLE_FILAMENT_WIDTH_COMPENSATION +`ENABLE_FILAMENT_WIDTH_COMPENSATION`: Turn on flow compensation based +on filament width sensor readings. + +#### DISABLE_FILAMENT_WIDTH_COMPENSATION +`DISABLE_FILAMENT_WIDTH_COMPENSATION`: Turn off flow compensation based +on filament width sensor readings. Does not disable the sensor itself or +the filament runout switch. Resets flow rate to 100%. + +#### QUERY_FILAMENT_WIDTH_COMPENSATION +`QUERY_FILAMENT_WIDTH_COMPENSATION`: Query the state of filament width sensor +flow compensation. + ### [heaters] The heaters module is automatically loaded if a heater is defined in diff --git a/docs/Hall_Filament_Width_Sensor.md b/docs/Hall_Filament_Width_Sensor.md index 9992ef730..11c7d5cc1 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 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_COMPENSATION** to enable flow compensation +or **DISABLE_FILAMENT_WIDTH_COMPENSATION** to disable it. + +Note that disabling filament width compensation automatically resets the extrusion +multiplier to 100%. + +**QUERY_FILAMENT_WIDTH_COMPENSATION** returns the current state of flow compensation. + ## 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..b11b9d94e 100644 --- a/klippy/extras/hall_filament_width_sensor.py +++ b/klippy/extras/hall_filament_width_sensor.py @@ -33,6 +33,16 @@ 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) + if self.rawdia1 == self.rawdia2: + raise config.error( + "hall_filament_width_sensor: raw_dia1 and raw_dia2 must be" + " different") + if self.min_diameter <= 0: + raise config.error( + "hall_filament_width_sensor: max_difference must be less than" + " default_nominal_filament_diameter") # Use the current diameter instead of nominal while the first # measurement isn't in place self.use_current_dia_while_delay = config.getboolean( @@ -61,19 +71,48 @@ class HallFilamentWidthSensor: self.extrude_factor_update_event) # Register commands self.gcode = self.printer.lookup_object('gcode') - self.gcode.register_command('QUERY_FILAMENT_WIDTH', self.cmd_M407) - self.gcode.register_command('RESET_FILAMENT_WIDTH_SENSOR', - self.cmd_ClearFilamentArray) - self.gcode.register_command('DISABLE_FILAMENT_WIDTH_SENSOR', - self.cmd_M406) - self.gcode.register_command('ENABLE_FILAMENT_WIDTH_SENSOR', - self.cmd_M405) - self.gcode.register_command('QUERY_RAW_FILAMENT_WIDTH', - self.cmd_Get_Raw_Values) - self.gcode.register_command('ENABLE_FILAMENT_WIDTH_LOG', - self.cmd_log_enable) - self.gcode.register_command('DISABLE_FILAMENT_WIDTH_LOG', - self.cmd_log_disable) + self.gcode.register_command( + 'QUERY_FILAMENT_WIDTH', + self.cmd_M407, + desc=self.cmd_QUERY_FILAMENT_WIDTH_help + ) + self.gcode.register_command( + 'RESET_FILAMENT_WIDTH_SENSOR', + self.cmd_ClearFilamentArray, + desc=self.cmd_RESET_FILAMENT_WIDTH_SENSOR_help + ) + self.gcode.register_command( + 'DISABLE_FILAMENT_WIDTH_SENSOR', + self.cmd_M406, + desc=self.cmd_DISABLE_FILAMENT_WIDTH_SENSOR_help) + self.gcode.register_command( + 'ENABLE_FILAMENT_WIDTH_SENSOR', + self.cmd_M405, + desc=self.cmd_ENABLE_FILAMENT_WIDTH_SENSOR_help) + self.gcode.register_command( + 'QUERY_RAW_FILAMENT_WIDTH', + self.cmd_Get_Raw_Values, + desc=self.cmd_QUERY_RAW_FILAMENT_WIDTH_help) + self.gcode.register_command( + 'ENABLE_FILAMENT_WIDTH_LOG', + self.cmd_log_enable, + desc=self.cmd_ENABLE_FILAMENT_WIDTH_LOG_help) + self.gcode.register_command( + 'DISABLE_FILAMENT_WIDTH_LOG', + self.cmd_log_disable, + desc=self.cmd_DISABLE_FILAMENT_WIDTH_LOG_help) + self.gcode.register_command( + 'ENABLE_FILAMENT_WIDTH_COMPENSATION', + self.cmd_flow_comp_enable, + desc=self.cmd_ENABLE_FILAMENT_WIDTH_COMPENSATION_help) + self.gcode.register_command( + 'DISABLE_FILAMENT_WIDTH_COMPENSATION', + self.cmd_flow_comp_disable, + desc=self.cmd_DISABLE_FILAMENT_WIDTH_COMPENSATION_help) + self.gcode.register_command( + 'QUERY_FILAMENT_WIDTH_COMPENSATION', + self.cmd_flow_comp_query, + desc=self.cmd_QUERY_FILAMENT_WIDTH_COMPENSATION_help) self.runout_helper = filament_switch_sensor.RunoutHelper(config) # Initialization @@ -147,15 +186,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: @@ -163,21 +204,24 @@ class HallFilamentWidthSensor: else: return self.reactor.NEVER + cmd_QUERY_FILAMENT_WIDTH_help = "Report the filament width in mm" def cmd_M407(self, gcmd): response = "" if self.diameter > 0: - response += ("Filament dia (measured mm): " - + str(self.diameter)) + response += ("Filament dia (measured mm): %.4f" % (self.diameter)) else: response += "Filament NOT present" gcmd.respond_info(response) + cmd_RESET_FILAMENT_WIDTH_SENSOR_help = "Clear all filament width readings" def cmd_ClearFilamentArray(self, gcmd): self.filament_array = [] gcmd.respond_info("Filament width measurements cleared!") # Set extrude multiplier to 100% self.gcode.run_script_from_command("M221 S100") + cmd_ENABLE_FILAMENT_WIDTH_SENSOR_help = ( + "Enable the filament width sensor") def cmd_M405(self, gcmd): response = "Filament width sensor Turned On" if self.is_active: @@ -189,6 +233,8 @@ class HallFilamentWidthSensor: self.reactor.NOW) gcmd.respond_info(response) + cmd_DISABLE_FILAMENT_WIDTH_SENSOR_help = ( + "Disable the filament width sensor") def cmd_M406(self, gcmd): response = "Filament width sensor Turned Off" if not self.is_active: @@ -204,28 +250,57 @@ class HallFilamentWidthSensor: self.gcode.run_script_from_command("M221 S100") gcmd.respond_info(response) + cmd_QUERY_RAW_FILAMENT_WIDTH_help = ( + "Report the raw filament width sensor values") def cmd_Get_Raw_Values(self, gcmd): - response = "ADC1=" - response += (" "+str(self.lastFilamentWidthReading)) + 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 + + cmd_ENABLE_FILAMENT_WIDTH_LOG_help = ( + "Enable filament width sensor logging") def cmd_log_enable(self, gcmd): self.is_log = True gcmd.respond_info("Filament width logging Turned On") + cmd_DISABLE_FILAMENT_WIDTH_LOG_help = ( + "Disable filament width sensor logging") def cmd_log_disable(self, gcmd): self.is_log = False gcmd.respond_info("Filament width logging Turned Off") + cmd_ENABLE_FILAMENT_WIDTH_COMPENSATION_help = ( + "Enable flow compensation based on filament width") + def cmd_flow_comp_enable(self, gcmd): + self.enable_flow_compensation = True + gcmd.respond_info("Filament width flow compensation Turned On") + + cmd_DISABLE_FILAMENT_WIDTH_COMPENSATION_help = ( + "Disable flow compensation based on filament width") + def cmd_flow_comp_disable(self, gcmd): + self.enable_flow_compensation = False + # Set extrude multiplier to 100% + self.gcode.run_script_from_command("M221 S100") + gcmd.respond_info("Filament width flow compensation Turned Off") + + cmd_QUERY_FILAMENT_WIDTH_COMPENSATION_help = ( + "Report filament width flow compensation status") + def cmd_flow_comp_query(self, gcmd): + gcmd.respond_info("Filament width flow compensation:"+ + (" ON" if self.enable_flow_compensation else " OFF")) + def load_config(config): return HallFilamentWidthSensor(config)