diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h index e6bfde5c3..f1c7d1fc5 100644 --- a/Marlin/Configuration_adv.h +++ b/Marlin/Configuration_adv.h @@ -32,11 +32,10 @@ */ #define CONFIGURATION_ADV_H_VERSION 020007 -// @section temperature - //=========================================================================== //============================= Thermal Settings ============================ //=========================================================================== +// @section temperature /** * Thermocouple sensors are quite sensitive to noise. Any noise induced in @@ -125,9 +124,19 @@ #define HEATER_BED_INVERTING true #endif -/** - * Heated Chamber settings - */ +// +// Heated Bed Bang-Bang options +// +#if DISABLED(PIDTEMPBED) + #define BED_CHECK_INTERVAL 5000 // (ms) Interval between checks in bang-bang control + #if ENABLED(BED_LIMIT_SWITCHING) + #define BED_HYSTERESIS 2 // (°C) Only set the relevant heater state when ABS(T-target) > BED_HYSTERESIS + #endif +#endif + +// +// Heated Chamber options +// #if TEMP_SENSOR_CHAMBER #define CHAMBER_MINTEMP 5 #define CHAMBER_MAXTEMP 60 @@ -135,12 +144,28 @@ //#define CHAMBER_LIMIT_SWITCHING //#define HEATER_CHAMBER_PIN 44 // Chamber heater on/off pin //#define HEATER_CHAMBER_INVERTING false -#endif -#if DISABLED(PIDTEMPBED) - #define BED_CHECK_INTERVAL 5000 // ms between checks in bang-bang control - #if ENABLED(BED_LIMIT_SWITCHING) - #define BED_HYSTERESIS 2 // Only disable heating if T>target+BED_HYSTERESIS and enable heating if T>target-BED_HYSTERESIS + //#define CHAMBER_FAN // Enable a fan on the chamber + #if ENABLED(CHAMBER_FAN) + #define CHAMBER_FAN_MODE 2 // Fan control mode: 0=Static; 1=Linear increase when temp is higher than target; 2=V-shaped curve. + #if CHAMBER_FAN_MODE == 0 + #define CHAMBER_FAN_BASE 255 // Chamber fan PWM (0-255) + #elif CHAMBER_FAN_MODE == 1 + #define CHAMBER_FAN_BASE 128 // Base chamber fan PWM (0-255); turns on when chamber temperature is above the target + #define CHAMBER_FAN_FACTOR 25 // PWM increase per °C above target + #elif CHAMBER_FAN_MODE == 2 + #define CHAMBER_FAN_BASE 128 // Minimum chamber fan PWM (0-255) + #define CHAMBER_FAN_FACTOR 25 // PWM increase per °C difference from target + #endif + #endif + + //#define CHAMBER_VENT // Enable a servo-controlled vent on the chamber + #if ENABLED(CHAMBER_VENT) + #define CHAMBER_VENT_SERVO_NR 1 // Index of the vent servo + #define HIGH_EXCESS_HEAT_LIMIT 5 // How much above target temp to consider there is excess heat in the chamber + #define LOW_EXCESS_HEAT_LIMIT 3 + #define MIN_COOLING_SLOPE_TIME_CHAMBER_VENT 20 + #define MIN_COOLING_SLOPE_DEG_CHAMBER_VENT 1.5 #endif #endif diff --git a/Marlin/src/inc/Conditionals_LCD.h b/Marlin/src/inc/Conditionals_LCD.h index d2c939b9b..210bf3e91 100644 --- a/Marlin/src/inc/Conditionals_LCD.h +++ b/Marlin/src/inc/Conditionals_LCD.h @@ -603,10 +603,6 @@ #define DO_SWITCH_EXTRUDER 1 #endif -#ifdef SWITCHING_NOZZLE_E1_SERVO_NR - #define SWITCHING_NOZZLE_TWO_SERVOS 1 -#endif - /** * Default hotend offsets, if not defined */ @@ -657,14 +653,7 @@ #ifndef Z_PROBE_SERVO_NR #define Z_PROBE_SERVO_NR 0 #endif - #ifndef NUM_SERVOS - #define NUM_SERVOS (Z_PROBE_SERVO_NR + 1) - #endif #undef DEACTIVATE_SERVOS_AFTER_MOVE - #if NUM_SERVOS == 1 - #undef SERVO_DELAY - #define SERVO_DELAY { 50 } - #endif // Always disable probe pin inverting for BLTouch #undef Z_MIN_PROBE_ENDSTOP_INVERTING @@ -675,14 +664,10 @@ #endif #endif -#ifndef NUM_SERVOS - #define NUM_SERVOS 0 -#endif - /** * Set a flag for a servo probe (or BLTouch) */ -#if defined(Z_PROBE_SERVO_NR) && Z_PROBE_SERVO_NR >= 0 +#ifdef Z_PROBE_SERVO_NR #define HAS_Z_SERVO_PROBE 1 #endif #if ANY(HAS_Z_SERVO_PROBE, SWITCHING_EXTRUDER, SWITCHING_NOZZLE) diff --git a/Marlin/src/inc/Conditionals_adv.h b/Marlin/src/inc/Conditionals_adv.h index d3f608e0a..0952148d1 100644 --- a/Marlin/src/inc/Conditionals_adv.h +++ b/Marlin/src/inc/Conditionals_adv.h @@ -26,6 +26,51 @@ * Defines that depend on advanced configuration. */ +#ifdef SWITCHING_NOZZLE_E1_SERVO_NR + #define SWITCHING_NOZZLE_TWO_SERVOS 1 +#endif + +// Determine NUM_SERVOS if none was supplied +#ifndef NUM_SERVOS + #define NUM_SERVOS 0 + #if ANY(CHAMBER_VENT, HAS_Z_SERVO_PROBE, SWITCHING_EXTRUDER, SWITCHING_NOZZLE) + #if NUM_SERVOS <= Z_PROBE_SERVO_NR + #undef NUM_SERVOS + #define NUM_SERVOS (Z_PROBE_SERVO_NR + 1) + #endif + #if NUM_SERVOS <= CHAMBER_VENT_SERVO_NR + #undef NUM_SERVOS + #define NUM_SERVOS (CHAMBER_VENT_SERVO_NR + 1) + #endif + #if NUM_SERVOS <= SWITCHING_TOOLHEAD_SERVO_NR + #undef NUM_SERVOS + #define NUM_SERVOS (SWITCHING_TOOLHEAD_SERVO_NR + 1) + #endif + #if NUM_SERVOS <= SWITCHING_NOZZLE_SERVO_NR + #undef NUM_SERVOS + #define NUM_SERVOS (SWITCHING_NOZZLE_SERVO_NR + 1) + #endif + #if NUM_SERVOS <= SWITCHING_NOZZLE_E1_SERVO_NR + #undef NUM_SERVOS + #define NUM_SERVOS (SWITCHING_NOZZLE_E1_SERVO_NR + 1) + #endif + #if NUM_SERVOS <= SWITCHING_EXTRUDER_SERVO_NR + #undef NUM_SERVOS + #define NUM_SERVOS (SWITCHING_EXTRUDER_SERVO_NR + 1) + #endif + #if NUM_SERVOS <= SWITCHING_EXTRUDER_E23_SERVO_NR + #undef NUM_SERVOS + #define NUM_SERVOS (SWITCHING_EXTRUDER_E23_SERVO_NR + 1) + #endif + #endif +#endif + +// Convenience override for a BLTouch alone +#if ENABLED(BLTOUCH) && NUM_SERVOS == 1 + #undef SERVO_DELAY + #define SERVO_DELAY { 50 } +#endif + #if EXTRUDERS == 0 #define NO_VOLUMETRICS #undef TEMP_SENSOR_0 diff --git a/Marlin/src/inc/SanityCheck.h b/Marlin/src/inc/SanityCheck.h index 5bd6ef7c7..c4dcfd54a 100644 --- a/Marlin/src/inc/SanityCheck.h +++ b/Marlin/src/inc/SanityCheck.h @@ -1249,8 +1249,10 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS * NUM_SERVOS is required for a Z servo probe */ #if HAS_Z_SERVO_PROBE - #ifndef NUM_SERVOS - #error "You must set NUM_SERVOS for a Z servo probe (Z_PROBE_SERVO_NR)." + #if !NUM_SERVOS + #error "NUM_SERVOS is required for a Z servo probe (Z_PROBE_SERVO_NR)." + #elif Z_PROBE_SERVO_NR >= NUM_SERVOS + #error "Z_PROBE_SERVO_NR must be smaller than NUM_SERVOS." #elif Z_PROBE_SERVO_NR == 0 && !PIN_EXISTS(SERVO0) #error "SERVO0_PIN must be defined for your servo or BLTOUCH probe." #elif Z_PROBE_SERVO_NR == 1 && !PIN_EXISTS(SERVO1) @@ -1259,8 +1261,6 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS #error "SERVO2_PIN must be defined for your servo or BLTOUCH probe." #elif Z_PROBE_SERVO_NR == 3 && !PIN_EXISTS(SERVO3) #error "SERVO3_PIN must be defined for your servo or BLTOUCH probe." - #elif Z_PROBE_SERVO_NR >= NUM_SERVOS - #error "Z_PROBE_SERVO_NR must be smaller than NUM_SERVOS." #endif #endif @@ -1807,6 +1807,30 @@ static_assert(hbm[Z_AXIS] >= 0, "HOMING_BUMP_MM.Z must be greater than or equal #error "TEMP_SENSOR_CHAMBER requires TEMP_CHAMBER_PIN. Please add it to your configuration." #endif +#if ENABLED(CHAMBER_FAN) && !(defined(CHAMBER_FAN_MODE) && WITHIN(CHAMBER_FAN_MODE, 0, 2)) + #error "CHAMBER_FAN_MODE must be between 0 and 2. Please update your Configuration_adv.h." +#endif + +#if ENABLED(CHAMBER_VENT) + #ifndef CHAMBER_VENT_SERVO_NR + #error "CHAMBER_VENT_SERVO_NR is required for CHAMBER SERVO. Update your Configuration_adv.h." + #elif !NUM_SERVOS + #error "NUM_SERVOS is required for a Heated Chamber vent servo (CHAMBER_VENT_SERVO_NR)." + #elif CHAMBER_VENT_SERVO_NR >= NUM_SERVOS + #error "CHAMBER_VENT_SERVO_NR must be smaller than NUM_SERVOS." + #elif HAS_Z_SERVO_PROBE && CHAMBER_VENT_SERVO_NR == Z_PROBE_SERVO_NR + #error "CHAMBER SERVO is already used by BLTOUCH. Please change." + #elif CHAMBER_VENT_SERVO_NR == 0 && !PIN_EXISTS(SERVO0) + #error "SERVO0_PIN must be defined for your Heated Chamber vent servo." + #elif CHAMBER_VENT_SERVO_NR == 1 && !PIN_EXISTS(SERVO1) + #error "SERVO1_PIN must be defined for your Heated Chamber vent servo." + #elif CHAMBER_VENT_SERVO_NR == 2 && !PIN_EXISTS(SERVO2) + #error "SERVO2_PIN must be defined for your Heated Chamber vent servo." + #elif CHAMBER_VENT_SERVO_NR == 3 && !PIN_EXISTS(SERVO3) + #error "SERVO3_PIN must be defined for your Heated Chamber vent servo." + #endif +#endif + #if TEMP_SENSOR_PROBE #if !PIN_EXISTS(TEMP_PROBE) #error "TEMP_SENSOR_PROBE requires TEMP_PROBE_PIN. Please add it to your configuration." diff --git a/Marlin/src/module/temperature.cpp b/Marlin/src/module/temperature.cpp index f58914089..004c2d123 100644 --- a/Marlin/src/module/temperature.cpp +++ b/Marlin/src/module/temperature.cpp @@ -111,6 +111,9 @@ #include "../libs/buzzer.h" #endif +#if HAS_SERVOS + #include "./servo.h" +#endif #if HOTEND_USES_THERMISTOR #if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT) static const temp_entry_t* heater_ttbl_map[2] = { HEATER_0_TEMPTABLE, HEATER_1_TEMPTABLE }; @@ -271,6 +274,11 @@ const char str_t_thermal_runaway[] PROGMEM = STR_T_THERMAL_RUNAWAY, #if HAS_TEMP_CHAMBER chamber_info_t Temperature::temp_chamber; // = { 0 } #if HAS_HEATED_CHAMBER + int16_t fan_chamber_pwm; + bool flag_chamber_off; + bool flag_chamber_excess_heat = false; + millis_t next_cool_check_ms_2 = 0; + float old_temp = 9999; #ifdef CHAMBER_MINTEMP int16_t Temperature::mintemp_raw_CHAMBER = HEATER_CHAMBER_RAW_LO_TEMP; #endif @@ -1189,18 +1197,84 @@ void Temperature::manage_heater() { } #endif + #if EITHER(CHAMBER_FAN, CHAMBER_VENT) + if (temp_chamber.target > CHAMBER_MINTEMP) { + flag_chamber_off = false; + + #if ENABLED(CHAMBER_FAN) + #if CHAMBER_FAN_MODE == 0 + fan_chamber_pwm = CHAMBER_FAN_BASE + #elif CHAMBER_FAN_MODE == 1 + fan_chamber_pwm = temp_chamber.celsius > temp_chamber.target ? CHAMBER_FAN_BASE + ((temp_chamber.celsius - temp_chamber.target) * CHAMBER_FAN_FACTOR ) : 0; + #elif CHAMBER_FAN_MODE == 2 + fan_chamber_pwm = (CHAMBER_FAN_BASE) + (CHAMBER_FAN_FACTOR) * ABS(temp_chamber.celsius - temp_chamber.target); + if (temp_chamber.soft_pwm_amount) + fan_chamber_pwm += (CHAMBER_FAN_FACTOR) * 2; + #endif + fan_chamber_pwm = _MIN(225, fan_chamber_pwm); + thermalManager.set_fan_speed(2, fan_chamber_pwm); // TODO: instead of fan 2, set to chamber fan + #endif + + #if ENABLED(CHAMBER_VENT) + #ifndef MIN_COOLING_SLOPE_TIME_CHAMBER_VENT + #define MIN_COOLING_SLOPE_TIME_CHAMBER_VENT 20 + #endif + #ifndef MIN_COOLING_SLOPE_DEG_CHAMBER_VENT + #define MIN_COOLING_SLOPE_DEG_CHAMBER_VENT 1.5 + #endif + if( (temp_chamber.celsius - temp_chamber.target >= HIGH_EXCESS_HEAT_LIMIT) && !flag_chamber_excess_heat) { + // open vent after MIN_COOLING_SLOPE_TIME_CHAMBER_VENT seconds + // if the temperature did not drop at least MIN_COOLING_SLOPE_DEG_CHAMBER_VENT + if (next_cool_check_ms_2 == 0 || ELAPSED(ms, next_cool_check_ms_2)) { + if (old_temp - temp_chamber.celsius < float(MIN_COOLING_SLOPE_DEG_CHAMBER_VENT)) flag_chamber_excess_heat = true; //the bed is heating the chamber too much + next_cool_check_ms_2 = ms + 1000UL * MIN_COOLING_SLOPE_TIME_CHAMBER_VENT; + old_temp = temp_chamber.celsius; + } + } + else { + next_cool_check_ms_2 = 0; + old_temp = 9999; + } + if (flag_chamber_excess_heat && (temp_chamber.celsius - temp_chamber.target <= -LOW_EXCESS_HEAT_LIMIT) ) { + flag_chamber_excess_heat = false; + } + #endif + } + else if (!flag_chamber_off) { + #if ENABLED(CHAMBER_FAN) + flag_chamber_off = true; + thermalManager.set_fan_speed(2, 0); + #endif + #if ENABLED(CHAMBER_VENT) + flag_chamber_excess_heat = false; + MOVE_SERVO(CHAMBER_VENT_SERVO_NR, 90); + #endif + } + #endif + if (ELAPSED(ms, next_chamber_check_ms)) { next_chamber_check_ms = ms + CHAMBER_CHECK_INTERVAL; if (WITHIN(temp_chamber.celsius, CHAMBER_MINTEMP, CHAMBER_MAXTEMP)) { - #if ENABLED(CHAMBER_LIMIT_SWITCHING) - if (temp_chamber.celsius >= temp_chamber.target + TEMP_CHAMBER_HYSTERESIS) - temp_chamber.soft_pwm_amount = 0; - else if (temp_chamber.celsius <= temp_chamber.target - (TEMP_CHAMBER_HYSTERESIS)) - temp_chamber.soft_pwm_amount = MAX_CHAMBER_POWER >> 1; - #else - temp_chamber.soft_pwm_amount = temp_chamber.celsius < temp_chamber.target ? MAX_CHAMBER_POWER >> 1 : 0; - #endif + if (!flag_chamber_excess_heat){ + #if ENABLED(CHAMBER_LIMIT_SWITCHING) + if (temp_chamber.celsius >= temp_chamber.target + TEMP_CHAMBER_HYSTERESIS) + temp_chamber.soft_pwm_amount = 0; + else if (temp_chamber.celsius <= temp_chamber.target - (TEMP_CHAMBER_HYSTERESIS)) + temp_chamber.soft_pwm_amount = (MAX_CHAMBER_POWER) >> 1; + #else + temp_chamber.soft_pwm_amount = temp_chamber.celsius < temp_chamber.target ? (MAX_CHAMBER_POWER) >> 1 : 0; + #endif + #if ENABLED(CHAMBER_VENT) + if (!flag_chamber_off) MOVE_SERVO(CHAMBER_VENT_SERVO_NR, 0); + #endif + } + else { + temp_chamber.soft_pwm_amount = 0; + #if ENABLED(CHAMBER_VENT) + if (!flag_chamber_off) MOVE_SERVO(CHAMBER_VENT_SERVO_NR, temp_chamber.celsius <= temp_chamber.target ? 0 : 90); + #endif + } } else { temp_chamber.soft_pwm_amount = 0; @@ -3365,7 +3439,7 @@ void Temperature::tick() { #define MIN_COOLING_SLOPE_DEG_CHAMBER 1.50 #endif #ifndef MIN_COOLING_SLOPE_TIME_CHAMBER - #define MIN_COOLING_SLOPE_TIME_CHAMBER 60 + #define MIN_COOLING_SLOPE_TIME_CHAMBER 120 #endif bool Temperature::wait_for_chamber(const bool no_wait_for_cooling/*=true*/) { diff --git a/Marlin/src/pins/stm32f4/pins_BTT_SKR_PRO_common.h b/Marlin/src/pins/stm32f4/pins_BTT_SKR_PRO_common.h index 1cd7e9dd8..83fd987d9 100644 --- a/Marlin/src/pins/stm32f4/pins_BTT_SKR_PRO_common.h +++ b/Marlin/src/pins/stm32f4/pins_BTT_SKR_PRO_common.h @@ -41,6 +41,7 @@ // Servos // #define SERVO0_PIN PA1 +#define SERVO1_PIN PC9 // // Trinamic Stallguard pins