@ -35,6 +35,11 @@
# include "endstops.h"
# include "endstops.h"
# include "planner.h"
# include "planner.h"
# if HAS_COOLER
# include "../feature/cooler.h"
# include "../feature/spindle_laser.h"
# endif
# if ENABLED(EMERGENCY_PARSER)
# if ENABLED(EMERGENCY_PARSER)
# include "motion.h"
# include "motion.h"
# endif
# endif
@ -232,8 +237,13 @@ const char str_t_thermal_runaway[] PROGMEM = STR_T_THERMAL_RUNAWAY,
# else
# else
# define _CHAMBER_PSTR(h)
# define _CHAMBER_PSTR(h)
# endif
# endif
# if HAS_COOLER
# define _COOLER_PSTR(h) (h) == H_COOLER ? GET_TEXT(MSG_COOLER) :
# else
# define _COOLER_PSTR(h)
# endif
# define _E_PSTR(h,N) ((HOTENDS) > N && (h) == N) ? PSTR(LCD_STR_E##N) :
# define _E_PSTR(h,N) ((HOTENDS) > N && (h) == N) ? PSTR(LCD_STR_E##N) :
# define HEATER_PSTR(h) _BED_PSTR(h) _CHAMBER_PSTR(h) _E_PSTR(h,1) _E_PSTR(h,2) _E_PSTR(h,3) _E_PSTR(h,4) _E_PSTR(h,5) PSTR(LCD_STR_E0)
# define HEATER_PSTR(h) _BED_PSTR(h) _CHAMBER_PSTR(h) _ COOLER_PSTR(h) _ E_PSTR(h,1) _E_PSTR(h,2) _E_PSTR(h,3) _E_PSTR(h,4) _E_PSTR(h,5) PSTR(LCD_STR_E0)
// public:
// public:
@ -254,6 +264,9 @@ const char str_t_thermal_runaway[] PROGMEM = STR_T_THERMAL_RUNAWAY,
uint8_t Temperature : : chamberfan_speed ; // = 0
uint8_t Temperature : : chamberfan_speed ; // = 0
# endif
# endif
# if ENABLED(AUTO_POWER_COOLER_FAN)
uint8_t Temperature : : coolerfan_speed ; // = 0
# endif
# if HAS_FAN
# if HAS_FAN
uint8_t Temperature : : fan_speed [ FAN_COUNT ] ; // = { 0 }
uint8_t Temperature : : fan_speed [ FAN_COUNT ] ; // = { 0 }
@ -355,14 +368,11 @@ const char str_t_thermal_runaway[] PROGMEM = STR_T_THERMAL_RUNAWAY,
# endif
# endif
TERN_ ( WATCH_BED , bed_watch_t Temperature : : watch_bed ) ; // = { 0 }
TERN_ ( WATCH_BED , bed_watch_t Temperature : : watch_bed ) ; // = { 0 }
IF_DISABLED ( PIDTEMPBED , millis_t Temperature : : next_bed_check_ms ) ;
IF_DISABLED ( PIDTEMPBED , millis_t Temperature : : next_bed_check_ms ) ;
# endif // HAS_HEATED_BED
# endif
# if HAS_TEMP_CHAMBER
# if HAS_TEMP_CHAMBER
chamber_info_t Temperature : : temp_chamber ; // = { 0 }
chamber_info_t Temperature : : temp_chamber ; // = { 0 }
# if HAS_HEATED_CHAMBER
# 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 ;
millis_t next_cool_check_ms_2 = 0 ;
float old_temp = 9999 ;
float old_temp = 9999 ;
# ifdef CHAMBER_MINTEMP
# ifdef CHAMBER_MINTEMP
@ -373,8 +383,27 @@ const char str_t_thermal_runaway[] PROGMEM = STR_T_THERMAL_RUNAWAY,
# endif
# endif
TERN_ ( WATCH_CHAMBER , chamber_watch_t Temperature : : watch_chamber { 0 } ) ;
TERN_ ( WATCH_CHAMBER , chamber_watch_t Temperature : : watch_chamber { 0 } ) ;
IF_DISABLED ( PIDTEMPCHAMBER , millis_t Temperature : : next_chamber_check_ms ) ;
IF_DISABLED ( PIDTEMPCHAMBER , millis_t Temperature : : next_chamber_check_ms ) ;
# endif // HAS_HEATED_CHAMBER
# endif
# endif // HAS_TEMP_CHAMBER
# endif
# if HAS_TEMP_COOLER
cooler_info_t Temperature : : temp_cooler ; // = { 0 }
# if HAS_COOLER
bool flag_cooler_state ;
//bool flag_cooler_excess = false;
float previous_temp = 9999 ;
# ifdef COOLER_MINTEMP
int16_t Temperature : : mintemp_raw_COOLER = TEMP_SENSOR_COOLER_RAW_LO_TEMP ;
# endif
# ifdef COOLER_MAXTEMP
int16_t Temperature : : maxtemp_raw_COOLER = TEMP_SENSOR_COOLER_RAW_HI_TEMP ;
# endif
# if WATCH_COOLER
cooler_watch_t Temperature : : watch_cooler { 0 } ;
# endif
millis_t Temperature : : next_cooler_check_ms , Temperature : : cooler_fan_flush_ms ;
# endif
# endif
# if HAS_TEMP_PROBE
# if HAS_TEMP_PROBE
probe_info_t Temperature : : temp_probe ; // = { 0 }
probe_info_t Temperature : : temp_probe ; // = { 0 }
@ -744,6 +773,9 @@ int16_t Temperature::getHeaterPower(const heater_id_t heater_id) {
# if HAS_HEATED_CHAMBER
# if HAS_HEATED_CHAMBER
case H_CHAMBER : return temp_chamber . soft_pwm_amount ;
case H_CHAMBER : return temp_chamber . soft_pwm_amount ;
# endif
# endif
# if HAS_COOLER
case H_COOLER : return temp_cooler . soft_pwm_amount ;
# endif
default :
default :
return TERN0 ( HAS_HOTEND , temp_hotend [ heater_id ] . soft_pwm_amount ) ;
return TERN0 ( HAS_HOTEND , temp_hotend [ heater_id ] . soft_pwm_amount ) ;
}
}
@ -779,6 +811,11 @@ int16_t Temperature::getHeaterPower(const heater_id_t heater_id) {
SBI ( fanState , pgm_read_byte ( & fanBit [ CHAMBER_FAN_INDEX ] ) ) ;
SBI ( fanState , pgm_read_byte ( & fanBit [ CHAMBER_FAN_INDEX ] ) ) ;
# endif
# endif
# if HAS_AUTO_COOLER_FAN
if ( temp_cooler . celsius > = COOLER_AUTO_FAN_TEMPERATURE )
SBI ( fanState , pgm_read_byte ( & fanBit [ COOLER_FAN_INDEX ] ) ) ;
# endif
# define _UPDATE_AUTO_FAN(P,D,A) do{ \
# define _UPDATE_AUTO_FAN(P,D,A) do{ \
if ( PWM_PIN ( P # # _AUTO_FAN_PIN ) & & A < 255 ) \
if ( PWM_PIN ( P # # _AUTO_FAN_PIN ) & & A < 255 ) \
analogWrite ( pin_t ( P # # _AUTO_FAN_PIN ) , D ? A : 0 ) ; \
analogWrite ( pin_t ( P # # _AUTO_FAN_PIN ) , D ? A : 0 ) ; \
@ -874,6 +911,8 @@ void Temperature::_temp_error(const heater_id_t heater_id, PGM_P const serial_ms
SERIAL_ECHO ( heater_id ) ;
SERIAL_ECHO ( heater_id ) ;
else if ( TERN0 ( HAS_HEATED_CHAMBER , heater_id = = H_CHAMBER ) )
else if ( TERN0 ( HAS_HEATED_CHAMBER , heater_id = = H_CHAMBER ) )
SERIAL_ECHOPGM ( STR_HEATER_CHAMBER ) ;
SERIAL_ECHOPGM ( STR_HEATER_CHAMBER ) ;
else if ( TERN0 ( HAS_COOLER , heater_id = = H_COOLER ) )
SERIAL_ECHOPGM ( STR_COOLER ) ;
else
else
SERIAL_ECHOPGM ( STR_HEATER_BED ) ;
SERIAL_ECHOPGM ( STR_HEATER_BED ) ;
SERIAL_EOL ( ) ;
SERIAL_EOL ( ) ;
@ -1347,11 +1386,18 @@ void Temperature::manage_heater() {
}
}
# endif
# endif
# if EITHER(CHAMBER_FAN, CHAMBER_VENT) || DISABLED(PIDTEMPCHAMBER)
static bool flag_chamber_excess_heat ; // = false;
# endif
# if EITHER(CHAMBER_FAN, CHAMBER_VENT)
# if EITHER(CHAMBER_FAN, CHAMBER_VENT)
static bool flag_chamber_off ; // = false
if ( temp_chamber . target > CHAMBER_MINTEMP ) {
if ( temp_chamber . target > CHAMBER_MINTEMP ) {
flag_chamber_off = false ;
flag_chamber_off = false ;
# if ENABLED(CHAMBER_FAN)
# if ENABLED(CHAMBER_FAN)
int16_t fan_chamber_pwm ;
# if CHAMBER_FAN_MODE == 0
# if CHAMBER_FAN_MODE == 0
fan_chamber_pwm = CHAMBER_FAN_BASE ;
fan_chamber_pwm = CHAMBER_FAN_BASE ;
# elif CHAMBER_FAN_MODE == 1
# elif CHAMBER_FAN_MODE == 1
@ -1376,7 +1422,8 @@ void Temperature::manage_heater() {
// Open vent after MIN_COOLING_SLOPE_TIME_CHAMBER_VENT seconds if the
// Open vent after MIN_COOLING_SLOPE_TIME_CHAMBER_VENT seconds if the
// temperature didn't drop at least MIN_COOLING_SLOPE_DEG_CHAMBER_VENT
// temperature didn't drop at least MIN_COOLING_SLOPE_DEG_CHAMBER_VENT
if ( next_cool_check_ms_2 = = 0 | | ELAPSED ( ms , next_cool_check_ms_2 ) ) {
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
if ( temp_chamber . celsius - old_temp > 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 + SEC_TO_MS ( MIN_COOLING_SLOPE_TIME_CHAMBER_VENT ) ;
next_cool_check_ms_2 = ms + SEC_TO_MS ( MIN_COOLING_SLOPE_TIME_CHAMBER_VENT ) ;
old_temp = temp_chamber . celsius ;
old_temp = temp_chamber . celsius ;
}
}
@ -1385,9 +1432,8 @@ void Temperature::manage_heater() {
next_cool_check_ms_2 = 0 ;
next_cool_check_ms_2 = 0 ;
old_temp = 9999 ;
old_temp = 9999 ;
}
}
if ( flag_chamber_excess_heat & & ( temp_chamber . celsius - temp_chamber . target < = - LOW_EXCESS_HEAT_LIMIT ) ) {
if ( flag_chamber_excess_heat & & ( temp_chamber . target - temp_chamber . celsius > = LOW_EXCESS_HEAT_LIMIT ) )
flag_chamber_excess_heat = false ;
flag_chamber_excess_heat = false ;
}
# endif
# endif
}
}
else if ( ! flag_chamber_off ) {
else if ( ! flag_chamber_off ) {
@ -1402,17 +1448,14 @@ void Temperature::manage_heater() {
}
}
# endif
# endif
# if ENABLED(PIDTEMPCHAMBER)
# if ENABLED(PIDTEMPCHAMBER)
// PIDTEMPCHAMBER doens't support a CHAMBER_VENT yet.
// PIDTEMPCHAMBER doens't support a CHAMBER_VENT yet.
temp_chamber . soft_pwm_amount = WITHIN ( temp_chamber . celsius , CHAMBER_MINTEMP , CHAMBER_MAXTEMP ) ? ( int ) get_pid_output_chamber ( ) > > 1 : 0 ;
temp_chamber . soft_pwm_amount = WITHIN ( temp_chamber . celsius , CHAMBER_MINTEMP , CHAMBER_MAXTEMP ) ? ( int ) get_pid_output_chamber ( ) > > 1 : 0 ;
# else
# else
if ( ELAPSED ( ms , next_chamber_check_ms ) ) {
if ( ELAPSED ( ms , next_chamber_check_ms ) ) {
next_chamber_check_ms = ms + CHAMBER_CHECK_INTERVAL ;
next_chamber_check_ms = ms + CHAMBER_CHECK_INTERVAL ;
if ( WITHIN ( temp_chamber . celsius , CHAMBER_MINTEMP , CHAMBER_MAXTEMP ) ) {
if ( WITHIN ( temp_chamber . celsius , CHAMBER_MINTEMP , CHAMBER_MAXTEMP ) ) {
if ( flag_chamber_excess_heat ) {
if ( flag_chamber_excess_heat ) {
temp_chamber . soft_pwm_amount = 0 ;
temp_chamber . soft_pwm_amount = 0 ;
# if ENABLED(CHAMBER_VENT)
# if ENABLED(CHAMBER_VENT)
@ -1437,7 +1480,6 @@ void Temperature::manage_heater() {
temp_chamber . soft_pwm_amount = 0 ;
temp_chamber . soft_pwm_amount = 0 ;
WRITE_HEATER_CHAMBER ( LOW ) ;
WRITE_HEATER_CHAMBER ( LOW ) ;
}
}
}
}
# if ENABLED(THERMAL_PROTECTION_CHAMBER)
# if ENABLED(THERMAL_PROTECTION_CHAMBER)
tr_state_machine [ RUNAWAY_IND_CHAMBER ] . run ( temp_chamber . celsius , temp_chamber . target , H_CHAMBER , THERMAL_PROTECTION_CHAMBER_PERIOD , THERMAL_PROTECTION_CHAMBER_HYSTERESIS ) ;
tr_state_machine [ RUNAWAY_IND_CHAMBER ] . run ( temp_chamber . celsius , temp_chamber . target , H_CHAMBER , THERMAL_PROTECTION_CHAMBER_PERIOD , THERMAL_PROTECTION_CHAMBER_HYSTERESIS ) ;
@ -1446,6 +1488,66 @@ void Temperature::manage_heater() {
# endif // HAS_HEATED_CHAMBER
# endif // HAS_HEATED_CHAMBER
# if HAS_COOLER
# ifndef COOLER_CHECK_INTERVAL
# define COOLER_CHECK_INTERVAL 2000UL
# endif
# if ENABLED(THERMAL_PROTECTION_COOLER)
if ( degCooler ( ) > COOLER_MAXTEMP ) max_temp_error ( H_COOLER ) ;
# endif
# if WATCH_COOLER
// Make sure temperature is decreasing
if ( watch_cooler . elapsed ( ms ) ) { // Time to check the cooler?
if ( degCooler ( ) > watch_cooler . target ) // Failed to decrease enough?
_temp_error ( H_COOLER , GET_TEXT ( MSG_COOLING_FAILED ) , GET_TEXT ( MSG_COOLING_FAILED ) ) ;
else
start_watching_cooler ( ) ; // Start again if the target is still far off
}
# endif
static bool flag_cooler_state ; // = false
if ( cooler . is_enabled ( ) ) {
flag_cooler_state = true ; // used to allow M106 fan control when cooler is disabled
if ( temp_cooler . target = = 0 ) temp_cooler . target = COOLER_MINTEMP ;
if ( ELAPSED ( ms , next_cooler_check_ms ) ) {
next_cooler_check_ms = ms + COOLER_CHECK_INTERVAL ;
if ( temp_cooler . celsius > temp_cooler . target ) {
temp_cooler . soft_pwm_amount = temp_cooler . celsius > temp_cooler . target ? MAX_COOLER_POWER : 0 ;
flag_cooler_state = temp_cooler . soft_pwm_amount > 0 ? true : false ; // used to allow M106 fan control when cooler is disabled
# if ENABLED(COOLER_FAN)
int16_t fan_cooler_pwm = ( COOLER_FAN_BASE ) + ( COOLER_FAN_FACTOR ) * ABS ( temp_cooler . celsius - temp_cooler . target ) ;
NOMORE ( fan_cooler_pwm , 255 ) ;
set_fan_speed ( COOLER_FAN_INDEX , fan_cooler_pwm ) ; // Set cooler fan pwm
cooler_fan_flush_ms = ms + 5000 ;
# endif
}
else {
temp_cooler . soft_pwm_amount = 0 ;
# if ENABLED(COOLER_FAN)
set_fan_speed ( COOLER_FAN_INDEX , temp_cooler . celsius > temp_cooler . target - 2 ? COOLER_FAN_BASE : 0 ) ;
# endif
WRITE_HEATER_COOLER ( LOW ) ;
}
}
}
else {
temp_cooler . soft_pwm_amount = 0 ;
if ( flag_cooler_state ) {
flag_cooler_state = false ;
thermalManager . set_fan_speed ( COOLER_FAN_INDEX , 0 ) ;
}
WRITE_HEATER_COOLER ( LOW ) ;
}
# if ENABLED(THERMAL_PROTECTION_COOLER)
tr_state_machine [ RUNAWAY_IND_COOLER ] . run ( temp_cooler . celsius , temp_cooler . target , H_COOLER , THERMAL_PROTECTION_COOLER_PERIOD , THERMAL_PROTECTION_COOLER_HYSTERESIS ) ;
# endif
# endif // HAS_COOLER
UNUSED ( ms ) ;
UNUSED ( ms ) ;
}
}
@ -1510,6 +1612,9 @@ void Temperature::manage_heater() {
# if TEMP_SENSOR_CHAMBER_IS_CUSTOM
# if TEMP_SENSOR_CHAMBER_IS_CUSTOM
{ true , 0 , 0 , CHAMBER_PULLUP_RESISTOR_OHMS , CHAMBER_RESISTANCE_25C_OHMS , 0 , 0 , CHAMBER_BETA , 0 }
{ true , 0 , 0 , CHAMBER_PULLUP_RESISTOR_OHMS , CHAMBER_RESISTANCE_25C_OHMS , 0 , 0 , CHAMBER_BETA , 0 }
# endif
# endif
# if TEMP_SENSOR_COOLER_IS_CUSTOM
{ true , 0 , 0 , COOLER_PULLUP_RESISTOR_OHMS , COOLER_RESISTANCE_25C_OHMS , 0 , 0 , COOLER_BETA , 0 }
# endif
# if TEMP_SENSOR_PROBE_IS_CUSTOM
# if TEMP_SENSOR_PROBE_IS_CUSTOM
{ true , 0 , 0 , PROBE_PULLUP_RESISTOR_OHMS , PROBE_RESISTANCE_25C_OHMS , 0 , 0 , PROBE_BETA , 0 }
{ true , 0 , 0 , PROBE_PULLUP_RESISTOR_OHMS , PROBE_RESISTANCE_25C_OHMS , 0 , 0 , PROBE_BETA , 0 }
# endif
# endif
@ -1543,6 +1648,7 @@ void Temperature::manage_heater() {
TERN_ ( TEMP_SENSOR_7_IS_CUSTOM , t_index = = CTI_HOTEND_7 ? PSTR ( " HOTEND 7 " ) : )
TERN_ ( TEMP_SENSOR_7_IS_CUSTOM , t_index = = CTI_HOTEND_7 ? PSTR ( " HOTEND 7 " ) : )
TERN_ ( TEMP_SENSOR_BED_IS_CUSTOM , t_index = = CTI_BED ? PSTR ( " BED " ) : )
TERN_ ( TEMP_SENSOR_BED_IS_CUSTOM , t_index = = CTI_BED ? PSTR ( " BED " ) : )
TERN_ ( TEMP_SENSOR_CHAMBER_IS_CUSTOM , t_index = = CTI_CHAMBER ? PSTR ( " CHAMBER " ) : )
TERN_ ( TEMP_SENSOR_CHAMBER_IS_CUSTOM , t_index = = CTI_CHAMBER ? PSTR ( " CHAMBER " ) : )
TERN_ ( TEMP_SENSOR_COOLER_IS_CUSTOM , t_index = = CTI_COOLER ? PSTR ( " COOLER " ) : )
TERN_ ( TEMP_SENSOR_PROBE_IS_CUSTOM , t_index = = CTI_PROBE ? PSTR ( " PROBE " ) : )
TERN_ ( TEMP_SENSOR_PROBE_IS_CUSTOM , t_index = = CTI_PROBE ? PSTR ( " PROBE " ) : )
nullptr
nullptr
) ;
) ;
@ -1706,7 +1812,6 @@ void Temperature::manage_heater() {
# endif // HAS_HOTEND
# endif // HAS_HOTEND
# if HAS_HEATED_BED
# if HAS_HEATED_BED
// Derived from RepRap FiveD extruder::getTemperature()
// For bed temperature measurement.
// For bed temperature measurement.
float Temperature : : analog_to_celsius_bed ( const int raw ) {
float Temperature : : analog_to_celsius_bed ( const int raw ) {
# if TEMP_SENSOR_BED_IS_CUSTOM
# if TEMP_SENSOR_BED_IS_CUSTOM
@ -1725,7 +1830,6 @@ void Temperature::manage_heater() {
# endif // HAS_HEATED_BED
# endif // HAS_HEATED_BED
# if HAS_TEMP_CHAMBER
# if HAS_TEMP_CHAMBER
// Derived from RepRap FiveD extruder::getTemperature()
// For chamber temperature measurement.
// For chamber temperature measurement.
float Temperature : : analog_to_celsius_chamber ( const int raw ) {
float Temperature : : analog_to_celsius_chamber ( const int raw ) {
# if TEMP_SENSOR_CHAMBER_IS_CUSTOM
# if TEMP_SENSOR_CHAMBER_IS_CUSTOM
@ -1743,8 +1847,25 @@ void Temperature::manage_heater() {
}
}
# endif // HAS_TEMP_CHAMBER
# endif // HAS_TEMP_CHAMBER
# if HAS_TEMP_COOLER
// For cooler temperature measurement.
float Temperature : : analog_to_celsius_cooler ( const int raw ) {
# if TEMP_SENSOR_COOLER_IS_CUSTOM
return user_thermistor_to_deg_c ( CTI_COOLER , raw ) ;
# elif TEMP_SENSOR_COOLER_IS_THERMISTOR
SCAN_THERMISTOR_TABLE ( TEMPTABLE_COOLER , TEMPTABLE_COOLER_LEN ) ;
# elif TEMP_SENSOR_COOLER_IS_AD595
return TEMP_AD595 ( raw ) ;
# elif TEMP_SENSOR_COOLER_IS_AD8495
return TEMP_AD8495 ( raw ) ;
# else
UNUSED ( raw ) ;
return 0 ;
# endif
}
# endif // HAS_TEMP_COOLER
# if HAS_TEMP_PROBE
# if HAS_TEMP_PROBE
// Derived from RepRap FiveD extruder::getTemperature()
// For probe temperature measurement.
// For probe temperature measurement.
float Temperature : : analog_to_celsius_probe ( const int raw ) {
float Temperature : : analog_to_celsius_probe ( const int raw ) {
# if TEMP_SENSOR_PROBE_IS_CUSTOM
# if TEMP_SENSOR_PROBE_IS_CUSTOM
@ -1776,6 +1897,7 @@ void Temperature::updateTemperaturesFromRawValues() {
# endif
# endif
TERN_ ( HAS_HEATED_BED , temp_bed . celsius = analog_to_celsius_bed ( temp_bed . raw ) ) ;
TERN_ ( HAS_HEATED_BED , temp_bed . celsius = analog_to_celsius_bed ( temp_bed . raw ) ) ;
TERN_ ( HAS_TEMP_CHAMBER , temp_chamber . celsius = analog_to_celsius_chamber ( temp_chamber . raw ) ) ;
TERN_ ( HAS_TEMP_CHAMBER , temp_chamber . celsius = analog_to_celsius_chamber ( temp_chamber . raw ) ) ;
TERN_ ( HAS_TEMP_COOLER , temp_cooler . celsius = analog_to_celsius_cooler ( temp_cooler . raw ) ) ;
TERN_ ( HAS_TEMP_PROBE , temp_probe . celsius = analog_to_celsius_probe ( temp_probe . raw ) ) ;
TERN_ ( HAS_TEMP_PROBE , temp_probe . celsius = analog_to_celsius_probe ( temp_probe . raw ) ) ;
TERN_ ( TEMP_SENSOR_1_AS_REDUNDANT , redundant_temperature = analog_to_celsius_hotend ( redundant_temperature_raw , 1 ) ) ;
TERN_ ( TEMP_SENSOR_1_AS_REDUNDANT , redundant_temperature = analog_to_celsius_hotend ( redundant_temperature_raw , 1 ) ) ;
TERN_ ( FILAMENT_WIDTH_SENSOR , filwidth . update_measured_mm ( ) ) ;
TERN_ ( FILAMENT_WIDTH_SENSOR , filwidth . update_measured_mm ( ) ) ;
@ -1927,6 +2049,10 @@ void Temperature::init() {
OUT_WRITE ( HEATER_CHAMBER_PIN , HEATER_CHAMBER_INVERTING ) ;
OUT_WRITE ( HEATER_CHAMBER_PIN , HEATER_CHAMBER_INVERTING ) ;
# endif
# endif
# if HAS_COOLER
OUT_WRITE ( COOLER_PIN , COOLER_INVERTING ) ;
# endif
# if HAS_FAN0
# if HAS_FAN0
INIT_FAN_PIN ( FAN_PIN ) ;
INIT_FAN_PIN ( FAN_PIN ) ;
# endif
# endif
@ -2001,6 +2127,9 @@ void Temperature::init() {
# if HAS_TEMP_ADC_CHAMBER
# if HAS_TEMP_ADC_CHAMBER
HAL_ANALOG_SELECT ( TEMP_CHAMBER_PIN ) ;
HAL_ANALOG_SELECT ( TEMP_CHAMBER_PIN ) ;
# endif
# endif
# if HAS_TEMP_ADC_COOLER
HAL_ANALOG_SELECT ( TEMP_COOLER_PIN ) ;
# endif
# if HAS_TEMP_ADC_PROBE
# if HAS_TEMP_ADC_PROBE
HAL_ANALOG_SELECT ( TEMP_PROBE_PIN ) ;
HAL_ANALOG_SELECT ( TEMP_PROBE_PIN ) ;
# endif
# endif
@ -2137,6 +2266,15 @@ void Temperature::init() {
# endif
# endif
# endif
# endif
# if HAS_COOLER
# ifdef COOLER_MINTEMP
while ( analog_to_celsius_cooler ( mintemp_raw_COOLER ) > COOLER_MINTEMP ) mintemp_raw_COOLER + = TEMPDIR ( COOLER ) * ( OVERSAMPLENR ) ;
# endif
# ifdef COOLER_MAXTEMP
while ( analog_to_celsius_cooler ( maxtemp_raw_COOLER ) < COOLER_MAXTEMP ) maxtemp_raw_COOLER - = TEMPDIR ( COOLER ) * ( OVERSAMPLENR ) ;
# endif
# endif
TERN_ ( PROBING_HEATERS_OFF , paused = false ) ;
TERN_ ( PROBING_HEATERS_OFF , paused = false ) ;
}
}
@ -2174,6 +2312,17 @@ void Temperature::init() {
}
}
# endif
# endif
# if WATCH_COOLER
/**
* Start Cooling Sanity Check for cooler that is above
* its target temperature by a configurable margin .
* This is called when the temperature is set . ( M143 , M193 )
*/
void Temperature : : start_watching_cooler ( ) {
watch_cooler . restart ( degCooler ( ) , degTargetCooler ( ) ) ;
}
# endif
# if HAS_THERMAL_PROTECTION
# if HAS_THERMAL_PROTECTION
Temperature : : tr_state_machine_t Temperature : : tr_state_machine [ NR_HEATER_RUNAWAY ] ; // = { { TRInactive, 0 } };
Temperature : : tr_state_machine_t Temperature : : tr_state_machine [ NR_HEATER_RUNAWAY ] ; // = { { TRInactive, 0 } };
@ -2301,10 +2450,18 @@ void Temperature::disable_all_heaters() {
temp_chamber . soft_pwm_amount = 0 ;
temp_chamber . soft_pwm_amount = 0 ;
WRITE_HEATER_CHAMBER ( LOW ) ;
WRITE_HEATER_CHAMBER ( LOW ) ;
# endif
# endif
# if HAS_COOLER
setTargetCooler ( 0 ) ;
temp_cooler . soft_pwm_amount = 0 ;
WRITE_HEATER_COOLER ( LOW ) ;
# endif
}
}
# if ENABLED(PRINTJOB_TIMER_AUTOSTART)
# if ENABLED(PRINTJOB_TIMER_AUTOSTART)
# include "printcounter.h"
bool Temperature : : auto_job_over_threshold ( ) {
bool Temperature : : auto_job_over_threshold ( ) {
# if HAS_HOTEND
# if HAS_HOTEND
HOTEND_LOOP ( ) if ( degTargetHotend ( e ) > ( EXTRUDE_MINTEMP ) / 2 ) return true ;
HOTEND_LOOP ( ) if ( degTargetHotend ( e ) > ( EXTRUDE_MINTEMP ) / 2 ) return true ;
@ -2564,6 +2721,7 @@ void Temperature::update_raw_temperatures() {
TERN_ ( HAS_TEMP_ADC_BED , temp_bed . update ( ) ) ;
TERN_ ( HAS_TEMP_ADC_BED , temp_bed . update ( ) ) ;
TERN_ ( HAS_TEMP_ADC_CHAMBER , temp_chamber . update ( ) ) ;
TERN_ ( HAS_TEMP_ADC_CHAMBER , temp_chamber . update ( ) ) ;
TERN_ ( HAS_TEMP_ADC_PROBE , temp_probe . update ( ) ) ;
TERN_ ( HAS_TEMP_ADC_PROBE , temp_probe . update ( ) ) ;
TERN_ ( HAS_TEMP_ADC_COOLER , temp_cooler . update ( ) ) ;
TERN_ ( HAS_JOY_ADC_X , joystick . x . update ( ) ) ;
TERN_ ( HAS_JOY_ADC_X , joystick . x . update ( ) ) ;
TERN_ ( HAS_JOY_ADC_Y , joystick . y . update ( ) ) ;
TERN_ ( HAS_JOY_ADC_Y , joystick . y . update ( ) ) ;
@ -2588,6 +2746,7 @@ void Temperature::readings_ready() {
TERN_ ( HAS_HEATED_BED , temp_bed . reset ( ) ) ;
TERN_ ( HAS_HEATED_BED , temp_bed . reset ( ) ) ;
TERN_ ( HAS_TEMP_CHAMBER , temp_chamber . reset ( ) ) ;
TERN_ ( HAS_TEMP_CHAMBER , temp_chamber . reset ( ) ) ;
TERN_ ( HAS_TEMP_PROBE , temp_probe . reset ( ) ) ;
TERN_ ( HAS_TEMP_PROBE , temp_probe . reset ( ) ) ;
TERN_ ( HAS_TEMP_COOLER , temp_cooler . reset ( ) ) ;
TERN_ ( HAS_JOY_ADC_X , joystick . x . reset ( ) ) ;
TERN_ ( HAS_JOY_ADC_X , joystick . x . reset ( ) ) ;
TERN_ ( HAS_JOY_ADC_Y , joystick . y . reset ( ) ) ;
TERN_ ( HAS_JOY_ADC_Y , joystick . y . reset ( ) ) ;
@ -2650,6 +2809,18 @@ void Temperature::readings_ready() {
if ( CHAMBERCMP ( temp_chamber . raw , maxtemp_raw_CHAMBER ) ) max_temp_error ( H_CHAMBER ) ;
if ( CHAMBERCMP ( temp_chamber . raw , maxtemp_raw_CHAMBER ) ) max_temp_error ( H_CHAMBER ) ;
if ( chamber_on & & CHAMBERCMP ( mintemp_raw_CHAMBER , temp_chamber . raw ) ) min_temp_error ( H_CHAMBER ) ;
if ( chamber_on & & CHAMBERCMP ( mintemp_raw_CHAMBER , temp_chamber . raw ) ) min_temp_error ( H_CHAMBER ) ;
# endif
# endif
# if BOTH(HAS_COOLER, THERMAL_PROTECTION_COOLER)
# if TEMPDIR(COOLER) < 0
# define COOLERCMP(A,B) ((A)<(B))
# else
# define COOLERCMP(A,B) ((A)>(B))
# endif
if ( cutter . unitPower > 0 ) {
if ( COOLERCMP ( temp_cooler . raw , maxtemp_raw_COOLER ) ) max_temp_error ( H_COOLER ) ;
}
if ( COOLERCMP ( mintemp_raw_COOLER , temp_cooler . raw ) ) min_temp_error ( H_COOLER ) ;
# endif
}
}
/**
/**
@ -2735,11 +2906,15 @@ void Temperature::tick() {
static SoftPWM soft_pwm_chamber ;
static SoftPWM soft_pwm_chamber ;
# endif
# endif
# if HAS_COOLER
static SoftPWM soft_pwm_cooler ;
# endif
# define WRITE_FAN(n, v) WRITE(FAN##n##_PIN, (v) ^ FAN_INVERTING)
# define WRITE_FAN(n, v) WRITE(FAN##n##_PIN, (v) ^ FAN_INVERTING)
# if DISABLED(SLOW_PWM_HEATERS)
# if DISABLED(SLOW_PWM_HEATERS)
# if ANY(HAS_HOTEND, HAS_HEATED_BED, HAS_HEATED_CHAMBER, FAN_SOFT_PWM)
# if ANY(HAS_HOTEND, HAS_HEATED_BED, HAS_HEATED_CHAMBER, HAS_COOLER, FAN_SOFT_PWM)
constexpr uint8_t pwm_mask = TERN0 ( SOFT_PWM_DITHER , _BV ( SOFT_PWM_SCALE ) - 1 ) ;
constexpr uint8_t pwm_mask = TERN0 ( SOFT_PWM_DITHER , _BV ( SOFT_PWM_SCALE ) - 1 ) ;
# define _PWM_MOD(N,S,T) do{ \
# define _PWM_MOD(N,S,T) do{ \
const bool on = S . add ( pwm_mask , T . soft_pwm_amount ) ; \
const bool on = S . add ( pwm_mask , T . soft_pwm_amount ) ; \
@ -2766,6 +2941,10 @@ void Temperature::tick() {
_PWM_MOD ( CHAMBER , soft_pwm_chamber , temp_chamber ) ;
_PWM_MOD ( CHAMBER , soft_pwm_chamber , temp_chamber ) ;
# endif
# endif
# if HAS_COOLER
_PWM_MOD ( COOLER , soft_pwm_cooler , temp_cooler ) ;
# endif
# if ENABLED(FAN_SOFT_PWM)
# if ENABLED(FAN_SOFT_PWM)
# define _FAN_PWM(N) do{ \
# define _FAN_PWM(N) do{ \
uint8_t & spcf = soft_pwm_count_fan [ N ] ; \
uint8_t & spcf = soft_pwm_count_fan [ N ] ; \
@ -2813,6 +2992,10 @@ void Temperature::tick() {
_PWM_LOW ( CHAMBER , soft_pwm_chamber ) ;
_PWM_LOW ( CHAMBER , soft_pwm_chamber ) ;
# endif
# endif
# if HAS_COOLER
_PWM_LOW ( COOLER , soft_pwm_cooler ) ;
# endif
# if ENABLED(FAN_SOFT_PWM)
# if ENABLED(FAN_SOFT_PWM)
# if HAS_FAN0
# if HAS_FAN0
if ( soft_pwm_count_fan [ 0 ] < = pwm_count_tmp ) WRITE_FAN ( 0 , LOW ) ;
if ( soft_pwm_count_fan [ 0 ] < = pwm_count_tmp ) WRITE_FAN ( 0 , LOW ) ;
@ -2879,6 +3062,10 @@ void Temperature::tick() {
_SLOW_PWM ( CHAMBER , soft_pwm_chamber , temp_chamber ) ;
_SLOW_PWM ( CHAMBER , soft_pwm_chamber , temp_chamber ) ;
# endif
# endif
# if HAS_COOLER
_SLOW_PWM ( COOLER , soft_pwm_cooler , temp_cooler ) ;
# endif
} // slow_pwm_count == 0
} // slow_pwm_count == 0
# if HAS_HOTEND
# if HAS_HOTEND
@ -2894,6 +3081,10 @@ void Temperature::tick() {
_PWM_OFF ( CHAMBER , soft_pwm_chamber ) ;
_PWM_OFF ( CHAMBER , soft_pwm_chamber ) ;
# endif
# endif
# if HAS_COOLER
_PWM_OFF ( COOLER , soft_pwm_cooler , temp_cooler ) ;
# endif
# if ENABLED(FAN_SOFT_PWM)
# if ENABLED(FAN_SOFT_PWM)
if ( pwm_count_tmp > = 127 ) {
if ( pwm_count_tmp > = 127 ) {
pwm_count_tmp = 0 ;
pwm_count_tmp = 0 ;
@ -2973,6 +3164,7 @@ void Temperature::tick() {
# endif
# endif
TERN_ ( HAS_HEATED_BED , soft_pwm_bed . dec ( ) ) ;
TERN_ ( HAS_HEATED_BED , soft_pwm_bed . dec ( ) ) ;
TERN_ ( HAS_HEATED_CHAMBER , soft_pwm_chamber . dec ( ) ) ;
TERN_ ( HAS_HEATED_CHAMBER , soft_pwm_chamber . dec ( ) ) ;
TERN_ ( HAS_COOLER , soft_pwm_cooler . dec ( ) ) ;
}
}
# endif // SLOW_PWM_HEATERS
# endif // SLOW_PWM_HEATERS
@ -3040,6 +3232,11 @@ void Temperature::tick() {
case MeasureTemp_CHAMBER : ACCUMULATE_ADC ( temp_chamber ) ; break ;
case MeasureTemp_CHAMBER : ACCUMULATE_ADC ( temp_chamber ) ; break ;
# endif
# endif
# if HAS_TEMP_ADC_COOLER
case PrepareTemp_COOLER : HAL_START_ADC ( TEMP_COOLER_PIN ) ; break ;
case MeasureTemp_COOLER : ACCUMULATE_ADC ( temp_cooler ) ; break ;
# endif
# if HAS_TEMP_ADC_PROBE
# if HAS_TEMP_ADC_PROBE
case PrepareTemp_PROBE : HAL_START_ADC ( TEMP_PROBE_PIN ) ; break ;
case PrepareTemp_PROBE : HAL_START_ADC ( TEMP_PROBE_PIN ) ; break ;
case MeasureTemp_PROBE : ACCUMULATE_ADC ( temp_probe ) ; break ;
case MeasureTemp_PROBE : ACCUMULATE_ADC ( temp_probe ) ; break ;
@ -3183,22 +3380,24 @@ void Temperature::tick() {
) {
) {
char k ;
char k ;
switch ( e ) {
switch ( e ) {
default :
# if HAS_TEMP_HOTEND
k = ' T ' ; break ;
# endif
# if HAS_TEMP_BED
case H_BED : k = ' B ' ; break ;
# endif
# if HAS_TEMP_CHAMBER
# if HAS_TEMP_CHAMBER
case H_CHAMBER : k = ' C ' ; break ;
case H_CHAMBER : k = ' C ' ; break ;
# endif
# endif
# if HAS_TEMP_PROBE
# if HAS_TEMP_PROBE
case H_PROBE : k = ' P ' ; break ;
case H_PROBE : k = ' P ' ; break ;
# endif
# endif
# if HAS_TEMP_HOTEND
# if HAS_TEMP_COOLER
default : k = ' T ' ; break ;
case H_COOLER : k = ' L ' ; break ;
# if HAS_HEATED_BED
# endif
case H_BED : k = ' B ' ; break ;
# if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT)
# endif
case H_REDUNDANT : k = ' R ' ; break ;
# if ENABLED(TEMP_SENSOR_1_AS_REDUNDANT)
case H_REDUNDANT : k = ' R ' ; break ;
# endif
# elif HAS_HEATED_BED
default : k = ' B ' ; break ;
# endif
# endif
}
}
SERIAL_CHAR ( ' ' , k ) ;
SERIAL_CHAR ( ' ' , k ) ;
@ -3251,18 +3450,21 @@ void Temperature::tick() {
) ;
) ;
# endif
# endif
# if HAS_TEMP_CHAMBER
# if HAS_TEMP_CHAMBER
print_heater_state ( degChamber ( )
print_heater_state ( degChamber ( ) , TERN0 ( HAS_HEATED_CHAMBER , degTargetChamber ( ) )
# if HAS_HEATED_CHAMBER
, degTargetChamber ( )
# else
, 0
# endif
# if ENABLED(SHOW_TEMP_ADC_VALUES)
# if ENABLED(SHOW_TEMP_ADC_VALUES)
, rawChamberTemp ( )
, rawChamberTemp ( )
# endif
# endif
, H_CHAMBER
, H_CHAMBER
) ;
) ;
# endif
# endif // HAS_TEMP_CHAMBER
# if HAS_TEMP_COOLER
print_heater_state ( degCooler ( ) , TERN0 ( HAS_COOLER , degTargetCooler ( ) )
# if ENABLED(SHOW_TEMP_ADC_VALUES)
, rawCoolerTemp ( )
# endif
, H_COOLER
) ;
# endif // HAS_TEMP_COOLER
# if HAS_TEMP_PROBE
# if HAS_TEMP_PROBE
print_heater_state ( degProbe ( ) , 0
print_heater_state ( degProbe ( ) , 0
# if ENABLED(SHOW_TEMP_ADC_VALUES)
# if ENABLED(SHOW_TEMP_ADC_VALUES)
@ -3286,6 +3488,9 @@ void Temperature::tick() {
# if HAS_HEATED_CHAMBER
# if HAS_HEATED_CHAMBER
SERIAL_ECHOPAIR ( " C@: " , getHeaterPower ( H_CHAMBER ) ) ;
SERIAL_ECHOPAIR ( " C@: " , getHeaterPower ( H_CHAMBER ) ) ;
# endif
# endif
# if HAS_COOLER
SERIAL_ECHOPAIR ( " C@: " , getHeaterPower ( H_COOLER ) ) ;
# endif
# if HAS_MULTI_HOTEND
# if HAS_MULTI_HOTEND
HOTEND_LOOP ( ) {
HOTEND_LOOP ( ) {
SERIAL_ECHOPAIR ( " @ " , e ) ;
SERIAL_ECHOPAIR ( " @ " , e ) ;
@ -3759,4 +3964,103 @@ void Temperature::tick() {
# endif // HAS_HEATED_CHAMBER
# endif // HAS_HEATED_CHAMBER
# if HAS_COOLER
# ifndef MIN_COOLING_SLOPE_DEG_COOLER
# define MIN_COOLING_SLOPE_DEG_COOLER 1.50
# endif
# ifndef MIN_COOLING_SLOPE_TIME_COOLER
# define MIN_COOLING_SLOPE_TIME_COOLER 120
# endif
bool Temperature : : wait_for_cooler ( const bool no_wait_for_cooling /*=true*/ ) {
# if TEMP_COOLER_RESIDENCY_TIME > 0
millis_t residency_start_ms = 0 ;
bool first_loop = true ;
// Loop until the temperature has stabilized
# define TEMP_COOLER_CONDITIONS (!residency_start_ms || PENDING(now, residency_start_ms + SEC_TO_MS(TEMP_COOLER_RESIDENCY_TIME)))
# else
// Loop until the temperature is very close target
# define TEMP_COOLER_CONDITIONS (wants_to_cool ? isLaserHeating() : isLaserCooling())
# endif
# if DISABLED(BUSY_WHILE_HEATING) && ENABLED(HOST_KEEPALIVE_FEATURE)
KEEPALIVE_STATE ( NOT_BUSY ) ;
# endif
bool wants_to_cool = false ;
float target_temp = - 1 , previous_temp = 9999 ;
millis_t now , next_temp_ms = 0 , next_cooling_check_ms = 0 ;
wait_for_heatup = true ;
do {
// Target temperature might be changed during the loop
if ( target_temp ! = degTargetCooler ( ) ) {
wants_to_cool = isLaserHeating ( ) ;
target_temp = degTargetCooler ( ) ;
// Exit if S<lower>, continue if S<higher>, R<lower>, or R<higher>
if ( no_wait_for_cooling & & wants_to_cool ) break ;
}
now = millis ( ) ;
if ( ELAPSED ( now , next_temp_ms ) ) { // Print Temp Reading every 1 second while heating up.
next_temp_ms = now + 1000UL ;
print_heater_states ( active_extruder ) ;
# if TEMP_COOLER_RESIDENCY_TIME > 0
SERIAL_ECHOPGM ( " W: " ) ;
if ( residency_start_ms )
SERIAL_ECHO ( long ( ( SEC_TO_MS ( TEMP_COOLER_RESIDENCY_TIME ) - ( now - residency_start_ms ) ) / 1000UL ) ) ;
else
SERIAL_CHAR ( ' ? ' ) ;
# endif
SERIAL_EOL ( ) ;
}
idle ( ) ;
gcode . reset_stepper_timeout ( ) ; // Keep steppers powered
const float current_temp = degCooler ( ) ;
# if TEMP_COOLER_RESIDENCY_TIME > 0
const float temp_diff = ABS ( target_temp - temp ) ;
if ( ! residency_start_ms ) {
// Start the TEMP_COOLER_RESIDENCY_TIME timer when we reach target temp for the first time.
if ( temp_diff < TEMP_COOLER_WINDOW )
residency_start_ms = now + ( first_loop ? SEC_TO_MS ( TEMP_COOLER_RESIDENCY_TIME ) / 3 : 0 ) ;
}
else if ( temp_diff > TEMP_COOLER_HYSTERESIS ) {
// Restart the timer whenever the temperature falls outside the hysteresis.
residency_start_ms = now ;
}
first_loop = false ;
# endif // TEMP_COOLER_RESIDENCY_TIME > 0
if ( wants_to_cool ) {
// Break after MIN_COOLING_SLOPE_TIME_CHAMBER seconds
// if the temperature did not drop at least MIN_COOLING_SLOPE_DEG_CHAMBER
if ( ! next_cooling_check_ms | | ELAPSED ( now , next_cooling_check_ms ) ) {
if ( previous_temp - current_temp < float ( MIN_COOLING_SLOPE_DEG_COOLER ) ) break ;
next_cooling_check_ms = now + SEC_TO_MS ( MIN_COOLING_SLOPE_TIME_COOLER ) ;
previous_temp = current_temp ;
}
}
} while ( wait_for_heatup & & TEMP_COOLER_CONDITIONS ) ;
// Prevent a wait-forever situation if R is misused i.e. M191 R0
if ( wait_for_heatup ) {
wait_for_heatup = false ;
ui . reset_status ( ) ;
return true ;
}
return false ;
}
# endif // HAS_COOLER
# endif // HAS_TEMP_SENSOR
# endif // HAS_TEMP_SENSOR