Add "Thermal Runaway Protection" feature
This is a feature to protect your printer from burn up in flames if it has a thermistor coming off place (this happened to a friend of mine recently and motivated me writing this feature). The issue: If a thermistor come off, it will read a lower temperature than actual. The system will turn the heater on forever, burning up the filament and anything else around. After the temperature reaches the target for the first time, this feature will start measuring for how long the current temperature stays below the target minus _HYSTERESIS (set_temperature - THERMAL_RUNAWAY_PROTECTION_HYSTERESIS). If it stays longer than _PERIOD, it means the thermistor temperature cannot catch up with the target, so something *may be* wrong. Then, to be on the safe side, the system will he halt. Bear in mind the count down will just start AFTER the first time the thermistor temperature is over the target, so you will have no problem if your extruder heater takes 2 minutes to hit the target on heating.
This commit is contained in:
parent
2096188ac3
commit
50b4e86f75
3 changed files with 117 additions and 0 deletions
|
@ -251,6 +251,44 @@
|
||||||
#define EXTRUDE_MINTEMP 170
|
#define EXTRUDE_MINTEMP 170
|
||||||
#define EXTRUDE_MAXLENGTH (X_MAX_LENGTH+Y_MAX_LENGTH) //prevent extrusion of very large distances.
|
#define EXTRUDE_MAXLENGTH (X_MAX_LENGTH+Y_MAX_LENGTH) //prevent extrusion of very large distances.
|
||||||
|
|
||||||
|
/*================== Thermal Runaway Protection ==============================
|
||||||
|
This is a feature to protect your printer from burn up in flames if it has
|
||||||
|
a thermistor coming off place (this happened to a friend of mine recently and
|
||||||
|
motivated me writing this feature).
|
||||||
|
|
||||||
|
The issue: If a thermistor come off, it will read a lower temperature than actual.
|
||||||
|
The system will turn the heater on forever, burning up the filament and anything
|
||||||
|
else around.
|
||||||
|
|
||||||
|
After the temperature reaches the target for the first time, this feature will
|
||||||
|
start measuring for how long the current temperature stays below the target
|
||||||
|
minus _HYSTERESIS (set_temperature - THERMAL_RUNAWAY_PROTECTION_HYSTERESIS).
|
||||||
|
|
||||||
|
If it stays longer than _PERIOD, it means the thermistor temperature
|
||||||
|
cannot catch up with the target, so something *may be* wrong. Then, to be on the
|
||||||
|
safe side, the system will he halt.
|
||||||
|
|
||||||
|
Bear in mind the count down will just start AFTER the first time the
|
||||||
|
thermistor temperature is over the target, so you will have no problem if
|
||||||
|
your extruder heater takes 2 minutes to hit the target on heating.
|
||||||
|
|
||||||
|
*/
|
||||||
|
// If you want to enable this feature for all your extruder heaters,
|
||||||
|
// uncomment the 2 defines below:
|
||||||
|
|
||||||
|
// Parameters for all extruder heaters
|
||||||
|
//#define THERMAL_RUNAWAY_PROTECTION_PERIOD 40 //in seconds
|
||||||
|
//#define THERMAL_RUNAWAY_PROTECTION_HYSTERESIS 4 // in degree Celsius
|
||||||
|
|
||||||
|
// If you want to enable this feature for your bed heater,
|
||||||
|
// uncomment the 2 defines below:
|
||||||
|
|
||||||
|
// Parameters for the bed heater
|
||||||
|
//#define THERMAL_RUNAWAY_PROTECTION_BED_PERIOD 20 //in seconds
|
||||||
|
//#define THERMAL_RUNAWAY_PROTECTION_BED_HYSTERESIS 2 // in degree Celsius
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//=============================Mechanical Settings===========================
|
//=============================Mechanical Settings===========================
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
|
@ -416,6 +416,10 @@ void manage_heater()
|
||||||
for(int e = 0; e < EXTRUDERS; e++)
|
for(int e = 0; e < EXTRUDERS; e++)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#ifdef THERMAL_RUNAWAY_PROTECTION_PERIOD && THERMAL_RUNAWAY_PROTECTION_PERIOD > 0
|
||||||
|
thermal_runaway_protection(&thermal_runaway_state_machine[e], &thermal_runaway_timer[e], current_temperature[e], target_temperature[e], e, THERMAL_RUNAWAY_PROTECTION_PERIOD, THERMAL_RUNAWAY_PROTECTION_HYSTERESIS);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef PIDTEMP
|
#ifdef PIDTEMP
|
||||||
pid_input = current_temperature[e];
|
pid_input = current_temperature[e];
|
||||||
|
|
||||||
|
@ -526,6 +530,10 @@ void manage_heater()
|
||||||
|
|
||||||
#if TEMP_SENSOR_BED != 0
|
#if TEMP_SENSOR_BED != 0
|
||||||
|
|
||||||
|
#ifdef THERMAL_RUNAWAY_PROTECTION_PERIOD && THERMAL_RUNAWAY_PROTECTION_PERIOD > 0
|
||||||
|
thermal_runaway_protection(&thermal_runaway_bed_state_machine, &thermal_runaway_bed_timer, current_temperature_bed, target_temperature_bed, 9, THERMAL_RUNAWAY_PROTECTION_BED_PERIOD, THERMAL_RUNAWAY_PROTECTION_BED_HYSTERESIS);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef PIDTEMPBED
|
#ifdef PIDTEMPBED
|
||||||
pid_input = current_temperature_bed;
|
pid_input = current_temperature_bed;
|
||||||
|
|
||||||
|
@ -896,6 +904,66 @@ void setWatch()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef THERMAL_RUNAWAY_PROTECTION_PERIOD && THERMAL_RUNAWAY_PROTECTION_PERIOD > 0
|
||||||
|
void thermal_runaway_protection(int *state, unsigned long *timer, float temperature, float target_temperature, int heater_id, int period_seconds, int hysteresis_degc)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
SERIAL_ECHO_START;
|
||||||
|
SERIAL_ECHO("Thermal Thermal Runaway Running. Heater ID:");
|
||||||
|
SERIAL_ECHO(heater_id);
|
||||||
|
SERIAL_ECHO(" ; State:");
|
||||||
|
SERIAL_ECHO(*state);
|
||||||
|
SERIAL_ECHO(" ; Timer:");
|
||||||
|
SERIAL_ECHO(*timer);
|
||||||
|
SERIAL_ECHO(" ; Temperature:");
|
||||||
|
SERIAL_ECHO(temperature);
|
||||||
|
SERIAL_ECHO(" ; Target Temp:");
|
||||||
|
SERIAL_ECHO(target_temperature);
|
||||||
|
SERIAL_ECHOLN("");
|
||||||
|
*/
|
||||||
|
if ((target_temperature == 0) || thermal_runaway)
|
||||||
|
{
|
||||||
|
*state = 0;
|
||||||
|
*timer = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch (*state)
|
||||||
|
{
|
||||||
|
case 0: // "Heater Inactive" state
|
||||||
|
if (target_temperature > 0) *state = 1;
|
||||||
|
break;
|
||||||
|
case 1: // "First Heating" state
|
||||||
|
if (temperature >= target_temperature) *state = 2;
|
||||||
|
break;
|
||||||
|
case 2: // "Temperature Stable" state
|
||||||
|
if (temperature >= (target_temperature - hysteresis_degc))
|
||||||
|
{
|
||||||
|
*timer = millis();
|
||||||
|
}
|
||||||
|
else if ( (millis() - *timer) > period_seconds*1000)
|
||||||
|
{
|
||||||
|
SERIAL_ERROR_START;
|
||||||
|
SERIAL_ERRORLNPGM("Thermal Runaway, system stopped! Heater_ID: ");
|
||||||
|
SERIAL_ERRORLN((int)heater_id);
|
||||||
|
LCD_ALERTMESSAGEPGM("THERMAL RUNAWAY");
|
||||||
|
thermal_runaway = true;
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
disable_heater();
|
||||||
|
disable_x();
|
||||||
|
disable_y();
|
||||||
|
disable_z();
|
||||||
|
disable_e0();
|
||||||
|
disable_e1();
|
||||||
|
disable_e2();
|
||||||
|
manage_heater();
|
||||||
|
lcd_update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void disable_heater()
|
void disable_heater()
|
||||||
{
|
{
|
||||||
|
|
|
@ -154,6 +154,17 @@ void disable_heater();
|
||||||
void setWatch();
|
void setWatch();
|
||||||
void updatePID();
|
void updatePID();
|
||||||
|
|
||||||
|
#ifdef THERMAL_RUNAWAY_PROTECTION_PERIOD && THERMAL_RUNAWAY_PROTECTION_PERIOD > 0
|
||||||
|
void thermal_runaway_protection(int *state, unsigned long *timer, float temperature, float target_temperature, int heater_id, int period_seconds, int hysteresis_degc);
|
||||||
|
static int thermal_runaway_state_machine[3]; // = {0,0,0};
|
||||||
|
static unsigned long thermal_runaway_timer[3]; // = {0,0,0};
|
||||||
|
static bool thermal_runaway = false;
|
||||||
|
#if TEMP_SENSOR_BED != 0
|
||||||
|
static int thermal_runaway_bed_state_machine;
|
||||||
|
static unsigned long thermal_runaway_bed_timer;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
FORCE_INLINE void autotempShutdown(){
|
FORCE_INLINE void autotempShutdown(){
|
||||||
#ifdef AUTOTEMP
|
#ifdef AUTOTEMP
|
||||||
if(autotemp_enabled)
|
if(autotemp_enabled)
|
||||||
|
|
Reference in a new issue