diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h
index d20432f683a35..588b0933f719f 100644
--- a/Marlin/Configuration_adv.h
+++ b/Marlin/Configuration_adv.h
@@ -1169,7 +1169,8 @@
//#define CALIBRATION_SCRIPT_PRE "M117 Starting Auto-Calibration\nT0\nG28\nG12\nM117 Calibrating..."
//#define CALIBRATION_SCRIPT_POST "M500\nM117 Calibration data saved"
-
+ //#define CALIBRATION_ALLOW_XY_IS_CORE // Backlash & calibration allowed for CORE X/Y axis
+ //#define CALIBRATION_TOOLCHANGE_FEATURE_DISABLED // Disable prime, swap, moves and park during calibration
#define CALIBRATION_MEASUREMENT_RESOLUTION 0.01 // mm
#define CALIBRATION_FEEDRATE_SLOW 60 // mm/min
@@ -2493,10 +2494,8 @@
// Z raise distance for tool-change, as needed for some extruders
#define TOOLCHANGE_ZRAISE 2 // (mm)
//#define TOOLCHANGE_ZRAISE_BEFORE_RETRACT // Apply raise before swap retraction (if enabled)
- //#define TOOLCHANGE_NO_RETURN // Never return to previous position on tool-change
- #if ENABLED(TOOLCHANGE_NO_RETURN)
- //#define EVENT_GCODE_AFTER_TOOLCHANGE "G12X" // Extra G-code to run after tool-change
- #endif
+ //#define TOOLCHANGE_NO_RETURN_DEFAULT_ON // M216 R 0/1 Never return to previous position on tool-change
+ //#define EVENT_GCODE_AFTER_TOOLCHANGE "G12X" // Extra G-code to run after tool-change
/**
* Extra G-code to run while executing tool-change commands. Can be used to use an additional
@@ -2540,13 +2539,13 @@
//#define TOOLCHANGE_FS_SLOW_FIRST_PRIME
/**
- * Prime T0 the first time T0 is sent to the printer:
+ * Prime Txxx the first time Txxx 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
+ #define TOOLCHANGE_FS_PRIME_FIRST_USED 1 // 0-1
/**
* Tool Change Migration
@@ -2559,12 +2558,26 @@
* - Switch to a different nozzle on an extruder jam
*/
#define TOOLCHANGE_MIGRATION_FEATURE
-
+ #if ENABLED(TOOLCHANGE_MIGRATION_FEATURE)
+ //Override toolchange settings (To use settings for prime tower and for Migration outside the bed with long prime and cooling)
+ #define MIGRATION_OVERRIDE_TOOLCHANGE_SETTINGS
+ #if ENABLED(MIGRATION_OVERRIDE_TOOLCHANGE_SETTINGS)
+ // Longer prime to clean out
+ #define MIGRATION_FS_EXTRA_PRIME 50 // (mm) Extra priming length
+ #define MIGRATION_FS_WIPE_RETRACT 3 // (mm) Retract before cooling for less stringing, better wipe, etc.
+ // Cool after prime to reduce stringing
+ #ifdef TOOLCHANGE_FS_FAN
+ #define MIGRATION_FS_FAN_SPEED 255 // 0-255
+ #define MIGRATION_FS_FAN_TIME 10 // (seconds)
+ #endif
+ #endif // MIGRATION_OVERRIDE_TOOLCHANGE_SETTINGS
+ #endif //ENABLED(TOOLCHANGE_MIGRATION_FEATURE)
#endif
/**
* Position to park head during tool change.
* Doesn't apply to SWITCHING_TOOLHEAD, DUAL_X_CARRIAGE, or PARKING_EXTRUDER
+ * M216 Gcodes (See m216.cpp for settings documentation)
*/
//#define TOOLCHANGE_PARK
#if ENABLED(TOOLCHANGE_PARK)
@@ -2572,6 +2585,9 @@
#define TOOLCHANGE_PARK_XY_FEEDRATE 6000 // (mm/min)
//#define TOOLCHANGE_PARK_X_ONLY // X axis only move
//#define TOOLCHANGE_PARK_Y_ONLY // Y axis only move
+ #if ENABLED(TOOLCHANGE_MIGRATION_FEATURE)
+ #define TOOLCHANGE_MIGRATION_ALWAYS_PARK
+ #endif
#endif
#endif // HAS_MULTI_EXTRUDER
diff --git a/Marlin/src/gcode/calibrate/G425.cpp b/Marlin/src/gcode/calibrate/G425.cpp
index a22608f5b42b5..10bdd236a77b1 100644
--- a/Marlin/src/gcode/calibrate/G425.cpp
+++ b/Marlin/src/gcode/calibrate/G425.cpp
@@ -163,7 +163,21 @@ inline void park_above_object(measurements_t &m, const float uncertainty) {
inline void set_nozzle(measurements_t &m, const uint8_t extruder) {
if (extruder != active_extruder) {
park_above_object(m, CALIBRATION_MEASUREMENT_UNKNOWN);
- tool_change(extruder);
+ #if ENABLED(CALIBRATION_TOOLCHANGE_FEATURE_DISABLED)
+ toolchange_settings_t tmp0 = {0};
+ REMEMBER(tmp, toolchange_settings);
+ toolchange_settings = tmp0;
+ tool_change(extruder);
+ RESTORE(tmp);
+ /* or
+ toolchange_settings_t tmp0 = {0},
+ tmp = toolchange_settings;
+ toolchange_settings = tmp0;
+ tool_change(extruder);
+ toolchange_settings = tmp;*/
+ #else
+ tool_change(extruder);
+ #endif
}
}
#endif
@@ -268,10 +282,10 @@ inline void probe_side(measurements_t &m, const float uncertainty, const side_t
#define _PCASE(N) _ACASE(N, N##MINIMUM, N##MAXIMUM)
switch (side) {
- #if AXIS_CAN_CALIBRATE(X)
+ #if HAS_X_AXIS && ( AXIS_CAN_CALIBRATE(X) || CALIBRATION_ALLOW_XY_IS_CORE)
_ACASE(X, RIGHT, LEFT);
#endif
- #if HAS_Y_AXIS && AXIS_CAN_CALIBRATE(Y)
+ #if HAS_Y_AXIS && ( AXIS_CAN_CALIBRATE(Y) || CALIBRATION_ALLOW_XY_IS_CORE)
_ACASE(Y, BACK, FRONT);
#endif
#if HAS_Z_AXIS && AXIS_CAN_CALIBRATE(Z)
diff --git a/Marlin/src/gcode/config/M216.cpp b/Marlin/src/gcode/config/M216.cpp
new file mode 100644
index 0000000000000..9078b4f76a590
--- /dev/null
+++ b/Marlin/src/gcode/config/M216.cpp
@@ -0,0 +1,101 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+#include "../../inc/MarlinConfigPre.h"
+
+#if HAS_MULTI_EXTRUDER && ENABLED(TOOLCHANGE_PARK)
+
+#include "../gcode.h"
+#include "../../module/tool_change.h"
+#include "../../MarlinCore.h" // for SP_X_STR, etc.
+
+/**
+ * M216 - Set Tool change Park parameters
+ *
+ * // Tool change Park settings
+ * P[linear] 0/1 Enable park
+ * R[linear] 0/1 Enable return to previous position before park
+ * X[linear] Park X
+ * Y[linear] Park Y
+ * I[linear] Park I (Requires NUM_AXES >= 4)
+ * J[linear] Park J (Requires NUM_AXES >= 5)
+ * K[linear] Park K (Requires NUM_AXES >= 6)
+ * C[linear] Park U (Requires NUM_AXES >= 7)
+ * H[linear] Park V (Requires NUM_AXES >= 8)
+ * O[linear] Park W (Requires NUM_AXES >= 9)
+ *
+ */
+void GcodeSuite::M216() {
+
+ if (parser.seenval('P')) { toolchange_settings.enable_park = parser.value_linear_units(); }
+ if (parser.seenval('R')) { toolchange_settings.no_return = parser.value_linear_units(); }
+ if (parser.seenval('X')) { const int16_t v = parser.value_linear_units(); toolchange_settings.change_point.x = constrain(v, X_MIN_POS, X_MAX_POS); }
+ #if HAS_Y_AXIS
+ if (parser.seenval('Y')) { const int16_t v = parser.value_linear_units(); toolchange_settings.change_point.y = constrain(v, Y_MIN_POS, Y_MAX_POS); }
+ #endif
+ #if HAS_I_AXIS
+ if (parser.seenval('I')) { const int16_t v = parser.TERN(AXIS4_ROTATES, value_int, value_linear_units)(); toolchange_settings.change_point.i = constrain(v, I_MIN_POS, I_MAX_POS); }
+ #endif
+ #if HAS_J_AXIS
+ if (parser.seenval('J')) { const int16_t v = parser.TERN(AXIS5_ROTATES, value_int, value_linear_units)(); toolchange_settings.change_point.j = constrain(v, J_MIN_POS, J_MAX_POS); }
+ #endif
+ #if HAS_K_AXIS
+ if (parser.seenval('K')) { const int16_t v = parser.TERN(AXIS6_ROTATES, value_int, value_linear_units)(); toolchange_settings.change_point.k = constrain(v, K_MIN_POS, K_MAX_POS); }
+ #endif
+ #if HAS_U_AXIS
+ if (parser.seenval('C')) { const int16_t v = parser.TERN(AXIS7_ROTATES, value_int, value_linear_units)(); toolchange_settings.change_point.u = constrain(v, U_MIN_POS, U_MAX_POS); }
+ #endif
+ #if HAS_V_AXIS
+ if (parser.seenval('H')) { const int16_t v = parser.TERN(AXIS8_ROTATES, value_int, value_linear_units)(); toolchange_settings.change_point.v = constrain(v, V_MIN_POS, V_MAX_POS); }
+ #endif
+ #if HAS_W_AXIS
+ if (parser.seenval('O')) { const int16_t v = parser.TERN(AXIS9_ROTATES, value_int, value_linear_units)(); toolchange_settings.change_point.w = constrain(v, W_MIN_POS, W_MAX_POS); }
+ #endif
+
+ M216_report();
+}
+
+void GcodeSuite::M216_report(const bool forReplay/*=true*/) {
+
+ SERIAL_ECHOPGM(" M216");
+
+ SERIAL_ECHOPGM(" P", LINEAR_UNIT(toolchange_settings.enable_park));
+ SERIAL_ECHOPGM(" R", LINEAR_UNIT(toolchange_settings.no_return));
+ SERIAL_ECHOPGM_P(
+ SP_X_STR, LINEAR_UNIT(toolchange_settings.change_point.x)
+ #if HAS_Y_AXIS
+ , SP_Y_STR, LINEAR_UNIT(toolchange_settings.change_point.y)
+ #endif
+ #if SECONDARY_AXES >= 1
+ , 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
+ );
+}
+
+#endif // HAS_MULTI_EXTRUDER && ENABLED(TOOLCHANGE_PARK)
diff --git a/Marlin/src/gcode/config/M217.cpp b/Marlin/src/gcode/config/M217.cpp
index d6c0b0169917a..592991e899510 100644
--- a/Marlin/src/gcode/config/M217.cpp
+++ b/Marlin/src/gcode/config/M217.cpp
@@ -36,26 +36,21 @@
/**
* M217 - Set toolchange parameters
*
+ * // Tool change command
+ * Q Prime active tool and exit
+ * C[extruder] Reset specified (or active) extruder primed status (To prime on next T...)
+ *
* // Tool change settings
* S[linear] Swap length
* B[linear] Extra Swap resume length
* E[linear] Extra Prime length (as used by M217 Q)
- * G[linear] Cutting wipe retract length (<=100mm)
+ * W[linear] Cutting wipe retract length (<=100mm)
* R[linear/min] Retract speed
* U[linear/min] UnRetract speed
* P[linear/min] Prime speed
- * Q[extruder] Reset specified (or active) extruder primed status (To prime on next T...)
* V[linear] 0/1 Enable auto prime first extruder used
- * W[linear] 0/1 Enable park
- * X[linear] Park X (Requires TOOLCHANGE_PARK)
- * Y[linear] Park Y (Requires TOOLCHANGE_PARK and NUM_AXES >= 2)
- * 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
*
@@ -71,48 +66,27 @@ void GcodeSuite::M217() {
#if ENABLED(TOOLCHANGE_FILAMENT_SWAP)
static constexpr float max_extrude = TERN(PREVENT_LENGTHY_EXTRUDE, EXTRUDE_MAXLENGTH, 500);
- if (parser.seen('Q')) { const uint16_t v = parser.ushortval('Q', active_extruder); extruder_was_primed.clear(constrain(v, 0, EXTRUDERS - 1)); }
+ if (parser.seen('C')) { const uint16_t v = parser.ushortval('C', active_extruder); extruder_was_primed.clear(constrain(v, 0, EXTRUDERS - 1)); }
+ if (parser.seen('Q')) {
+ extruder_was_primed.clear(active_extruder);
+ REMEMBER(tmp, enable_first_prime_used);
+ enable_first_prime_used = true;
+ tool_change(active_extruder);
+ RESTORE(tmp);
+ return;
+ }
if (parser.seenval('S')) { const float v = parser.value_linear_units(); toolchange_settings.swap_length = constrain(v, 0, max_extrude); }
if (parser.seenval('B')) { const float v = parser.value_linear_units(); toolchange_settings.extra_resume = constrain(v, -10, 10); }
if (parser.seenval('E')) { const float v = parser.value_linear_units(); toolchange_settings.extra_prime = constrain(v, 0, max_extrude); }
if (parser.seenval('P')) { const int16_t v = parser.value_linear_units(); toolchange_settings.prime_speed = constrain(v, 10, 5400); }
- if (parser.seenval('G')) { const int16_t v = parser.value_linear_units(); toolchange_settings.wipe_retract = constrain(v, 0, 100); }
+ if (parser.seenval('W')) { const int16_t v = parser.value_linear_units(); toolchange_settings.wipe_retract = constrain(v, 0, 100); }
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 HAS_FAN && defined(TOOLCHANGE_FS_FAN)
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
-
- #if ENABLED(TOOLCHANGE_FS_PRIME_FIRST_USED)
- if (parser.seenval('V')) { enable_first_prime = parser.value_linear_units(); }
- #endif
-
- #if ENABLED(TOOLCHANGE_PARK)
- if (parser.seenval('W')) { toolchange_settings.enable_park = parser.value_linear_units(); }
- if (parser.seenval('X')) { const int16_t v = parser.value_linear_units(); toolchange_settings.change_point.x = constrain(v, X_MIN_POS, X_MAX_POS); }
- #if HAS_Y_AXIS
- if (parser.seenval('Y')) { const int16_t v = parser.value_linear_units(); toolchange_settings.change_point.y = constrain(v, Y_MIN_POS, Y_MAX_POS); }
- #endif
- #if HAS_I_AXIS
- if (parser.seenval('I')) { const int16_t v = parser.TERN(AXIS4_ROTATES, value_int, value_linear_units)(); toolchange_settings.change_point.i = constrain(v, I_MIN_POS, I_MAX_POS); }
- #endif
- #if HAS_J_AXIS
- if (parser.seenval('J')) { const int16_t v = parser.TERN(AXIS5_ROTATES, value_int, value_linear_units)(); toolchange_settings.change_point.j = constrain(v, J_MIN_POS, J_MAX_POS); }
- #endif
- #if HAS_K_AXIS
- if (parser.seenval('K')) { const int16_t v = parser.TERN(AXIS6_ROTATES, value_int, value_linear_units)(); toolchange_settings.change_point.k = constrain(v, K_MIN_POS, K_MAX_POS); }
- #endif
- #if HAS_U_AXIS
- if (parser.seenval('C')) { const int16_t v = parser.TERN(AXIS7_ROTATES, value_int, value_linear_units)(); toolchange_settings.change_point.u = constrain(v, U_MIN_POS, U_MAX_POS); }
- #endif
- #if HAS_V_AXIS
- if (parser.seenval('H')) { const int16_t v = parser.TERN(AXIS8_ROTATES, value_int, value_linear_units)(); toolchange_settings.change_point.v = constrain(v, V_MIN_POS, V_MAX_POS); }
- #endif
- #if HAS_W_AXIS
- if (parser.seenval('O')) { const int16_t v = parser.TERN(AXIS9_ROTATES, value_int, value_linear_units)(); toolchange_settings.change_point.w = constrain(v, W_MIN_POS, W_MAX_POS); }
- #endif
+ if (parser.seenval('V')) { enable_first_prime_used = parser.value_linear_units(); }
#endif
#if HAS_Z_AXIS
@@ -178,31 +152,7 @@ void GcodeSuite::M217_report(const bool forReplay/*=true*/) {
SERIAL_ECHOPGM(" A", migration.automode, " L", LINEAR_UNIT(migration.last));
#endif
- #if ENABLED(TOOLCHANGE_PARK)
- {
- SERIAL_ECHOPGM(" W", LINEAR_UNIT(toolchange_settings.enable_park));
- SERIAL_ECHOPGM_P(
- SP_X_STR, LINEAR_UNIT(toolchange_settings.change_point.x)
- #if HAS_Y_AXIS
- , SP_Y_STR, LINEAR_UNIT(toolchange_settings.change_point.y)
- #endif
- #if SECONDARY_AXES >= 1
- , 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
- );
- }
- #endif
-
- #if ENABLED(TOOLCHANGE_FS_PRIME_FIRST_USED)
- SERIAL_ECHOPGM(" V", LINEAR_UNIT(enable_first_prime));
- #endif
+ SERIAL_ECHOPGM(" V", LINEAR_UNIT(enable_first_prime_used));
#endif
diff --git a/Marlin/src/gcode/gcode.cpp b/Marlin/src/gcode/gcode.cpp
index 405e2d460ca8b..581d818a7c641 100644
--- a/Marlin/src/gcode/gcode.cpp
+++ b/Marlin/src/gcode/gcode.cpp
@@ -737,8 +737,12 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
case 211: M211(); break; // M211: Enable, Disable, and/or Report software endstops
#endif
+ #if HAS_MULTI_EXTRUDER && ENABLED(TOOLCHANGE_PARK)
+ case 216: M216(); break; // M216: Set Toolchange park parameters
+ #endif
+
#if HAS_MULTI_EXTRUDER
- case 217: M217(); break; // M217: Set filament swap parameters
+ case 217: M217(); break; // M217: Set Toolchange parameters
#endif
#if HAS_HOTEND_OFFSET
diff --git a/Marlin/src/gcode/gcode.h b/Marlin/src/gcode/gcode.h
index 2b15706395bd4..ea1c1a8f4761b 100644
--- a/Marlin/src/gcode/gcode.h
+++ b/Marlin/src/gcode/gcode.h
@@ -863,6 +863,10 @@ class GcodeSuite {
static void M211_report(const bool forReplay=true);
#if HAS_MULTI_EXTRUDER
+ #if ENABLED(TOOLCHANGE_PARK)
+ static void M216();
+ static void M216_report(const bool forReplay=true);
+ #endif
static void M217();
static void M217_report(const bool forReplay=true);
#endif
diff --git a/Marlin/src/module/settings.cpp b/Marlin/src/module/settings.cpp
index c8b43b485d7fa..9fcc33a0b7507 100644
--- a/Marlin/src/module/settings.cpp
+++ b/Marlin/src/module/settings.cpp
@@ -2870,26 +2870,23 @@ void MarlinSettings::reset() {
#if HAS_MULTI_EXTRUDER
#if ENABLED(TOOLCHANGE_FILAMENT_SWAP)
- toolchange_settings.swap_length = TOOLCHANGE_FS_LENGTH;
- toolchange_settings.extra_resume = TOOLCHANGE_FS_EXTRA_RESUME_LENGTH;
- toolchange_settings.retract_speed = TOOLCHANGE_FS_RETRACT_SPEED;
- toolchange_settings.unretract_speed = TOOLCHANGE_FS_UNRETRACT_SPEED;
- toolchange_settings.extra_prime = TOOLCHANGE_FS_EXTRA_PRIME;
- toolchange_settings.prime_speed = TOOLCHANGE_FS_PRIME_SPEED;
- toolchange_settings.wipe_retract = TOOLCHANGE_FS_WIPE_RETRACT;
+ toolchange_settings.swap_length = TOOLCHANGE_FS_LENGTH;
+ toolchange_settings.extra_resume = TOOLCHANGE_FS_EXTRA_RESUME_LENGTH;
+ toolchange_settings.retract_speed = TOOLCHANGE_FS_RETRACT_SPEED;
+ toolchange_settings.unretract_speed = TOOLCHANGE_FS_UNRETRACT_SPEED;
+ toolchange_settings.extra_prime = TOOLCHANGE_FS_EXTRA_PRIME;
+ toolchange_settings.prime_speed = TOOLCHANGE_FS_PRIME_SPEED;
+ toolchange_settings.wipe_retract = TOOLCHANGE_FS_WIPE_RETRACT;
#ifdef TOOLCHANGE_FS_FAN
toolchange_settings.fan_speed = TOOLCHANGE_FS_FAN_SPEED;
toolchange_settings.fan_time = TOOLCHANGE_FS_FAN_TIME;
#endif
+ enable_first_prime_used = !TOOLCHANGE_FS_PRIME_FIRST_USED;
#endif
-
- #if ENABLED(TOOLCHANGE_FS_PRIME_FIRST_USED)
- enable_first_prime = false;
- #endif
-
#if ENABLED(TOOLCHANGE_PARK)
constexpr xyz_pos_t tpxy = TOOLCHANGE_PARK_XY;
toolchange_settings.enable_park = true;
+ toolchange_settings.no_return = TERN(TOOLCHANGE_NO_RETURN_DEFAULT_ON, true, false);
toolchange_settings.change_point = tpxy;
#endif
diff --git a/Marlin/src/module/tool_change.cpp b/Marlin/src/module/tool_change.cpp
index b5174049323a9..85171159e3641 100644
--- a/Marlin/src/module/tool_change.cpp
+++ b/Marlin/src/module/tool_change.cpp
@@ -39,6 +39,7 @@
#if HAS_MULTI_EXTRUDER
toolchange_settings_t toolchange_settings; // Initialized by settings.load()
+ bool enable_first_prime_used ;
#endif
#if ENABLED(TOOLCHANGE_MIGRATION_FEATURE)
@@ -902,13 +903,6 @@ void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_axis, 0.
#define FS_DEBUG(...) NOOP
#endif
- // Define any variables required
- 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 && defined(TOOLCHANGE_FS_FAN)
@@ -952,6 +946,8 @@ void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_axis, 0.
}
}
+ Flags extruder_did_first_prime; // Extruders first priming status
+
/**
* Prime the currently selected extruder (Filament loading only)
*
@@ -972,7 +968,6 @@ void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_axis, 0.
/**
* 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.
@@ -1015,6 +1010,9 @@ void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_axis, 0.
if (toolchange_settings.fan_time) filament_swap_cooling();
}
+ // Define any variables required
+ Flags extruder_was_primed; // Extruders primed status
+
#endif // TOOLCHANGE_FILAMENT_SWAP
/**
@@ -1088,14 +1086,15 @@ 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. -- Should only occur for first T0 after powerup!
- #if ENABLED(TOOLCHANGE_FS_PRIME_FIRST_USED)
- const bool can_prime_T0 = (enable_first_prime && old_tool == 0 && new_tool == 0 && !extruder_was_primed[0]);
- if (can_prime_T0) no_move = false;
+ // First tool priming. To prime again, use M217 Q. -- Should only occur for first Txxx after powerup!
+ #if ENABLED(TOOLCHANGE_FILAMENT_SWAP)
+ const bool can_prime_tool = (!extruder_was_primed[new_tool] && enable_first_prime_used);
+ if (can_prime_tool) no_move = false;
#endif
+
const bool can_move_away = !no_move && !idex_full_control;
- if (new_tool != old_tool || TERN0(PARKING_EXTRUDER, extruder_parked) || TERN0(TOOLCHANGE_FS_PRIME_FIRST_USED, can_prime_T0)) { // PARKING_EXTRUDER may need to attach old_tool when homing
+ if (new_tool != old_tool || TERN0(PARKING_EXTRUDER, extruder_parked) || TERN0(TOOLCHANGE_FILAMENT_SWAP,can_prime_tool)) { // PARKING_EXTRUDER may need to attach old_tool when homing
destination = current_position;
#if HAS_FAN && defined(TOOLCHANGE_FS_FAN)
@@ -1126,7 +1125,7 @@ void tool_change(const uint8_t new_tool, bool no_move/*=false*/) {
// If SingleNozzle setup is too cold, unable to perform tool_change.
if (ENABLED(SINGLENOZZLE)) { active_extruder = new_tool; return; }
}
- else if (extruder_was_primed[old_tool]) {
+ else if (extruder_was_primed[old_tool] || extruder_did_first_prime[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");
@@ -1258,27 +1257,18 @@ void tool_change(const uint8_t new_tool, bool no_move/*=false*/) {
// Should the nozzle move back to the old position?
if (can_move_away) {
- #if ENABLED(TOOLCHANGE_NO_RETURN)
- // Just move back down
- DEBUG_ECHOLNPGM("Move back Z only");
-
- if (TERN1(TOOLCHANGE_PARK, toolchange_settings.enable_park))
- do_blocking_move_to_z(destination.z, planner.settings.max_feedrate_mm_s[Z_AXIS]);
-
+ #if ENABLED(TOOLCHANGE_PARK)
+ // Move back or not, to the original position
+ if (toolchange_settings.enable_park && !toolchange_settings.no_return) {
+ DEBUG_POS("Move back", destination);
+ do_blocking_move_to_xy(destination, MMM_TO_MMS(TOOLCHANGE_PARK_XY_FEEDRATE));
+ }
#else
- // Move back to the original (or adjusted) position
- DEBUG_POS("Move back", destination);
-
- #if ENABLED(TOOLCHANGE_PARK)
- if (toolchange_settings.enable_park) do_blocking_move_to_xy_z(destination, destination.z, MMM_TO_MMS(TOOLCHANGE_PARK_XY_FEEDRATE));
- #else
- do_blocking_move_to_xy(destination, planner.settings.max_feedrate_mm_s[X_AXIS]);
- do_blocking_move_to_z(destination.z, planner.settings.max_feedrate_mm_s[Z_AXIS]);
- #endif
-
+ do_blocking_move_to_xy(destination, planner.settings.max_feedrate_mm_s[X_AXIS]);
#endif
+ DEBUG_ECHOLNPGM("Move back Z");
+ do_blocking_move_to_z(destination.z, planner.settings.max_feedrate_mm_s[Z_AXIS]);
}
-
else DEBUG_ECHOLNPGM("Move back skipped");
#if ENABLED(TOOLCHANGE_FILAMENT_SWAP)
@@ -1414,9 +1404,30 @@ void tool_change(const uint8_t new_tool, bool no_move/*=false*/) {
// Migrate Linear Advance K factor to the new extruder
TERN_(LIN_ADVANCE, planner.extruder_advance_K[active_extruder] = planner.extruder_advance_K[migration_extruder]);
+ #if BOTH(TOOLCHANGE_MIGRATION_FEATURE,MIGRATION_OVERRIDE_TOOLCHANGE_SETTINGS)
+ REMEMBER(tmp_mig_override, toolchange_settings);
+ TERN_(TOOLCHANGE_MIGRATION_ALWAYS_PARK, toolchange_settings.enable_park = true);
+ #ifdef MIGRATION_FS_EXTRA_PRIME
+ toolchange_settings.extra_prime = MIGRATION_FS_EXTRA_PRIME ;
+ #endif
+ #ifdef MIGRATION_FS_WIPE_RETRACT
+ toolchange_settings.wipe_retract = MIGRATION_FS_WIPE_RETRACT ;
+ #endif
+ #ifdef MIGRATION_FS_FAN_SPEED
+ toolchange_settings.fan_speed = MIGRATION_FS_FAN_SPEED ;
+ #endif
+ #ifdef MIGRATION_FS_FAN_TIME
+ toolchange_settings.fan_time = MIGRATION_FS_FAN_TIME ;
+ #endif
+ #endif
+
// Perform the tool change
tool_change(migration_extruder);
+ #if BOTH(TOOLCHANGE_MIGRATION_FEATURE,MIGRATION_OVERRIDE_TOOLCHANGE_SETTINGS)
+ RESTORE(tmp_mig_override);
+ #endif
+
// Retract if previously retracted
#if ENABLED(FWRETRACT)
if (fwretract.retracted[active_extruder])
diff --git a/Marlin/src/module/tool_change.h b/Marlin/src/module/tool_change.h
index 39c23a33d4aa2..262ba34867748 100644
--- a/Marlin/src/module/tool_change.h
+++ b/Marlin/src/module/tool_change.h
@@ -33,27 +33,24 @@
float extra_prime; // M217 E
float extra_resume; // M217 B
int16_t prime_speed; // M217 P
- int16_t wipe_retract; // M217 G
+ int16_t wipe_retract; // M217 W
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; // M217 W
- xyz_pos_t change_point; // M217 X Y I J K C H O
+ bool enable_park; // M216 P
+ bool no_return; // M216 R
+ xyz_pos_t change_point; // M216 X Y I J K C H O
#endif
float z_raise; // M217 Z
} toolchange_settings_t;
extern toolchange_settings_t toolchange_settings;
- #if ENABLED(TOOLCHANGE_FS_PRIME_FIRST_USED)
- extern bool enable_first_prime; // M217 V
- #endif
-
- #if ENABLED(TOOLCHANGE_FILAMENT_SWAP)
- extern Flags extruder_was_primed; // Extruders primed status
+ #if ENABLED(TOOLCHANGE_FS_INIT_BEFORE_SWAP)
+ extern Flags toolchange_extruder_ready;
#endif
#if ENABLED(TOOLCHANGE_MIGRATION_FEATURE)
@@ -129,3 +126,7 @@
* previous tool out of the way and the new tool into place.
*/
void tool_change(const uint8_t tmp_extruder, bool no_move=false);
+
+// Define any variables required
+extern Flags extruder_was_primed; // Extruders primed status
+extern bool enable_first_prime_used ; // M217 V