From 3c927901a4dcc4fb4bbfd6bf914a35f8277165db Mon Sep 17 00:00:00 2001 From: Dim3nsioneer Date: Mon, 2 Jun 2014 17:02:10 +0200 Subject: [PATCH 1/6] Implementation of FW extruder change retract FW retraction is extended onto swap retraction invoked by 'G10 S1'. Bookkeeping of the retract state of all extruders allows for having one extruder fw standard retracted while another extruder is swap retracted. An LCD menu item for the swap retract and recover length was added. --- Marlin/Configuration_adv.h | 2 + Marlin/Marlin.h | 6 +-- Marlin/Marlin_main.cpp | 75 +++++++++++++++++++++++++++++++++----- Marlin/language.h | 26 +++++++++++++ Marlin/ultralcd.cpp | 8 +++- 5 files changed, 103 insertions(+), 14 deletions(-) diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h index 245f65c9e..6398f4161 100644 --- a/Marlin/Configuration_adv.h +++ b/Marlin/Configuration_adv.h @@ -410,9 +410,11 @@ const unsigned int dropsegments=5; //everything with less than this number of st #ifdef FWRETRACT #define MIN_RETRACT 0.1 //minimum extruded mm to accept a automatic gcode retraction attempt #define RETRACT_LENGTH 3 //default retract length (positive mm) + #define RETRACT_LENGTH_SWAP 13 //default swap retract length (positive mm), for extruder change #define RETRACT_FEEDRATE 45 //default feedrate for retracting (mm/s) #define RETRACT_ZLIFT 0 //default retract Z-lift #define RETRACT_RECOVER_LENGTH 0 //default additional recover length (mm, added to retract length when recovering) + #define RETRACT_RECOVER_LENGTH_SWAP 0 //default additional swap recover length (mm, added to retract length when recovering from extruder change) #define RETRACT_RECOVER_FEEDRATE 8 //default feedrate for recovering from retraction (mm/s) #endif diff --git a/Marlin/Marlin.h b/Marlin/Marlin.h index e7282092e..062b6d43c 100644 --- a/Marlin/Marlin.h +++ b/Marlin/Marlin.h @@ -231,9 +231,9 @@ extern unsigned char fanSpeedSoftPwm; #ifdef FWRETRACT extern bool autoretract_enabled; -extern bool retracted; -extern float retract_length, retract_feedrate, retract_zlift; -extern float retract_recover_length, retract_recover_feedrate; +extern bool retracted[EXTRUDERS]; +extern float retract_length, retract_length_swap, retract_feedrate, retract_zlift; +extern float retract_recover_length, retract_recover_length_swap, retract_recover_feedrate; #endif extern unsigned long starttime; diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp index c4afca7f6..cdbdd83ed 100644 --- a/Marlin/Marlin_main.cpp +++ b/Marlin/Marlin_main.cpp @@ -243,11 +243,29 @@ int EtoPPressure=0; #ifdef FWRETRACT bool autoretract_enabled=false; - bool retracted=false; + bool retracted[EXTRUDERS]={false + #if EXTRUDERS > 1 + , false + #if EXTRUDERS > 2 + , false + #endif + #endif + }; + bool retracted_swap[EXTRUDERS]={false + #if EXTRUDERS > 1 + , false + #if EXTRUDERS > 2 + , false + #endif + #endif + }; + float retract_length = RETRACT_LENGTH; + float retract_length_swap = RETRACT_LENGTH_SWAP; float retract_feedrate = RETRACT_FEEDRATE; float retract_zlift = RETRACT_ZLIFT; float retract_recover_length = RETRACT_RECOVER_LENGTH; + float retract_recover_length_swap = RETRACT_RECOVER_LENGTH_SWAP; float retract_recover_feedrate = RETRACT_RECOVER_FEEDRATE; #endif @@ -1117,23 +1135,27 @@ void refresh_cmd_timeout(void) } #ifdef FWRETRACT - void retract(bool retracting) { - if(retracting && !retracted) { + void retract(bool retracting, bool swapretract = false) { + if(retracting && !retracted[active_extruder]) { destination[X_AXIS]=current_position[X_AXIS]; destination[Y_AXIS]=current_position[Y_AXIS]; destination[Z_AXIS]=current_position[Z_AXIS]; destination[E_AXIS]=current_position[E_AXIS]; - current_position[E_AXIS]+=retract_length/volumetric_multiplier[active_extruder]; + if (swapretract) { + current_position[E_AXIS]+=retract_length_swap/volumetric_multiplier[active_extruder]; + } else { + current_position[E_AXIS]+=retract_length/volumetric_multiplier[active_extruder]; + } plan_set_e_position(current_position[E_AXIS]); float oldFeedrate = feedrate; feedrate=retract_feedrate*60; - retracted=true; + retracted[active_extruder]=true; prepare_move(); current_position[Z_AXIS]-=retract_zlift; plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); prepare_move(); feedrate = oldFeedrate; - } else if(!retracting && retracted) { + } else if(!retracting && retracted[active_extruder]) { destination[X_AXIS]=current_position[X_AXIS]; destination[Y_AXIS]=current_position[Y_AXIS]; destination[Z_AXIS]=current_position[Z_AXIS]; @@ -1141,11 +1163,15 @@ void refresh_cmd_timeout(void) current_position[Z_AXIS]+=retract_zlift; plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]); //prepare_move(); - current_position[E_AXIS]-=(retract_length+retract_recover_length)/volumetric_multiplier[active_extruder]; + if (swapretract) { + current_position[E_AXIS]-=(retract_length_swap+retract_recover_length_swap)/volumetric_multiplier[active_extruder]; + } else { + current_position[E_AXIS]-=(retract_length+retract_recover_length)/volumetric_multiplier[active_extruder]; + } plan_set_e_position(current_position[E_AXIS]); float oldFeedrate = feedrate; feedrate=retract_recover_feedrate*60; - retracted=false; + retracted[active_extruder]=false; prepare_move(); feedrate = oldFeedrate; } @@ -1215,10 +1241,19 @@ void process_commands() break; #ifdef FWRETRACT case 10: // G10 retract + #if EXTRUDERS > 1 + retracted_swap[active_extruder]=(code_seen('S') && code_value_long() == 1); // checks for swap retract argument + retract(true,retracted_swap[active_extruder]); + #else retract(true); + #endif break; case 11: // G11 retract_recover + #if EXTRUDERS > 1 + retract(false,retracted_swap[active_extruder]); + #else retract(false); + #endif break; #endif //FWRETRACT case 28: //G28 Home all Axis one at a time @@ -2391,8 +2426,28 @@ void process_commands() int t= code_value() ; switch(t) { - case 0: autoretract_enabled=false;retracted=false;break; - case 1: autoretract_enabled=true;retracted=false;break; + case 0: + { + autoretract_enabled=false; + retracted[0]=false; + #if EXTRUDERS > 1 + retracted[1]=false; + #endif + #if EXTRUDERS > 2 + retracted[2]=false; + #endif + }break; + case 1: + { + autoretract_enabled=true; + retracted[0]=false; + #if EXTRUDERS > 1 + retracted[1]=false; + #endif + #if EXTRUDERS > 2 + retracted[2]=false; + #endif + }break; default: SERIAL_ECHO_START; SERIAL_ECHOPGM(MSG_UNKNOWN_COMMAND); diff --git a/Marlin/language.h b/Marlin/language.h index c032aca89..8522018bf 100644 --- a/Marlin/language.h +++ b/Marlin/language.h @@ -171,9 +171,11 @@ #define MSG_KILLED "KILLED. " #define MSG_STOPPED "STOPPED. " #define MSG_CONTROL_RETRACT "Retract mm" + #define MSG_CONTROL_RETRACT_SWAP "Swap Re.mm" #define MSG_CONTROL_RETRACTF "Retract V" #define MSG_CONTROL_RETRACT_ZLIFT "Hop mm" #define MSG_CONTROL_RETRACT_RECOVER "UnRet +mm" + #define MSG_CONTROL_RETRACT_RECOVER_SWAP "S UnRet+mm" #define MSG_CONTROL_RETRACT_RECOVERF "UnRet V" #define MSG_AUTORETRACT "AutoRetr." #define MSG_FILAMENTCHANGE "Change filament" @@ -371,9 +373,11 @@ #define MSG_STOPPED "Zatrzymany. " #define MSG_STEPPER_RELEASED "Zwolniony." #define MSG_CONTROL_RETRACT "Wycofaj mm" + #define MSG_CONTROL_RETRACT_SWAP "Z Wycof. mm" #define MSG_CONTROL_RETRACTF "Wycofaj V" #define MSG_CONTROL_RETRACT_ZLIFT "Skok Z mm:" #define MSG_CONTROL_RETRACT_RECOVER "Cof. wycof. +mm" + #define MSG_CONTROL_RETRACT_RECOVER_SWAP "Z Cof. wyc. +mm" #define MSG_CONTROL_RETRACT_RECOVERF "Cof. wycof. V" #define MSG_AUTORETRACT "Auto. wycofanie" #define MSG_FILAMENTCHANGE "Zmien filament" @@ -572,9 +576,11 @@ #define MSG_STOPPED "STOPPE." #define MSG_STEPPER_RELEASED "RELACHE." #define MSG_CONTROL_RETRACT "Retraction mm" + #define MSG_CONTROL_RETRACT_SWAP "Ech. Retr. mm" #define MSG_CONTROL_RETRACTF "Retraction V" #define MSG_CONTROL_RETRACT_ZLIFT "Hop mm" #define MSG_CONTROL_RETRACT_RECOVER "UnRet +mm" + #define MSG_CONTROL_RETRACT_RECOVER_SWAP "Ech. UnRet +mm" #define MSG_CONTROL_RETRACT_RECOVERF "UnRet V" #define MSG_AUTORETRACT "Retract. Auto." #define MSG_FILAMENTCHANGE "Changer filament" @@ -774,9 +780,11 @@ #define MSG_STOPPED "GESTOPPT" #define MSG_STEPPER_RELEASED "Stepper frei" #define MSG_CONTROL_RETRACT "Retract mm" + #define MSG_CONTROL_RETRACT_SWAP "Wechs. Retract mm" #define MSG_CONTROL_RETRACTF "Retract V" #define MSG_CONTROL_RETRACT_ZLIFT "Hop mm" #define MSG_CONTROL_RETRACT_RECOVER "UnRet +mm" + #define MSG_CONTROL_RETRACT_RECOVER_SWAP "Wechs. UnRet +mm" #define MSG_CONTROL_RETRACT_RECOVERF "UnRet V" #define MSG_AUTORETRACT "AutoRetr." #define MSG_FILAMENTCHANGE "Filament wechseln" @@ -972,9 +980,11 @@ #define MSG_KILLED "PARADA DE EMERG." #define MSG_STOPPED "PARADA" #define MSG_CONTROL_RETRACT "Retraer mm" + #define MSG_CONTROL_RETRACT_SWAP "Interc. Retraer mm" #define MSG_CONTROL_RETRACTF "Retraer V" #define MSG_CONTROL_RETRACT_ZLIFT "Levantar mm" #define MSG_CONTROL_RETRACT_RECOVER "DesRet +mm" + #define MSG_CONTROL_RETRACT_RECOVER_SWAP "Interc. DesRet +mm" #define MSG_CONTROL_RETRACT_RECOVERF "DesRet V" #define MSG_AUTORETRACT "AutoRetr." #define MSG_FILAMENTCHANGE "Cambiar filamento" @@ -1179,9 +1189,11 @@ #define MSG_KILLED "УБИТО." #define MSG_STOPPED "ОСТАНОВЛЕНО." #define MSG_CONTROL_RETRACT "Откат mm:" + #define MSG_CONTROL_RETRACT_SWAP "своп Откат mm:" #define MSG_CONTROL_RETRACTF "Откат V:" #define MSG_CONTROL_RETRACT_ZLIFT "Прыжок mm:" #define MSG_CONTROL_RETRACT_RECOVER "Возврат +mm:" + #define MSG_CONTROL_RETRACT_RECOVER_SWAP "своп Возврат +mm:" #define MSG_CONTROL_RETRACT_RECOVERF "Возврат V:" #define MSG_AUTORETRACT "АвтоОткат:" #define MSG_FILAMENTCHANGE "Change filament" @@ -1376,9 +1388,11 @@ #define MSG_KILLED "UCCISO. " #define MSG_STOPPED "ARRESTATO. " #define MSG_CONTROL_RETRACT "Ritrai mm" + #define MSG_CONTROL_RETRACT_SWAP "Scamb. Ritrai mm" #define MSG_CONTROL_RETRACTF "Ritrai V" #define MSG_CONTROL_RETRACT_ZLIFT "Salta mm" #define MSG_CONTROL_RETRACT_RECOVER "UnRet +mm" + #define MSG_CONTROL_RETRACT_RECOVER_SWAP "Scamb. UnRet +mm" #define MSG_CONTROL_RETRACT_RECOVERF "UnRet V" #define MSG_AUTORETRACT "AutoArretramento" #define MSG_FILAMENTCHANGE "Cambia filamento" @@ -1581,9 +1595,11 @@ #define MSG_STOPPED "PARADA. " #define MSG_STEPPER_RELEASED "Lancado." #define MSG_CONTROL_RETRACT " Retrair mm:" + #define MSG_CONTROL_RETRACT_SWAP "Troca Retrair mm:" #define MSG_CONTROL_RETRACTF " Retrair V:" #define MSG_CONTROL_RETRACT_ZLIFT " Levantar mm:" #define MSG_CONTROL_RETRACT_RECOVER " DesRet +mm:" + #define MSG_CONTROL_RETRACT_RECOVER_SWAP "Troca DesRet +mm:" #define MSG_CONTROL_RETRACT_RECOVERF " DesRet V:" #define MSG_AUTORETRACT " AutoRetr.:" #define MSG_FILAMENTCHANGE "Change filament" @@ -1781,9 +1797,11 @@ #define MSG_KILLED "KILLED. " #define MSG_STOPPED "STOPPED. " #define MSG_CONTROL_RETRACT "Veda mm" + #define MSG_CONTROL_RETRACT_SWAP "Va. Veda mm" #define MSG_CONTROL_RETRACTF "Veda V" #define MSG_CONTROL_RETRACT_ZLIFT "Z mm" #define MSG_CONTROL_RETRACT_RECOVER "UnRet +mm" + #define MSG_CONTROL_RETRACT_RECOVER_SWAP "Va. UnRet +mm" #define MSG_CONTROL_RETRACT_RECOVERF "UnRet V" #define MSG_AUTORETRACT "AutoVeto." #define MSG_FILAMENTCHANGE "Change filament" @@ -1979,9 +1997,11 @@ #define MSG_KILLED "ATURADA D'EMERCH." #define MSG_STOPPED "ATURADA." #define MSG_CONTROL_RETRACT "Retraer mm" + #define MSG_CONTROL_RETRACT_SWAP "Swap Retraer mm" #define MSG_CONTROL_RETRACTF "Retraer F" #define MSG_CONTROL_RETRACT_ZLIFT "Devantar mm" #define MSG_CONTROL_RETRACT_RECOVER "DesRet +mm" + #define MSG_CONTROL_RETRACT_RECOVER_SWAP "Swap DesRet +mm" #define MSG_CONTROL_RETRACT_RECOVERF "DesRet F" #define MSG_AUTORETRACT "AutoRetr." #define MSG_FILAMENTCHANGE "Cambear" @@ -2185,9 +2205,11 @@ #define MSG_KILLED "AFGEBROKEN. " #define MSG_STOPPED "GESTOPT. " #define MSG_CONTROL_RETRACT "Retract mm" + #define MSG_CONTROL_RETRACT_SWAP "Ruil Retract mm" #define MSG_CONTROL_RETRACTF "Retract F" #define MSG_CONTROL_RETRACT_ZLIFT "Hop mm" #define MSG_CONTROL_RETRACT_RECOVER "UnRet +mm" + #define MSG_CONTROL_RETRACT_RECOVER_SWAP "Ruil UnRet +mm" #define MSG_CONTROL_RETRACT_RECOVERF "UnRet F" #define MSG_AUTORETRACT "AutoRetr." #define MSG_FILAMENTCHANGE "Verv. Filament" @@ -2384,9 +2406,11 @@ #define MSG_KILLED "PARADA DE EMERG. " #define MSG_STOPPED "ATURAT. " #define MSG_CONTROL_RETRACT "Retreure mm" + #define MSG_CONTROL_RETRACT_SWAP "Swap Retreure mm" #define MSG_CONTROL_RETRACTF "Retreure F" #define MSG_CONTROL_RETRACT_ZLIFT "Aixecar mm" #define MSG_CONTROL_RETRACT_RECOVER "DesRet +mm" + #define MSG_CONTROL_RETRACT_RECOVER_SWAP "Swap DesRet +mm" #define MSG_CONTROL_RETRACT_RECOVERF "DesRet F" #define MSG_AUTORETRACT "AutoRetr." #define MSG_FILAMENTCHANGE "Canviar filament" @@ -2582,9 +2606,11 @@ #define MSG_KILLED "LARRIALDI GELDIA" #define MSG_STOPPED "GELDITUTA. " #define MSG_CONTROL_RETRACT "Atzera egin mm" + #define MSG_CONTROL_RETRACT_SWAP "Swap Atzera egin mm" #define MSG_CONTROL_RETRACTF "Atzera egin V" #define MSG_CONTROL_RETRACT_ZLIFT "Igo mm" #define MSG_CONTROL_RETRACT_RECOVER "Atzera egin +mm" + #define MSG_CONTROL_RETRACT_RECOVER_SWAP "Swap Atzera egin +mm" #define MSG_CONTROL_RETRACT_RECOVERF "Atzera egin V" #define MSG_AUTORETRACT "Atzera egin" #define MSG_FILAMENTCHANGE "Aldatu filament." diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp index f09dd410d..da28901f8 100644 --- a/Marlin/ultralcd.cpp +++ b/Marlin/ultralcd.cpp @@ -194,7 +194,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 @@ -903,9 +903,15 @@ static void lcd_control_retract_menu() MENU_ITEM(back, MSG_CONTROL, lcd_control_menu); MENU_ITEM_EDIT(bool, MSG_AUTORETRACT, &autoretract_enabled); MENU_ITEM_EDIT(float52, MSG_CONTROL_RETRACT, &retract_length, 0, 100); + #if EXTRUDERS > 1 + MENU_ITEM_EDIT(float52, MSG_CONTROL_RETRACT_SWAP, &retract_length_swap, 0, 100); + #endif MENU_ITEM_EDIT(float3, MSG_CONTROL_RETRACTF, &retract_feedrate, 1, 999); MENU_ITEM_EDIT(float52, MSG_CONTROL_RETRACT_ZLIFT, &retract_zlift, 0, 999); MENU_ITEM_EDIT(float52, MSG_CONTROL_RETRACT_RECOVER, &retract_recover_length, 0, 100); + #if EXTRUDERS > 1 + MENU_ITEM_EDIT(float52, MSG_CONTROL_RETRACT_RECOVER_SWAP, &retract_recover_length_swap, 0, 100); + #endif MENU_ITEM_EDIT(float3, MSG_CONTROL_RETRACT_RECOVERF, &retract_recover_feedrate, 1, 999); END_MENU(); } From 86b4b805d25c004e71733dea7d40099f218ef6b4 Mon Sep 17 00:00:00 2001 From: Pablo Clemente Date: Thu, 12 Jun 2014 18:43:16 +0200 Subject: [PATCH 2/6] 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 c4afca7f6..a9a29dde6 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 f09dd410d..4f5aaac99 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 f4570f6a5..b4195f397 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/6] 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 a9a29dde6..315a9bb48 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 4f5aaac99..289b84e96 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/6] 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 315a9bb48..3e4416820 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 289b84e96..bb7dd0faa 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 b4195f397..9bf685805 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/6] 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 66bf69052..46d6b96dd 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 aac6ca66f..a10c255af 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 a8580def5..df2b5deac 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) From 2242a842189f8d65b86b63bcec7a84044b07c8e1 Mon Sep 17 00:00:00 2001 From: Pablo Clemente Date: Tue, 1 Jul 2014 16:45:03 +0200 Subject: [PATCH 6/6] Changed the declaration of the variable to Marlin_main.cpp to fix issue on commit #965 --- Marlin/Marlin_main.cpp | 2 ++ Marlin/ultralcd.cpp | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp index 3e4416820..0367eb46c 100644 --- a/Marlin/Marlin_main.cpp +++ b/Marlin/Marlin_main.cpp @@ -276,6 +276,8 @@ int EtoPPressure=0; float delta_segments_per_second= DELTA_SEGMENTS_PER_SECOND; #endif +bool cancel_heatup = false ; + //=========================================================================== //=============================Private Variables============================= //=========================================================================== diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp index bb7dd0faa..18c85887a 100644 --- a/Marlin/ultralcd.cpp +++ b/Marlin/ultralcd.cpp @@ -19,8 +19,6 @@ int absPreheatHotendTemp; int absPreheatHPBTemp; int absPreheatFanSpeed; -bool cancel_heatup = false ; - #ifdef ULTIPANEL static float manual_feedrate[] = MANUAL_FEEDRATE; #endif // ULTIPANEL