|
|
@ -377,7 +377,7 @@ volatile bool Temperature::raw_temps_ready = false; |
|
|
|
* Needs sufficient heater power to make some overshoot at target |
|
|
|
* temperature to succeed. |
|
|
|
*/ |
|
|
|
void Temperature::PID_autotune(const float &target, const heater_ind_t heater, const int8_t ncycles, const bool set_result/*=false*/) { |
|
|
|
void Temperature::PID_autotune(const float &target, const heater_id_t heater_id, const int8_t ncycles, const bool set_result/*=false*/) { |
|
|
|
float current_temp = 0.0; |
|
|
|
int cycles = 0; |
|
|
|
bool heating = true; |
|
|
@ -389,11 +389,11 @@ volatile bool Temperature::raw_temps_ready = false; |
|
|
|
PID_t tune_pid = { 0, 0, 0 }; |
|
|
|
float maxT = 0, minT = 10000; |
|
|
|
|
|
|
|
const bool isbed = (heater == H_BED); |
|
|
|
const bool isbed = (heater_id == H_BED); |
|
|
|
|
|
|
|
#if HAS_PID_FOR_BOTH |
|
|
|
#define GHV(B,H) (isbed ? (B) : (H)) |
|
|
|
#define SHV(B,H) do{ if (isbed) temp_bed.soft_pwm_amount = B; else temp_hotend[heater].soft_pwm_amount = H; }while(0) |
|
|
|
#define SHV(B,H) do{ if (isbed) temp_bed.soft_pwm_amount = B; else temp_hotend[heater_id].soft_pwm_amount = H; }while(0) |
|
|
|
#define ONHEATINGSTART() (isbed ? printerEventLEDs.onBedHeatingStart() : printerEventLEDs.onHotendHeatingStart()) |
|
|
|
#define ONHEATING(S,C,T) (isbed ? printerEventLEDs.onBedHeating(S,C,T) : printerEventLEDs.onHotendHeating(S,C,T)) |
|
|
|
#elif ENABLED(PIDTEMPBED) |
|
|
@ -403,7 +403,7 @@ volatile bool Temperature::raw_temps_ready = false; |
|
|
|
#define ONHEATING(S,C,T) printerEventLEDs.onBedHeating(S,C,T) |
|
|
|
#else |
|
|
|
#define GHV(B,H) H |
|
|
|
#define SHV(B,H) (temp_hotend[heater].soft_pwm_amount = H) |
|
|
|
#define SHV(B,H) (temp_hotend[heater_id].soft_pwm_amount = H) |
|
|
|
#define ONHEATINGSTART() printerEventLEDs.onHotendHeatingStart() |
|
|
|
#define ONHEATING(S,C,T) printerEventLEDs.onHotendHeating(S,C,T) |
|
|
|
#endif |
|
|
@ -427,7 +427,7 @@ volatile bool Temperature::raw_temps_ready = false; |
|
|
|
|
|
|
|
TERN_(HAS_AUTO_FAN, next_auto_fan_check_ms = next_temp_ms + 2500UL); |
|
|
|
|
|
|
|
if (target > GHV(BED_MAX_TARGET, temp_range[heater].maxtemp - HOTEND_OVERSHOOT)) { |
|
|
|
if (target > GHV(BED_MAX_TARGET, temp_range[heater_id].maxtemp - HOTEND_OVERSHOOT)) { |
|
|
|
SERIAL_ECHOLNPGM(STR_PID_TEMP_TOO_HIGH); |
|
|
|
TERN_(EXTENSIBLE_UI, ExtUI::onPidTuning(ExtUI::result_t::PID_TEMP_TOO_HIGH)); |
|
|
|
return; |
|
|
@ -441,7 +441,7 @@ volatile bool Temperature::raw_temps_ready = false; |
|
|
|
SHV(bias = d = (MAX_BED_POWER) >> 1, bias = d = (PID_MAX) >> 1); |
|
|
|
|
|
|
|
#if ENABLED(PRINTER_EVENT_LEDS) |
|
|
|
const float start_temp = GHV(temp_bed.celsius, temp_hotend[heater].celsius); |
|
|
|
const float start_temp = GHV(temp_bed.celsius, temp_hotend[heater_id].celsius); |
|
|
|
LEDColor color = ONHEATINGSTART(); |
|
|
|
#endif |
|
|
|
|
|
|
@ -457,7 +457,7 @@ volatile bool Temperature::raw_temps_ready = false; |
|
|
|
updateTemperaturesFromRawValues(); |
|
|
|
|
|
|
|
// Get the current temperature and constrain it
|
|
|
|
current_temp = GHV(temp_bed.celsius, temp_hotend[heater].celsius); |
|
|
|
current_temp = GHV(temp_bed.celsius, temp_hotend[heater_id].celsius); |
|
|
|
NOLESS(maxT, current_temp); |
|
|
|
NOMORE(minT, current_temp); |
|
|
|
|
|
|
@ -549,7 +549,7 @@ volatile bool Temperature::raw_temps_ready = false; |
|
|
|
// Report heater states every 2 seconds
|
|
|
|
if (ELAPSED(ms, next_temp_ms)) { |
|
|
|
#if HAS_TEMP_SENSOR |
|
|
|
print_heater_states(isbed ? active_extruder : heater); |
|
|
|
print_heater_states(isbed ? active_extruder : heater_id); |
|
|
|
SERIAL_EOL(); |
|
|
|
#endif |
|
|
|
next_temp_ms = ms + 2000UL; |
|
|
@ -564,10 +564,10 @@ volatile bool Temperature::raw_temps_ready = false; |
|
|
|
if (current_temp > watch_temp_target) heated = true; // - Flag if target temperature reached
|
|
|
|
} |
|
|
|
else if (ELAPSED(ms, temp_change_ms)) // Watch timer expired
|
|
|
|
_temp_error(heater, str_t_heating_failed, GET_TEXT(MSG_HEATING_FAILED_LCD)); |
|
|
|
_temp_error(heater_id, str_t_heating_failed, GET_TEXT(MSG_HEATING_FAILED_LCD)); |
|
|
|
} |
|
|
|
else if (current_temp < target - (MAX_OVERSHOOT_PID_AUTOTUNE)) // Heated, then temperature fell too far?
|
|
|
|
_temp_error(heater, str_t_thermal_runaway, GET_TEXT(MSG_THERMAL_RUNAWAY)); |
|
|
|
_temp_error(heater_id, str_t_thermal_runaway, GET_TEXT(MSG_THERMAL_RUNAWAY)); |
|
|
|
} |
|
|
|
#endif |
|
|
|
} // every 2 seconds
|
|
|
@ -608,9 +608,9 @@ volatile bool Temperature::raw_temps_ready = false; |
|
|
|
}while(0) |
|
|
|
|
|
|
|
#define _SET_EXTRUDER_PID() do { \ |
|
|
|
PID_PARAM(Kp, heater) = tune_pid.Kp; \ |
|
|
|
PID_PARAM(Ki, heater) = scalePID_i(tune_pid.Ki); \ |
|
|
|
PID_PARAM(Kd, heater) = scalePID_d(tune_pid.Kd); \ |
|
|
|
PID_PARAM(Kp, heater_id) = tune_pid.Kp; \ |
|
|
|
PID_PARAM(Ki, heater_id) = scalePID_i(tune_pid.Ki); \ |
|
|
|
PID_PARAM(Kd, heater_id) = scalePID_d(tune_pid.Kd); \ |
|
|
|
updatePID(); }while(0) |
|
|
|
|
|
|
|
// Use the result? (As with "M303 U1")
|
|
|
@ -651,7 +651,7 @@ volatile bool Temperature::raw_temps_ready = false; |
|
|
|
* Class and Instance Methods |
|
|
|
*/ |
|
|
|
|
|
|
|
int16_t Temperature::getHeaterPower(const heater_ind_t heater_id) { |
|
|
|
int16_t Temperature::getHeaterPower(const heater_id_t heater_id) { |
|
|
|
switch (heater_id) { |
|
|
|
#if HAS_HEATED_BED |
|
|
|
case H_BED: return temp_bed.soft_pwm_amount; |
|
|
@ -758,7 +758,7 @@ int16_t Temperature::getHeaterPower(const heater_ind_t heater_id) { |
|
|
|
// Temperature Error Handlers
|
|
|
|
//
|
|
|
|
|
|
|
|
inline void loud_kill(PGM_P const lcd_msg, const heater_ind_t heater) { |
|
|
|
inline void loud_kill(PGM_P const lcd_msg, const heater_id_t heater_id) { |
|
|
|
marlin_state = MF_KILLED; |
|
|
|
#if USE_BEEPER |
|
|
|
for (uint8_t i = 20; i--;) { |
|
|
@ -767,10 +767,10 @@ inline void loud_kill(PGM_P const lcd_msg, const heater_ind_t heater) { |
|
|
|
} |
|
|
|
WRITE(BEEPER_PIN, HIGH); |
|
|
|
#endif |
|
|
|
kill(lcd_msg, HEATER_PSTR(heater)); |
|
|
|
kill(lcd_msg, HEATER_PSTR(heater_id)); |
|
|
|
} |
|
|
|
|
|
|
|
void Temperature::_temp_error(const heater_ind_t heater, PGM_P const serial_msg, PGM_P const lcd_msg) { |
|
|
|
void Temperature::_temp_error(const heater_id_t heater_id, PGM_P const serial_msg, PGM_P const lcd_msg) { |
|
|
|
|
|
|
|
static uint8_t killed = 0; |
|
|
|
|
|
|
@ -778,9 +778,9 @@ void Temperature::_temp_error(const heater_ind_t heater, PGM_P const serial_msg, |
|
|
|
SERIAL_ERROR_START(); |
|
|
|
serialprintPGM(serial_msg); |
|
|
|
SERIAL_ECHOPGM(STR_STOPPED_HEATER); |
|
|
|
if (heater >= 0) |
|
|
|
SERIAL_ECHO((int)heater); |
|
|
|
else if (TERN0(HAS_HEATED_CHAMBER, heater == H_CHAMBER)) |
|
|
|
if (heater_id >= 0) |
|
|
|
SERIAL_ECHO((int)heater_id); |
|
|
|
else if (TERN0(HAS_HEATED_CHAMBER, heater_id == H_CHAMBER)) |
|
|
|
SERIAL_ECHOPGM(STR_HEATER_CHAMBER); |
|
|
|
else |
|
|
|
SERIAL_ECHOPGM(STR_HEATER_BED); |
|
|
@ -801,25 +801,25 @@ void Temperature::_temp_error(const heater_ind_t heater, PGM_P const serial_msg, |
|
|
|
if (ELAPSED(ms, expire_ms)) ++killed; |
|
|
|
break; |
|
|
|
case 2: |
|
|
|
loud_kill(lcd_msg, heater); |
|
|
|
loud_kill(lcd_msg, heater_id); |
|
|
|
++killed; |
|
|
|
break; |
|
|
|
} |
|
|
|
#elif defined(BOGUS_TEMPERATURE_GRACE_PERIOD) |
|
|
|
UNUSED(killed); |
|
|
|
#else |
|
|
|
if (!killed) { killed = 1; loud_kill(lcd_msg, heater); } |
|
|
|
if (!killed) { killed = 1; loud_kill(lcd_msg, heater_id); } |
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
void Temperature::max_temp_error(const heater_ind_t heater) { |
|
|
|
void Temperature::max_temp_error(const heater_id_t heater_id) { |
|
|
|
TERN_(DWIN_CREALITY_LCD, Popup_Window_Temperature(1)); |
|
|
|
_temp_error(heater, PSTR(STR_T_MAXTEMP), GET_TEXT(MSG_ERR_MAXTEMP)); |
|
|
|
_temp_error(heater_id, PSTR(STR_T_MAXTEMP), GET_TEXT(MSG_ERR_MAXTEMP)); |
|
|
|
} |
|
|
|
|
|
|
|
void Temperature::min_temp_error(const heater_ind_t heater) { |
|
|
|
void Temperature::min_temp_error(const heater_id_t heater_id) { |
|
|
|
TERN_(DWIN_CREALITY_LCD, Popup_Window_Temperature(0)); |
|
|
|
_temp_error(heater, PSTR(STR_T_MINTEMP), GET_TEXT(MSG_ERR_MINTEMP)); |
|
|
|
_temp_error(heater_id, PSTR(STR_T_MINTEMP), GET_TEXT(MSG_ERR_MINTEMP)); |
|
|
|
} |
|
|
|
|
|
|
|
#if HAS_HOTEND |
|
|
@ -1041,14 +1041,14 @@ void Temperature::manage_heater() { |
|
|
|
HOTEND_LOOP() { |
|
|
|
#if ENABLED(THERMAL_PROTECTION_HOTENDS) |
|
|
|
if (degHotend(e) > temp_range[e].maxtemp) |
|
|
|
_temp_error((heater_ind_t)e, str_t_thermal_runaway, GET_TEXT(MSG_THERMAL_RUNAWAY)); |
|
|
|
_temp_error((heater_id_t)e, str_t_thermal_runaway, GET_TEXT(MSG_THERMAL_RUNAWAY)); |
|
|
|
#endif |
|
|
|
|
|
|
|
TERN_(HEATER_IDLE_HANDLER, hotend_idle[e].update(ms)); |
|
|
|
|
|
|
|
#if ENABLED(THERMAL_PROTECTION_HOTENDS) |
|
|
|
// Check for thermal runaway
|
|
|
|
thermal_runaway_protection(tr_state_machine[e], temp_hotend[e].celsius, temp_hotend[e].target, (heater_ind_t)e, THERMAL_PROTECTION_PERIOD, THERMAL_PROTECTION_HYSTERESIS); |
|
|
|
thermal_runaway_protection(tr_state_machine[e], temp_hotend[e].celsius, temp_hotend[e].target, (heater_id_t)e, THERMAL_PROTECTION_PERIOD, THERMAL_PROTECTION_HYSTERESIS); |
|
|
|
#endif |
|
|
|
|
|
|
|
temp_hotend[e].soft_pwm_amount = (temp_hotend[e].celsius > temp_range[e].mintemp || is_preheating(e)) && temp_hotend[e].celsius < temp_range[e].maxtemp ? (int)get_pid_output_hotend(e) >> 1 : 0; |
|
|
@ -1058,7 +1058,7 @@ void Temperature::manage_heater() { |
|
|
|
if (watch_hotend[e].next_ms && ELAPSED(ms, watch_hotend[e].next_ms)) { // Time to check this extruder?
|
|
|
|
if (degHotend(e) < watch_hotend[e].target) { // Failed to increase enough?
|
|
|
|
TERN_(DWIN_CREALITY_LCD, Popup_Window_Temperature(0)); |
|
|
|
_temp_error((heater_ind_t)e, str_t_heating_failed, GET_TEXT(MSG_HEATING_FAILED_LCD)); |
|
|
|
_temp_error((heater_id_t)e, str_t_heating_failed, GET_TEXT(MSG_HEATING_FAILED_LCD)); |
|
|
|
} |
|
|
|
else // Start again if the target is still far off
|
|
|
|
start_watching_hotend(e); |
|
|
@ -1945,7 +1945,7 @@ void Temperature::init() { |
|
|
|
Temperature::tr_state_machine_t Temperature::tr_state_machine_chamber; // = { TRInactive, 0 };
|
|
|
|
#endif |
|
|
|
|
|
|
|
void Temperature::thermal_runaway_protection(Temperature::tr_state_machine_t &sm, const float ¤t, const float &target, const heater_ind_t heater_id, const uint16_t period_seconds, const uint16_t hysteresis_degc) { |
|
|
|
void Temperature::thermal_runaway_protection(Temperature::tr_state_machine_t &sm, const float ¤t, const float &target, const heater_id_t heater_id, const uint16_t period_seconds, const uint16_t hysteresis_degc) { |
|
|
|
|
|
|
|
static float tr_target_temperature[HOTENDS + 1] = { 0.0 }; |
|
|
|
|
|
|
@ -2311,12 +2311,12 @@ void Temperature::readings_ready() { |
|
|
|
const bool heater_on = (temp_hotend[e].target > 0 |
|
|
|
|| TERN0(PIDTEMP, temp_hotend[e].soft_pwm_amount) > 0 |
|
|
|
); |
|
|
|
if (rawtemp > temp_range[e].raw_max * tdir) max_temp_error((heater_ind_t)e); |
|
|
|
if (rawtemp > temp_range[e].raw_max * tdir) max_temp_error((heater_id_t)e); |
|
|
|
if (heater_on && rawtemp < temp_range[e].raw_min * tdir && !is_preheating(e)) { |
|
|
|
#ifdef MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED |
|
|
|
if (++consecutive_low_temperature_error[e] >= MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED) |
|
|
|
#endif |
|
|
|
min_temp_error((heater_ind_t)e); |
|
|
|
min_temp_error((heater_id_t)e); |
|
|
|
} |
|
|
|
#ifdef MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED |
|
|
|
else |
|
|
@ -2883,7 +2883,7 @@ void Temperature::tick() { |
|
|
|
#if ENABLED(SHOW_TEMP_ADC_VALUES) |
|
|
|
, const float r |
|
|
|
#endif |
|
|
|
, const heater_ind_t e=INDEX_NONE |
|
|
|
, const heater_id_t e=INDEX_NONE |
|
|
|
) { |
|
|
|
char k; |
|
|
|
switch (e) { |
|
|
@ -2974,10 +2974,10 @@ void Temperature::tick() { |
|
|
|
#if ENABLED(SHOW_TEMP_ADC_VALUES) |
|
|
|
, rawHotendTemp(e) |
|
|
|
#endif |
|
|
|
, (heater_ind_t)e |
|
|
|
, (heater_id_t)e |
|
|
|
); |
|
|
|
#endif |
|
|
|
SERIAL_ECHOPAIR(" @:", getHeaterPower((heater_ind_t)target_extruder)); |
|
|
|
SERIAL_ECHOPAIR(" @:", getHeaterPower((heater_id_t)target_extruder)); |
|
|
|
#if HAS_HEATED_BED |
|
|
|
SERIAL_ECHOPAIR(" B@:", getHeaterPower(H_BED)); |
|
|
|
#endif |
|
|
@ -2988,7 +2988,7 @@ void Temperature::tick() { |
|
|
|
HOTEND_LOOP() { |
|
|
|
SERIAL_ECHOPAIR(" @", e); |
|
|
|
SERIAL_CHAR(':'); |
|
|
|
SERIAL_ECHO(getHeaterPower((heater_ind_t)e)); |
|
|
|
SERIAL_ECHO(getHeaterPower((heater_id_t)e)); |
|
|
|
} |
|
|
|
#endif |
|
|
|
} |
|
|
|