diff --git a/klippy/extras/heater_bed.py b/klippy/extras/heater_bed.py index 96afb8f..f272e4c 100644 --- a/klippy/extras/heater_bed.py +++ b/klippy/extras/heater_bed.py @@ -15,6 +15,9 @@ class PrinterHeaterBed: gcode = self.printer.lookup_object('gcode') gcode.register_command("M140", self.cmd_M140) gcode.register_command("M190", self.cmd_M190) + gcode.register_command("CLOSE_BED_DEBUG", self.cmd_close_bed_debug) + self.heater_bed_state = 0 + self.is_heater_bed = 1 def cmd_M140(self, gcmd, wait=False): # Set Bed Temperature temp = gcmd.get_float('S', 0.) @@ -23,6 +26,9 @@ class PrinterHeaterBed: def cmd_M190(self, gcmd): # Set Bed Temperature and Wait self.cmd_M140(gcmd, wait=True) + def cmd_close_bed_debug(self, gcmd): + is_close = gcmd.get_int('S', 1) + self.is_heater_bed = is_close def load_config(config): return PrinterHeaterBed(config) diff --git a/klippy/extras/heaters.py b/klippy/extras/heaters.py index 08cabda..b8860c4 100644 --- a/klippy/extras/heaters.py +++ b/klippy/extras/heaters.py @@ -21,6 +21,10 @@ class Heater: self.name = config.get_name().split()[-1] # Setup sensor self.sensor = sensor + self.target_min_temp = config.getfloat('target_min_temp', 0.) + self.target_max_temp = config.getfloat('target_max_temp', 999.) + self.heat_with_heater_bed = config.getboolean("heat_with_heater_bed", False) + self.heat_with_heater_bed_tem_add = config.getfloat('heat_with_heater_bed_tem_add', 0.) self.min_temp = config.getfloat('min_temp', minval=KELVIN_TO_CELSIUS) self.max_temp = config.getfloat('max_temp', above=self.min_temp) self.sensor.setup_minmax(self.min_temp, self.max_temp) @@ -149,7 +153,20 @@ class Heater: def cmd_SET_HEATER_TEMPERATURE(self, gcmd): temp = gcmd.get_float('TARGET', 0.) pheaters = self.printer.lookup_object('heaters') - pheaters.set_temperature(self, temp) + if self.name == "chamber" : + if temp and (temp < max(self.target_min_temp,self.min_temp) or temp > min(self.target_max_temp,self.max_temp)): + raise self.printer.command_error( + "Requested temperature (%.1f) out of range (%.1f:%.1f)" + % (temp, max(self.target_min_temp,self.min_temp),min(self.target_max_temp,self.max_temp))) + pheaters.set_temperature(self, temp) + if self.heat_with_heater_bed and temp > 0.: + heater_bed = pheaters.lookup_heater("heater_bed") + if heater_bed.target_temp < (temp+self.heat_with_heater_bed_tem_add): + pheaters.set_temperature(heater_bed, (temp+self.heat_with_heater_bed_tem_add)) + msg = "The hotbed temperature is too low, and it will automatically heat up to " + str((temp+self.heat_with_heater_bed_tem_add)) + gcmd.respond_info(msg) + else: + pheaters.set_temperature(self, temp) ###################################################################### @@ -184,6 +201,7 @@ PID_SETTLE_SLOPE = .1 class ControlPID: def __init__(self, heater, config): + self.printer = config.get_printer() self.heater = heater self.heater_max_power = heater.get_max_power() self.Kp = config.getfloat('pid_Kp') / PID_PARAM_BASE @@ -198,6 +216,7 @@ class ControlPID: self.prev_temp_deriv = 0. self.prev_temp_integ = 0. def temperature_update(self, read_time, temp, target_temp): + heater_bed = self.printer.lookup_object('heater_bed') time_diff = read_time - self.prev_temp_time # Calculate change of temperature temp_diff = temp - self.prev_temp @@ -215,13 +234,24 @@ class ControlPID: #logging.debug("pid: %f@%.3f -> diff=%f deriv=%f err=%f integ=%f co=%d", # temp, read_time, temp_diff, temp_deriv, temp_err, temp_integ, co) bounded_co = max(0., min(self.heater_max_power, co)) - self.heater.set_pwm(read_time, bounded_co) + if self.heater.name == "chamber" and heater_bed.heater_bed_state != 2 and heater_bed.is_heater_bed == 1: + self.heater.set_pwm(read_time, 0.) + else: + self.heater.set_pwm(read_time, bounded_co) # Store state for next measurement self.prev_temp = temp self.prev_temp_time = read_time self.prev_temp_deriv = temp_deriv if co == bounded_co: self.prev_temp_integ = temp_integ + if self.heater.name == "heater_bed" : + if target_temp < 70: + heater_bed.heater_bed_state = 0 + elif temp < target_temp - 2.: + heater_bed.heater_bed_state = 1 + else: + heater_bed.heater_bed_state = 2 + def check_busy(self, eventtime, smoothed_temp, target_temp): temp_diff = target_temp - smoothed_temp return (abs(temp_diff) > PID_SETTLE_DELTA diff --git a/klippy/extras/verify_heater.py b/klippy/extras/verify_heater.py index 5f9c86b..76592b6 100644 --- a/klippy/extras/verify_heater.py +++ b/klippy/extras/verify_heater.py @@ -23,7 +23,6 @@ class HeaterCheck: self.max_error = config.getfloat('max_error', 120., minval=0.) self.heating_gain = config.getfloat('heating_gain', 2., above=0.) self.position_z = config.getfloat('position_z', 9999., minval=0.) - logging.info("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA %f", self.position_z) default_gain_time = 20. if self.heater_name == 'heater_bed': default_gain_time = 60. @@ -47,6 +46,7 @@ class HeaterCheck: reactor = self.printer.get_reactor() reactor.update_timer(self.check_timer, reactor.NEVER) def check_event(self, eventtime): + heater_bed = self.printer.lookup_object('heater_bed') temp, target = self.heater.get_temp(eventtime) if temp >= target - self.hysteresis or target <= 0.: # Temperature near target - reset checks @@ -60,7 +60,6 @@ class HeaterCheck: return eventtime + 1. self.error += (target - self.hysteresis) - temp if not self.approaching_target: - logging.info("CCCCC self.error is %f", self.error) if target != self.last_target: # Target changed - reset checks logging.info("Heater %s approaching new target of %.3f", @@ -71,12 +70,15 @@ class HeaterCheck: elif self.error >= self.max_error: toolhead = self.printer.lookup_object('toolhead') position_z = toolhead.get_position()[2] - logging.info("CCCCC position_z is %f", position_z) + logging.info("Check error: position_z is %f", position_z) if position_z > self.position_z: self.error = 0. - else: + else: # Failure due to inability to maintain target temperature return self.heater_fault() + elif heater_bed.heater_bed_state == 1 and self.heater_name == "chamber": + self.error = 0. + self.goal_temp = temp - self.heating_gain elif temp >= self.goal_temp: # Temperature approaching target - reset checks self.starting_approach = False