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:
alexborro
2014-06-30 15:22:37 -03:00
parent 4c823224b0
commit 43c298a7a9
3 changed files with 117 additions and 0 deletions

View File

@ -416,6 +416,10 @@ void manage_heater()
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
pid_input = current_temperature[e];
@ -526,6 +530,10 @@ void manage_heater()
#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
pid_input = current_temperature_bed;
@ -896,6 +904,66 @@ void setWatch()
#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()
{