From 6e6e4e214323c42f949ed86a67551f136fe41365 Mon Sep 17 00:00:00 2001 From: Greg Tan Date: Sun, 8 Jun 2014 09:35:04 +0800 Subject: [PATCH 1/5] Added thermistor table for the 500C thermistor shipped with the Pico hot end. --- Marlin/Configuration.h | 1 + Marlin/thermistortables.h | 75 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h index 1355a7ab9f..66bf69052d 100644 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@ -132,6 +132,7 @@ // 1010 is Pt1000 with 1k pullup (non standard) // 147 is Pt100 with 4k7 pullup // 110 is Pt100 with 1k pullup (non standard) +// 70 is 500C thermistor for Pico hot end #define TEMP_SENSOR_0 -1 #define TEMP_SENSOR_1 -1 diff --git a/Marlin/thermistortables.h b/Marlin/thermistortables.h index 07b385e119..86bf5c2d4e 100644 --- a/Marlin/thermistortables.h +++ b/Marlin/thermistortables.h @@ -1021,6 +1021,81 @@ const short temptable_1047[][2] PROGMEM = { PtLine(300,1000,4700) }; #endif +#if (THERMISTORHEATER_0 == 70) || (THERMISTORHEATER_1 == 70) || (THERMISTORHEATER_2 == 70) || (THERMISTORBED == 70) // 500C thermistor for Pico hot end +const short temptable_70[][2] PROGMEM = { + { 110.774119598719*OVERSAMPLENR , 350 }, + { 118.214386957249*OVERSAMPLENR , 345 }, + { 126.211418543166*OVERSAMPLENR , 340 }, + { 134.789559066223*OVERSAMPLENR , 335 }, + { 144.004513869701*OVERSAMPLENR , 330 }, + { 153.884483790827*OVERSAMPLENR , 325 }, + { 164.484880793637*OVERSAMPLENR , 320 }, + { 175.848885102724*OVERSAMPLENR , 315 }, + { 188.006799079015*OVERSAMPLENR , 310 }, + { 201.008072969044*OVERSAMPLENR , 305 }, + { 214.83716032276*OVERSAMPLENR , 300 }, + { 229.784739779664*OVERSAMPLENR , 295 }, + { 245.499466045473*OVERSAMPLENR , 290 }, + { 262.2766342096*OVERSAMPLENR , 285 }, + { 280.073883176433*OVERSAMPLENR , 280 }, + { 298.952693467726*OVERSAMPLENR , 275 }, + { 318.808251051674*OVERSAMPLENR , 270 }, + { 337.490932563222*OVERSAMPLENR , 265 }, + { 361.683649122745*OVERSAMPLENR , 260 }, + { 384.717024083981*OVERSAMPLENR , 255 }, + { 408.659301759076*OVERSAMPLENR , 250 }, + { 433.471659455884*OVERSAMPLENR , 245 }, + { 459.199039926034*OVERSAMPLENR , 240 }, + { 485.566500982316*OVERSAMPLENR , 235 }, + { 512.538918631075*OVERSAMPLENR , 230 }, + { 539.980999544838*OVERSAMPLENR , 225 }, + { 567.783095549935*OVERSAMPLENR , 220 }, + { 595.698041673552*OVERSAMPLENR , 215 }, + { 623.633922319597*OVERSAMPLENR , 210 }, + { 651.356162750829*OVERSAMPLENR , 205 }, + { 678.700901620956*OVERSAMPLENR , 200 }, + { 705.528145361264*OVERSAMPLENR , 195 }, + { 731.61267976339*OVERSAMPLENR , 190 }, + { 756.786212184365*OVERSAMPLENR , 185 }, + { 780.950223357761*OVERSAMPLENR , 180 }, + { 804.012961595082*OVERSAMPLENR , 175 }, + { 825.904975939166*OVERSAMPLENR , 170 }, + { 846.403941639008*OVERSAMPLENR , 165 }, + { 865.52326974895*OVERSAMPLENR , 160 }, + { 883.246145367727*OVERSAMPLENR , 155 }, + { 899.5821946515*OVERSAMPLENR , 150 }, + { 914.544289228582*OVERSAMPLENR , 145 }, + { 928.145628221761*OVERSAMPLENR , 140 }, + { 940.422208546562*OVERSAMPLENR , 135 }, + { 951.456922916497*OVERSAMPLENR , 130 }, + { 961.303500633788*OVERSAMPLENR , 125 }, + { 970.044756889055*OVERSAMPLENR , 120 }, + { 977.761456230051*OVERSAMPLENR , 115 }, + { 984.540978083453*OVERSAMPLENR , 110 }, + { 990.440780765757*OVERSAMPLENR , 105 }, + { 995.589621465301*OVERSAMPLENR , 100 }, + { 1000.02514280144*OVERSAMPLENR , 95 }, + { 1003.84429789876*OVERSAMPLENR , 90 }, + { 1007.10199009318*OVERSAMPLENR , 85 }, + { 1009.87151698323*OVERSAMPLENR , 80 }, + { 1012.21633594237*OVERSAMPLENR , 75 }, + { 1014.18959892949*OVERSAMPLENR , 70 }, + { 1015.84079162998*OVERSAMPLENR , 65 }, + { 1017.21555915335*OVERSAMPLENR , 60 }, + { 1018.35284662863*OVERSAMPLENR , 55 }, + { 1019.28926921888*OVERSAMPLENR , 50 }, + { 1020.05398015669*OVERSAMPLENR , 45 }, + { 1020.67737496272*OVERSAMPLENR , 40 }, + { 1021.1802909627*OVERSAMPLENR , 35 }, + { 1021.58459281248*OVERSAMPLENR , 30 }, + { 1021.90701441192*OVERSAMPLENR , 25 }, + { 1022.16215103698*OVERSAMPLENR , 20 }, + { 1022.36275529549*OVERSAMPLENR , 15 }, + { 1022.51930392497*OVERSAMPLENR , 10 }, + { 1022.64051573734*OVERSAMPLENR , 5 }, + { 1022.73355805611*OVERSAMPLENR , 0 } +}; +#endif #define _TT_NAME(_N) temptable_ ## _N #define TT_NAME(_N) _TT_NAME(_N) From 86b4b805d25c004e71733dea7d40099f218ef6b4 Mon Sep 17 00:00:00 2001 From: Pablo Clemente Date: Thu, 12 Jun 2014 18:43:16 +0200 Subject: [PATCH 2/5] Fixed stop print LCD function on M104 --- Marlin/Marlin_main.cpp | 6 ++++-- Marlin/ultralcd.cpp | 3 +++ Marlin/ultralcd.h | 2 ++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp index c4afca7f68..a9a29dde60 100644 --- a/Marlin/Marlin_main.cpp +++ b/Marlin/Marlin_main.cpp @@ -1945,14 +1945,16 @@ void process_commands() /* See if we are heating up or cooling down */ target_direction = isHeatingHotend(tmp_extruder); // true if heating, false if cooling + + forced_heating_stop = true; #ifdef TEMP_RESIDENCY_TIME long residencyStart; residencyStart = -1; /* continue to loop until we have reached the target temp _and_ until TEMP_RESIDENCY_TIME hasn't passed since we reached it */ - while((residencyStart == -1) || - (residencyStart >= 0 && (((unsigned int) (millis() - residencyStart)) < (TEMP_RESIDENCY_TIME * 1000UL))) ) { + while((forced_heating_stop == true)&&((residencyStart == -1) || + (residencyStart >= 0 && (((unsigned int) (millis() - residencyStart)) < (TEMP_RESIDENCY_TIME * 1000UL)))) ) { #else while ( target_direction ? (isHeatingHotend(tmp_extruder)) : (isCoolingHotend(tmp_extruder)&&(CooldownNoWait==false)) ) { #endif //TEMP_RESIDENCY_TIME diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp index f09dd410d6..4f5aaac998 100644 --- a/Marlin/ultralcd.cpp +++ b/Marlin/ultralcd.cpp @@ -19,6 +19,7 @@ int absPreheatHotendTemp; int absPreheatHPBTemp; int absPreheatFanSpeed; +boolean forced_heating_stop = true ; #ifdef ULTIPANEL static float manual_feedrate[] = MANUAL_FEEDRATE; @@ -256,6 +257,8 @@ static void lcd_sdcard_stop() enquecommand_P(PSTR(SD_FINISHED_RELEASECOMMAND)); } autotempShutdown(); + + forced_heating_stop = false; } /* Menu implementation */ diff --git a/Marlin/ultralcd.h b/Marlin/ultralcd.h index f4570f6a58..b4195f3975 100644 --- a/Marlin/ultralcd.h +++ b/Marlin/ultralcd.h @@ -42,6 +42,8 @@ extern int absPreheatHotendTemp; extern int absPreheatHPBTemp; extern int absPreheatFanSpeed; + + extern boolean forced_heating_stop; void lcd_buzz(long duration,uint16_t freq); bool lcd_clicked(); From cd3220d055cee14f9feb6f483d992cce80d03a87 Mon Sep 17 00:00:00 2001 From: Pablo Clemente Date: Fri, 13 Jun 2014 08:39:58 +0200 Subject: [PATCH 3/5] Inverted state logic for forced_heating_stop variable --- Marlin/Marlin_main.cpp | 4 ++-- Marlin/ultralcd.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp index a9a29dde60..315a9bb481 100644 --- a/Marlin/Marlin_main.cpp +++ b/Marlin/Marlin_main.cpp @@ -1946,14 +1946,14 @@ void process_commands() /* See if we are heating up or cooling down */ target_direction = isHeatingHotend(tmp_extruder); // true if heating, false if cooling - forced_heating_stop = true; + forced_heating_stop = false; #ifdef TEMP_RESIDENCY_TIME long residencyStart; residencyStart = -1; /* continue to loop until we have reached the target temp _and_ until TEMP_RESIDENCY_TIME hasn't passed since we reached it */ - while((forced_heating_stop == true)&&((residencyStart == -1) || + while((forced_heating_stop == false)&&((residencyStart == -1) || (residencyStart >= 0 && (((unsigned int) (millis() - residencyStart)) < (TEMP_RESIDENCY_TIME * 1000UL)))) ) { #else while ( target_direction ? (isHeatingHotend(tmp_extruder)) : (isCoolingHotend(tmp_extruder)&&(CooldownNoWait==false)) ) { diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp index 4f5aaac998..289b84e969 100644 --- a/Marlin/ultralcd.cpp +++ b/Marlin/ultralcd.cpp @@ -19,7 +19,7 @@ int absPreheatHotendTemp; int absPreheatHPBTemp; int absPreheatFanSpeed; -boolean forced_heating_stop = true ; +boolean forced_heating_stop = false ; #ifdef ULTIPANEL static float manual_feedrate[] = MANUAL_FEEDRATE; @@ -258,7 +258,7 @@ static void lcd_sdcard_stop() } autotempShutdown(); - forced_heating_stop = false; + forced_heating_stop = true; } /* Menu implementation */ From d86c3cf43c6ee542d2f47db091b04f633c1fcf46 Mon Sep 17 00:00:00 2001 From: Pablo Clemente Date: Mon, 30 Jun 2014 15:12:13 +0200 Subject: [PATCH 4/5] Changed the type of variable to bool, the name to "cancel_heatup", flags implementation and added this fix to M190 gcode too. --- Marlin/Marlin_main.cpp | 9 +++++---- Marlin/ultralcd.cpp | 6 +++--- Marlin/ultralcd.h | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp index 315a9bb481..3e44168208 100644 --- a/Marlin/Marlin_main.cpp +++ b/Marlin/Marlin_main.cpp @@ -1946,14 +1946,14 @@ void process_commands() /* See if we are heating up or cooling down */ target_direction = isHeatingHotend(tmp_extruder); // true if heating, false if cooling - forced_heating_stop = false; + cancel_heatup = false; #ifdef TEMP_RESIDENCY_TIME long residencyStart; residencyStart = -1; /* continue to loop until we have reached the target temp _and_ until TEMP_RESIDENCY_TIME hasn't passed since we reached it */ - while((forced_heating_stop == false)&&((residencyStart == -1) || + while((!cancel_heatup)&&((residencyStart == -1) || (residencyStart >= 0 && (((unsigned int) (millis() - residencyStart)) < (TEMP_RESIDENCY_TIME * 1000UL)))) ) { #else while ( target_direction ? (isHeatingHotend(tmp_extruder)) : (isCoolingHotend(tmp_extruder)&&(CooldownNoWait==false)) ) { @@ -2010,10 +2010,11 @@ void process_commands() CooldownNoWait = false; } codenum = millis(); - + + cancel_heatup = false; target_direction = isHeatingBed(); // true if heating, false if cooling - while ( target_direction ? (isHeatingBed()) : (isCoolingBed()&&(CooldownNoWait==false)) ) + while ( (target_direction)&&(!cancel_heatup) ? (isHeatingBed()) : (isCoolingBed()&&(CooldownNoWait==false)) ) { if(( millis() - codenum) > 1000 ) //Print Temp Reading every 1 second while heating up. { diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp index 289b84e969..bb7dd0faa8 100644 --- a/Marlin/ultralcd.cpp +++ b/Marlin/ultralcd.cpp @@ -19,7 +19,7 @@ int absPreheatHotendTemp; int absPreheatHPBTemp; int absPreheatFanSpeed; -boolean forced_heating_stop = false ; +bool cancel_heatup = false ; #ifdef ULTIPANEL static float manual_feedrate[] = MANUAL_FEEDRATE; @@ -195,7 +195,7 @@ static void lcd_status_screen() currentMenu = lcd_main_menu; encoderPosition = 0; lcd_quick_feedback(); - lcd_implementation_init(); // to maybe revive the LCD if static electricity killed it. + lcd_implementation_init(); // to maybe revive the LCD if static electricity killed it. } #ifdef ULTIPANEL_FEEDMULTIPLY @@ -258,7 +258,7 @@ static void lcd_sdcard_stop() } autotempShutdown(); - forced_heating_stop = true; + cancel_heatup = true; } /* Menu implementation */ diff --git a/Marlin/ultralcd.h b/Marlin/ultralcd.h index b4195f3975..9bf685805d 100644 --- a/Marlin/ultralcd.h +++ b/Marlin/ultralcd.h @@ -43,7 +43,7 @@ extern int absPreheatHPBTemp; extern int absPreheatFanSpeed; - extern boolean forced_heating_stop; + extern bool cancel_heatup; void lcd_buzz(long duration,uint16_t freq); bool lcd_clicked(); From 43c298a7a9674bade1395a75fe54667cdb22fce4 Mon Sep 17 00:00:00 2001 From: alexborro Date: Mon, 30 Jun 2014 15:22:37 -0300 Subject: [PATCH 5/5] 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. --- Marlin/Configuration.h | 38 +++++++++++++++++++++++ Marlin/temperature.cpp | 68 ++++++++++++++++++++++++++++++++++++++++++ Marlin/temperature.h | 11 +++++++ 3 files changed, 117 insertions(+) diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h index 66bf69052d..46d6b96dd1 100644 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@ -251,6 +251,44 @@ #define EXTRUDE_MINTEMP 170 #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=========================== //=========================================================================== diff --git a/Marlin/temperature.cpp b/Marlin/temperature.cpp index aac6ca66f5..a10c255af9 100644 --- a/Marlin/temperature.cpp +++ b/Marlin/temperature.cpp @@ -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() { diff --git a/Marlin/temperature.h b/Marlin/temperature.h index a8580def56..df2b5deacf 100644 --- a/Marlin/temperature.h +++ b/Marlin/temperature.h @@ -154,6 +154,17 @@ void disable_heater(); void setWatch(); 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(){ #ifdef AUTOTEMP if(autotemp_enabled)