Ver código fonte

Fix mixing extruder filament change (#13803)

Thomas Moore 6 anos atrás
pai
commit
ee243e4edf

+ 2
- 4
Marlin/src/HAL/shared/backtrace/unwarm_arm.cpp Ver arquivo

124
 
124
 
125
     /* MRS */
125
     /* MRS */
126
     else if ((instr & 0xFFBF0FFF) == 0xE10F0000) {
126
     else if ((instr & 0xFFBF0FFF) == 0xE10F0000) {
127
+      uint8_t rd = (instr & 0x0000F000) >> 12;
127
       #ifdef UNW_DEBUG
128
       #ifdef UNW_DEBUG
128
         const bool R = !!(instr & 0x00400000);
129
         const bool R = !!(instr & 0x00400000);
129
-      #else
130
-        constexpr bool R = false;
130
+        UnwPrintd4("MRS r%d,%s\t; r%d invalidated", rd, R ? "SPSR" : "CPSR", rd);
131
       #endif
131
       #endif
132
-      uint8_t rd = (instr & 0x0000F000) >> 12;
133
-      UnwPrintd4("MRS r%d,%s\t; r%d invalidated", rd, R ? "SPSR" : "CPSR", rd);
134
 
132
 
135
       /* Status registers untracked */
133
       /* Status registers untracked */
136
       state->regData[rd].o = REG_VAL_INVALID;
134
       state->regData[rd].o = REG_VAL_INVALID;

+ 2
- 0
Marlin/src/core/language.h Ver arquivo

162
 #define MSG_BEGIN_FILE_LIST                 "Begin file list"
162
 #define MSG_BEGIN_FILE_LIST                 "Begin file list"
163
 #define MSG_END_FILE_LIST                   "End file list"
163
 #define MSG_END_FILE_LIST                   "End file list"
164
 #define MSG_INVALID_EXTRUDER                "Invalid extruder"
164
 #define MSG_INVALID_EXTRUDER                "Invalid extruder"
165
+#define MSG_INVALID_E_STEPPER               "Invalid E stepper"
166
+#define MSG_E_STEPPER_NOT_SPECIFIED         "E stepper not specified"
165
 #define MSG_INVALID_SOLENOID                "Invalid solenoid"
167
 #define MSG_INVALID_SOLENOID                "Invalid solenoid"
166
 #define MSG_ERR_NO_THERMISTORS              "No thermistors - no temperature"
168
 #define MSG_ERR_NO_THERMISTORS              "No thermistors - no temperature"
167
 #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
169
 #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

+ 3
- 3
Marlin/src/feature/mixing.cpp Ver arquivo

132
   #endif
132
   #endif
133
 }
133
 }
134
 
134
 
135
-void Mixer::refresh_collector(const float proportion/*=1.0*/, const uint8_t t/*=selected_vtool*/) {
135
+void Mixer::refresh_collector(const float proportion/*=1.0*/, const uint8_t t/*=selected_vtool*/, float (&c)[MIXING_STEPPERS]/*=collector*/) {
136
   float csum = 0, cmax = 0;
136
   float csum = 0, cmax = 0;
137
   MIXER_STEPPER_LOOP(i) {
137
   MIXER_STEPPER_LOOP(i) {
138
     const float v = color[t][i];
138
     const float v = color[t][i];
142
   //SERIAL_ECHOPAIR("Mixer::refresh_collector(", proportion, ", ", int(t), ") cmax=", cmax, "  csum=", csum, "  color");
142
   //SERIAL_ECHOPAIR("Mixer::refresh_collector(", proportion, ", ", int(t), ") cmax=", cmax, "  csum=", csum, "  color");
143
   const float inv_prop = proportion / csum;
143
   const float inv_prop = proportion / csum;
144
   MIXER_STEPPER_LOOP(i) {
144
   MIXER_STEPPER_LOOP(i) {
145
-    collector[i] = color[t][i] * inv_prop;
146
-    //SERIAL_ECHOPAIR(" [", int(t), "][", int(i), "] = ", int(color[t][i]), " (", collector[i], ")  ");
145
+    c[i] = color[t][i] * inv_prop;
146
+    //SERIAL_ECHOPAIR(" [", int(t), "][", int(i), "] = ", int(color[t][i]), " (", c[i], ")  ");
147
   }
147
   }
148
   //SERIAL_EOL();
148
   //SERIAL_EOL();
149
 }
149
 }

+ 9
- 9
Marlin/src/feature/mixing.h Ver arquivo

51
   FIRST_USER_VIRTUAL_TOOL = 0,
51
   FIRST_USER_VIRTUAL_TOOL = 0,
52
   LAST_USER_VIRTUAL_TOOL = MIXING_VIRTUAL_TOOLS - 1,
52
   LAST_USER_VIRTUAL_TOOL = MIXING_VIRTUAL_TOOLS - 1,
53
   NR_USER_VIRTUAL_TOOLS,
53
   NR_USER_VIRTUAL_TOOLS,
54
-  #ifdef RETRACT_SYNC_MIXING
55
-    MIXER_AUTORETRACT_TOOL = NR_USER_VIRTUAL_TOOLS,
56
-    NR_MIXING_VIRTUAL_TOOLS
57
-  #else
58
-    NR_MIXING_VIRTUAL_TOOLS = NR_USER_VIRTUAL_TOOLS
54
+  MIXER_DIRECT_SET_TOOL = NR_USER_VIRTUAL_TOOLS,
55
+  #if ENABLED(RETRACT_SYNC_MIXING)
56
+    MIXER_AUTORETRACT_TOOL,
59
   #endif
57
   #endif
58
+  NR_MIXING_VIRTUAL_TOOLS
60
 };
59
 };
61
 
60
 
62
-#ifdef RETRACT_SYNC_MIXING
63
-  static_assert(NR_MIXING_VIRTUAL_TOOLS <= 254, "MIXING_VIRTUAL_TOOLS must be <= 254!");
61
+#if ENABLED(RETRACT_SYNC_MIXING)
62
+  #define MAX_VTOOLS 254
64
 #else
63
 #else
65
-  static_assert(NR_MIXING_VIRTUAL_TOOLS <= 255, "MIXING_VIRTUAL_TOOLS must be <= 255!");
64
+  #define MAX_VTOOLS 255
66
 #endif
65
 #endif
66
+static_assert(NR_MIXING_VIRTUAL_TOOLS <= MAX_VTOOLS, "MIXING_VIRTUAL_TOOLS must be <= " STRINGIFY(MAX_VTOOLS) "!");
67
 
67
 
68
 #define MIXER_STEPPER_LOOP(VAR) \
68
 #define MIXER_STEPPER_LOOP(VAR) \
69
   for (uint_fast8_t VAR = 0; VAR < MIXING_STEPPERS; VAR++)
69
   for (uint_fast8_t VAR = 0; VAR < MIXING_STEPPERS; VAR++)
100
   static void init(); // Populate colors at boot time
100
   static void init(); // Populate colors at boot time
101
 
101
 
102
   static void reset_vtools();
102
   static void reset_vtools();
103
-  static void refresh_collector(const float proportion=1.0, const uint8_t t=selected_vtool);
103
+  static void refresh_collector(const float proportion=1.0, const uint8_t t=selected_vtool, float (&c)[MIXING_STEPPERS]=collector);
104
 
104
 
105
   // Used up to Planner level
105
   // Used up to Planner level
106
   FORCE_INLINE static void set_collector(const uint8_t c, const float f) { collector[c] = MAX(f, 0.0f); }
106
   FORCE_INLINE static void set_collector(const uint8_t c, const float f) { collector[c] = MAX(f, 0.0f); }

+ 11
- 4
Marlin/src/feature/pause.cpp Ver arquivo

302
  */
302
  */
303
 bool unload_filament(const float &unload_length, const bool show_lcd/*=false*/,
303
 bool unload_filament(const float &unload_length, const bool show_lcd/*=false*/,
304
                      const PauseMode mode/*=PAUSE_MODE_PAUSE_PRINT*/
304
                      const PauseMode mode/*=PAUSE_MODE_PAUSE_PRINT*/
305
+                     #if BOTH(FILAMENT_UNLOAD_ALL_EXTRUDERS, MIXING_EXTRUDER)
306
+                       , const float &mix_multiplier/*=1.0*/
307
+                     #endif
305
 ) {
308
 ) {
306
   #if !HAS_LCD_MENU
309
   #if !HAS_LCD_MENU
307
     UNUSED(show_lcd);
310
     UNUSED(show_lcd);
308
   #endif
311
   #endif
309
 
312
 
313
+  #if !BOTH(FILAMENT_UNLOAD_ALL_EXTRUDERS, MIXING_EXTRUDER)
314
+    constexpr float mix_multiplier = 1.0;
315
+  #endif
316
+
310
   if (!ensure_safe_temperature(mode)) {
317
   if (!ensure_safe_temperature(mode)) {
311
     #if HAS_LCD_MENU
318
     #if HAS_LCD_MENU
312
       if (show_lcd) lcd_pause_show_message(PAUSE_MESSAGE_STATUS);
319
       if (show_lcd) lcd_pause_show_message(PAUSE_MESSAGE_STATUS);
313
     #endif
320
     #endif
314
-
315
     return false;
321
     return false;
316
   }
322
   }
317
 
323
 
320
   #endif
326
   #endif
321
 
327
 
322
   // Retract filament
328
   // Retract filament
323
-  do_pause_e_move(-FILAMENT_UNLOAD_RETRACT_LENGTH, PAUSE_PARK_RETRACT_FEEDRATE);
329
+  do_pause_e_move(-(FILAMENT_UNLOAD_RETRACT_LENGTH) * mix_multiplier, (PAUSE_PARK_RETRACT_FEEDRATE) * mix_multiplier);
324
 
330
 
325
   // Wait for filament to cool
331
   // Wait for filament to cool
326
   safe_delay(FILAMENT_UNLOAD_DELAY);
332
   safe_delay(FILAMENT_UNLOAD_DELAY);
327
 
333
 
328
   // Quickly purge
334
   // Quickly purge
329
-  do_pause_e_move(FILAMENT_UNLOAD_RETRACT_LENGTH + FILAMENT_UNLOAD_PURGE_LENGTH, planner.settings.max_feedrate_mm_s[E_AXIS]);
335
+  do_pause_e_move((FILAMENT_UNLOAD_RETRACT_LENGTH + FILAMENT_UNLOAD_PURGE_LENGTH) * mix_multiplier,
336
+                  planner.settings.max_feedrate_mm_s[E_AXIS] * mix_multiplier);
330
 
337
 
331
   // Unload filament
338
   // Unload filament
332
   #if FILAMENT_CHANGE_UNLOAD_ACCEL > 0
339
   #if FILAMENT_CHANGE_UNLOAD_ACCEL > 0
334
     planner.settings.retract_acceleration = FILAMENT_CHANGE_UNLOAD_ACCEL;
341
     planner.settings.retract_acceleration = FILAMENT_CHANGE_UNLOAD_ACCEL;
335
   #endif
342
   #endif
336
 
343
 
337
-  do_pause_e_move(unload_length, FILAMENT_CHANGE_UNLOAD_FEEDRATE);
344
+  do_pause_e_move(unload_length * mix_multiplier, (FILAMENT_CHANGE_UNLOAD_FEEDRATE) * mix_multiplier);
338
 
345
 
339
   #if FILAMENT_CHANGE_FAST_LOAD_ACCEL > 0
346
   #if FILAMENT_CHANGE_FAST_LOAD_ACCEL > 0
340
     planner.settings.retract_acceleration = saved_acceleration;
347
     planner.settings.retract_acceleration = saved_acceleration;

+ 5
- 1
Marlin/src/feature/pause.h Ver arquivo

92
 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,
92
 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,
93
                           const bool pause_for_user=false, const PauseMode mode=PAUSE_MODE_PAUSE_PRINT DXC_PARAMS);
93
                           const bool pause_for_user=false, const PauseMode mode=PAUSE_MODE_PAUSE_PRINT DXC_PARAMS);
94
 
94
 
95
-bool unload_filament(const float &unload_length, const bool show_lcd=false, const PauseMode mode=PAUSE_MODE_PAUSE_PRINT);
95
+bool unload_filament(const float &unload_length, const bool show_lcd=false, const PauseMode mode=PAUSE_MODE_PAUSE_PRINT
96
+  #if BOTH(FILAMENT_UNLOAD_ALL_EXTRUDERS, MIXING_EXTRUDER)
97
+    , const float &mix_multiplier=1.0
98
+  #endif
99
+);
96
 
100
 
97
 #endif // ADVANCED_PAUSE_FEATURE
101
 #endif // ADVANCED_PAUSE_FEATURE

+ 23
- 2
Marlin/src/gcode/feature/pause/M600.cpp Ver arquivo

41
   #include "../../../lcd/menu/menu_mmu2.h"
41
   #include "../../../lcd/menu/menu_mmu2.h"
42
 #endif
42
 #endif
43
 
43
 
44
+#if ENABLED(MIXING_EXTRUDER)
45
+  #include "../../../feature/mixing.h"
46
+#endif
47
+
44
 /**
48
 /**
45
  * M600: Pause for filament change
49
  * M600: Pause for filament change
46
  *
50
  *
58
 void GcodeSuite::M600() {
62
 void GcodeSuite::M600() {
59
   point_t park_point = NOZZLE_PARK_POINT;
63
   point_t park_point = NOZZLE_PARK_POINT;
60
 
64
 
61
-  const int8_t target_extruder = get_target_extruder_from_command();
62
-  if (target_extruder < 0) return;
65
+  #if ENABLED(MIXING_EXTRUDER)
66
+    const int8_t target_e_stepper = get_target_e_stepper_from_command();
67
+    if (target_e_stepper < 0) return;
68
+
69
+    const uint8_t old_mixing_tool = mixer.get_current_vtool();
70
+    mixer.T(MIXER_DIRECT_SET_TOOL);
71
+
72
+    MIXER_STEPPER_LOOP(i) mixer.set_collector(i, i == uint8_t(target_e_stepper) ? 1.0 : 0.0);
73
+    mixer.normalize();
74
+
75
+    const int8_t target_extruder = active_extruder;
76
+  #else
77
+    const int8_t target_extruder = get_target_extruder_from_command();
78
+    if (target_extruder < 0) return;
79
+  #endif
63
 
80
 
64
   #if ENABLED(DUAL_X_CARRIAGE)
81
   #if ENABLED(DUAL_X_CARRIAGE)
65
     int8_t DXC_ext = target_extruder;
82
     int8_t DXC_ext = target_extruder;
155
     if (active_extruder_before_filament_change != active_extruder)
172
     if (active_extruder_before_filament_change != active_extruder)
156
       tool_change(active_extruder_before_filament_change, 0, false);
173
       tool_change(active_extruder_before_filament_change, 0, false);
157
   #endif
174
   #endif
175
+
176
+  #if ENABLED(MIXING_EXTRUDER)
177
+    mixer.T(old_mixing_tool); // Restore original mixing tool
178
+  #endif
158
 }
179
 }
159
 
180
 
160
 #endif // ADVANCED_PAUSE_FEATURE
181
 #endif // ADVANCED_PAUSE_FEATURE

+ 61
- 7
Marlin/src/gcode/feature/pause/M701_M702.cpp Ver arquivo

42
   #include "../../../feature/prusa_MMU2/mmu2.h"
42
   #include "../../../feature/prusa_MMU2/mmu2.h"
43
 #endif
43
 #endif
44
 
44
 
45
+#if ENABLED(MIXING_EXTRUDER)
46
+  #include "../../../feature/mixing.h"
47
+#endif
48
+
45
 /**
49
 /**
46
  * M701: Load filament
50
  * M701: Load filament
47
  *
51
  *
48
- *  T<extruder> - Optional extruder number. Current extruder if omitted.
52
+ *  T<extruder> - Extruder number. Required for mixing extruder.
53
+ *                For non-mixing, current extruder if omitted.
49
  *  Z<distance> - Move the Z axis by this distance
54
  *  Z<distance> - Move the Z axis by this distance
50
  *  L<distance> - Extrude distance for insertion (positive value) (manual reload)
55
  *  L<distance> - Extrude distance for insertion (positive value) (manual reload)
51
  *
56
  *
59
     if (axis_unhomed_error()) park_point.z = 0;
64
     if (axis_unhomed_error()) park_point.z = 0;
60
   #endif
65
   #endif
61
 
66
 
62
-  const int8_t target_extruder = get_target_extruder_from_command();
63
-  if (target_extruder < 0) return;
67
+  #if ENABLED(MIXING_EXTRUDER)
68
+    const int8_t target_e_stepper = get_target_e_stepper_from_command();
69
+    if (target_e_stepper < 0) return;
70
+
71
+    const uint8_t old_mixing_tool = mixer.get_current_vtool();
72
+    mixer.T(MIXER_DIRECT_SET_TOOL);
64
 
73
 
74
+    MIXER_STEPPER_LOOP(i) mixer.set_collector(i, (i == (uint8_t)target_e_stepper) ? 1.0 : 0.0);
75
+    mixer.normalize();
76
+
77
+    const int8_t target_extruder = active_extruder;
78
+  #else
79
+    const int8_t target_extruder = get_target_extruder_from_command();
80
+    if (target_extruder < 0) return;
81
+  #endif
65
 
82
 
66
   // Z axis lift
83
   // Z axis lift
67
   if (parser.seenval('Z')) park_point.z = parser.linearval('Z');
84
   if (parser.seenval('Z')) park_point.z = parser.linearval('Z');
107
       tool_change(active_extruder_before_filament_change, 0, false);
124
       tool_change(active_extruder_before_filament_change, 0, false);
108
   #endif
125
   #endif
109
 
126
 
127
+  #if ENABLED(MIXING_EXTRUDER)
128
+    mixer.T(old_mixing_tool); // Restore original mixing tool
129
+  #endif
130
+
110
   // Show status screen
131
   // Show status screen
111
   #if HAS_LCD_MENU
132
   #if HAS_LCD_MENU
112
     lcd_pause_show_message(PAUSE_MESSAGE_STATUS);
133
     lcd_pause_show_message(PAUSE_MESSAGE_STATUS);
116
 /**
137
 /**
117
  * M702: Unload filament
138
  * M702: Unload filament
118
  *
139
  *
119
- *  T<extruder> - Optional extruder number. If omitted, current extruder
140
+ *  T<extruder> - Extruder number. Required for mixing extruder.
141
+ *                For non-mixing, if omitted, current extruder
120
  *                (or ALL extruders with FILAMENT_UNLOAD_ALL_EXTRUDERS).
142
  *                (or ALL extruders with FILAMENT_UNLOAD_ALL_EXTRUDERS).
121
  *  Z<distance> - Move the Z axis by this distance
143
  *  Z<distance> - Move the Z axis by this distance
122
  *  U<distance> - Retract distance for removal (manual reload)
144
  *  U<distance> - Retract distance for removal (manual reload)
131
     if (axis_unhomed_error()) park_point.z = 0;
153
     if (axis_unhomed_error()) park_point.z = 0;
132
   #endif
154
   #endif
133
 
155
 
134
-  const int8_t target_extruder = get_target_extruder_from_command();
135
-  if (target_extruder < 0) return;
156
+  #if ENABLED(MIXING_EXTRUDER)
157
+    const uint8_t old_mixing_tool = mixer.get_current_vtool();
158
+
159
+    #if ENABLED(FILAMENT_UNLOAD_ALL_EXTRUDERS)
160
+      float mix_multiplier = 1.0;
161
+      if (!parser.seenval('T')) {
162
+        mixer.T(MIXER_AUTORETRACT_TOOL);
163
+        mix_multiplier = MIXING_STEPPERS;
164
+      }
165
+      else
166
+    #endif
167
+    {
168
+      const int8_t target_e_stepper = get_target_e_stepper_from_command();
169
+      if (target_e_stepper < 0) return;
170
+
171
+      mixer.T(MIXER_DIRECT_SET_TOOL);
172
+      MIXER_STEPPER_LOOP(i) mixer.set_collector(i, (i == (uint8_t)target_e_stepper) ? 1.0 : 0.0);
173
+      mixer.normalize();
174
+    }
175
+
176
+    const int8_t target_extruder = active_extruder;
177
+  #else
178
+    const float unload_length_multiplier = 1.0;
179
+    const int8_t target_extruder = get_target_extruder_from_command();
180
+    if (target_extruder < 0) return;
181
+  #endif
136
 
182
 
137
   // Z axis lift
183
   // Z axis lift
138
   if (parser.seenval('Z')) park_point.z = parser.linearval('Z');
184
   if (parser.seenval('Z')) park_point.z = parser.linearval('Z');
171
       const float unload_length = -ABS(parser.seen('U') ? parser.value_axis_units(E_AXIS)
217
       const float unload_length = -ABS(parser.seen('U') ? parser.value_axis_units(E_AXIS)
172
                                                         : fc_settings[target_extruder].unload_length);
218
                                                         : fc_settings[target_extruder].unload_length);
173
 
219
 
174
-      unload_filament(unload_length, true, PAUSE_MODE_UNLOAD_FILAMENT);
220
+      unload_filament(unload_length, true, PAUSE_MODE_UNLOAD_FILAMENT
221
+        #if ALL(FILAMENT_UNLOAD_ALL_EXTRUDERS, MIXING_EXTRUDER)
222
+          , mix_multiplier
223
+        #endif
224
+      );
175
     }
225
     }
176
   #endif
226
   #endif
177
 
227
 
185
       tool_change(active_extruder_before_filament_change, 0, false);
235
       tool_change(active_extruder_before_filament_change, 0, false);
186
   #endif
236
   #endif
187
 
237
 
238
+  #if ENABLED(MIXING_EXTRUDER)
239
+    mixer.T(old_mixing_tool); // Restore original mixing tool
240
+  #endif
241
+
188
   // Show status screen
242
   // Show status screen
189
   #if HAS_LCD_MENU
243
   #if HAS_LCD_MENU
190
     lcd_pause_show_message(PAUSE_MESSAGE_STATUS);
244
     lcd_pause_show_message(PAUSE_MESSAGE_STATUS);

+ 22
- 7
Marlin/src/gcode/gcode.cpp Ver arquivo

72
 int8_t GcodeSuite::get_target_extruder_from_command() {
72
 int8_t GcodeSuite::get_target_extruder_from_command() {
73
   if (parser.seenval('T')) {
73
   if (parser.seenval('T')) {
74
     const int8_t e = parser.value_byte();
74
     const int8_t e = parser.value_byte();
75
-    if (e >= EXTRUDERS) {
76
-      SERIAL_ECHO_START();
77
-      SERIAL_CHAR('M'); SERIAL_ECHO(parser.codenum);
78
-      SERIAL_ECHOLNPAIR(" " MSG_INVALID_EXTRUDER " ", int(e));
79
-      return -1;
80
-    }
81
-    return e;
75
+    if (e < EXTRUDERS) return e;
76
+    SERIAL_ECHO_START();
77
+    SERIAL_CHAR('M'); SERIAL_ECHO(parser.codenum);
78
+    SERIAL_ECHOLNPAIR(" " MSG_INVALID_EXTRUDER " ", int(e));
79
+    return -1;
82
   }
80
   }
83
   return active_extruder;
81
   return active_extruder;
84
 }
82
 }
85
 
83
 
86
 /**
84
 /**
85
+ * Get the target e stepper from the T parameter
86
+ * Return -1 if the T parameter is out of range or unspecified
87
+ */
88
+int8_t GcodeSuite::get_target_e_stepper_from_command() {
89
+  const int8_t e = parser.intval('T', -1);
90
+  if (WITHIN(e, 0, E_STEPPERS - 1)) return e;
91
+
92
+  SERIAL_ECHO_START();
93
+  SERIAL_CHAR('M'); SERIAL_ECHO(parser.codenum);
94
+  if (e == -1)
95
+    SERIAL_ECHOLNPGM(" " MSG_E_STEPPER_NOT_SPECIFIED);
96
+  else
97
+    SERIAL_ECHOLNPAIR(" " MSG_INVALID_E_STEPPER " ", int(e));
98
+  return -1;
99
+}
100
+
101
+/**
87
  * Set XYZE destination and feedrate from the current GCode command
102
  * Set XYZE destination and feedrate from the current GCode command
88
  *
103
  *
89
  *  - Set destination from included axis codes
104
  *  - Set destination from included axis codes

+ 1
- 0
Marlin/src/gcode/gcode.h Ver arquivo

298
   FORCE_INLINE static void reset_stepper_timeout() { previous_move_ms = millis(); }
298
   FORCE_INLINE static void reset_stepper_timeout() { previous_move_ms = millis(); }
299
 
299
 
300
   static int8_t get_target_extruder_from_command();
300
   static int8_t get_target_extruder_from_command();
301
+  static int8_t get_target_e_stepper_from_command();
301
   static void get_destination_from_command();
302
   static void get_destination_from_command();
302
 
303
 
303
   static void process_parsed_command(
304
   static void process_parsed_command(

+ 2
- 2
Marlin/src/lcd/menu/menu_mixer.cpp Ver arquivo

101
       MENU_ITEM_EDIT_CALLBACK(int8, MSG_GRADIENT_ALIAS, &mixer.gradient.vtool_index, 0, MIXING_VIRTUAL_TOOLS - 1, mixer.refresh_gradient);
101
       MENU_ITEM_EDIT_CALLBACK(int8, MSG_GRADIENT_ALIAS, &mixer.gradient.vtool_index, 0, MIXING_VIRTUAL_TOOLS - 1, mixer.refresh_gradient);
102
     #endif
102
     #endif
103
 
103
 
104
-    char tmp[10];
104
+    char tmp[18];
105
 
105
 
106
     MENU_ITEM(submenu, MSG_START_Z ":", lcd_mixer_gradient_z_start_edit);
106
     MENU_ITEM(submenu, MSG_START_Z ":", lcd_mixer_gradient_z_start_edit);
107
     MENU_ITEM_ADDON_START(9);
107
     MENU_ITEM_ADDON_START(9);
298
 
298
 
299
   #if ENABLED(GRADIENT_MIX)
299
   #if ENABLED(GRADIENT_MIX)
300
   {
300
   {
301
-    char tmp[10];
301
+    char tmp[13];
302
     MENU_ITEM(submenu, MSG_GRADIENT, lcd_mixer_edit_gradient_menu);
302
     MENU_ITEM(submenu, MSG_GRADIENT, lcd_mixer_edit_gradient_menu);
303
     MENU_ITEM_ADDON_START(10);
303
     MENU_ITEM_ADDON_START(10);
304
       sprintf_P(tmp, PSTR("T%i->T%i"), mixer.gradient.start_vtool, mixer.gradient.end_vtool);
304
       sprintf_P(tmp, PSTR("T%i->T%i"), mixer.gradient.start_vtool, mixer.gradient.end_vtool);

+ 2
- 2
Marlin/src/lcd/menu/menu_ubl.cpp Ver arquivo

228
  * UBL Grid Leveling Command
228
  * UBL Grid Leveling Command
229
  */
229
  */
230
 void _lcd_ubl_grid_level_cmd() {
230
 void _lcd_ubl_grid_level_cmd() {
231
-  char UBL_LCD_GCODE[10];
231
+  char UBL_LCD_GCODE[12];
232
   sprintf_P(UBL_LCD_GCODE, PSTR("G29 J%i"), side_points);
232
   sprintf_P(UBL_LCD_GCODE, PSTR("G29 J%i"), side_points);
233
   lcd_enqueue_command(UBL_LCD_GCODE);
233
   lcd_enqueue_command(UBL_LCD_GCODE);
234
 }
234
 }
269
  * UBL Fill-in Amount Mesh Command
269
  * UBL Fill-in Amount Mesh Command
270
  */
270
  */
271
 void _lcd_ubl_fillin_amount_cmd() {
271
 void _lcd_ubl_fillin_amount_cmd() {
272
-  char UBL_LCD_GCODE[16];
272
+  char UBL_LCD_GCODE[18];
273
   sprintf_P(UBL_LCD_GCODE, PSTR("G29 P3 R C.%i"), ubl_fillin_amount);
273
   sprintf_P(UBL_LCD_GCODE, PSTR("G29 P3 R C.%i"), ubl_fillin_amount);
274
   lcd_enqueue_command(UBL_LCD_GCODE);
274
   lcd_enqueue_command(UBL_LCD_GCODE);
275
 }
275
 }

+ 15
- 3
Marlin/src/module/motion.cpp Ver arquivo

982
           }
982
           }
983
         #endif // PREVENT_COLD_EXTRUSION
983
         #endif // PREVENT_COLD_EXTRUSION
984
         #if ENABLED(PREVENT_LENGTHY_EXTRUDE)
984
         #if ENABLED(PREVENT_LENGTHY_EXTRUDE)
985
-          if (ABS(destination[E_AXIS] - current_position[E_AXIS]) * planner.e_factor[active_extruder] > (EXTRUDE_MAXLENGTH)) {
986
-            current_position[E_AXIS] = destination[E_AXIS]; // Behave as if the move really took place, but ignore E part
987
-            SERIAL_ECHO_MSG(MSG_ERR_LONG_EXTRUDE_STOP);
985
+          const float e_delta = ABS(destination[E_AXIS] - current_position[E_AXIS]) * planner.e_factor[active_extruder];
986
+          if (e_delta > (EXTRUDE_MAXLENGTH)) {
987
+            #if ENABLED(MIXING_EXTRUDER)
988
+              bool ignore_e = false;
989
+              float collector[MIXING_STEPPERS];
990
+              mixer.refresh_collector(1.0, mixer.get_current_vtool(), collector);
991
+              MIXER_STEPPER_LOOP(e)
992
+                if (e_delta * collector[e] > (EXTRUDE_MAXLENGTH)) { ignore_e = true; break; }
993
+            #else
994
+              constexpr bool ignore_e = true;
995
+            #endif
996
+            if (ignore_e) {
997
+              current_position[E_AXIS] = destination[E_AXIS]; // Behave as if the move really took place, but ignore E part
998
+              SERIAL_ECHO_MSG(MSG_ERR_LONG_EXTRUDE_STOP);
999
+            }
988
           }
1000
           }
989
         #endif // PREVENT_LENGTHY_EXTRUDE
1001
         #endif // PREVENT_LENGTHY_EXTRUDE
990
       }
1002
       }

+ 19
- 6
Marlin/src/module/planner.cpp Ver arquivo

1767
         }
1767
         }
1768
       #endif // PREVENT_COLD_EXTRUSION
1768
       #endif // PREVENT_COLD_EXTRUSION
1769
       #if ENABLED(PREVENT_LENGTHY_EXTRUDE)
1769
       #if ENABLED(PREVENT_LENGTHY_EXTRUDE)
1770
-        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
1771
-          position[E_AXIS] = target[E_AXIS]; // Behave as if the move really took place, but ignore E part
1772
-          #if HAS_POSITION_FLOAT
1773
-            position_float[E_AXIS] = target_float[E_AXIS];
1770
+        const float e_steps = ABS(de * e_factor[extruder]);
1771
+        const float max_e_steps = settings.axis_steps_per_mm[E_AXIS_N(extruder)] * (EXTRUDE_MAXLENGTH);
1772
+        if (e_steps > max_e_steps) {
1773
+          #if ENABLED(MIXING_EXTRUDER)
1774
+            bool ignore_e = false;
1775
+            float collector[MIXING_STEPPERS];
1776
+            mixer.refresh_collector(1.0, mixer.get_current_vtool(), collector);
1777
+            MIXER_STEPPER_LOOP(e)
1778
+              if (e_steps * collector[e] > max_e_steps) { ignore_e = true; break; }
1779
+          #else
1780
+            constexpr bool ignore_e = true;
1774
           #endif
1781
           #endif
1775
-          de = 0; // no difference
1776
-          SERIAL_ECHO_MSG(MSG_ERR_LONG_EXTRUDE_STOP);
1782
+          if (ignore_e) {
1783
+            position[E_AXIS] = target[E_AXIS]; // Behave as if the move really took place, but ignore E part
1784
+            #if HAS_POSITION_FLOAT
1785
+              position_float[E_AXIS] = target_float[E_AXIS];
1786
+            #endif
1787
+            de = 0; // no difference
1788
+            SERIAL_ECHO_MSG(MSG_ERR_LONG_EXTRUDE_STOP);
1789
+          }
1777
         }
1790
         }
1778
       #endif // PREVENT_LENGTHY_EXTRUDE
1791
       #endif // PREVENT_LENGTHY_EXTRUDE
1779
     }
1792
     }

+ 5
- 2
Marlin/src/module/temperature.cpp Ver arquivo

2825
     ) {
2825
     ) {
2826
       #if TEMP_BED_RESIDENCY_TIME > 0
2826
       #if TEMP_BED_RESIDENCY_TIME > 0
2827
         millis_t residency_start_ms = 0;
2827
         millis_t residency_start_ms = 0;
2828
+        bool first_loop = true;
2828
         // Loop until the temperature has stabilized
2829
         // Loop until the temperature has stabilized
2829
         #define TEMP_BED_CONDITIONS (!residency_start_ms || PENDING(now, residency_start_ms + (TEMP_BED_RESIDENCY_TIME) * 1000UL))
2830
         #define TEMP_BED_CONDITIONS (!residency_start_ms || PENDING(now, residency_start_ms + (TEMP_BED_RESIDENCY_TIME) * 1000UL))
2830
       #else
2831
       #else
2833
       #endif
2834
       #endif
2834
 
2835
 
2835
       float target_temp = -1, old_temp = 9999;
2836
       float target_temp = -1, old_temp = 9999;
2836
-      bool wants_to_cool = false, first_loop = true;
2837
+      bool wants_to_cool = false;
2837
       wait_for_heatup = true;
2838
       wait_for_heatup = true;
2838
       millis_t now, next_temp_ms = 0, next_cool_check_ms = 0;
2839
       millis_t now, next_temp_ms = 0, next_cool_check_ms = 0;
2839
 
2840
 
2917
           }
2918
           }
2918
         #endif
2919
         #endif
2919
 
2920
 
2920
-        first_loop = false;
2921
+        #if TEMP_BED_RESIDENCY_TIME > 0
2922
+          first_loop = false;
2923
+        #endif
2921
 
2924
 
2922
       } while (wait_for_heatup && TEMP_BED_CONDITIONS);
2925
       } while (wait_for_heatup && TEMP_BED_CONDITIONS);
2923
 
2926
 

Carregando…
Cancelar
Salvar