From 83a9f75abe092cb0afb57045d2d03eb553dc38bd Mon Sep 17 00:00:00 2001 From: MRprusa3d Date: Wed, 28 Nov 2018 23:43:16 +0100 Subject: [PATCH 1/5] minTemp correct minTemp detection @ MK2.5 & MK3 --- Firmware/temperature.cpp | 90 +++++++++++-------- .../variants/1_75mm_MK25-RAMBo10a-E3Dv6full.h | 6 +- .../variants/1_75mm_MK25-RAMBo13a-E3Dv6full.h | 6 +- .../variants/1_75mm_MK3-EINSy10a-E3Dv6full.h | 2 + 4 files changed, 64 insertions(+), 40 deletions(-) diff --git a/Firmware/temperature.cpp b/Firmware/temperature.cpp index cae3fada..5ba4824d 100644 --- a/Firmware/temperature.cpp +++ b/Firmware/temperature.cpp @@ -41,6 +41,9 @@ #include "adc.h" #include "ConfigurationStore.h" +#include "Timer.h" +#include "Configuration_prusa.h" + //=========================================================================== //=============================public variables============================ @@ -152,6 +155,8 @@ static volatile bool temp_meas_ready = false; # define ARRAY_BY_EXTRUDERS(v1, v2, v3) { v1 } #endif +static ShortTimer oTimer4minTempHeater,oTimer4minTempBed; + // Init min and max temp with extreme values to prevent false errors during startup static int minttemp_raw[EXTRUDERS] = ARRAY_BY_EXTRUDERS( HEATER_0_RAW_LO_TEMP , HEATER_1_RAW_LO_TEMP , HEATER_2_RAW_LO_TEMP ); static int maxttemp_raw[EXTRUDERS] = ARRAY_BY_EXTRUDERS( HEATER_0_RAW_HI_TEMP , HEATER_1_RAW_HI_TEMP , HEATER_2_RAW_HI_TEMP ); @@ -596,6 +601,9 @@ void manage_heater() updateTemperaturesFromRawValues(); + check_max_temp(); + check_min_temp(); + #ifdef TEMP_RUNAWAY_BED_HYSTERESIS temp_runaway_check(0, target_temperature_bed, current_temperature_bed, (int)soft_pwm_bed, true); #endif @@ -669,11 +677,7 @@ void manage_heater() #endif // Check if temperature is within the correct range -#ifdef AMBIENT_THERMISTOR - if(((current_temperature_ambient < MINTEMP_MINAMBIENT) || (current_temperature[e] > minttemp[e])) && (current_temperature[e] < maxttemp[e])) -#else //AMBIENT_THERMISTOR - if((current_temperature[e] > minttemp[e]) && (current_temperature[e] < maxttemp[e])) -#endif //AMBIENT_THERMISTOR + if(current_temperature[e] < maxttemp[e]) { soft_pwm[e] = (int)pid_output >> 1; } @@ -763,11 +767,7 @@ void manage_heater() pid_output = constrain(target_temperature_bed, 0, MAX_BED_POWER); #endif //PID_OPENLOOP -#ifdef AMBIENT_THERMISTOR - if(((current_temperature_bed > BED_MINTEMP) || (current_temperature_ambient < MINTEMP_MINAMBIENT)) && (current_temperature_bed < BED_MAXTEMP)) -#else //AMBIENT_THERMISTOR - if((current_temperature_bed > BED_MINTEMP) && (current_temperature_bed < BED_MAXTEMP)) -#endif //AMBIENT_THERMISTOR + if(current_temperature_bed < BED_MAXTEMP) { soft_pwm_bed = (int)pid_output >> 1; } @@ -777,7 +777,7 @@ void manage_heater() #elif !defined(BED_LIMIT_SWITCHING) // Check if temperature is within the correct range - if((current_temperature_bed > BED_MINTEMP) && (current_temperature_bed < BED_MAXTEMP)) + if(current_temperature_bed < BED_MAXTEMP) { if(current_temperature_bed >= target_temperature_bed) { @@ -795,7 +795,7 @@ void manage_heater() } #else //#ifdef BED_LIMIT_SWITCHING // Check if temperature is within the correct band - if((current_temperature_bed > BED_MINTEMP) && (current_temperature_bed < BED_MAXTEMP)) + if(current_temperature_bed < BED_MAXTEMP) { if(current_temperature_bed > target_temperature_bed + BED_HYSTERESIS) { @@ -1526,7 +1526,7 @@ void adc_ready(void) //callback from adc when sampling finished // Timer 0 is shared with millies -ISR(TIMER0_COMPB_vect) +ISR(TIMER0_COMPB_vect) // @ 1kHz ~ 1ms { static bool _lock = false; if (_lock) return; @@ -1534,11 +1534,6 @@ ISR(TIMER0_COMPB_vect) asm("sei"); if (!temp_meas_ready) adc_cycle(); - else - { - check_max_temp(); - check_min_temp(); - } lcd_buttons_update(); static unsigned char pwm_count = (1 << SOFT_PWM_SCALE); @@ -1931,26 +1926,49 @@ void check_min_temp_bed() void check_min_temp() { +static bool bCheckingOnHeater=false; // state variable, which allows to short no-checking delay (is set, when temperature is (first time) over heaterMintemp) +static bool bCheckingOnBed=false; // state variable, which allows to short no-checking delay (is set, when temperature is (first time) over bedMintemp) #ifdef AMBIENT_THERMISTOR - static uint8_t heat_cycles = 0; - if (current_temperature_raw_ambient > OVERSAMPLENR*MINTEMP_MINAMBIENT_RAW) - { - if (READ(HEATER_0_PIN) == HIGH) - { -// if ((heat_cycles % 10) == 0) -// printf_P(PSTR("X%d\n"), heat_cycles); - if (heat_cycles > 50) //reaction time 5-10s - check_min_temp_heater0(); - else - heat_cycles++; - } - else - heat_cycles = 0; - return; - } +if(current_temperature_raw_ambient>(OVERSAMPLENR*MINTEMP_MINAMBIENT_RAW)) // thermistor is NTC type, so operator is ">" ;-) + { // ambient temperature is low +#endif //AMBIENT_THERMISTOR +// *** 'common' part of code for MK2.5 & MK3 +// * nozzle checking +if(target_temperature[active_extruder]>minttemp[active_extruder]) + { // ~ nozzle heating is on + bCheckingOnHeater=bCheckingOnHeater||(current_temperature[active_extruder]>=minttemp[active_extruder]); // for eventually delay cutting + if(oTimer4minTempHeater.expired(HEATER_MINTEMP_DELAY)||(!oTimer4minTempHeater.running())||bCheckingOnHeater) + { + bCheckingOnHeater=true; // not necessary + check_min_temp_heater0(); // delay is elapsed or temperature is/was over minTemp => periodical checking is active + } + } +else { // ~ nozzle heating is off + oTimer4minTempHeater.start(); + bCheckingOnHeater=false; + } +// * bed checking +if(target_temperature_bed>BED_MINTEMP) + { // ~ bed heating is on + bCheckingOnBed=bCheckingOnBed||(current_temperature_bed>=BED_MINTEMP); // for eventually delay cutting + if(oTimer4minTempBed.expired(BED_MINTEMP_DELAY)||(!oTimer4minTempBed.running())||bCheckingOnBed) + { + bCheckingOnBed=true; // not necessary + check_min_temp_bed(); // delay is elapsed or temperature is/was over minTemp => periodical checking is active + } + } +else { // ~ bed heating is off + oTimer4minTempBed.start(); + bCheckingOnBed=false; + } +// *** end of 'common' part +#ifdef AMBIENT_THERMISTOR + } +else { // ambient temperature is standard + check_min_temp_heater0(); + check_min_temp_bed(); + } #endif //AMBIENT_THERMISTOR - check_min_temp_heater0(); - check_min_temp_bed(); } #if (defined(FANCHECK) && defined(TACH_0) && (TACH_0 > -1)) diff --git a/Firmware/variants/1_75mm_MK25-RAMBo10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK25-RAMBo10a-E3Dv6full.h index f3a5285d..82620444 100644 --- a/Firmware/variants/1_75mm_MK25-RAMBo10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK25-RAMBo10a-E3Dv6full.h @@ -153,10 +153,12 @@ *------------------------------------*/ // Mintemps -#define HEATER_0_MINTEMP 15 +#define HEATER_0_MINTEMP 30 #define HEATER_1_MINTEMP 5 #define HEATER_2_MINTEMP 5 -#define BED_MINTEMP 15 +#define HEATER_MINTEMP_DELAY 15000 // [ms] ! if changed, check maximal allowed value @ ShortTimer +#define BED_MINTEMP 30 +#define BED_MINTEMP_DELAY 50000 // [ms] ! if changed, check maximal allowed value @ ShortTimer // Maxtemps #if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP) diff --git a/Firmware/variants/1_75mm_MK25-RAMBo13a-E3Dv6full.h b/Firmware/variants/1_75mm_MK25-RAMBo13a-E3Dv6full.h index 2aff81e0..e080e398 100644 --- a/Firmware/variants/1_75mm_MK25-RAMBo13a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK25-RAMBo13a-E3Dv6full.h @@ -154,10 +154,12 @@ *------------------------------------*/ // Mintemps -#define HEATER_0_MINTEMP 15 +#define HEATER_0_MINTEMP 30 #define HEATER_1_MINTEMP 5 #define HEATER_2_MINTEMP 5 -#define BED_MINTEMP 15 +#define HEATER_MINTEMP_DELAY 15000 // [ms] ! if changed, check maximal allowed value @ ShortTimer +#define BED_MINTEMP 30 +#define BED_MINTEMP_DELAY 50000 // [ms] ! if changed, check maximal allowed value @ ShortTimer // Maxtemps #if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP) diff --git a/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h index 4655107c..0fd79510 100644 --- a/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h @@ -276,7 +276,9 @@ #define HEATER_0_MINTEMP 15 #define HEATER_1_MINTEMP 5 #define HEATER_2_MINTEMP 5 +#define HEATER_MINTEMP_DELAY 15000 // [ms] ! if changed, check maximal allowed value @ ShortTimer #define BED_MINTEMP 15 +#define BED_MINTEMP_DELAY 50000 // [ms] ! if changed, check maximal allowed value @ ShortTimer // Maxtemps #if defined(E3D_PT100_EXTRUDER_WITH_AMP) || defined(E3D_PT100_EXTRUDER_NO_AMP) From 4e300fd552a9780c177660d47174aa9dab8e44af Mon Sep 17 00:00:00 2001 From: MRprusa3d Date: Wed, 2 Jan 2019 18:25:41 +0100 Subject: [PATCH 2/5] minTemp safety heaters management during/after minTemp --- Firmware/Marlin_main.cpp | 1 + Firmware/temperature.cpp | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 3496a971..662003e0 100644 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -7579,6 +7579,7 @@ void Stop() disable_heater(); if(Stopped == false) { Stopped = true; + lcd_print_stop(); Stopped_gcode_LastN = gcode_LastN; // Save last g_code for restart SERIAL_ERROR_START; SERIAL_ERRORLNRPGM(MSG_ERR_STOPPED); diff --git a/Firmware/temperature.cpp b/Firmware/temperature.cpp index 5ba4824d..b651c273 100644 --- a/Firmware/temperature.cpp +++ b/Firmware/temperature.cpp @@ -685,6 +685,8 @@ void manage_heater() { soft_pwm[e] = 0; } + if(target_temperature[e]==0) + soft_pwm[e] = 0; #ifdef WATCH_TEMP_PERIOD if(watchmillis[e] && millis() - watchmillis[e] > WATCH_TEMP_PERIOD) @@ -812,6 +814,8 @@ void manage_heater() WRITE(HEATER_BED_PIN,LOW); } #endif + if(target_temperature_bed==0) + soft_pwm_bed = 0; #endif #ifdef HOST_KEEPALIVE_FEATURE From d9f8e4eb9ed3f54622d74ed580513f7e0aec6130 Mon Sep 17 00:00:00 2001 From: MRprusa3d Date: Thu, 17 Jan 2019 02:57:08 +0100 Subject: [PATCH 3/5] PID / manage_heater PSD regulator improvement --- Firmware/Configuration.h | 2 ++ Firmware/temperature.cpp | 73 ++++++++++++++++++++++------------------ Firmware/temperature.h | 8 ++++- 3 files changed, 49 insertions(+), 34 deletions(-) diff --git a/Firmware/Configuration.h b/Firmware/Configuration.h index 3bed653b..e4eb7e17 100644 --- a/Firmware/Configuration.h +++ b/Firmware/Configuration.h @@ -131,8 +131,10 @@ //#define PID_DEBUG // Sends debug data to the serial port. //#define PID_OPENLOOP 1 // Puts PID in open loop. M104/M140 sets the output power from 0 to PID_MAX //#define SLOW_PWM_HEATERS // PWM with very low frequency (roughly 0.125Hz=8s) and minimum state time of approximately 1s useful for heaters driven by a relay +// :-O :-O :-O #define PID_FUNCTIONAL_RANGE 10 // If the temperature difference between the target temperature and the actual temperature // is more then PID_FUNCTIONAL_RANGE then the PID will be shut off and the heater will be set to min/max. +// :-O :-O :-O #define PID_INTEGRAL_DRIVE_MAX PID_MAX //limit for the integral term #define K1 0.95 //smoothing factor within the PID #define PID_dT ((OVERSAMPLENR * 10.0)/(F_CPU / 64.0 / 256.0)) //sampling period of the temperature routine diff --git a/Firmware/temperature.cpp b/Firmware/temperature.cpp index b651c273..e4315dd4 100644 --- a/Firmware/temperature.cpp +++ b/Firmware/temperature.cpp @@ -106,15 +106,15 @@ static volatile bool temp_meas_ready = false; #ifdef PIDTEMP //static cannot be external: - static float temp_iState[EXTRUDERS] = { 0 }; - static float temp_dState[EXTRUDERS] = { 0 }; + static float iState_sum[EXTRUDERS] = { 0 }; + static float dState_last[EXTRUDERS] = { 0 }; static float pTerm[EXTRUDERS]; static float iTerm[EXTRUDERS]; static float dTerm[EXTRUDERS]; //int output; static float pid_error[EXTRUDERS]; - static float temp_iState_min[EXTRUDERS]; - static float temp_iState_max[EXTRUDERS]; + static float iState_sum_min[EXTRUDERS]; + static float iState_sum_max[EXTRUDERS]; // static float pid_input[EXTRUDERS]; // static float pid_output[EXTRUDERS]; static bool pid_reset[EXTRUDERS]; @@ -418,7 +418,7 @@ void updatePID() { #ifdef PIDTEMP for(int e = 0; e < EXTRUDERS; e++) { - temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / cs.Ki; + iState_sum_max[e] = PID_INTEGRAL_DRIVE_MAX / cs.Ki; } #endif #ifdef PIDTEMPBED @@ -587,6 +587,10 @@ void checkExtruderAutoFans() #endif // any extruder auto fan pins set +void resetPID(uint8_t extruder) // ready for eventually parameters adjusting +{ +} + void manage_heater() { #ifdef WATCHDOG @@ -598,6 +602,7 @@ void manage_heater() if(temp_meas_ready != true) //better readability return; +// more precisely - this condition partially stabilizes time interval for regulation values evaluation (@ ~ 230ms) updateTemperaturesFromRawValues(); @@ -619,38 +624,42 @@ void manage_heater() pid_input = current_temperature[e]; #ifndef PID_OPENLOOP - pid_error[e] = target_temperature[e] - pid_input; - if(pid_error[e] > PID_FUNCTIONAL_RANGE) { - pid_output = BANG_MAX; - pid_reset[e] = true; - } - else if(pid_error[e] < -PID_FUNCTIONAL_RANGE || target_temperature[e] == 0) { + if(target_temperature[e] == 0) { pid_output = 0; pid_reset[e] = true; - } - else { - if(pid_reset[e] == true) { - temp_iState[e] = 0.0; + } else { + pid_error[e] = target_temperature[e] - pid_input; + if(pid_reset[e]) { + iState_sum[e] = 0.0; + dTerm[e] = 0.0; // 'dState_last[e]' initial setting is not necessary (see end of if-statement) pid_reset[e] = false; } +#ifndef PonM pTerm[e] = cs.Kp * pid_error[e]; - temp_iState[e] += pid_error[e]; - temp_iState[e] = constrain(temp_iState[e], temp_iState_min[e], temp_iState_max[e]); - iTerm[e] = cs.Ki * temp_iState[e]; - - //K1 defined in Configuration.h in the PID settings + iState_sum[e] += pid_error[e]; + iState_sum[e] = constrain(iState_sum[e], iState_sum_min[e], iState_sum_max[e]); + iTerm[e] = cs.Ki * iState_sum[e]; + // K1 defined in Configuration.h in the PID settings #define K2 (1.0-K1) - dTerm[e] = (cs.Kd * (pid_input - temp_dState[e]))*K2 + (K1 * dTerm[e]); - pid_output = pTerm[e] + iTerm[e] - dTerm[e]; + dTerm[e] = (cs.Kd * (pid_input - dState_last[e]))*K2 + (K1 * dTerm[e]); // e.g. digital filtration of derivative term changes + pid_output = pTerm[e] + iTerm[e] - dTerm[e]; // subtraction due to "Derivative on Measurement" method (i.e. derivative of input instead derivative of error is used) if (pid_output > PID_MAX) { - if (pid_error[e] > 0 ) temp_iState[e] -= pid_error[e]; // conditional un-integration + if (pid_error[e] > 0 ) iState_sum[e] -= pid_error[e]; // conditional un-integration pid_output=PID_MAX; - } else if (pid_output < 0){ - if (pid_error[e] < 0 ) temp_iState[e] -= pid_error[e]; // conditional un-integration + } else if (pid_output < 0) { + if (pid_error[e] < 0 ) iState_sum[e] -= pid_error[e]; // conditional un-integration pid_output=0; } +#else // PonM ("Proportional on Measurement" method) + iState_sum[e] += cs.Ki * pid_error[e]; + iState_sum[e] -= cs.Kp * (pid_input - dState_last[e]); + iState_sum[e] = constrain(iState_sum[e], 0, PID_INTEGRAL_DRIVE_MAX); + dTerm[e] = cs.Kd * (pid_input - dState_last[e]); + pid_output = iState_sum[e] - dTerm[e]; // subtraction due to "Derivative on Measurement" method (i.e. derivative of input instead derivative of error is used) + pid_output = constrain(pid_output, 0, PID_MAX); +#endif // PonM } - temp_dState[e] = pid_input; + dState_last[e] = pid_input; #else pid_output = constrain(target_temperature[e], 0, PID_MAX); #endif //PID_OPENLOOP @@ -667,7 +676,7 @@ void manage_heater() SERIAL_ECHO(" iTerm "); SERIAL_ECHO(iTerm[e]); SERIAL_ECHO(" dTerm "); - SERIAL_ECHOLN(dTerm[e]); + SERIAL_ECHOLN(-dTerm[e]); #endif //PID_DEBUG #else /* PID off */ pid_output = 0; @@ -677,16 +686,14 @@ void manage_heater() #endif // Check if temperature is within the correct range - if(current_temperature[e] < maxttemp[e]) + if((current_temperature[e] < maxttemp[e]) && (target_temperature[e] != 0)) { soft_pwm[e] = (int)pid_output >> 1; } else - { + { soft_pwm[e] = 0; } - if(target_temperature[e]==0) - soft_pwm[e] = 0; #ifdef WATCH_TEMP_PERIOD if(watchmillis[e] && millis() - watchmillis[e] > WATCH_TEMP_PERIOD) @@ -1001,8 +1008,8 @@ void tp_init() // populate with the first value maxttemp[e] = maxttemp[0]; #ifdef PIDTEMP - temp_iState_min[e] = 0.0; - temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / cs.Ki; + iState_sum_min[e] = 0.0; + iState_sum_max[e] = PID_INTEGRAL_DRIVE_MAX / cs.Ki; #endif //PIDTEMP #ifdef PIDTEMPBED temp_iState_min_bed = 0.0; diff --git a/Firmware/temperature.h b/Firmware/temperature.h index 9a3cee83..8db41672 100644 --- a/Firmware/temperature.h +++ b/Firmware/temperature.h @@ -87,6 +87,8 @@ extern int current_voltage_raw_bed; extern volatile int babystepsTodo[3]; #endif +void resetPID(uint8_t extruder); + inline void babystepsTodoZadd(int n) { if (n != 0) { @@ -137,11 +139,15 @@ FORCE_INLINE float degTargetBed() { FORCE_INLINE void setTargetHotend(const float &celsius, uint8_t extruder) { target_temperature[extruder] = celsius; + resetPID[extruder]; }; static inline void setTargetHotendSafe(const float &celsius, uint8_t extruder) { - if (extruder Date: Sun, 20 Jan 2019 01:23:15 +0100 Subject: [PATCH 4/5] PID / manage_heater build-warnings elimination --- Firmware/temperature.h | 4 ++-- Firmware/variants/1_75mm_MK2-RAMBo10a-E3Dv6full.h | 2 ++ Firmware/variants/1_75mm_MK2-RAMBo13a-E3Dv6full.h | 2 ++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Firmware/temperature.h b/Firmware/temperature.h index 8db41672..9697f440 100644 --- a/Firmware/temperature.h +++ b/Firmware/temperature.h @@ -139,14 +139,14 @@ FORCE_INLINE float degTargetBed() { FORCE_INLINE void setTargetHotend(const float &celsius, uint8_t extruder) { target_temperature[extruder] = celsius; - resetPID[extruder]; + resetPID(extruder); }; static inline void setTargetHotendSafe(const float &celsius, uint8_t extruder) { if (extruder Date: Mon, 21 Jan 2019 18:20:40 +0100 Subject: [PATCH 5/5] PID / manage_heater some small corrections --- Firmware/Configuration.h | 6 +----- Firmware/temperature.cpp | 1 + 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/Firmware/Configuration.h b/Firmware/Configuration.h index e4eb7e17..774e6444 100644 --- a/Firmware/Configuration.h +++ b/Firmware/Configuration.h @@ -126,15 +126,11 @@ // Comment the following line to disable PID and enable bang-bang. #define PIDTEMP #define BANG_MAX 255 // limits current to nozzle while in bang-bang mode; 255=full current -#define PID_MAX BANG_MAX // limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current +#define PID_MAX BANG_MAX // limits current to nozzle while PID is active; 255=full current #ifdef PIDTEMP //#define PID_DEBUG // Sends debug data to the serial port. //#define PID_OPENLOOP 1 // Puts PID in open loop. M104/M140 sets the output power from 0 to PID_MAX //#define SLOW_PWM_HEATERS // PWM with very low frequency (roughly 0.125Hz=8s) and minimum state time of approximately 1s useful for heaters driven by a relay -// :-O :-O :-O - #define PID_FUNCTIONAL_RANGE 10 // If the temperature difference between the target temperature and the actual temperature - // is more then PID_FUNCTIONAL_RANGE then the PID will be shut off and the heater will be set to min/max. -// :-O :-O :-O #define PID_INTEGRAL_DRIVE_MAX PID_MAX //limit for the integral term #define K1 0.95 //smoothing factor within the PID #define PID_dT ((OVERSAMPLENR * 10.0)/(F_CPU / 64.0 / 256.0)) //sampling period of the temperature routine diff --git a/Firmware/temperature.cpp b/Firmware/temperature.cpp index e4315dd4..e1e74fac 100644 --- a/Firmware/temperature.cpp +++ b/Firmware/temperature.cpp @@ -589,6 +589,7 @@ void checkExtruderAutoFans() void resetPID(uint8_t extruder) // ready for eventually parameters adjusting { +extruder=extruder; // only for compiler-warning elimination (if function do nothing) } void manage_heater()