From ee243e4edfe45fa855d4ff71abf8a9a118b66369 Mon Sep 17 00:00:00 2001 From: Thomas Moore Date: Wed, 1 May 2019 22:55:58 -0400 Subject: [PATCH] Fix mixing extruder filament change (#13803) --- .../src/HAL/shared/backtrace/unwarm_arm.cpp | 6 +- Marlin/src/core/language.h | 2 + Marlin/src/feature/mixing.cpp | 6 +- Marlin/src/feature/mixing.h | 18 ++--- Marlin/src/feature/pause.cpp | 15 ++-- Marlin/src/feature/pause.h | 6 +- Marlin/src/gcode/feature/pause/M600.cpp | 25 ++++++- Marlin/src/gcode/feature/pause/M701_M702.cpp | 68 +++++++++++++++++-- Marlin/src/gcode/gcode.cpp | 29 ++++++-- Marlin/src/gcode/gcode.h | 1 + Marlin/src/lcd/menu/menu_mixer.cpp | 4 +- Marlin/src/lcd/menu/menu_ubl.cpp | 4 +- Marlin/src/module/motion.cpp | 18 ++++- Marlin/src/module/planner.cpp | 25 +++++-- Marlin/src/module/temperature.cpp | 7 +- 15 files changed, 182 insertions(+), 52 deletions(-) diff --git a/Marlin/src/HAL/shared/backtrace/unwarm_arm.cpp b/Marlin/src/HAL/shared/backtrace/unwarm_arm.cpp index 3c9c5aaeec..0ec9bd56af 100644 --- a/Marlin/src/HAL/shared/backtrace/unwarm_arm.cpp +++ b/Marlin/src/HAL/shared/backtrace/unwarm_arm.cpp @@ -124,13 +124,11 @@ UnwResult UnwStartArm(UnwState * const state) { /* MRS */ else if ((instr & 0xFFBF0FFF) == 0xE10F0000) { + uint8_t rd = (instr & 0x0000F000) >> 12; #ifdef UNW_DEBUG const bool R = !!(instr & 0x00400000); - #else - constexpr bool R = false; + UnwPrintd4("MRS r%d,%s\t; r%d invalidated", rd, R ? "SPSR" : "CPSR", rd); #endif - uint8_t rd = (instr & 0x0000F000) >> 12; - UnwPrintd4("MRS r%d,%s\t; r%d invalidated", rd, R ? "SPSR" : "CPSR", rd); /* Status registers untracked */ state->regData[rd].o = REG_VAL_INVALID; diff --git a/Marlin/src/core/language.h b/Marlin/src/core/language.h index 14dcf8bd30..a8d214fba2 100644 --- a/Marlin/src/core/language.h +++ b/Marlin/src/core/language.h @@ -162,6 +162,8 @@ #define MSG_BEGIN_FILE_LIST "Begin file list" #define MSG_END_FILE_LIST "End file list" #define MSG_INVALID_EXTRUDER "Invalid extruder" +#define MSG_INVALID_E_STEPPER "Invalid E stepper" +#define MSG_E_STEPPER_NOT_SPECIFIED "E stepper not specified" #define MSG_INVALID_SOLENOID "Invalid solenoid" #define MSG_ERR_NO_THERMISTORS "No thermistors - no temperature" #define MSG_M115_REPORT "FIRMWARE_NAME:Marlin " DETAILED_BUILD_VERSION " SOURCE_CODE_URL:" SOURCE_CODE_URL " PROTOCOL_VERSION:" PROTOCOL_VERSION " MACHINE_TYPE:" MACHINE_NAME " EXTRUDER_COUNT:" STRINGIFY(EXTRUDERS) " UUID:" MACHINE_UUID diff --git a/Marlin/src/feature/mixing.cpp b/Marlin/src/feature/mixing.cpp index 98b26e29ce..21d1ee433e 100644 --- a/Marlin/src/feature/mixing.cpp +++ b/Marlin/src/feature/mixing.cpp @@ -132,7 +132,7 @@ void Mixer::init() { #endif } -void Mixer::refresh_collector(const float proportion/*=1.0*/, const uint8_t t/*=selected_vtool*/) { +void Mixer::refresh_collector(const float proportion/*=1.0*/, const uint8_t t/*=selected_vtool*/, float (&c)[MIXING_STEPPERS]/*=collector*/) { float csum = 0, cmax = 0; MIXER_STEPPER_LOOP(i) { const float v = color[t][i]; @@ -142,8 +142,8 @@ void Mixer::refresh_collector(const float proportion/*=1.0*/, const uint8_t t/*= //SERIAL_ECHOPAIR("Mixer::refresh_collector(", proportion, ", ", int(t), ") cmax=", cmax, " csum=", csum, " color"); const float inv_prop = proportion / csum; MIXER_STEPPER_LOOP(i) { - collector[i] = color[t][i] * inv_prop; - //SERIAL_ECHOPAIR(" [", int(t), "][", int(i), "] = ", int(color[t][i]), " (", collector[i], ") "); + c[i] = color[t][i] * inv_prop; + //SERIAL_ECHOPAIR(" [", int(t), "][", int(i), "] = ", int(color[t][i]), " (", c[i], ") "); } //SERIAL_EOL(); } diff --git a/Marlin/src/feature/mixing.h b/Marlin/src/feature/mixing.h index bb069c97d7..12bf091fd7 100644 --- a/Marlin/src/feature/mixing.h +++ b/Marlin/src/feature/mixing.h @@ -51,19 +51,19 @@ enum MixTool { FIRST_USER_VIRTUAL_TOOL = 0, LAST_USER_VIRTUAL_TOOL = MIXING_VIRTUAL_TOOLS - 1, NR_USER_VIRTUAL_TOOLS, - #ifdef RETRACT_SYNC_MIXING - MIXER_AUTORETRACT_TOOL = NR_USER_VIRTUAL_TOOLS, - NR_MIXING_VIRTUAL_TOOLS - #else - NR_MIXING_VIRTUAL_TOOLS = NR_USER_VIRTUAL_TOOLS + MIXER_DIRECT_SET_TOOL = NR_USER_VIRTUAL_TOOLS, + #if ENABLED(RETRACT_SYNC_MIXING) + MIXER_AUTORETRACT_TOOL, #endif + NR_MIXING_VIRTUAL_TOOLS }; -#ifdef RETRACT_SYNC_MIXING - static_assert(NR_MIXING_VIRTUAL_TOOLS <= 254, "MIXING_VIRTUAL_TOOLS must be <= 254!"); +#if ENABLED(RETRACT_SYNC_MIXING) + #define MAX_VTOOLS 254 #else - static_assert(NR_MIXING_VIRTUAL_TOOLS <= 255, "MIXING_VIRTUAL_TOOLS must be <= 255!"); + #define MAX_VTOOLS 255 #endif +static_assert(NR_MIXING_VIRTUAL_TOOLS <= MAX_VTOOLS, "MIXING_VIRTUAL_TOOLS must be <= " STRINGIFY(MAX_VTOOLS) "!"); #define MIXER_STEPPER_LOOP(VAR) \ for (uint_fast8_t VAR = 0; VAR < MIXING_STEPPERS; VAR++) @@ -100,7 +100,7 @@ class Mixer { static void init(); // Populate colors at boot time static void reset_vtools(); - static void refresh_collector(const float proportion=1.0, const uint8_t t=selected_vtool); + static void refresh_collector(const float proportion=1.0, const uint8_t t=selected_vtool, float (&c)[MIXING_STEPPERS]=collector); // Used up to Planner level FORCE_INLINE static void set_collector(const uint8_t c, const float f) { collector[c] = MAX(f, 0.0f); } diff --git a/Marlin/src/feature/pause.cpp b/Marlin/src/feature/pause.cpp index 99dbb380e5..7d5135151c 100644 --- a/Marlin/src/feature/pause.cpp +++ b/Marlin/src/feature/pause.cpp @@ -302,16 +302,22 @@ bool load_filament(const float &slow_load_length/*=0*/, const float &fast_load_l */ bool unload_filament(const float &unload_length, const bool show_lcd/*=false*/, const PauseMode mode/*=PAUSE_MODE_PAUSE_PRINT*/ + #if BOTH(FILAMENT_UNLOAD_ALL_EXTRUDERS, MIXING_EXTRUDER) + , const float &mix_multiplier/*=1.0*/ + #endif ) { #if !HAS_LCD_MENU UNUSED(show_lcd); #endif + #if !BOTH(FILAMENT_UNLOAD_ALL_EXTRUDERS, MIXING_EXTRUDER) + constexpr float mix_multiplier = 1.0; + #endif + if (!ensure_safe_temperature(mode)) { #if HAS_LCD_MENU if (show_lcd) lcd_pause_show_message(PAUSE_MESSAGE_STATUS); #endif - return false; } @@ -320,13 +326,14 @@ bool unload_filament(const float &unload_length, const bool show_lcd/*=false*/, #endif // Retract filament - do_pause_e_move(-FILAMENT_UNLOAD_RETRACT_LENGTH, PAUSE_PARK_RETRACT_FEEDRATE); + do_pause_e_move(-(FILAMENT_UNLOAD_RETRACT_LENGTH) * mix_multiplier, (PAUSE_PARK_RETRACT_FEEDRATE) * mix_multiplier); // Wait for filament to cool safe_delay(FILAMENT_UNLOAD_DELAY); // Quickly purge - do_pause_e_move(FILAMENT_UNLOAD_RETRACT_LENGTH + FILAMENT_UNLOAD_PURGE_LENGTH, planner.settings.max_feedrate_mm_s[E_AXIS]); + do_pause_e_move((FILAMENT_UNLOAD_RETRACT_LENGTH + FILAMENT_UNLOAD_PURGE_LENGTH) * mix_multiplier, + planner.settings.max_feedrate_mm_s[E_AXIS] * mix_multiplier); // Unload filament #if FILAMENT_CHANGE_UNLOAD_ACCEL > 0 @@ -334,7 +341,7 @@ bool unload_filament(const float &unload_length, const bool show_lcd/*=false*/, planner.settings.retract_acceleration = FILAMENT_CHANGE_UNLOAD_ACCEL; #endif - do_pause_e_move(unload_length, FILAMENT_CHANGE_UNLOAD_FEEDRATE); + do_pause_e_move(unload_length * mix_multiplier, (FILAMENT_CHANGE_UNLOAD_FEEDRATE) * mix_multiplier); #if FILAMENT_CHANGE_FAST_LOAD_ACCEL > 0 planner.settings.retract_acceleration = saved_acceleration; diff --git a/Marlin/src/feature/pause.h b/Marlin/src/feature/pause.h index 8a0653b2bd..36a2a2cc0c 100644 --- a/Marlin/src/feature/pause.h +++ b/Marlin/src/feature/pause.h @@ -92,6 +92,10 @@ void resume_print(const float &slow_load_length=0, const float &fast_load_length bool load_filament(const float &slow_load_length=0, const float &fast_load_length=0, const float &extrude_length=0, const int8_t max_beep_count=0, const bool show_lcd=false, const bool pause_for_user=false, const PauseMode mode=PAUSE_MODE_PAUSE_PRINT DXC_PARAMS); -bool unload_filament(const float &unload_length, const bool show_lcd=false, const PauseMode mode=PAUSE_MODE_PAUSE_PRINT); +bool unload_filament(const float &unload_length, const bool show_lcd=false, const PauseMode mode=PAUSE_MODE_PAUSE_PRINT + #if BOTH(FILAMENT_UNLOAD_ALL_EXTRUDERS, MIXING_EXTRUDER) + , const float &mix_multiplier=1.0 + #endif +); #endif // ADVANCED_PAUSE_FEATURE diff --git a/Marlin/src/gcode/feature/pause/M600.cpp b/Marlin/src/gcode/feature/pause/M600.cpp index 78e7e8e658..147cc9c573 100644 --- a/Marlin/src/gcode/feature/pause/M600.cpp +++ b/Marlin/src/gcode/feature/pause/M600.cpp @@ -41,6 +41,10 @@ #include "../../../lcd/menu/menu_mmu2.h" #endif +#if ENABLED(MIXING_EXTRUDER) + #include "../../../feature/mixing.h" +#endif + /** * M600: Pause for filament change * @@ -58,8 +62,21 @@ void GcodeSuite::M600() { point_t park_point = NOZZLE_PARK_POINT; - const int8_t target_extruder = get_target_extruder_from_command(); - if (target_extruder < 0) return; + #if ENABLED(MIXING_EXTRUDER) + const int8_t target_e_stepper = get_target_e_stepper_from_command(); + if (target_e_stepper < 0) return; + + const uint8_t old_mixing_tool = mixer.get_current_vtool(); + mixer.T(MIXER_DIRECT_SET_TOOL); + + MIXER_STEPPER_LOOP(i) mixer.set_collector(i, i == uint8_t(target_e_stepper) ? 1.0 : 0.0); + mixer.normalize(); + + const int8_t target_extruder = active_extruder; + #else + const int8_t target_extruder = get_target_extruder_from_command(); + if (target_extruder < 0) return; + #endif #if ENABLED(DUAL_X_CARRIAGE) int8_t DXC_ext = target_extruder; @@ -155,6 +172,10 @@ void GcodeSuite::M600() { if (active_extruder_before_filament_change != active_extruder) tool_change(active_extruder_before_filament_change, 0, false); #endif + + #if ENABLED(MIXING_EXTRUDER) + mixer.T(old_mixing_tool); // Restore original mixing tool + #endif } #endif // ADVANCED_PAUSE_FEATURE diff --git a/Marlin/src/gcode/feature/pause/M701_M702.cpp b/Marlin/src/gcode/feature/pause/M701_M702.cpp index a09d8aa710..19c6eed209 100644 --- a/Marlin/src/gcode/feature/pause/M701_M702.cpp +++ b/Marlin/src/gcode/feature/pause/M701_M702.cpp @@ -42,10 +42,15 @@ #include "../../../feature/prusa_MMU2/mmu2.h" #endif +#if ENABLED(MIXING_EXTRUDER) + #include "../../../feature/mixing.h" +#endif + /** * M701: Load filament * - * T - Optional extruder number. Current extruder if omitted. + * T - Extruder number. Required for mixing extruder. + * For non-mixing, current extruder if omitted. * Z - Move the Z axis by this distance * L - Extrude distance for insertion (positive value) (manual reload) * @@ -59,9 +64,21 @@ void GcodeSuite::M701() { if (axis_unhomed_error()) park_point.z = 0; #endif - const int8_t target_extruder = get_target_extruder_from_command(); - if (target_extruder < 0) return; + #if ENABLED(MIXING_EXTRUDER) + const int8_t target_e_stepper = get_target_e_stepper_from_command(); + if (target_e_stepper < 0) return; + + const uint8_t old_mixing_tool = mixer.get_current_vtool(); + mixer.T(MIXER_DIRECT_SET_TOOL); + MIXER_STEPPER_LOOP(i) mixer.set_collector(i, (i == (uint8_t)target_e_stepper) ? 1.0 : 0.0); + mixer.normalize(); + + const int8_t target_extruder = active_extruder; + #else + const int8_t target_extruder = get_target_extruder_from_command(); + if (target_extruder < 0) return; + #endif // Z axis lift if (parser.seenval('Z')) park_point.z = parser.linearval('Z'); @@ -107,6 +124,10 @@ void GcodeSuite::M701() { tool_change(active_extruder_before_filament_change, 0, false); #endif + #if ENABLED(MIXING_EXTRUDER) + mixer.T(old_mixing_tool); // Restore original mixing tool + #endif + // Show status screen #if HAS_LCD_MENU lcd_pause_show_message(PAUSE_MESSAGE_STATUS); @@ -116,7 +137,8 @@ void GcodeSuite::M701() { /** * M702: Unload filament * - * T - Optional extruder number. If omitted, current extruder + * T - Extruder number. Required for mixing extruder. + * For non-mixing, if omitted, current extruder * (or ALL extruders with FILAMENT_UNLOAD_ALL_EXTRUDERS). * Z - Move the Z axis by this distance * U - Retract distance for removal (manual reload) @@ -131,8 +153,32 @@ void GcodeSuite::M702() { if (axis_unhomed_error()) park_point.z = 0; #endif - const int8_t target_extruder = get_target_extruder_from_command(); - if (target_extruder < 0) return; + #if ENABLED(MIXING_EXTRUDER) + const uint8_t old_mixing_tool = mixer.get_current_vtool(); + + #if ENABLED(FILAMENT_UNLOAD_ALL_EXTRUDERS) + float mix_multiplier = 1.0; + if (!parser.seenval('T')) { + mixer.T(MIXER_AUTORETRACT_TOOL); + mix_multiplier = MIXING_STEPPERS; + } + else + #endif + { + const int8_t target_e_stepper = get_target_e_stepper_from_command(); + if (target_e_stepper < 0) return; + + mixer.T(MIXER_DIRECT_SET_TOOL); + MIXER_STEPPER_LOOP(i) mixer.set_collector(i, (i == (uint8_t)target_e_stepper) ? 1.0 : 0.0); + mixer.normalize(); + } + + const int8_t target_extruder = active_extruder; + #else + const float unload_length_multiplier = 1.0; + const int8_t target_extruder = get_target_extruder_from_command(); + if (target_extruder < 0) return; + #endif // Z axis lift if (parser.seenval('Z')) park_point.z = parser.linearval('Z'); @@ -171,7 +217,11 @@ void GcodeSuite::M702() { const float unload_length = -ABS(parser.seen('U') ? parser.value_axis_units(E_AXIS) : fc_settings[target_extruder].unload_length); - unload_filament(unload_length, true, PAUSE_MODE_UNLOAD_FILAMENT); + unload_filament(unload_length, true, PAUSE_MODE_UNLOAD_FILAMENT + #if ALL(FILAMENT_UNLOAD_ALL_EXTRUDERS, MIXING_EXTRUDER) + , mix_multiplier + #endif + ); } #endif @@ -185,6 +235,10 @@ void GcodeSuite::M702() { tool_change(active_extruder_before_filament_change, 0, false); #endif + #if ENABLED(MIXING_EXTRUDER) + mixer.T(old_mixing_tool); // Restore original mixing tool + #endif + // Show status screen #if HAS_LCD_MENU lcd_pause_show_message(PAUSE_MESSAGE_STATUS); diff --git a/Marlin/src/gcode/gcode.cpp b/Marlin/src/gcode/gcode.cpp index 5b179dcaf0..45f00b7ddc 100644 --- a/Marlin/src/gcode/gcode.cpp +++ b/Marlin/src/gcode/gcode.cpp @@ -72,17 +72,32 @@ bool GcodeSuite::axis_relative_modes[] = AXIS_RELATIVE_MODES; int8_t GcodeSuite::get_target_extruder_from_command() { if (parser.seenval('T')) { const int8_t e = parser.value_byte(); - if (e >= EXTRUDERS) { - SERIAL_ECHO_START(); - SERIAL_CHAR('M'); SERIAL_ECHO(parser.codenum); - SERIAL_ECHOLNPAIR(" " MSG_INVALID_EXTRUDER " ", int(e)); - return -1; - } - return e; + if (e < EXTRUDERS) return e; + SERIAL_ECHO_START(); + SERIAL_CHAR('M'); SERIAL_ECHO(parser.codenum); + SERIAL_ECHOLNPAIR(" " MSG_INVALID_EXTRUDER " ", int(e)); + return -1; } return active_extruder; } +/** + * Get the target e stepper from the T parameter + * Return -1 if the T parameter is out of range or unspecified + */ +int8_t GcodeSuite::get_target_e_stepper_from_command() { + const int8_t e = parser.intval('T', -1); + if (WITHIN(e, 0, E_STEPPERS - 1)) return e; + + SERIAL_ECHO_START(); + SERIAL_CHAR('M'); SERIAL_ECHO(parser.codenum); + if (e == -1) + SERIAL_ECHOLNPGM(" " MSG_E_STEPPER_NOT_SPECIFIED); + else + SERIAL_ECHOLNPAIR(" " MSG_INVALID_E_STEPPER " ", int(e)); + return -1; +} + /** * Set XYZE destination and feedrate from the current GCode command * diff --git a/Marlin/src/gcode/gcode.h b/Marlin/src/gcode/gcode.h index af99e4fbed..e6cd1f59f7 100644 --- a/Marlin/src/gcode/gcode.h +++ b/Marlin/src/gcode/gcode.h @@ -298,6 +298,7 @@ public: FORCE_INLINE static void reset_stepper_timeout() { previous_move_ms = millis(); } static int8_t get_target_extruder_from_command(); + static int8_t get_target_e_stepper_from_command(); static void get_destination_from_command(); static void process_parsed_command( diff --git a/Marlin/src/lcd/menu/menu_mixer.cpp b/Marlin/src/lcd/menu/menu_mixer.cpp index 77124d1146..cbc375a3a3 100644 --- a/Marlin/src/lcd/menu/menu_mixer.cpp +++ b/Marlin/src/lcd/menu/menu_mixer.cpp @@ -101,7 +101,7 @@ MENU_ITEM_EDIT_CALLBACK(int8, MSG_GRADIENT_ALIAS, &mixer.gradient.vtool_index, 0, MIXING_VIRTUAL_TOOLS - 1, mixer.refresh_gradient); #endif - char tmp[10]; + char tmp[18]; MENU_ITEM(submenu, MSG_START_Z ":", lcd_mixer_gradient_z_start_edit); MENU_ITEM_ADDON_START(9); @@ -298,7 +298,7 @@ void menu_mixer() { #if ENABLED(GRADIENT_MIX) { - char tmp[10]; + char tmp[13]; MENU_ITEM(submenu, MSG_GRADIENT, lcd_mixer_edit_gradient_menu); MENU_ITEM_ADDON_START(10); sprintf_P(tmp, PSTR("T%i->T%i"), mixer.gradient.start_vtool, mixer.gradient.end_vtool); diff --git a/Marlin/src/lcd/menu/menu_ubl.cpp b/Marlin/src/lcd/menu/menu_ubl.cpp index 8b182b89b9..2bb9409794 100644 --- a/Marlin/src/lcd/menu/menu_ubl.cpp +++ b/Marlin/src/lcd/menu/menu_ubl.cpp @@ -228,7 +228,7 @@ void _lcd_ubl_validate_mesh() { * UBL Grid Leveling Command */ void _lcd_ubl_grid_level_cmd() { - char UBL_LCD_GCODE[10]; + char UBL_LCD_GCODE[12]; sprintf_P(UBL_LCD_GCODE, PSTR("G29 J%i"), side_points); lcd_enqueue_command(UBL_LCD_GCODE); } @@ -269,7 +269,7 @@ void _lcd_ubl_mesh_leveling() { * UBL Fill-in Amount Mesh Command */ void _lcd_ubl_fillin_amount_cmd() { - char UBL_LCD_GCODE[16]; + char UBL_LCD_GCODE[18]; sprintf_P(UBL_LCD_GCODE, PSTR("G29 P3 R C.%i"), ubl_fillin_amount); lcd_enqueue_command(UBL_LCD_GCODE); } diff --git a/Marlin/src/module/motion.cpp b/Marlin/src/module/motion.cpp index 30f63ebed5..7f1f9172c9 100644 --- a/Marlin/src/module/motion.cpp +++ b/Marlin/src/module/motion.cpp @@ -982,9 +982,21 @@ void prepare_move_to_destination() { } #endif // PREVENT_COLD_EXTRUSION #if ENABLED(PREVENT_LENGTHY_EXTRUDE) - if (ABS(destination[E_AXIS] - current_position[E_AXIS]) * planner.e_factor[active_extruder] > (EXTRUDE_MAXLENGTH)) { - current_position[E_AXIS] = destination[E_AXIS]; // Behave as if the move really took place, but ignore E part - SERIAL_ECHO_MSG(MSG_ERR_LONG_EXTRUDE_STOP); + const float e_delta = ABS(destination[E_AXIS] - current_position[E_AXIS]) * planner.e_factor[active_extruder]; + if (e_delta > (EXTRUDE_MAXLENGTH)) { + #if ENABLED(MIXING_EXTRUDER) + bool ignore_e = false; + float collector[MIXING_STEPPERS]; + mixer.refresh_collector(1.0, mixer.get_current_vtool(), collector); + MIXER_STEPPER_LOOP(e) + if (e_delta * collector[e] > (EXTRUDE_MAXLENGTH)) { ignore_e = true; break; } + #else + constexpr bool ignore_e = true; + #endif + if (ignore_e) { + current_position[E_AXIS] = destination[E_AXIS]; // Behave as if the move really took place, but ignore E part + SERIAL_ECHO_MSG(MSG_ERR_LONG_EXTRUDE_STOP); + } } #endif // PREVENT_LENGTHY_EXTRUDE } diff --git a/Marlin/src/module/planner.cpp b/Marlin/src/module/planner.cpp index ff4f13e1d7..5073d903da 100644 --- a/Marlin/src/module/planner.cpp +++ b/Marlin/src/module/planner.cpp @@ -1767,13 +1767,26 @@ bool Planner::_populate_block(block_t * const block, bool split_move, } #endif // PREVENT_COLD_EXTRUSION #if ENABLED(PREVENT_LENGTHY_EXTRUDE) - if (ABS(de * e_factor[extruder]) > (int32_t)settings.axis_steps_per_mm[E_AXIS_N(extruder)] * (EXTRUDE_MAXLENGTH)) { // It's not important to get max. extrusion length in a precision < 1mm, so save some cycles and cast to int - position[E_AXIS] = target[E_AXIS]; // Behave as if the move really took place, but ignore E part - #if HAS_POSITION_FLOAT - position_float[E_AXIS] = target_float[E_AXIS]; + const float e_steps = ABS(de * e_factor[extruder]); + const float max_e_steps = settings.axis_steps_per_mm[E_AXIS_N(extruder)] * (EXTRUDE_MAXLENGTH); + if (e_steps > max_e_steps) { + #if ENABLED(MIXING_EXTRUDER) + bool ignore_e = false; + float collector[MIXING_STEPPERS]; + mixer.refresh_collector(1.0, mixer.get_current_vtool(), collector); + MIXER_STEPPER_LOOP(e) + if (e_steps * collector[e] > max_e_steps) { ignore_e = true; break; } + #else + constexpr bool ignore_e = true; #endif - de = 0; // no difference - SERIAL_ECHO_MSG(MSG_ERR_LONG_EXTRUDE_STOP); + if (ignore_e) { + position[E_AXIS] = target[E_AXIS]; // Behave as if the move really took place, but ignore E part + #if HAS_POSITION_FLOAT + position_float[E_AXIS] = target_float[E_AXIS]; + #endif + de = 0; // no difference + SERIAL_ECHO_MSG(MSG_ERR_LONG_EXTRUDE_STOP); + } } #endif // PREVENT_LENGTHY_EXTRUDE } diff --git a/Marlin/src/module/temperature.cpp b/Marlin/src/module/temperature.cpp index 25a45661aa..957b2db2ab 100644 --- a/Marlin/src/module/temperature.cpp +++ b/Marlin/src/module/temperature.cpp @@ -2825,6 +2825,7 @@ void Temperature::isr() { ) { #if TEMP_BED_RESIDENCY_TIME > 0 millis_t residency_start_ms = 0; + bool first_loop = true; // Loop until the temperature has stabilized #define TEMP_BED_CONDITIONS (!residency_start_ms || PENDING(now, residency_start_ms + (TEMP_BED_RESIDENCY_TIME) * 1000UL)) #else @@ -2833,7 +2834,7 @@ void Temperature::isr() { #endif float target_temp = -1, old_temp = 9999; - bool wants_to_cool = false, first_loop = true; + bool wants_to_cool = false; wait_for_heatup = true; millis_t now, next_temp_ms = 0, next_cool_check_ms = 0; @@ -2917,7 +2918,9 @@ void Temperature::isr() { } #endif - first_loop = false; + #if TEMP_BED_RESIDENCY_TIME > 0 + first_loop = false; + #endif } while (wait_for_heatup && TEMP_BED_CONDITIONS);