🐛 Fix Tool Change priming (#21142)
Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
This commit is contained in:
parent
e2353be24f
commit
6ee34331b7
|
@ -2494,12 +2494,16 @@
|
||||||
#define TOOLCHANGE_FS_FAN_SPEED 255 // 0-255
|
#define TOOLCHANGE_FS_FAN_SPEED 255 // 0-255
|
||||||
#define TOOLCHANGE_FS_FAN_TIME 10 // (seconds)
|
#define TOOLCHANGE_FS_FAN_TIME 10 // (seconds)
|
||||||
|
|
||||||
// Swap uninitialized extruder (using TOOLCHANGE_FS_PRIME_SPEED feedrate)
|
// Use TOOLCHANGE_FS_PRIME_SPEED feedrate the first time each extruder is primed
|
||||||
// (May break filament if not retracted beforehand.)
|
//#define TOOLCHANGE_FS_SLOW_FIRST_PRIME
|
||||||
//#define TOOLCHANGE_FS_INIT_BEFORE_SWAP
|
|
||||||
|
|
||||||
// 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
|
//#define TOOLCHANGE_FS_PRIME_FIRST_USED
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -34,18 +34,18 @@
|
||||||
#include "../../MarlinCore.h" // for SP_X_STR, etc.
|
#include "../../MarlinCore.h" // for SP_X_STR, etc.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* M217 - Set SINGLENOZZLE toolchange parameters
|
* M217 - Set toolchange parameters
|
||||||
*
|
*
|
||||||
* // Tool change command
|
* // Tool change command
|
||||||
* Q Prime active tool and exit
|
* Q Prime active tool and exit
|
||||||
*
|
*
|
||||||
* // Tool change settings
|
* // Tool change settings
|
||||||
* S[linear] Swap length
|
* S[linear] Swap length
|
||||||
* B[linear] Extra Swap length
|
* B[linear] Extra Swap resume length
|
||||||
* E[linear] Prime length
|
* E[linear] Extra Prime length (as used by M217 Q)
|
||||||
* P[linear/m] Prime speed
|
* P[linear/min] Prime speed
|
||||||
* R[linear/m] Retract speed
|
* R[linear/min] Retract speed
|
||||||
* U[linear/m] UnRetract speed
|
* U[linear/min] UnRetract speed
|
||||||
* V[linear] 0/1 Enable auto prime first extruder used
|
* V[linear] 0/1 Enable auto prime first extruder used
|
||||||
* W[linear] 0/1 Enable park & Z Raise
|
* W[linear] 0/1 Enable park & Z Raise
|
||||||
* X[linear] Park X (Requires TOOLCHANGE_PARK)
|
* X[linear] Park X (Requires TOOLCHANGE_PARK)
|
||||||
|
@ -57,8 +57,8 @@
|
||||||
* H[linear] Park V (Requires TOOLCHANGE_PARK and NUM_AXES >= 8)
|
* H[linear] Park V (Requires TOOLCHANGE_PARK and NUM_AXES >= 8)
|
||||||
* O[linear] Park W (Requires TOOLCHANGE_PARK and NUM_AXES >= 9)
|
* O[linear] Park W (Requires TOOLCHANGE_PARK and NUM_AXES >= 9)
|
||||||
* Z[linear] Z Raise
|
* Z[linear] Z Raise
|
||||||
* F[linear] Fan Speed 0-255
|
* F[speed] Fan Speed 0-255
|
||||||
* G[linear/s] Fan time
|
* D[seconds] Fan time
|
||||||
*
|
*
|
||||||
* Tool migration settings
|
* Tool migration settings
|
||||||
* A[0|1] Enable auto-migration on runout
|
* 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('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 (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 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('F')) { const uint16_t v = parser.value_ushort(); 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('D')) { const uint16_t v = parser.value_ushort(); toolchange_settings.fan_time = constrain(v, 1, 30); }
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -171,7 +171,7 @@ void GcodeSuite::M217_report(const bool forReplay/*=true*/) {
|
||||||
SERIAL_ECHOPGM(" R", LINEAR_UNIT(toolchange_settings.retract_speed),
|
SERIAL_ECHOPGM(" R", LINEAR_UNIT(toolchange_settings.retract_speed),
|
||||||
" U", LINEAR_UNIT(toolchange_settings.unretract_speed),
|
" U", LINEAR_UNIT(toolchange_settings.unretract_speed),
|
||||||
" F", toolchange_settings.fan_speed,
|
" F", toolchange_settings.fan_speed,
|
||||||
" G", toolchange_settings.fan_time);
|
" D", toolchange_settings.fan_time);
|
||||||
|
|
||||||
#if ENABLED(TOOLCHANGE_MIGRATION_FEATURE)
|
#if ENABLED(TOOLCHANGE_MIGRATION_FEATURE)
|
||||||
SERIAL_ECHOPGM(" A", migration.automode);
|
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)
|
, SP_Y_STR, LINEAR_UNIT(toolchange_settings.change_point.y)
|
||||||
#endif
|
#endif
|
||||||
#if SECONDARY_AXES >= 1
|
#if SECONDARY_AXES >= 1
|
||||||
, LIST_N(DOUBLE(SECONDARY_AXES),
|
, LIST_N(DOUBLE(SECONDARY_AXES)
|
||||||
PSTR(" I"), I_AXIS_UNIT(toolchange_settings.change_point.i),
|
, SP_I_STR, I_AXIS_UNIT(toolchange_settings.change_point.i)
|
||||||
PSTR(" J"), J_AXIS_UNIT(toolchange_settings.change_point.j),
|
, SP_J_STR, J_AXIS_UNIT(toolchange_settings.change_point.j)
|
||||||
PSTR(" K"), K_AXIS_UNIT(toolchange_settings.change_point.k),
|
, SP_K_STR, K_AXIS_UNIT(toolchange_settings.change_point.k)
|
||||||
SP_C_STR, U_AXIS_UNIT(toolchange_settings.change_point.u),
|
, SP_C_STR, U_AXIS_UNIT(toolchange_settings.change_point.u)
|
||||||
PSTR(" H"), V_AXIS_UNIT(toolchange_settings.change_point.v),
|
, PSTR(" H"), V_AXIS_UNIT(toolchange_settings.change_point.v)
|
||||||
PSTR(" O"), W_AXIS_UNIT(toolchange_settings.change_point.w)
|
, PSTR(" O"), W_AXIS_UNIT(toolchange_settings.change_point.w)
|
||||||
)
|
)
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
|
|
|
@ -712,7 +712,7 @@
|
||||||
* Number of Primary Linear Axes (e.g., XYZ)
|
* Number of Primary Linear Axes (e.g., XYZ)
|
||||||
* X, XY, or XYZ axes. Excluding duplicate axes (X2, Y2. Z2. Z3, Z4)
|
* 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
|
#define PRIMARY_LINEAR_AXES 3
|
||||||
#else
|
#else
|
||||||
#define PRIMARY_LINEAR_AXES NUM_AXES
|
#define PRIMARY_LINEAR_AXES NUM_AXES
|
||||||
|
|
|
@ -390,6 +390,8 @@
|
||||||
#error "ENDSTOP_NOISE_FILTER is now ENDSTOP_NOISE_THRESHOLD [2-7]."
|
#error "ENDSTOP_NOISE_FILTER is now ENDSTOP_NOISE_THRESHOLD [2-7]."
|
||||||
#elif defined(RETRACT_ZLIFT)
|
#elif defined(RETRACT_ZLIFT)
|
||||||
#error "RETRACT_ZLIFT is now RETRACT_ZRAISE."
|
#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)
|
#elif defined(TOOLCHANGE_PARK_ZLIFT) || defined(TOOLCHANGE_UNPARK_ZLIFT)
|
||||||
#error "TOOLCHANGE_PARK_ZLIFT and TOOLCHANGE_UNPARK_ZLIFT are now TOOLCHANGE_ZRAISE."
|
#error "TOOLCHANGE_PARK_ZLIFT and TOOLCHANGE_UNPARK_ZLIFT are now TOOLCHANGE_ZRAISE."
|
||||||
#elif defined(SINGLENOZZLE_TOOLCHANGE_ZRAISE)
|
#elif defined(SINGLENOZZLE_TOOLCHANGE_ZRAISE)
|
||||||
|
|
|
@ -122,8 +122,8 @@ void menu_advanced_settings();
|
||||||
EDIT_ITEM_FAST(int4, MSG_SINGLENOZZLE_UNRETRACT_SPEED, &toolchange_settings.unretract_speed, 10, 5400);
|
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(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_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(uint8, 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_TIME, &toolchange_settings.fan_time, 1, 30);
|
||||||
#endif
|
#endif
|
||||||
EDIT_ITEM(float3, MSG_TOOL_CHANGE_ZLIFT, &toolchange_settings.z_raise, 0, 10);
|
EDIT_ITEM(float3, MSG_TOOL_CHANGE_ZLIFT, &toolchange_settings.z_raise, 0, 10);
|
||||||
END_MENU();
|
END_MENU();
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include "../MarlinCore.h"
|
#include "../MarlinCore.h"
|
||||||
|
|
||||||
//#define DEBUG_TOOL_CHANGE
|
//#define DEBUG_TOOL_CHANGE
|
||||||
|
//#define DEBUG_TOOLCHANGE_FILAMENT_SWAP
|
||||||
|
|
||||||
#define DEBUG_OUT ENABLED(DEBUG_TOOL_CHANGE)
|
#define DEBUG_OUT ENABLED(DEBUG_TOOL_CHANGE)
|
||||||
#include "../core/debug_out.h"
|
#include "../core/debug_out.h"
|
||||||
|
@ -42,7 +43,6 @@
|
||||||
|
|
||||||
#if ENABLED(TOOLCHANGE_MIGRATION_FEATURE)
|
#if ENABLED(TOOLCHANGE_MIGRATION_FEATURE)
|
||||||
migration_settings_t migration = migration_defaults;
|
migration_settings_t migration = migration_defaults;
|
||||||
bool enable_first_prime;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ENABLED(TOOLCHANGE_FS_INIT_BEFORE_SWAP)
|
#if ENABLED(TOOLCHANGE_FS_INIT_BEFORE_SWAP)
|
||||||
|
@ -150,6 +150,7 @@
|
||||||
|
|
||||||
#endif // SWITCHING_NOZZLE
|
#endif // SWITCHING_NOZZLE
|
||||||
|
|
||||||
|
// Move to position routines
|
||||||
void _line_to_current(const AxisEnum fr_axis, const float fscale=1) {
|
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);
|
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)
|
#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<EXTRUDERS> 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<EXTRUDERS> 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() {
|
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
|
destination = current_position; // Remember the old position
|
||||||
|
|
||||||
const bool ok = TERN1(TOOLCHANGE_PARK, all_axes_homed() && toolchange_settings.enable_park);
|
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
|
#endif
|
||||||
|
|
||||||
// Prime (All distances are added and slowed down to ensure secure priming in all circumstances)
|
extruder_prime();
|
||||||
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
|
|
||||||
|
|
||||||
// Move back
|
// Move back
|
||||||
#if ENABLED(TOOLCHANGE_PARK)
|
#if ENABLED(TOOLCHANGE_PARK)
|
||||||
|
@ -968,13 +1081,11 @@ void fast_line_to_current(const AxisEnum fr_axis) { _line_to_current(fr_axis, 0.
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Cutting recover
|
extruder_cutting_recover(destination.e); // 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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FS_DEBUG("<<< tool_change_prime");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // TOOLCHANGE_FILAMENT_SWAP
|
#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);
|
TEMPORARY_BED_LEVELING_STATE(false);
|
||||||
#endif
|
#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)
|
#if ENABLED(TOOLCHANGE_FS_PRIME_FIRST_USED)
|
||||||
static bool first_tool_is_primed = false;
|
if (enable_first_prime && old_tool == 0 && new_tool == 0 && !extruder_was_primed[0]) {
|
||||||
if (new_tool == old_tool && !first_tool_is_primed && enable_first_prime) {
|
|
||||||
tool_change_prime();
|
tool_change_prime();
|
||||||
first_tool_is_primed = true;
|
|
||||||
TERN_(TOOLCHANGE_FS_INIT_BEFORE_SWAP, toolchange_extruder_ready.set(old_tool)); // Primed and initialized
|
TERN_(TOOLCHANGE_FS_INIT_BEFORE_SWAP, toolchange_extruder_ready.set(old_tool)); // Primed and initialized
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1082,20 +1191,17 @@ void tool_change(const uint8_t new_tool, bool no_move/*=false*/) {
|
||||||
|
|
||||||
// Unload / Retract
|
// Unload / Retract
|
||||||
#if ENABLED(TOOLCHANGE_FILAMENT_SWAP)
|
#if ENABLED(TOOLCHANGE_FILAMENT_SWAP)
|
||||||
const bool should_swap = can_move_away && toolchange_settings.swap_length,
|
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))
|
|
||||||
);
|
|
||||||
if (should_swap) {
|
if (should_swap) {
|
||||||
if (too_cold) {
|
if (too_cold(old_tool)) {
|
||||||
SERIAL_ECHO_MSG(STR_ERR_HOTEND_TOO_COLD);
|
// If SingleNozzle setup is too cold, unable to perform tool_change.
|
||||||
if (ENABLED(SINGLENOZZLE)) { active_extruder = new_tool; return; }
|
if (ENABLED(SINGLENOZZLE)) { active_extruder = new_tool; return; }
|
||||||
}
|
}
|
||||||
else {
|
else if (extruder_was_primed[old_tool]) {
|
||||||
// For first new tool, change without unloading the old. 'Just prime/init the new'
|
// Retract the old extruder if it was previously primed
|
||||||
if (TERN1(TOOLCHANGE_FS_PRIME_FIRST_USED, first_tool_is_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));
|
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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1210,36 +1316,8 @@ void tool_change(const uint8_t new_tool, bool no_move/*=false*/) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ENABLED(TOOLCHANGE_FILAMENT_SWAP)
|
#if ENABLED(TOOLCHANGE_FILAMENT_SWAP)
|
||||||
if (should_swap && !too_cold) {
|
if (should_swap && !too_cold(active_extruder))
|
||||||
|
extruder_prime(); // Prime selected Extruder
|
||||||
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
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Prevent a move outside physical bounds
|
// 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");
|
else DEBUG_ECHOLNPGM("Move back skipped");
|
||||||
|
|
||||||
#if ENABLED(TOOLCHANGE_FILAMENT_SWAP)
|
#if ENABLED(TOOLCHANGE_FILAMENT_SWAP)
|
||||||
if (should_swap && !too_cold) {
|
if (should_swap && !too_cold(active_extruder)) {
|
||||||
// Cutting recover
|
extruder_cutting_recover(0); // New extruder primed and set to 0
|
||||||
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
|
|
||||||
|
|
||||||
// Restart Fan
|
// Restart Fan
|
||||||
#if HAS_FAN && TOOLCHANGE_FS_FAN >= 0
|
#if HAS_FAN && TOOLCHANGE_FS_FAN >= 0
|
||||||
|
@ -1342,7 +1417,7 @@ void tool_change(const uint8_t new_tool, bool no_move/*=false*/) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
SERIAL_ECHO_MSG(STR_ACTIVE_EXTRUDER, active_extruder);
|
SERIAL_ECHOLNPGM(STR_ACTIVE_EXTRUDER, active_extruder);
|
||||||
|
|
||||||
#endif // HAS_MULTI_EXTRUDER
|
#endif // HAS_MULTI_EXTRUDER
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,24 +29,30 @@
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
#if ENABLED(TOOLCHANGE_FILAMENT_SWAP)
|
#if ENABLED(TOOLCHANGE_FILAMENT_SWAP)
|
||||||
float swap_length, extra_prime, extra_resume;
|
float swap_length; // M217 S
|
||||||
int16_t prime_speed, retract_speed, unretract_speed, fan, fan_speed, fan_time;
|
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
|
#endif
|
||||||
#if ENABLED(TOOLCHANGE_PARK)
|
#if ENABLED(TOOLCHANGE_PARK)
|
||||||
bool enable_park;
|
bool enable_park; // M217 W
|
||||||
xyz_pos_t change_point;
|
xyz_pos_t change_point; // M217 X Y I J K C H O
|
||||||
#endif
|
#endif
|
||||||
float z_raise;
|
float z_raise; // M217 Z
|
||||||
} toolchange_settings_t;
|
} toolchange_settings_t;
|
||||||
|
|
||||||
extern toolchange_settings_t toolchange_settings;
|
extern toolchange_settings_t toolchange_settings;
|
||||||
|
|
||||||
#if ENABLED(TOOLCHANGE_FILAMENT_SWAP)
|
#if ENABLED(TOOLCHANGE_FS_PRIME_FIRST_USED)
|
||||||
void tool_change_prime();
|
extern bool enable_first_prime; // M217 V
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ENABLED(TOOLCHANGE_FS_PRIME_FIRST_USED)
|
#if ENABLED(TOOLCHANGE_FILAMENT_SWAP)
|
||||||
extern bool enable_first_prime;
|
void tool_change_prime(); // Prime the currently selected extruder
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ENABLED(TOOLCHANGE_FS_INIT_BEFORE_SWAP)
|
#if ENABLED(TOOLCHANGE_FS_INIT_BEFORE_SWAP)
|
||||||
|
|
|
@ -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 \
|
EXTRUDERS 5 TEMP_SENSOR_1 1 TEMP_SENSOR_2 1 TEMP_SENSOR_3 1 TEMP_SENSOR_4 1 \
|
||||||
NUM_Z_STEPPER_DRIVERS 4 \
|
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 }'
|
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
|
PID_PARAMS_PER_HOTEND Z_MULTI_ENDSTOPS
|
||||||
exec_test $1 $2 "BigTreeTech GTR | 6 Extruders | Quad Z + Endstops" "$3"
|
exec_test $1 $2 "BigTreeTech GTR | 6 Extruders | Quad Z + Endstops" "$3"
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue