diff --git a/Marlin/src/module/temperature.cpp b/Marlin/src/module/temperature.cpp index 0e6e0686ec..09f492ee18 100644 --- a/Marlin/src/module/temperature.cpp +++ b/Marlin/src/module/temperature.cpp @@ -244,11 +244,11 @@ uint8_t Temperature::soft_pwm_amount[HOTENDS], ; const int8_t watch_temp_period = #if ENABLED(THERMAL_PROTECTION_BED) && ENABLED(PIDTEMPBED) && ENABLED(THERMAL_PROTECTION_HOTENDS) && ENABLED(PIDTEMP) - hotend < 0 ? THERMAL_PROTECTION_BED_PERIOD : THERMAL_PROTECTION_PERIOD + hotend < 0 ? WATCH_BED_TEMP_PERIOD : WATCH_TEMP_PERIOD #elif ENABLED(THERMAL_PROTECTION_BED) && ENABLED(PIDTEMPBED) - THERMAL_PROTECTION_BED_PERIOD + WATCH_BED_TEMP_PERIOD #else - THERMAL_PROTECTION_PERIOD + WATCH_TEMP_PERIOD #endif ; const int8_t watch_temp_increase = @@ -437,7 +437,9 @@ uint8_t Temperature::soft_pwm_amount[HOTENDS], next_watch_temp = input + watch_temp_increase; temp_change_ms = ms + watch_temp_period * 1000UL; } - else if ((!heated && ELAPSED(ms, temp_change_ms)) || (heated && input < temp - MAX_OVERSHOOT_PID_AUTOTUNE)) + else if (!heated && ELAPSED(ms, temp_change_ms)) + _temp_error(hotend, PSTR(MSG_T_HEATING_FAILED), PSTR(MSG_HEATING_FAILED_LCD)); + else if (heated && input < temp - MAX_OVERSHOOT_PID_AUTOTUNE) _temp_error(hotend, PSTR(MSG_T_THERMAL_RUNAWAY), PSTR(MSG_THERMAL_RUNAWAY)); #endif } // every 2 seconds @@ -834,10 +836,8 @@ void Temperature::manage_heater() { #endif #if HEATER_IDLE_HANDLER - if (bed_idle_timeout_exceeded) - { + if (bed_idle_timeout_exceeded) { soft_pwm_amount_bed = 0; - #if DISABLED(PIDTEMPBED) WRITE_HEATER_BED(LOW); #endif @@ -847,23 +847,17 @@ void Temperature::manage_heater() { { #if ENABLED(PIDTEMPBED) soft_pwm_amount_bed = WITHIN(current_temperature_bed, BED_MINTEMP, BED_MAXTEMP) ? (int)get_pid_output_bed() >> 1 : 0; - - #elif ENABLED(BED_LIMIT_SWITCHING) + #else // Check if temperature is within the correct band if (WITHIN(current_temperature_bed, BED_MINTEMP, BED_MAXTEMP)) { - if (current_temperature_bed >= target_temperature_bed + BED_HYSTERESIS) - soft_pwm_amount_bed = 0; - else if (current_temperature_bed <= target_temperature_bed - (BED_HYSTERESIS)) - soft_pwm_amount_bed = MAX_BED_POWER >> 1; - } - else { - soft_pwm_amount_bed = 0; - WRITE_HEATER_BED(LOW); - } - #else // !PIDTEMPBED && !BED_LIMIT_SWITCHING - // Check if temperature is within the correct range - if (WITHIN(current_temperature_bed, BED_MINTEMP, BED_MAXTEMP)) { - soft_pwm_amount_bed = current_temperature_bed < target_temperature_bed ? MAX_BED_POWER >> 1 : 0; + #if ENABLED(BED_LIMIT_SWITCHING) + if (current_temperature_bed >= target_temperature_bed + BED_HYSTERESIS) + soft_pwm_amount_bed = 0; + else if (current_temperature_bed <= target_temperature_bed - (BED_HYSTERESIS)) + soft_pwm_amount_bed = MAX_BED_POWER >> 1; + #else // !PIDTEMPBED && !BED_LIMIT_SWITCHING + soft_pwm_amount_bed = current_temperature_bed < target_temperature_bed ? MAX_BED_POWER >> 1 : 0; + #endif } else { soft_pwm_amount_bed = 0; @@ -878,7 +872,7 @@ void Temperature::manage_heater() { // Derived from RepRap FiveD extruder::getTemperature() // For hot end temperature measurement. -float Temperature::analog2temp(int raw, uint8_t e) { +float Temperature::analog2temp(const int raw, const uint8_t e) { #if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT) if (e > HOTENDS) #else @@ -919,39 +913,41 @@ float Temperature::analog2temp(int raw, uint8_t e) { return ((raw * ((5.0 * 100.0) / 1024.0) / OVERSAMPLENR) * (TEMP_SENSOR_AD595_GAIN)) + TEMP_SENSOR_AD595_OFFSET; } -// Derived from RepRap FiveD extruder::getTemperature() -// For bed temperature measurement. -float Temperature::analog2tempBed(const int raw) { - #if ENABLED(BED_USES_THERMISTOR) - float celsius = 0; - byte i; +#if HAS_TEMP_BED + // Derived from RepRap FiveD extruder::getTemperature() + // For bed temperature measurement. + float Temperature::analog2tempBed(const int raw) { + #if ENABLED(BED_USES_THERMISTOR) + float celsius = 0; + byte i; - for (i = 1; i < BEDTEMPTABLE_LEN; i++) { - if (PGM_RD_W(BEDTEMPTABLE[i][0]) > raw) { - celsius = PGM_RD_W(BEDTEMPTABLE[i - 1][1]) + - (raw - PGM_RD_W(BEDTEMPTABLE[i - 1][0])) * - (float)(PGM_RD_W(BEDTEMPTABLE[i][1]) - PGM_RD_W(BEDTEMPTABLE[i - 1][1])) / - (float)(PGM_RD_W(BEDTEMPTABLE[i][0]) - PGM_RD_W(BEDTEMPTABLE[i - 1][0])); - break; + for (i = 1; i < BEDTEMPTABLE_LEN; i++) { + if (PGM_RD_W(BEDTEMPTABLE[i][0]) > raw) { + celsius = PGM_RD_W(BEDTEMPTABLE[i - 1][1]) + + (raw - PGM_RD_W(BEDTEMPTABLE[i - 1][0])) * + (float)(PGM_RD_W(BEDTEMPTABLE[i][1]) - PGM_RD_W(BEDTEMPTABLE[i - 1][1])) / + (float)(PGM_RD_W(BEDTEMPTABLE[i][0]) - PGM_RD_W(BEDTEMPTABLE[i - 1][0])); + break; + } } - } - // Overflow: Set to last value in the table - if (i == BEDTEMPTABLE_LEN) celsius = PGM_RD_W(BEDTEMPTABLE[i - 1][1]); + // Overflow: Set to last value in the table + if (i == BEDTEMPTABLE_LEN) celsius = PGM_RD_W(BEDTEMPTABLE[i - 1][1]); - return celsius; + return celsius; - #elif defined(BED_USES_AD595) + #elif defined(BED_USES_AD595) - return ((raw * ((5.0 * 100.0) / 1024.0) / OVERSAMPLENR) * (TEMP_SENSOR_AD595_GAIN)) + TEMP_SENSOR_AD595_OFFSET; + return ((raw * ((5.0 * 100.0) / 1024.0) / OVERSAMPLENR) * (TEMP_SENSOR_AD595_GAIN)) + TEMP_SENSOR_AD595_OFFSET; - #else + #else - UNUSED(raw); - return 0; + UNUSED(raw); + return 0; - #endif -} + #endif + } +#endif // HAS_TEMP_BED /** * Get the raw values into the actual temperatures. @@ -1236,24 +1232,26 @@ void Temperature::init() { #endif // HOTENDS > 2 #endif // HOTENDS > 1 - #ifdef BED_MINTEMP - while (analog2tempBed(bed_minttemp_raw) < BED_MINTEMP) { - #if HEATER_BED_RAW_LO_TEMP < HEATER_BED_RAW_HI_TEMP - bed_minttemp_raw += OVERSAMPLENR; - #else - bed_minttemp_raw -= OVERSAMPLENR; - #endif - } - #endif // BED_MINTEMP - #ifdef BED_MAXTEMP - while (analog2tempBed(bed_maxttemp_raw) > BED_MAXTEMP) { - #if HEATER_BED_RAW_LO_TEMP < HEATER_BED_RAW_HI_TEMP - bed_maxttemp_raw -= OVERSAMPLENR; - #else - bed_maxttemp_raw += OVERSAMPLENR; - #endif - } - #endif // BED_MAXTEMP + #if HAS_TEMP_BED + #ifdef BED_MINTEMP + while (analog2tempBed(bed_minttemp_raw) < BED_MINTEMP) { + #if HEATER_BED_RAW_LO_TEMP < HEATER_BED_RAW_HI_TEMP + bed_minttemp_raw += OVERSAMPLENR; + #else + bed_minttemp_raw -= OVERSAMPLENR; + #endif + } + #endif // BED_MINTEMP + #ifdef BED_MAXTEMP + while (analog2tempBed(bed_maxttemp_raw) > BED_MAXTEMP) { + #if HEATER_BED_RAW_LO_TEMP < HEATER_BED_RAW_HI_TEMP + bed_maxttemp_raw -= OVERSAMPLENR; + #else + bed_maxttemp_raw += OVERSAMPLENR; + #endif + } + #endif // BED_MAXTEMP + #endif // HAS_TEMP_BED #if ENABLED(PROBING_HEATERS_OFF) paused = false; @@ -1348,7 +1346,7 @@ void Temperature::init() { millis_t Temperature::thermal_runaway_bed_timer; #endif - void Temperature::thermal_runaway_protection(Temperature::TRState * const state, millis_t * const timer, const float current, const float target, const int8_t heater_id, const uint16_t period_seconds, const uint16_t hysteresis_degc) { + void Temperature::thermal_runaway_protection(Temperature::TRState * const state, millis_t * const timer, const float ¤t, const float &target, const int8_t heater_id, const uint16_t period_seconds, const uint16_t hysteresis_degc) { static float tr_target_temperature[HOTENDS + 1] = { 0.0 }; @@ -1371,22 +1369,22 @@ void Temperature::init() { #if HEATER_IDLE_HANDLER // If the heater idle timeout expires, restart - if (heater_id >= 0 && heater_idle_timeout_exceeded[heater_id]) { + if ((heater_id >= 0 && heater_idle_timeout_exceeded[heater_id]) + #if HAS_TEMP_BED + || (heater_id < 0 && bed_idle_timeout_exceeded) + #endif + ) { *state = TRInactive; tr_target_temperature[heater_index] = 0; } - #if HAS_TEMP_BED - else if (heater_id < 0 && bed_idle_timeout_exceeded) { - *state = TRInactive; - tr_target_temperature[heater_index] = 0; - } - #endif else #endif - // If the target temperature changes, restart - if (tr_target_temperature[heater_index] != target) { - tr_target_temperature[heater_index] = target; - *state = target > 0 ? TRFirstHeating : TRInactive; + { + // If the target temperature changes, restart + if (tr_target_temperature[heater_index] != target) { + tr_target_temperature[heater_index] = target; + *state = target > 0 ? TRFirstHeating : TRInactive; + } } switch (*state) { @@ -2172,19 +2170,19 @@ void Temperature::isr() { ); #endif #if HAS_TEMP_BED - print_heater_state(degBed(), degTargetBed(), + print_heater_state(degBed(), degTargetBed() #if ENABLED(SHOW_TEMP_ADC_VALUES) - rawBedTemp(), + , rawBedTemp() #endif - -1 // BED + , -1 // BED ); #endif #if HOTENDS > 1 - HOTEND_LOOP() print_heater_state(degHotend(e), degTargetHotend(e), + HOTEND_LOOP() print_heater_state(degHotend(e), degTargetHotend(e) #if ENABLED(SHOW_TEMP_ADC_VALUES) - rawHotendTemp(e), + , rawHotendTemp(e) #endif - e + , e ); #endif SERIAL_PROTOCOLPGM(" @:"); diff --git a/Marlin/src/module/temperature.h b/Marlin/src/module/temperature.h index 52d49dcfa6..adbab87ae5 100644 --- a/Marlin/src/module/temperature.h +++ b/Marlin/src/module/temperature.h @@ -170,14 +170,22 @@ class Temperature { #if ENABLED(PREVENT_COLD_EXTRUSION) static bool allow_cold_extrude; static int16_t extrude_min_temp; - static bool tooColdToExtrude(uint8_t e) { + FORCE_INLINE static bool tooCold(const int16_t temp) { return allow_cold_extrude ? false : temp < extrude_min_temp; } + FORCE_INLINE static bool tooColdToExtrude(const uint8_t e) { #if HOTENDS == 1 UNUSED(e); #endif - return allow_cold_extrude ? false : degHotend(HOTEND_INDEX) < extrude_min_temp; + return tooCold(degHotend(HOTEND_INDEX)); + } + FORCE_INLINE static bool targetTooColdToExtrude(const uint8_t e) { + #if HOTENDS == 1 + UNUSED(e); + #endif + return tooCold(degTargetHotend(HOTEND_INDEX)); } #else - static bool tooColdToExtrude(uint8_t e) { UNUSED(e); return false; } + FORCE_INLINE static bool tooColdToExtrude(const uint8_t e) { UNUSED(e); return false; } + FORCE_INLINE static bool targetTooColdToExtrude(const uint8_t e) { UNUSED(e); return false; } #endif private: @@ -285,8 +293,11 @@ class Temperature { /** * Static (class) methods */ - static float analog2temp(int raw, uint8_t e); - static float analog2tempBed(int raw); + static float analog2temp(const int raw, const uint8_t e); + + #if HAS_TEMP_BED + static float analog2tempBed(const int raw); + #endif /** * Called from the Temperature ISR @@ -302,19 +313,19 @@ class Temperature { * Preheating hotends */ #ifdef MILLISECONDS_PREHEAT_TIME - static bool is_preheating(uint8_t e) { + static bool is_preheating(const uint8_t e) { #if HOTENDS == 1 UNUSED(e); #endif return preheat_end_time[HOTEND_INDEX] && PENDING(millis(), preheat_end_time[HOTEND_INDEX]); } - static void start_preheat_time(uint8_t e) { + static void start_preheat_time(const uint8_t e) { #if HOTENDS == 1 UNUSED(e); #endif preheat_end_time[HOTEND_INDEX] = millis() + MILLISECONDS_PREHEAT_TIME; } - static void reset_preheat_time(uint8_t e) { + static void reset_preheat_time(const uint8_t e) { #if HOTENDS == 1 UNUSED(e); #endif @@ -329,36 +340,37 @@ class Temperature { static int8_t widthFil_to_size_ratio(); // Convert Filament Width (mm) to an extrusion ratio #endif + //high level conversion routines, for use outside of temperature.cpp //inline so that there is no performance decrease. //deg=degreeCelsius - static float degHotend(uint8_t e) { + FORCE_INLINE static float degHotend(const uint8_t e) { #if HOTENDS == 1 UNUSED(e); #endif return current_temperature[HOTEND_INDEX]; } - static float degBed() { return current_temperature_bed; } + FORCE_INLINE static float degBed() { return current_temperature_bed; } #if ENABLED(SHOW_TEMP_ADC_VALUES) - static int16_t rawHotendTemp(uint8_t e) { + FORCE_INLINE static int16_t rawHotendTemp(const uint8_t e) { #if HOTENDS == 1 UNUSED(e); #endif return current_temperature_raw[HOTEND_INDEX]; } - static int16_t rawBedTemp() { return current_temperature_bed_raw; } + FORCE_INLINE static int16_t rawBedTemp() { return current_temperature_bed_raw; } #endif - static int16_t degTargetHotend(uint8_t e) { + FORCE_INLINE static int16_t degTargetHotend(const uint8_t e) { #if HOTENDS == 1 UNUSED(e); #endif return target_temperature[HOTEND_INDEX]; } - static int16_t degTargetBed() { return target_temperature_bed; } + FORCE_INLINE static int16_t degTargetBed() { return target_temperature_bed; } #if WATCH_HOTENDS static void start_watching_heater(const uint8_t e = 0); @@ -399,21 +411,25 @@ class Temperature { #endif } - static bool isHeatingHotend(uint8_t e) { + FORCE_INLINE static bool isHeatingHotend(const uint8_t e) { #if HOTENDS == 1 UNUSED(e); #endif return target_temperature[HOTEND_INDEX] > current_temperature[HOTEND_INDEX]; } - static bool isHeatingBed() { return target_temperature_bed > current_temperature_bed; } + FORCE_INLINE static bool isHeatingBed() { return target_temperature_bed > current_temperature_bed; } - static bool isCoolingHotend(uint8_t e) { + FORCE_INLINE static bool isCoolingHotend(const uint8_t e) { #if HOTENDS == 1 UNUSED(e); #endif return target_temperature[HOTEND_INDEX] < current_temperature[HOTEND_INDEX]; } - static bool isCoolingBed() { return target_temperature_bed < current_temperature_bed; } + FORCE_INLINE static bool isCoolingBed() { return target_temperature_bed < current_temperature_bed; } + + FORCE_INLINE static bool wait_for_heating(const uint8_t e) { + return degTargetHotend(e) > TEMP_HYSTERESIS && abs(degHotend(e) - degTargetHotend(e)) > TEMP_HYSTERESIS; + } /** * The software PWM power for a heater @@ -480,11 +496,12 @@ class Temperature { #if ENABLED(PROBING_HEATERS_OFF) static void pause(const bool p); - static bool is_paused() { return paused; } + FORCE_INLINE static bool is_paused() { return paused; } #endif #if HEATER_IDLE_HANDLER - static void start_heater_idle_timer(uint8_t e, millis_t timeout_ms) { + + static void start_heater_idle_timer(const uint8_t e, const millis_t timeout_ms) { #if HOTENDS == 1 UNUSED(e); #endif @@ -492,7 +509,7 @@ class Temperature { heater_idle_timeout_exceeded[HOTEND_INDEX] = false; } - static void reset_heater_idle_timer(uint8_t e) { + static void reset_heater_idle_timer(const uint8_t e) { #if HOTENDS == 1 UNUSED(e); #endif @@ -503,7 +520,7 @@ class Temperature { #endif } - static bool is_heater_idle(uint8_t e) { + FORCE_INLINE static bool is_heater_idle(const uint8_t e) { #if HOTENDS == 1 UNUSED(e); #endif @@ -511,7 +528,7 @@ class Temperature { } #if HAS_TEMP_BED - static void start_bed_idle_timer(millis_t timeout_ms) { + static void start_bed_idle_timer(const millis_t timeout_ms) { bed_idle_timeout_ms = millis() + timeout_ms; bed_idle_timeout_exceeded = false; } @@ -524,11 +541,10 @@ class Temperature { #endif } - static bool is_bed_idle() { - return bed_idle_timeout_exceeded; - } + FORCE_INLINE static bool is_bed_idle() { return bed_idle_timeout_exceeded; } #endif - #endif + + #endif // HEATER_IDLE_HANDLER #if HAS_TEMP_HOTEND || HAS_TEMP_BED static void print_heaterstates(); @@ -574,7 +590,7 @@ class Temperature { typedef enum TRState { TRInactive, TRFirstHeating, TRStable, TRRunaway } TRstate; - static void thermal_runaway_protection(TRState * const state, millis_t * const timer, const float current, const float target, const int8_t heater_id, const uint16_t period_seconds, const uint16_t hysteresis_degc); + static void thermal_runaway_protection(TRState * const state, millis_t * const timer, const float ¤t, const float &target, const int8_t heater_id, const uint16_t period_seconds, const uint16_t hysteresis_degc); #if ENABLED(THERMAL_PROTECTION_HOTENDS) static TRState thermal_runaway_state_machine[HOTENDS];