From 6ee34331b7a0e5ea82768f4df5f3956ce5322742 Mon Sep 17 00:00:00 2001 From: Robert Brenckman Date: Sun, 10 Apr 2022 01:24:07 -0400 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20Fix=20Tool=20Change=20priming=20?= =?UTF-8?q?(#21142)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Scott Lahteine --- Marlin/Configuration_adv.h | 14 +- Marlin/src/gcode/config/M217.cpp | 60 +++--- Marlin/src/inc/Conditionals_LCD.h | 2 +- Marlin/src/inc/SanityCheck.h | 2 + Marlin/src/lcd/menu/menu_configuration.cpp | 4 +- Marlin/src/module/tool_change.cpp | 225 ++++++++++++++------- Marlin/src/module/tool_change.h | 24 ++- buildroot/tests/BIGTREE_GTR_V1_0 | 2 +- 8 files changed, 210 insertions(+), 123 deletions(-) diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h index 3ae6c1b31346..74eccccb1e8c 100644 --- a/Marlin/Configuration_adv.h +++ b/Marlin/Configuration_adv.h @@ -2494,12 +2494,16 @@ #define TOOLCHANGE_FS_FAN_SPEED 255 // 0-255 #define TOOLCHANGE_FS_FAN_TIME 10 // (seconds) - // Swap uninitialized extruder (using TOOLCHANGE_FS_PRIME_SPEED feedrate) - // (May break filament if not retracted beforehand.) - //#define TOOLCHANGE_FS_INIT_BEFORE_SWAP + // Use TOOLCHANGE_FS_PRIME_SPEED feedrate the first time each extruder is primed + //#define TOOLCHANGE_FS_SLOW_FIRST_PRIME - // Prime on the first T0 (For other tools use TOOLCHANGE_FS_INIT_BEFORE_SWAP) - // Enable with M217 V1 before printing to avoid unwanted priming on host connect + /** + * Prime T0 the first time T0 is sent to the printer: + * [ Power-On -> T0 { Activate & Prime T0 } -> T1 { Retract T0, Activate & Prime T1 } ] + * If disabled, no priming on T0 until switching back to T0 from another extruder: + * [ Power-On -> T0 { T0 Activated } -> T1 { Activate & Prime T1 } -> T0 { Retract T1, Activate & Prime T0 } ] + * Enable with M217 V1 before printing to avoid unwanted priming on host connect. + */ //#define TOOLCHANGE_FS_PRIME_FIRST_USED /** diff --git a/Marlin/src/gcode/config/M217.cpp b/Marlin/src/gcode/config/M217.cpp index b8f1aa846bad..989e4d0870a4 100644 --- a/Marlin/src/gcode/config/M217.cpp +++ b/Marlin/src/gcode/config/M217.cpp @@ -34,31 +34,31 @@ #include "../../MarlinCore.h" // for SP_X_STR, etc. /** - * M217 - Set SINGLENOZZLE toolchange parameters + * M217 - Set toolchange parameters * * // Tool change command * Q Prime active tool and exit * * // Tool change settings - * S[linear] Swap length - * B[linear] Extra Swap length - * E[linear] Prime length - * P[linear/m] Prime speed - * R[linear/m] Retract speed - * U[linear/m] UnRetract speed - * V[linear] 0/1 Enable auto prime first extruder used - * W[linear] 0/1 Enable park & Z Raise - * X[linear] Park X (Requires TOOLCHANGE_PARK) - * Y[linear] Park Y (Requires TOOLCHANGE_PARK) - * I[linear] Park I (Requires TOOLCHANGE_PARK and NUM_AXES >= 4) - * J[linear] Park J (Requires TOOLCHANGE_PARK and NUM_AXES >= 5) - * K[linear] Park K (Requires TOOLCHANGE_PARK and NUM_AXES >= 6) - * C[linear] Park U (Requires TOOLCHANGE_PARK and NUM_AXES >= 7) - * H[linear] Park V (Requires TOOLCHANGE_PARK and NUM_AXES >= 8) - * O[linear] Park W (Requires TOOLCHANGE_PARK and NUM_AXES >= 9) - * Z[linear] Z Raise - * F[linear] Fan Speed 0-255 - * G[linear/s] Fan time + * S[linear] Swap length + * B[linear] Extra Swap resume length + * E[linear] Extra Prime length (as used by M217 Q) + * P[linear/min] Prime speed + * R[linear/min] Retract speed + * U[linear/min] UnRetract speed + * V[linear] 0/1 Enable auto prime first extruder used + * W[linear] 0/1 Enable park & Z Raise + * X[linear] Park X (Requires TOOLCHANGE_PARK) + * Y[linear] Park Y (Requires TOOLCHANGE_PARK) + * I[linear] Park I (Requires TOOLCHANGE_PARK and NUM_AXES >= 4) + * J[linear] Park J (Requires TOOLCHANGE_PARK and NUM_AXES >= 5) + * K[linear] Park K (Requires TOOLCHANGE_PARK and NUM_AXES >= 6) + * C[linear] Park U (Requires TOOLCHANGE_PARK and NUM_AXES >= 7) + * H[linear] Park V (Requires TOOLCHANGE_PARK and NUM_AXES >= 8) + * O[linear] Park W (Requires TOOLCHANGE_PARK and NUM_AXES >= 9) + * Z[linear] Z Raise + * F[speed] Fan Speed 0-255 + * D[seconds] Fan time * * Tool migration settings * A[0|1] Enable auto-migration on runout @@ -82,8 +82,8 @@ void GcodeSuite::M217() { if (parser.seenval('R')) { const int16_t v = parser.value_linear_units(); toolchange_settings.retract_speed = constrain(v, 10, 5400); } if (parser.seenval('U')) { const int16_t v = parser.value_linear_units(); toolchange_settings.unretract_speed = constrain(v, 10, 5400); } #if TOOLCHANGE_FS_FAN >= 0 && HAS_FAN - if (parser.seenval('F')) { const int16_t v = parser.value_linear_units(); toolchange_settings.fan_speed = constrain(v, 0, 255); } - if (parser.seenval('G')) { const int16_t v = parser.value_linear_units(); toolchange_settings.fan_time = constrain(v, 1, 30); } + if (parser.seenval('F')) { const uint16_t v = parser.value_ushort(); toolchange_settings.fan_speed = constrain(v, 0, 255); } + if (parser.seenval('D')) { const uint16_t v = parser.value_ushort(); toolchange_settings.fan_time = constrain(v, 1, 30); } #endif #endif @@ -171,7 +171,7 @@ void GcodeSuite::M217_report(const bool forReplay/*=true*/) { SERIAL_ECHOPGM(" R", LINEAR_UNIT(toolchange_settings.retract_speed), " U", LINEAR_UNIT(toolchange_settings.unretract_speed), " F", toolchange_settings.fan_speed, - " G", toolchange_settings.fan_time); + " D", toolchange_settings.fan_time); #if ENABLED(TOOLCHANGE_MIGRATION_FEATURE) SERIAL_ECHOPGM(" A", migration.automode); @@ -186,13 +186,13 @@ void GcodeSuite::M217_report(const bool forReplay/*=true*/) { , SP_Y_STR, LINEAR_UNIT(toolchange_settings.change_point.y) #endif #if SECONDARY_AXES >= 1 - , LIST_N(DOUBLE(SECONDARY_AXES), - PSTR(" I"), I_AXIS_UNIT(toolchange_settings.change_point.i), - PSTR(" J"), J_AXIS_UNIT(toolchange_settings.change_point.j), - PSTR(" K"), K_AXIS_UNIT(toolchange_settings.change_point.k), - SP_C_STR, U_AXIS_UNIT(toolchange_settings.change_point.u), - PSTR(" H"), V_AXIS_UNIT(toolchange_settings.change_point.v), - PSTR(" O"), W_AXIS_UNIT(toolchange_settings.change_point.w) + , LIST_N(DOUBLE(SECONDARY_AXES) + , SP_I_STR, I_AXIS_UNIT(toolchange_settings.change_point.i) + , SP_J_STR, J_AXIS_UNIT(toolchange_settings.change_point.j) + , SP_K_STR, K_AXIS_UNIT(toolchange_settings.change_point.k) + , SP_C_STR, U_AXIS_UNIT(toolchange_settings.change_point.u) + , PSTR(" H"), V_AXIS_UNIT(toolchange_settings.change_point.v) + , PSTR(" O"), W_AXIS_UNIT(toolchange_settings.change_point.w) ) #endif ); diff --git a/Marlin/src/inc/Conditionals_LCD.h b/Marlin/src/inc/Conditionals_LCD.h index 65c4ac002fd1..41fa84ddfa22 100644 --- a/Marlin/src/inc/Conditionals_LCD.h +++ b/Marlin/src/inc/Conditionals_LCD.h @@ -712,7 +712,7 @@ * Number of Primary Linear Axes (e.g., XYZ) * X, XY, or XYZ axes. Excluding duplicate axes (X2, Y2. Z2. Z3, Z4) */ -#if HAS_I_AXIS +#if NUM_AXES >= 3 #define PRIMARY_LINEAR_AXES 3 #else #define PRIMARY_LINEAR_AXES NUM_AXES diff --git a/Marlin/src/inc/SanityCheck.h b/Marlin/src/inc/SanityCheck.h index 7d59200f4cc1..1da0bf4a8918 100644 --- a/Marlin/src/inc/SanityCheck.h +++ b/Marlin/src/inc/SanityCheck.h @@ -390,6 +390,8 @@ #error "ENDSTOP_NOISE_FILTER is now ENDSTOP_NOISE_THRESHOLD [2-7]." #elif defined(RETRACT_ZLIFT) #error "RETRACT_ZLIFT is now RETRACT_ZRAISE." +#elif defined(TOOLCHANGE_FS_INIT_BEFORE_SWAP) + #error "TOOLCHANGE_FS_INIT_BEFORE_SWAP is now TOOLCHANGE_FS_SLOW_FIRST_PRIME." #elif defined(TOOLCHANGE_PARK_ZLIFT) || defined(TOOLCHANGE_UNPARK_ZLIFT) #error "TOOLCHANGE_PARK_ZLIFT and TOOLCHANGE_UNPARK_ZLIFT are now TOOLCHANGE_ZRAISE." #elif defined(SINGLENOZZLE_TOOLCHANGE_ZRAISE) diff --git a/Marlin/src/lcd/menu/menu_configuration.cpp b/Marlin/src/lcd/menu/menu_configuration.cpp index b8267caef610..d4590a65f902 100644 --- a/Marlin/src/lcd/menu/menu_configuration.cpp +++ b/Marlin/src/lcd/menu/menu_configuration.cpp @@ -122,8 +122,8 @@ void menu_advanced_settings(); EDIT_ITEM_FAST(int4, MSG_SINGLENOZZLE_UNRETRACT_SPEED, &toolchange_settings.unretract_speed, 10, 5400); EDIT_ITEM(float3, MSG_FILAMENT_PURGE_LENGTH, &toolchange_settings.extra_prime, 0, max_extrude); EDIT_ITEM_FAST(int4, MSG_SINGLENOZZLE_PRIME_SPEED, &toolchange_settings.prime_speed, 10, 5400); - EDIT_ITEM_FAST(int4, MSG_SINGLENOZZLE_FAN_SPEED, &toolchange_settings.fan_speed, 0, 255); - EDIT_ITEM_FAST(int4, MSG_SINGLENOZZLE_FAN_TIME, &toolchange_settings.fan_time, 1, 30); + EDIT_ITEM_FAST(uint8, MSG_SINGLENOZZLE_FAN_SPEED, &toolchange_settings.fan_speed, 0, 255); + EDIT_ITEM_FAST(uint8, MSG_SINGLENOZZLE_FAN_TIME, &toolchange_settings.fan_time, 1, 30); #endif EDIT_ITEM(float3, MSG_TOOL_CHANGE_ZLIFT, &toolchange_settings.z_raise, 0, 10); END_MENU(); diff --git a/Marlin/src/module/tool_change.cpp b/Marlin/src/module/tool_change.cpp index 588322caa59c..e2f1443048ed 100644 --- a/Marlin/src/module/tool_change.cpp +++ b/Marlin/src/module/tool_change.cpp @@ -32,6 +32,7 @@ #include "../MarlinCore.h" //#define DEBUG_TOOL_CHANGE +//#define DEBUG_TOOLCHANGE_FILAMENT_SWAP #define DEBUG_OUT ENABLED(DEBUG_TOOL_CHANGE) #include "../core/debug_out.h" @@ -42,7 +43,6 @@ #if ENABLED(TOOLCHANGE_MIGRATION_FEATURE) migration_settings_t migration = migration_defaults; - bool enable_first_prime; #endif #if ENABLED(TOOLCHANGE_FS_INIT_BEFORE_SWAP) @@ -150,6 +150,7 @@ #endif // SWITCHING_NOZZLE +// Move to position routines void _line_to_current(const AxisEnum fr_axis, const float fscale=1) { line_to_current_position(planner.settings.max_feedrate_mm_s[fr_axis] * fscale); } @@ -899,10 +900,135 @@ void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_axis, 0. */ #if ENABLED(TOOLCHANGE_FILAMENT_SWAP) + #ifdef DEBUG_TOOLCHANGE_FILAMENT_SWAP + #define FS_DEBUG(V...) SERIAL_ECHOLNPGM("DEBUG: " V) + #else + #define FS_DEBUG(...) NOOP + #endif + + // Define any variables required + static Flags extruder_was_primed; // Extruders primed status + + #if ENABLED(TOOLCHANGE_FS_PRIME_FIRST_USED) + bool enable_first_prime; // As set by M217 V + #endif + + // Cool down with fan + inline void filament_swap_cooling() { + #if HAS_FAN && TOOLCHANGE_FS_FAN >= 0 + thermalManager.fan_speed[TOOLCHANGE_FS_FAN] = toolchange_settings.fan_speed; + gcode.dwell(SEC_TO_MS(toolchange_settings.fan_time)); + thermalManager.fan_speed[TOOLCHANGE_FS_FAN] = 0; + #endif + } + + /** + * Check if too cold to move the specified tool + * + * Returns TRUE if too cold to move (also echos message: STR_ERR_HOTEND_TOO_COLD) + * Returns FALSE if able to move. + */ + bool too_cold(uint8_t toolID){ + if (TERN0(PREVENT_COLD_EXTRUSION, !DEBUGGING(DRYRUN) && thermalManager.targetTooColdToExtrude(toolID))) { + SERIAL_ECHO_MSG(STR_ERR_HOTEND_TOO_COLD); + return true; + } + return false; + } + + /** + * Cutting recovery -- Recover from cutting retraction that occurs at the end of nozzle priming + * + * If the active_extruder is up to temp (!too_cold): + * Extrude filament distance = toolchange_settings.extra_resume + TOOLCHANGE_FS_WIPE_RETRACT + * current_position.e = e; + * sync_plan_position_e(); + */ + void extruder_cutting_recover(const_float_t e) { + if (!too_cold(active_extruder)) { + const float dist = toolchange_settings.extra_resume + (TOOLCHANGE_FS_WIPE_RETRACT); + FS_DEBUG("Performing Cutting Recover | Distance: ", dist, " | Speed: ", MMM_TO_MMS(toolchange_settings.unretract_speed), "mm/s"); + unscaled_e_move(dist, MMM_TO_MMS(toolchange_settings.unretract_speed)); + planner.synchronize(); + FS_DEBUG("Set position to: ", e); + current_position.e = e; + sync_plan_position_e(); // Resume new E Position + } + } + + /** + * Prime the currently selected extruder (Filament loading only) + * + * If too_cold(toolID) returns TRUE -> returns without moving extruder. + * Extruders filament = swap_length + extra prime, then performs cutting retraction if enabled. + * If cooling fan is enabled, calls filament_swap_cooling(); + */ + void extruder_prime() { + + if (too_cold(active_extruder)) { + FS_DEBUG("Priming Aborted - Nozzle Too Cold!"); + return; // Extruder too cold to prime + } + + float fr = toolchange_settings.unretract_speed; // Set default speed for unretract + + #if ENABLED(TOOLCHANGE_FS_SLOW_FIRST_PRIME) + /* + * Perform first unretract movement at the slower Prime_Speed to avoid breakage on first prime + */ + static Flags extruder_did_first_prime; // Extruders first priming status + if (!extruder_did_first_prime[active_extruder]) { + extruder_did_first_prime.set(active_extruder); // Log first prime complete + // new nozzle - prime at user-specified speed. + FS_DEBUG("First time priming T", active_extruder, ", reducing speed from ", MMM_TO_MMS(fr), " to ", MMM_TO_MMS(toolchange_settings.prime_speed), "mm/s"); + fr = toolchange_settings.prime_speed; + unscaled_e_move(0, MMM_TO_MMS(fr)); // Init planner with 0 length move + } + #endif + + //Calculate and perform the priming distance + if (toolchange_settings.extra_prime >= 0) { + // Positive extra_prime value + // - Return filament at speed (fr) then extra_prime at prime speed + FS_DEBUG("Loading Filament for T", active_extruder, " | Distance: ", toolchange_settings.swap_length, " | Speed: ", MMM_TO_MMS(fr), "mm/s"); + unscaled_e_move(toolchange_settings.swap_length, MMM_TO_MMS(fr)); // Prime (Unretract) filament by extruding equal to Swap Length (Unretract) + + if (toolchange_settings.extra_prime > 0) { + FS_DEBUG("Performing Extra Priming for T", active_extruder, " | Distance: ", toolchange_settings.extra_prime, " | Speed: ", MMM_TO_MMS(toolchange_settings.prime_speed), "mm/s"); + unscaled_e_move(toolchange_settings.extra_prime, MMM_TO_MMS(toolchange_settings.prime_speed)); // Extra Prime Distance + } + } + else { + // Negative extra_prime value + // - Unretract distance (swap length) is reduced by the value of extra_prime + const float eswap = toolchange_settings.swap_length + toolchange_settings.extra_prime; + FS_DEBUG("Negative ExtraPrime value - Swap Return Length has been reduced from ", toolchange_settings.swap_length, " to ", eswap); + FS_DEBUG("Loading Filament for T", active_extruder, " | Distance: ", eswap, " | Speed: ", MMM_TO_MMS(fr), "mm/s"); + unscaled_e_move(eswap, MMM_TO_MMS(fr)); + } + + extruder_was_primed.set(active_extruder); // Log that this extruder has been primed + + // Cutting retraction + #if TOOLCHANGE_FS_WIPE_RETRACT + FS_DEBUG("Performing Cutting Retraction | Distance: ", -(TOOLCHANGE_FS_WIPE_RETRACT), " | Speed: ", MMM_TO_MMS(toolchange_settings.retract_speed), "mm/s"); + unscaled_e_move(-(TOOLCHANGE_FS_WIPE_RETRACT), MMM_TO_MMS(toolchange_settings.retract_speed)); + #endif + + // Cool down with fan + filament_swap_cooling(); + + } + + /** + * Sequence to Prime the currently selected extruder + * Raise Z, move the ToolChange_Park if enabled, prime the extruder, move back. + */ void tool_change_prime() { - if (toolchange_settings.extra_prime > 0 - && TERN(PREVENT_COLD_EXTRUSION, !thermalManager.targetTooColdToExtrude(active_extruder), 1) - ) { + + FS_DEBUG(">>> tool_change_prime()"); + + if (!too_cold(active_extruder)) { destination = current_position; // Remember the old position const bool ok = TERN1(TOOLCHANGE_PARK, all_axes_homed() && toolchange_settings.enable_park); @@ -941,20 +1067,7 @@ void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_axis, 0. } #endif - // Prime (All distances are added and slowed down to ensure secure priming in all circumstances) - unscaled_e_move(toolchange_settings.swap_length + toolchange_settings.extra_prime, MMM_TO_MMS(toolchange_settings.prime_speed)); - - // Cutting retraction - #if TOOLCHANGE_FS_WIPE_RETRACT - unscaled_e_move(-(TOOLCHANGE_FS_WIPE_RETRACT), MMM_TO_MMS(toolchange_settings.retract_speed)); - #endif - - // Cool down with fan - #if HAS_FAN && TOOLCHANGE_FS_FAN >= 0 - thermalManager.fan_speed[TOOLCHANGE_FS_FAN] = toolchange_settings.fan_speed; - gcode.dwell(SEC_TO_MS(toolchange_settings.fan_time)); - thermalManager.fan_speed[TOOLCHANGE_FS_FAN] = 0; - #endif + extruder_prime(); // Move back #if ENABLED(TOOLCHANGE_PARK) @@ -968,13 +1081,11 @@ void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_axis, 0. } #endif - // Cutting recover - unscaled_e_move(toolchange_settings.extra_resume + TOOLCHANGE_FS_WIPE_RETRACT, MMM_TO_MMS(toolchange_settings.unretract_speed)); - - // Resume at the old E position - current_position.e = destination.e; - sync_plan_position_e(); + extruder_cutting_recover(destination.e); // Cutting recover } + + FS_DEBUG("<<< tool_change_prime"); + } #endif // TOOLCHANGE_FILAMENT_SWAP @@ -1051,12 +1162,10 @@ void tool_change(const uint8_t new_tool, bool no_move/*=false*/) { TEMPORARY_BED_LEVELING_STATE(false); #endif - // First tool priming. To prime again, reboot the machine. + // First tool priming. To prime again, reboot the machine. -- Should only occur for first T0 after powerup! #if ENABLED(TOOLCHANGE_FS_PRIME_FIRST_USED) - static bool first_tool_is_primed = false; - if (new_tool == old_tool && !first_tool_is_primed && enable_first_prime) { + if (enable_first_prime && old_tool == 0 && new_tool == 0 && !extruder_was_primed[0]) { tool_change_prime(); - first_tool_is_primed = true; TERN_(TOOLCHANGE_FS_INIT_BEFORE_SWAP, toolchange_extruder_ready.set(old_tool)); // Primed and initialized } #endif @@ -1082,20 +1191,17 @@ void tool_change(const uint8_t new_tool, bool no_move/*=false*/) { // Unload / Retract #if ENABLED(TOOLCHANGE_FILAMENT_SWAP) - const bool should_swap = can_move_away && toolchange_settings.swap_length, - too_cold = TERN0(PREVENT_COLD_EXTRUSION, - !DEBUGGING(DRYRUN) && (thermalManager.targetTooColdToExtrude(old_tool) || thermalManager.targetTooColdToExtrude(new_tool)) - ); + const bool should_swap = can_move_away && toolchange_settings.swap_length; if (should_swap) { - if (too_cold) { - SERIAL_ECHO_MSG(STR_ERR_HOTEND_TOO_COLD); + if (too_cold(old_tool)) { + // If SingleNozzle setup is too cold, unable to perform tool_change. if (ENABLED(SINGLENOZZLE)) { active_extruder = new_tool; return; } } - else { - // For first new tool, change without unloading the old. 'Just prime/init the new' - if (TERN1(TOOLCHANGE_FS_PRIME_FIRST_USED, first_tool_is_primed)) - unscaled_e_move(-toolchange_settings.swap_length, MMM_TO_MMS(toolchange_settings.retract_speed)); - TERN_(TOOLCHANGE_FS_PRIME_FIRST_USED, first_tool_is_primed = true); // The first new tool will be primed by toolchanging + else if (extruder_was_primed[old_tool]) { + // Retract the old extruder if it was previously primed + // To-Do: Should SingleNozzle always retract? + FS_DEBUG("Retracting Filament for T", old_tool, ". | Distance: ", toolchange_settings.swap_length, " | Speed: ", MMM_TO_MMS(toolchange_settings.retract_speed), "mm/s"); + unscaled_e_move(-toolchange_settings.swap_length, MMM_TO_MMS(toolchange_settings.retract_speed)); } } #endif @@ -1210,36 +1316,8 @@ void tool_change(const uint8_t new_tool, bool no_move/*=false*/) { #endif #if ENABLED(TOOLCHANGE_FILAMENT_SWAP) - if (should_swap && !too_cold) { - - float fr = toolchange_settings.unretract_speed; - - #if ENABLED(TOOLCHANGE_FS_INIT_BEFORE_SWAP) - if (!toolchange_extruder_ready[new_tool]) { - toolchange_extruder_ready.set(new_tool); - fr = toolchange_settings.prime_speed; // Next move is a prime - unscaled_e_move(0, MMM_TO_MMS(fr)); // Init planner with 0 length move - } - #endif - - // Unretract (or Prime) - unscaled_e_move(toolchange_settings.swap_length, MMM_TO_MMS(fr)); - - // Extra Prime - unscaled_e_move(toolchange_settings.extra_prime, MMM_TO_MMS(toolchange_settings.prime_speed)); - - // Cutting retraction - #if TOOLCHANGE_FS_WIPE_RETRACT - unscaled_e_move(-(TOOLCHANGE_FS_WIPE_RETRACT), MMM_TO_MMS(toolchange_settings.retract_speed)); - #endif - - // Cool down with fan - #if HAS_FAN && TOOLCHANGE_FS_FAN >= 0 - thermalManager.fan_speed[TOOLCHANGE_FS_FAN] = toolchange_settings.fan_speed; - gcode.dwell(SEC_TO_MS(toolchange_settings.fan_time)); - thermalManager.fan_speed[TOOLCHANGE_FS_FAN] = 0; - #endif - } + if (should_swap && !too_cold(active_extruder)) + extruder_prime(); // Prime selected Extruder #endif // Prevent a move outside physical bounds @@ -1280,11 +1358,8 @@ void tool_change(const uint8_t new_tool, bool no_move/*=false*/) { else DEBUG_ECHOLNPGM("Move back skipped"); #if ENABLED(TOOLCHANGE_FILAMENT_SWAP) - if (should_swap && !too_cold) { - // Cutting recover - unscaled_e_move(toolchange_settings.extra_resume + TOOLCHANGE_FS_WIPE_RETRACT, MMM_TO_MMS(toolchange_settings.unretract_speed)); - current_position.e = 0; - sync_plan_position_e(); // New extruder primed and set to 0 + if (should_swap && !too_cold(active_extruder)) { + extruder_cutting_recover(0); // New extruder primed and set to 0 // Restart Fan #if HAS_FAN && TOOLCHANGE_FS_FAN >= 0 @@ -1342,7 +1417,7 @@ void tool_change(const uint8_t new_tool, bool no_move/*=false*/) { #endif } - SERIAL_ECHO_MSG(STR_ACTIVE_EXTRUDER, active_extruder); + SERIAL_ECHOLNPGM(STR_ACTIVE_EXTRUDER, active_extruder); #endif // HAS_MULTI_EXTRUDER } diff --git a/Marlin/src/module/tool_change.h b/Marlin/src/module/tool_change.h index 409be1e96945..864062f572e3 100644 --- a/Marlin/src/module/tool_change.h +++ b/Marlin/src/module/tool_change.h @@ -29,24 +29,30 @@ typedef struct { #if ENABLED(TOOLCHANGE_FILAMENT_SWAP) - float swap_length, extra_prime, extra_resume; - int16_t prime_speed, retract_speed, unretract_speed, fan, fan_speed, fan_time; + float swap_length; // M217 S + float extra_prime; // M217 E + float extra_resume; // M217 B + int16_t prime_speed; // M217 P + int16_t retract_speed; // M217 R + int16_t unretract_speed; // M217 U + uint8_t fan_speed; // M217 F + uint8_t fan_time; // M217 D #endif #if ENABLED(TOOLCHANGE_PARK) - bool enable_park; - xyz_pos_t change_point; + bool enable_park; // M217 W + xyz_pos_t change_point; // M217 X Y I J K C H O #endif - float z_raise; + float z_raise; // M217 Z } toolchange_settings_t; extern toolchange_settings_t toolchange_settings; - #if ENABLED(TOOLCHANGE_FILAMENT_SWAP) - void tool_change_prime(); + #if ENABLED(TOOLCHANGE_FS_PRIME_FIRST_USED) + extern bool enable_first_prime; // M217 V #endif - #if ENABLED(TOOLCHANGE_FS_PRIME_FIRST_USED) - extern bool enable_first_prime; + #if ENABLED(TOOLCHANGE_FILAMENT_SWAP) + void tool_change_prime(); // Prime the currently selected extruder #endif #if ENABLED(TOOLCHANGE_FS_INIT_BEFORE_SWAP) diff --git a/buildroot/tests/BIGTREE_GTR_V1_0 b/buildroot/tests/BIGTREE_GTR_V1_0 index 4f1a4a690a9c..919822733b00 100755 --- a/buildroot/tests/BIGTREE_GTR_V1_0 +++ b/buildroot/tests/BIGTREE_GTR_V1_0 @@ -24,7 +24,7 @@ opt_set MOTHERBOARD BOARD_BTT_GTR_V1_0 SERIAL_PORT -1 \ EXTRUDERS 5 TEMP_SENSOR_1 1 TEMP_SENSOR_2 1 TEMP_SENSOR_3 1 TEMP_SENSOR_4 1 \ NUM_Z_STEPPER_DRIVERS 4 \ DEFAULT_Kp_LIST '{ 22.2, 20.0, 21.0, 19.0, 18.0 }' DEFAULT_Ki_LIST '{ 1.08 }' DEFAULT_Kd_LIST '{ 114.0, 112.0, 110.0, 108.0 }' -opt_enable TOOLCHANGE_FILAMENT_SWAP TOOLCHANGE_MIGRATION_FEATURE TOOLCHANGE_FS_INIT_BEFORE_SWAP TOOLCHANGE_FS_PRIME_FIRST_USED \ +opt_enable TOOLCHANGE_FILAMENT_SWAP TOOLCHANGE_MIGRATION_FEATURE TOOLCHANGE_FS_SLOW_FIRST_PRIME TOOLCHANGE_FS_PRIME_FIRST_USED \ PID_PARAMS_PER_HOTEND Z_MULTI_ENDSTOPS exec_test $1 $2 "BigTreeTech GTR | 6 Extruders | Quad Z + Endstops" "$3"