|
@@ -91,6 +91,9 @@ MMU2 mmu2;
|
91
|
91
|
#define mmuSerial MMU2_SERIAL
|
92
|
92
|
|
93
|
93
|
bool MMU2::enabled, MMU2::ready, MMU2::mmu_print_saved;
|
|
94
|
+#if ENABLED(PRUSA_MMU2_S_MODE)
|
|
95
|
+ bool MMU2::mmu2s_triggered;
|
|
96
|
+#endif
|
94
|
97
|
uint8_t MMU2::cmd, MMU2::cmd_arg, MMU2::last_cmd, MMU2::extruder;
|
95
|
98
|
int8_t MMU2::state = 0;
|
96
|
99
|
volatile int8_t MMU2::finda = 1;
|
|
@@ -106,8 +109,14 @@ char MMU2::rx_buffer[MMU_RX_SIZE], MMU2::tx_buffer[MMU_TX_SIZE];
|
106
|
109
|
feedRate_t feedRate; //!< feed rate in mm/s
|
107
|
110
|
};
|
108
|
111
|
|
109
|
|
- static constexpr E_Step ramming_sequence[] PROGMEM = { MMU2_RAMMING_SEQUENCE };
|
110
|
|
- static constexpr E_Step load_to_nozzle_sequence[] PROGMEM = { MMU2_LOAD_TO_NOZZLE_SEQUENCE };
|
|
112
|
+ static constexpr E_Step
|
|
113
|
+ ramming_sequence[] PROGMEM = { MMU2_RAMMING_SEQUENCE }
|
|
114
|
+ , load_to_nozzle_sequence[] PROGMEM = { MMU2_LOAD_TO_NOZZLE_SEQUENCE }
|
|
115
|
+ #if ENABLED(PRUSA_MMU2_S_MODE)
|
|
116
|
+ , can_load_sequence[] PROGMEM = { MMU2_CAN_LOAD_SEQUENCE }
|
|
117
|
+ , can_load_increment_sequence[] PROGMEM = { MMU2_CAN_LOAD_INCREMENT_SEQUENCE }
|
|
118
|
+ #endif
|
|
119
|
+ ;
|
111
|
120
|
|
112
|
121
|
#endif // MMU2_MENUS
|
113
|
122
|
|
|
@@ -228,6 +237,7 @@ void MMU2::mmu_loop() {
|
228
|
237
|
|
229
|
238
|
enabled = true;
|
230
|
239
|
state = 1;
|
|
240
|
+ TERN_(PRUSA_MMU2_S_MODE, mmu2s_triggered = false);
|
231
|
241
|
}
|
232
|
242
|
break;
|
233
|
243
|
|
|
@@ -291,6 +301,8 @@ void MMU2::mmu_loop() {
|
291
|
301
|
tx_str_P(PSTR("P0\n"));
|
292
|
302
|
state = 2; // wait for response
|
293
|
303
|
}
|
|
304
|
+
|
|
305
|
+ TERN_(PRUSA_MMU2_S_MODE, check_filament());
|
294
|
306
|
break;
|
295
|
307
|
|
296
|
308
|
case 2: // response to command P0
|
|
@@ -309,6 +321,7 @@ void MMU2::mmu_loop() {
|
309
|
321
|
else if (ELAPSED(millis(), last_request + MMU_P0_TIMEOUT)) // Resend request after timeout (3s)
|
310
|
322
|
state = 1;
|
311
|
323
|
|
|
324
|
+ TERN_(PRUSA_MMU2_S_MODE, check_filament());
|
312
|
325
|
break;
|
313
|
326
|
|
314
|
327
|
case 3: // response to mmu commands
|
|
@@ -327,6 +340,7 @@ void MMU2::mmu_loop() {
|
327
|
340
|
}
|
328
|
341
|
state = 1;
|
329
|
342
|
}
|
|
343
|
+ TERN_(PRUSA_MMU2_S_MODE, check_filament());
|
330
|
344
|
break;
|
331
|
345
|
}
|
332
|
346
|
}
|
|
@@ -437,6 +451,33 @@ void MMU2::check_version() {
|
437
|
451
|
}
|
438
|
452
|
}
|
439
|
453
|
|
|
454
|
+static bool mmu2_not_responding() {
|
|
455
|
+ LCD_MESSAGEPGM(MSG_MMU2_NOT_RESPONDING);
|
|
456
|
+ BUZZ(100, 659);
|
|
457
|
+ BUZZ(200, 698);
|
|
458
|
+ BUZZ(100, 659);
|
|
459
|
+ BUZZ(300, 440);
|
|
460
|
+ BUZZ(100, 659);
|
|
461
|
+}
|
|
462
|
+
|
|
463
|
+#if ENABLED(PRUSA_MMU2_S_MODE)
|
|
464
|
+
|
|
465
|
+ bool MMU2::load_to_gears() {
|
|
466
|
+ command(MMU_CMD_C0);
|
|
467
|
+ manage_response(true, true);
|
|
468
|
+ LOOP_L_N(i, MMU2_C0_RETRY) { // Keep loading until filament reaches gears
|
|
469
|
+ if (mmu2s_triggered) break;
|
|
470
|
+ command(MMU_CMD_C0);
|
|
471
|
+ manage_response(true, true);
|
|
472
|
+ check_filament();
|
|
473
|
+ }
|
|
474
|
+ const bool success = mmu2s_triggered && can_load();
|
|
475
|
+ if (!success) mmu2_not_responding();
|
|
476
|
+ return success;
|
|
477
|
+ }
|
|
478
|
+
|
|
479
|
+#endif
|
|
480
|
+
|
440
|
481
|
/**
|
441
|
482
|
* Handle tool change
|
442
|
483
|
*/
|
|
@@ -452,18 +493,15 @@ void MMU2::tool_change(uint8_t index) {
|
452
|
493
|
ui.status_printf_P(0, GET_TEXT(MSG_MMU2_LOADING_FILAMENT), int(index + 1));
|
453
|
494
|
|
454
|
495
|
command(MMU_CMD_T0 + index);
|
455
|
|
-
|
456
|
496
|
manage_response(true, true);
|
457
|
497
|
|
458
|
|
- command(MMU_CMD_C0);
|
459
|
|
- extruder = index; //filament change is finished
|
460
|
|
- active_extruder = 0;
|
461
|
|
-
|
462
|
|
- ENABLE_AXIS_E0();
|
463
|
|
-
|
464
|
|
- SERIAL_ECHO_START();
|
465
|
|
- SERIAL_ECHOLNPAIR(STR_ACTIVE_EXTRUDER, int(extruder));
|
466
|
|
-
|
|
498
|
+ if (load_to_gears()) {
|
|
499
|
+ extruder = index; // filament change is finished
|
|
500
|
+ active_extruder = 0;
|
|
501
|
+ ENABLE_AXIS_E0();
|
|
502
|
+ SERIAL_ECHO_START();
|
|
503
|
+ SERIAL_ECHOLNPAIR(STR_ACTIVE_EXTRUDER, int(extruder));
|
|
504
|
+ }
|
467
|
505
|
ui.reset_status();
|
468
|
506
|
}
|
469
|
507
|
|
|
@@ -500,12 +538,13 @@ void MMU2::tool_change(const char* special) {
|
500
|
538
|
DISABLE_AXIS_E0();
|
501
|
539
|
command(MMU_CMD_T0 + index);
|
502
|
540
|
manage_response(true, true);
|
503
|
|
- command(MMU_CMD_C0);
|
504
|
|
- mmu_loop();
|
505
|
541
|
|
506
|
|
- ENABLE_AXIS_E0();
|
507
|
|
- extruder = index;
|
508
|
|
- active_extruder = 0;
|
|
542
|
+ if (load_to_gears()) {
|
|
543
|
+ mmu_loop();
|
|
544
|
+ ENABLE_AXIS_E0();
|
|
545
|
+ extruder = index;
|
|
546
|
+ active_extruder = 0;
|
|
547
|
+ }
|
509
|
548
|
} break;
|
510
|
549
|
|
511
|
550
|
case 'c': {
|
|
@@ -579,12 +618,7 @@ void MMU2::manage_response(const bool move_axes, const bool turn_off_nozzle) {
|
579
|
618
|
|
580
|
619
|
if (turn_off_nozzle) thermalManager.setTargetHotend(0, active_extruder);
|
581
|
620
|
|
582
|
|
- LCD_MESSAGEPGM(MSG_MMU2_NOT_RESPONDING);
|
583
|
|
- BUZZ(100, 659);
|
584
|
|
- BUZZ(200, 698);
|
585
|
|
- BUZZ(100, 659);
|
586
|
|
- BUZZ(300, 440);
|
587
|
|
- BUZZ(100, 659);
|
|
621
|
+ mmu2_not_responding();
|
588
|
622
|
}
|
589
|
623
|
}
|
590
|
624
|
else if (mmu_print_saved) {
|
|
@@ -632,6 +666,39 @@ void MMU2::filament_runout() {
|
632
|
666
|
planner.synchronize();
|
633
|
667
|
}
|
634
|
668
|
|
|
669
|
+#if ENABLED(PRUSA_MMU2_S_MODE)
|
|
670
|
+ void MMU2::check_filament() {
|
|
671
|
+ const bool runout = READ(FIL_RUNOUT_PIN) ^ (FIL_RUNOUT_INVERTING);
|
|
672
|
+ if (runout && !mmu2s_triggered) {
|
|
673
|
+ DEBUG_ECHOLNPGM("MMU <= 'A'");
|
|
674
|
+ tx_str_P(PSTR("A\n"));
|
|
675
|
+ }
|
|
676
|
+ mmu2s_triggered = runout;
|
|
677
|
+ }
|
|
678
|
+
|
|
679
|
+ bool MMU2::can_load() {
|
|
680
|
+ execute_extruder_sequence((const E_Step *)can_load_sequence, COUNT(can_load_sequence));
|
|
681
|
+
|
|
682
|
+ int filament_detected_count = 0;
|
|
683
|
+ const int steps = MMU2_CAN_LOAD_RETRACT / MMU2_CAN_LOAD_INCREMENT;
|
|
684
|
+ DEBUG_ECHOLNPGM("MMU can_load:");
|
|
685
|
+ LOOP_L_N(i, steps) {
|
|
686
|
+ execute_extruder_sequence((const E_Step *)can_load_increment_sequence, COUNT(can_load_increment_sequence));
|
|
687
|
+ check_filament(); // Don't trust the idle function
|
|
688
|
+ DEBUG_CHAR(mmu2s_triggered ? 'O' : 'o');
|
|
689
|
+ if (mmu2s_triggered) ++filament_detected_count;
|
|
690
|
+ }
|
|
691
|
+
|
|
692
|
+ if (filament_detected_count <= steps - (MMU2_CAN_LOAD_DEVIATION / MMU2_CAN_LOAD_INCREMENT)) {
|
|
693
|
+ DEBUG_ECHOLNPGM(" failed.");
|
|
694
|
+ return false;
|
|
695
|
+ }
|
|
696
|
+
|
|
697
|
+ DEBUG_ECHOLNPGM(" succeeded.");
|
|
698
|
+ return true;
|
|
699
|
+ }
|
|
700
|
+#endif
|
|
701
|
+
|
635
|
702
|
#if BOTH(HAS_LCD_MENU, MMU2_MENUS)
|
636
|
703
|
|
637
|
704
|
// Load filament into MMU2
|
|
@@ -656,20 +723,19 @@ void MMU2::filament_runout() {
|
656
|
723
|
LCD_ALERTMESSAGEPGM(MSG_HOTEND_TOO_COLD);
|
657
|
724
|
return false;
|
658
|
725
|
}
|
659
|
|
- else {
|
660
|
|
- command(MMU_CMD_T0 + index);
|
661
|
|
- manage_response(true, true);
|
662
|
|
- command(MMU_CMD_C0);
|
663
|
|
- mmu_loop();
|
664
|
726
|
|
|
727
|
+ command(MMU_CMD_T0 + index);
|
|
728
|
+ manage_response(true, true);
|
|
729
|
+
|
|
730
|
+ const bool success = load_to_gears();
|
|
731
|
+ if (success) {
|
|
732
|
+ mmu_loop();
|
665
|
733
|
extruder = index;
|
666
|
734
|
active_extruder = 0;
|
667
|
|
-
|
668
|
735
|
load_to_nozzle();
|
669
|
|
-
|
670
|
736
|
BUZZ(200, 404);
|
671
|
|
- return true;
|
672
|
737
|
}
|
|
738
|
+ return success;
|
673
|
739
|
}
|
674
|
740
|
|
675
|
741
|
/**
|