Sfoglia il codice sorgente

MMU2 Extruder Sensor support (#17886)

Bastien R 4 anni fa
parent
commit
2ec482a102
Nessun account collegato all'indirizzo email del committer

+ 20
- 2
Marlin/Configuration_adv.h Vedi File

@@ -3279,7 +3279,7 @@
3279 3279
     // This is for Prusa MK3-style extruders. Customize for your hardware.
3280 3280
     #define MMU2_FILAMENTCHANGE_EJECT_FEED 80.0
3281 3281
     #define MMU2_LOAD_TO_NOZZLE_SEQUENCE \
3282
-      {  7.2,  562 }, \
3282
+      {  7.2, 1145 }, \
3283 3283
       { 14.4,  871 }, \
3284 3284
       { 36.0, 1393 }, \
3285 3285
       { 14.4,  871 }, \
@@ -3299,7 +3299,25 @@
3299 3299
       { -50.0, 2000 }
3300 3300
   #endif
3301 3301
 
3302
-  // Using a sensor like the MMU2S
3302
+  /**
3303
+   * MMU Extruder Sensor
3304
+   * Add support for Prusa IR Sensor (or other) to detect that filament reach the extruder to make loading filament more reliable
3305
+   * If your extruder is equipped with a filament sensor located less than 38mm from the gears you can use this feature
3306
+   * During loading to the extruder, the sensor will stop the loading command when he's triggered and make a last move to load filament to the gears
3307
+   * If no filament is detected, MMU2 will make more loading attemps, if finally no filament is detected, the printer will enter in runout state
3308
+   */
3309
+
3310
+  //#define MMU_EXTRUDER_SENSOR
3311
+  #if ENABLED(MMU_EXTRUDER_SENSOR) 
3312
+    #define MMU_LOADING_ATTEMPTS_NR 5 //max. number of attempts to load filament if first load fail
3313
+  #endif
3314
+
3315
+  /**
3316
+   * Using a sensor like the MMU2S
3317
+   * This mode only work if you have a MK3S extruder with sensor sensing the extruder idler mmu2s
3318
+   * See https://help.prusa3d.com/en/guide/3b-mk3s-mk2-5s-extruder-upgrade_41560, step 11
3319
+   */
3320
+
3303 3321
   //#define PRUSA_MMU2_S_MODE
3304 3322
   #if ENABLED(PRUSA_MMU2_S_MODE)
3305 3323
     #define MMU2_C0_RETRY   5             // Number of retries (total time = timeout*retries)

+ 245
- 55
Marlin/src/feature/mmu2/mmu2.cpp Vedi File

@@ -51,8 +51,13 @@ MMU2 mmu2;
51 51
 
52 52
 #define MMU_TODELAY 100
53 53
 #define MMU_TIMEOUT 10
54
-#define MMU_CMD_TIMEOUT 60000ul // 5min timeout for mmu commands (except P0)
55
-#define MMU_P0_TIMEOUT 3000ul   // Timeout for P0 command: 3seconds
54
+#define MMU_CMD_TIMEOUT 45000UL // 45s timeout for mmu commands (except P0)
55
+#define MMU_P0_TIMEOUT 3000UL   // Timeout for P0 command: 3seconds
56
+
57
+#if ENABLED(MMU_EXTRUDER_SENSOR)
58
+  uint8_t mmu_idl_sens = 0;
59
+  static bool mmu_loading_flag = false;
60
+#endif
56 61
 
57 62
 #define MMU_CMD_NONE 0
58 63
 #define MMU_CMD_T0   0x10
@@ -79,11 +84,7 @@ MMU2 mmu2;
79 84
 #define MMU_CMD_F3   0x73
80 85
 #define MMU_CMD_F4   0x74
81 86
 
82
-#if ENABLED(MMU2_MODE_12V)
83
-  #define MMU_REQUIRED_FW_BUILDNR 132
84
-#else
85
-  #define MMU_REQUIRED_FW_BUILDNR 126
86
-#endif
87
+#define MMU_REQUIRED_FW_BUILDNR TERN(MMU2_MODE_12V, 132, 126)
87 88
 
88 89
 #define MMU2_NO_TOOL 99
89 90
 #define MMU_BAUD    115200
@@ -99,7 +100,7 @@ int8_t MMU2::state = 0;
99 100
 volatile int8_t MMU2::finda = 1;
100 101
 volatile bool MMU2::finda_runout_valid;
101 102
 int16_t MMU2::version = -1, MMU2::buildnr = -1;
102
-millis_t MMU2::last_request, MMU2::next_P0_request;
103
+millis_t MMU2::prev_request, MMU2::prev_P0_request;
103 104
 char MMU2::rx_buffer[MMU_RX_SIZE], MMU2::tx_buffer[MMU_TX_SIZE];
104 105
 
105 106
 #if BOTH(HAS_LCD_MENU, MMU2_MENUS)
@@ -159,6 +160,10 @@ uint8_t MMU2::get_current_tool() {
159 160
   return extruder == MMU2_NO_TOOL ? -1 : extruder;
160 161
 }
161 162
 
163
+#if EITHER(PRUSA_MMU2_S_MODE, MMU_EXTRUDER_SENSOR)
164
+  #define FILAMENT_PRESENT() (READ(FIL_RUNOUT_PIN) != FIL_RUNOUT_INVERTING)
165
+#endif
166
+
162 167
 void MMU2::mmu_loop() {
163 168
 
164 169
   switch (state) {
@@ -248,6 +253,7 @@ void MMU2::mmu_loop() {
248 253
           int filament = cmd - MMU_CMD_T0;
249 254
           DEBUG_ECHOLNPAIR("MMU <= T", filament);
250 255
           tx_printf_P(PSTR("T%d\n"), filament);
256
+          TERN_(MMU_EXTRUDER_SENSOR, mmu_idl_sens = 1); // enable idler sensor, if any
251 257
           state = 3; // wait for response
252 258
         }
253 259
         else if (WITHIN(cmd, MMU_CMD_L0, MMU_CMD_L4)) {
@@ -296,7 +302,7 @@ void MMU2::mmu_loop() {
296 302
         last_cmd = cmd;
297 303
         cmd = MMU_CMD_NONE;
298 304
       }
299
-      else if (ELAPSED(millis(), next_P0_request)) {
305
+      else if (ELAPSED(millis(), prev_P0_request + 300)) {
300 306
         // read FINDA
301 307
         tx_str_P(PSTR("P0\n"));
302 308
         state = 2; // wait for response
@@ -312,26 +318,35 @@ void MMU2::mmu_loop() {
312 318
         // This is super annoying. Only activate if necessary
313 319
         // if (finda_runout_valid) DEBUG_ECHOLNPAIR_F("MMU <= 'P0'\nMMU => ", finda, 6);
314 320
 
315
-        state = 1;
316
-
317
-        if (cmd == 0) ready = true;
318
-
319 321
         if (!finda && finda_runout_valid) filament_runout();
322
+        if (cmd == 0) ready = true;
323
+        state = 1;
320 324
       }
321
-      else if (ELAPSED(millis(), last_request + MMU_P0_TIMEOUT)) // Resend request after timeout (3s)
325
+      else if (ELAPSED(millis(), prev_request + MMU_P0_TIMEOUT)) // Resend request after timeout (3s)
322 326
         state = 1;
323 327
 
324 328
       TERN_(PRUSA_MMU2_S_MODE, check_filament());
325 329
       break;
326 330
 
327 331
     case 3:   // response to mmu commands
332
+      #if ENABLED(MMU_EXTRUDER_SENSOR)
333
+        if (mmu_idl_sens) {
334
+          if (FILAMENT_PRESENT() && mmu_loading_flag) {
335
+            DEBUG_ECHOLNPGM("MMU <= 'A'\n");
336
+            tx_str_P(PSTR("A\n")); // send 'abort' request
337
+            mmu_idl_sens = 0;
338
+            DEBUG_ECHOLNPGM("MMU IDLER_SENSOR = 0 - ABORT\n");
339
+          }
340
+        }
341
+      #endif
342
+
328 343
       if (rx_ok()) {
329 344
         DEBUG_ECHOLNPGM("MMU => 'ok'");
330 345
         ready = true;
331 346
         state = 1;
332 347
         last_cmd = MMU_CMD_NONE;
333 348
       }
334
-      else if (ELAPSED(millis(), last_request + MMU_CMD_TIMEOUT)) {
349
+      else if (ELAPSED(millis(), prev_request + MMU_CMD_TIMEOUT)) {
335 350
         // resend request after timeout
336 351
         if (last_cmd) {
337 352
           DEBUG_ECHOLNPGM("MMU retry");
@@ -351,7 +366,7 @@ void MMU2::mmu_loop() {
351 366
 bool MMU2::rx_start() {
352 367
   // check for start message
353 368
   if (rx_str_P(PSTR("start\n"))) {
354
-    next_P0_request = millis() + 300;
369
+    prev_P0_request = millis();
355 370
     return true;
356 371
   }
357 372
   return false;
@@ -397,7 +412,7 @@ void MMU2::tx_str_P(const char* str) {
397 412
   uint8_t len = strlen_P(str);
398 413
   LOOP_L_N(i, len) mmuSerial.write(pgm_read_byte(str++));
399 414
   rx_buffer[0] = '\0';
400
-  last_request = millis();
415
+  prev_request = millis();
401 416
 }
402 417
 
403 418
 /**
@@ -408,7 +423,7 @@ void MMU2::tx_printf_P(const char* format, int argument = -1) {
408 423
   uint8_t len = sprintf_P(tx_buffer, format, argument);
409 424
   LOOP_L_N(i, len) mmuSerial.write(tx_buffer[i]);
410 425
   rx_buffer[0] = '\0';
411
-  last_request = millis();
426
+  prev_request = millis();
412 427
 }
413 428
 
414 429
 /**
@@ -419,7 +434,7 @@ void MMU2::tx_printf_P(const char* format, int argument1, int argument2) {
419 434
   uint8_t len = sprintf_P(tx_buffer, format, argument1, argument2);
420 435
   LOOP_L_N(i, len) mmuSerial.write(tx_buffer[i]);
421 436
   rx_buffer[0] = '\0';
422
-  last_request = millis();
437
+  prev_request = millis();
423 438
 }
424 439
 
425 440
 /**
@@ -435,7 +450,7 @@ void MMU2::clear_rx_buffer() {
435 450
  */
436 451
 bool MMU2::rx_ok() {
437 452
   if (rx_str_P(PSTR("ok\n"))) {
438
-    next_P0_request = millis() + 300;
453
+    prev_P0_request = millis();
439 454
     return true;
440 455
   }
441 456
   return false;
@@ -476,32 +491,206 @@ static bool mmu2_not_responding() {
476 491
     return success;
477 492
   }
478 493
 
479
-#endif
494
+  /**
495
+   * Handle tool change
496
+   */
497
+  void MMU2::tool_change(const uint8_t index) {
498
+
499
+    if (!enabled) return;
500
+
501
+    set_runout_valid(false);
502
+
503
+    if (index != extruder) {
504
+
505
+      DISABLE_AXIS_E0();
506
+      ui.status_printf_P(0, GET_TEXT(MSG_MMU2_LOADING_FILAMENT), int(index + 1));
507
+
508
+      command(MMU_CMD_T0 + index);
509
+      manage_response(true, true);
510
+
511
+      if (load_to_gears()) {
512
+        extruder = index; // filament change is finished
513
+        active_extruder = 0;
514
+        ENABLE_AXIS_E0();
515
+        SERIAL_ECHO_START();
516
+        SERIAL_ECHOLNPAIR(STR_ACTIVE_EXTRUDER, int(extruder));
517
+      }
518
+      ui.reset_status();
519
+    }
520
+
521
+    set_runout_valid(true);
522
+  }
523
+
524
+  /**
525
+   * Handle special T?/Tx/Tc commands
526
+   *
527
+   * T? Gcode to extrude shouldn't have to follow, load to extruder wheels is done automatically
528
+   * Tx Same as T?, except nozzle doesn't have to be preheated. Tc must be placed after extruder nozzle is preheated to finish filament load.
529
+   * Tc Load to nozzle after filament was prepared by Tx and extruder nozzle is already heated.
530
+   */
531
+  void MMU2::tool_change(const char* special) {
532
+
533
+    if (!enabled) return;
534
+
535
+    #if ENABLED(MMU2_MENUS)
536
+
537
+      set_runout_valid(false);
538
+
539
+      switch (*special) {
540
+        case '?': {
541
+          uint8_t index = mmu2_choose_filament();
542
+          while (!thermalManager.wait_for_hotend(active_extruder, false)) safe_delay(100);
543
+          load_filament_to_nozzle(index);
544
+        } break;
545
+
546
+        case 'x': {
547
+          planner.synchronize();
548
+          uint8_t index = mmu2_choose_filament();
549
+          DISABLE_AXIS_E0();
550
+          command(MMU_CMD_T0 + index);
551
+          manage_response(true, true);
552
+
553
+          if (load_to_gears()) {
554
+            mmu_loop();
555
+            ENABLE_AXIS_E0();
556
+            extruder = index;
557
+            active_extruder = 0;
558
+          }
559
+        } break;
560
+
561
+        case 'c': {
562
+          while (!thermalManager.wait_for_hotend(active_extruder, false)) safe_delay(100);
563
+          execute_extruder_sequence((const E_Step *)load_to_nozzle_sequence, COUNT(load_to_nozzle_sequence));
564
+        } break;
565
+      }
566
+
567
+      set_runout_valid(true);
568
+
569
+    #endif // MMU2_MENUS
570
+  }
571
+
572
+#elif ENABLED(MMU_EXTRUDER_SENSOR)
573
+
574
+  /**
575
+   * Handle tool change
576
+   */
577
+  void MMU2::tool_change(const uint8_t index) {
578
+    if (!enabled) return;
579
+
580
+    set_runout_valid(false);
581
+
582
+    if (index != extruder) {
583
+      DISABLE_AXIS_E0();
584
+      if (FILAMENT_PRESENT()) {
585
+        DEBUG_ECHOLNPGM("Unloading\n");
586
+        mmu_loading_flag = false;
587
+        command(MMU_CMD_U0);
588
+        manage_response(true, true);
589
+      }
590
+      ui.status_printf_P(0, GET_TEXT(MSG_MMU2_LOADING_FILAMENT), int(index + 1));
591
+      mmu_loading_flag = true;
592
+      command(MMU_CMD_T0 + index);
593
+      manage_response(true, true);
594
+      mmu_continue_loading();
595
+      command(MMU_CMD_C0);
596
+      extruder = index;
597
+      active_extruder = 0;
598
+
599
+      ENABLE_AXIS_E0();
600
+      SERIAL_ECHO_START();
601
+      SERIAL_ECHOLNPAIR(STR_ACTIVE_EXTRUDER, int(extruder));
602
+
603
+      ui.reset_status();
604
+    }
605
+
606
+    set_runout_valid(true);
607
+  }
608
+
609
+  /**
610
+   * Handle special T?/Tx/Tc commands
611
+   *
612
+   * T? Gcode to extrude shouldn't have to follow, load to extruder wheels is done automatically
613
+   * Tx Same as T?, except nozzle doesn't have to be preheated. Tc must be placed after extruder nozzle is preheated to finish filament load.
614
+   * Tc Load to nozzle after filament was prepared by Tx and extruder nozzle is already heated.
615
+   */
616
+  void MMU2::tool_change(const char* special) {
617
+    if (!enabled) return;
618
+
619
+    #if ENABLED(MMU2_MENUS)
620
+
621
+      set_runout_valid(false);
622
+
623
+      switch (*special) {
624
+        case '?': {
625
+          DEBUG_ECHOLNPGM("case ?\n");
626
+          uint8_t index = mmu2_choose_filament();
627
+          while (!thermalManager.wait_for_hotend(active_extruder, false)) safe_delay(100);
628
+          load_filament_to_nozzle(index);
629
+        } break;
630
+
631
+        case 'x': {
632
+          DEBUG_ECHOLNPGM("case x\n");
633
+          planner.synchronize();
634
+          uint8_t index = mmu2_choose_filament();
635
+          DISABLE_AXIS_E0();
636
+          command(MMU_CMD_T0 + index);
637
+          manage_response(true, true);
638
+          mmu_continue_loading();
639
+          command(MMU_CMD_C0);
640
+          mmu_loop();
641
+
642
+          ENABLE_AXIS_E0();
643
+          extruder = index;
644
+          active_extruder = 0;
645
+        } break;
646
+
647
+        case 'c': {
648
+          DEBUG_ECHOLNPGM("case c\n");
649
+          while (!thermalManager.wait_for_hotend(active_extruder, false)) safe_delay(100);
650
+          execute_extruder_sequence((const E_Step *)load_to_nozzle_sequence, COUNT(load_to_nozzle_sequence));
651
+        } break;
652
+      }
653
+
654
+      set_runout_valid(true);
655
+
656
+    #endif // MMU2_MENUS
657
+  }
658
+
659
+  void MMU2::mmu_continue_loading() {
660
+    for (uint8_t i = 0; i < MMU_LOADING_ATTEMPTS_NR; i++) {
661
+      DEBUG_ECHOLNPAIR("Additional load attempt #", i);
662
+      if (FILAMENT_PRESENT()) break;
663
+      command(MMU_CMD_C0);
664
+      manage_response(true, true);
665
+    }
666
+    if (!FILAMENT_PRESENT()) {
667
+      DEBUG_ECHOLNPGM("Filament never reached sensor, runout");
668
+      filament_runout();
669
+    }
670
+    mmu_idl_sens = 0;
671
+  }
672
+
673
+#elif DISABLED(MMU_EXTRUDER_SENSOR) && DISABLED(PRUSA_MMU2_S_MODE)
480 674
 
481 675
 /**
482 676
  * Handle tool change
483 677
  */
484
-void MMU2::tool_change(uint8_t index) {
485
-
678
+void MMU2::tool_change(const uint8_t index) {
486 679
   if (!enabled) return;
487 680
 
488 681
   set_runout_valid(false);
489 682
 
490 683
   if (index != extruder) {
491
-
492 684
     DISABLE_AXIS_E0();
493 685
     ui.status_printf_P(0, GET_TEXT(MSG_MMU2_LOADING_FILAMENT), int(index + 1));
494
-
495 686
     command(MMU_CMD_T0 + index);
496 687
     manage_response(true, true);
497
-
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
-    }
688
+    command(MMU_CMD_C0);
689
+    extruder = index; //filament change is finished
690
+    active_extruder = 0;
691
+    ENABLE_AXIS_E0();
692
+    SERIAL_ECHO_START();
693
+    SERIAL_ECHOLNPAIR(STR_ACTIVE_EXTRUDER, int(extruder));
505 694
     ui.reset_status();
506 695
   }
507 696
 
@@ -518,7 +707,6 @@ void MMU2::tool_change(uint8_t index) {
518 707
  *
519 708
  */
520 709
 void MMU2::tool_change(const char* special) {
521
-
522 710
   if (!enabled) return;
523 711
 
524 712
   #if ENABLED(MMU2_MENUS)
@@ -527,27 +715,29 @@ void MMU2::tool_change(const char* special) {
527 715
 
528 716
     switch (*special) {
529 717
       case '?': {
718
+        DEBUG_ECHOLNPGM("case ?\n");
530 719
         uint8_t index = mmu2_choose_filament();
531 720
         while (!thermalManager.wait_for_hotend(active_extruder, false)) safe_delay(100);
532 721
         load_filament_to_nozzle(index);
533 722
       } break;
534 723
 
535 724
       case 'x': {
725
+        DEBUG_ECHOLNPGM("case x\n");
536 726
         planner.synchronize();
537 727
         uint8_t index = mmu2_choose_filament();
538 728
         DISABLE_AXIS_E0();
539 729
         command(MMU_CMD_T0 + index);
540 730
         manage_response(true, true);
731
+        command(MMU_CMD_C0);
732
+        mmu_loop();
541 733
 
542
-        if (load_to_gears()) {
543
-          mmu_loop();
544
-          ENABLE_AXIS_E0();
545
-          extruder = index;
546
-          active_extruder = 0;
547
-        }
734
+        ENABLE_AXIS_E0();
735
+        extruder = index;
736
+        active_extruder = 0;
548 737
       } break;
549 738
 
550 739
       case 'c': {
740
+        DEBUG_ECHOLNPGM("case c\n");
551 741
         while (!thermalManager.wait_for_hotend(active_extruder, false)) safe_delay(100);
552 742
         execute_extruder_sequence((const E_Step *)load_to_nozzle_sequence, COUNT(load_to_nozzle_sequence));
553 743
       } break;
@@ -556,7 +746,9 @@ void MMU2::tool_change(const char* special) {
556 746
     set_runout_valid(true);
557 747
 
558 748
   #endif
559
-}
749
+  }
750
+
751
+#endif // MMU_EXTRUDER_SENSOR
560 752
 
561 753
 /**
562 754
  * Set next command
@@ -593,7 +785,7 @@ void MMU2::manage_response(const bool move_axes, const bool turn_off_nozzle) {
593 785
   bool response = false;
594 786
   mmu_print_saved = false;
595 787
   xyz_pos_t resume_position;
596
-  int16_t resume_hotend_temp;
788
+  int16_t resume_hotend_temp = thermalManager.degTargetHotend(active_extruder);
597 789
 
598 790
   KEEPALIVE_STATE(PAUSED_FOR_USER);
599 791
 
@@ -652,7 +844,7 @@ void MMU2::manage_response(const bool move_axes, const bool turn_off_nozzle) {
652 844
   }
653 845
 }
654 846
 
655
-void MMU2::set_filament_type(uint8_t index, uint8_t filamentType) {
847
+void MMU2::set_filament_type(const uint8_t index, const uint8_t filamentType) {
656 848
   if (!enabled) return;
657 849
 
658 850
   cmd_arg = filamentType;
@@ -667,20 +859,21 @@ void MMU2::filament_runout() {
667 859
 }
668 860
 
669 861
 #if ENABLED(PRUSA_MMU2_S_MODE)
862
+
670 863
   void MMU2::check_filament() {
671
-    const bool runout = READ(FIL_RUNOUT_PIN) ^ (FIL_RUNOUT_INVERTING);
672
-    if (runout && !mmu2s_triggered) {
864
+    const bool present = FILAMENT_PRESENT();
865
+    if (present && !mmu2s_triggered) {
673 866
       DEBUG_ECHOLNPGM("MMU <= 'A'");
674 867
       tx_str_P(PSTR("A\n"));
675 868
     }
676
-    mmu2s_triggered = runout;
869
+    mmu2s_triggered = present;
677 870
   }
678 871
 
679 872
   bool MMU2::can_load() {
680 873
     execute_extruder_sequence((const E_Step *)can_load_sequence, COUNT(can_load_sequence));
681 874
 
682 875
     int filament_detected_count = 0;
683
-    const int steps = MMU2_CAN_LOAD_RETRACT / MMU2_CAN_LOAD_INCREMENT;
876
+    const int steps = (MMU2_CAN_LOAD_RETRACT) / (MMU2_CAN_LOAD_INCREMENT);
684 877
     DEBUG_ECHOLNPGM("MMU can_load:");
685 878
     LOOP_L_N(i, steps) {
686 879
       execute_extruder_sequence((const E_Step *)can_load_increment_sequence, COUNT(can_load_increment_sequence));
@@ -689,7 +882,7 @@ void MMU2::filament_runout() {
689 882
       if (mmu2s_triggered) ++filament_detected_count;
690 883
     }
691 884
 
692
-    if (filament_detected_count <= steps - (MMU2_CAN_LOAD_DEVIATION / MMU2_CAN_LOAD_INCREMENT)) {
885
+    if (filament_detected_count <= steps - (MMU2_CAN_LOAD_DEVIATION) / (MMU2_CAN_LOAD_INCREMENT)) {
693 886
       DEBUG_ECHOLNPGM(" failed.");
694 887
       return false;
695 888
     }
@@ -702,7 +895,7 @@ void MMU2::filament_runout() {
702 895
 #if BOTH(HAS_LCD_MENU, MMU2_MENUS)
703 896
 
704 897
   // Load filament into MMU2
705
-  void MMU2::load_filament(uint8_t index) {
898
+  void MMU2::load_filament(const uint8_t index) {
706 899
     if (!enabled) return;
707 900
     command(MMU_CMD_L0 + index);
708 901
     manage_response(false, false);
@@ -714,7 +907,7 @@ void MMU2::filament_runout() {
714 907
    * Switch material and load to nozzle
715 908
    *
716 909
    */
717
-  bool MMU2::load_filament_to_nozzle(uint8_t index) {
910
+  bool MMU2::load_filament_to_nozzle(const uint8_t index) {
718 911
 
719 912
     if (!enabled) return false;
720 913
 
@@ -739,7 +932,6 @@ void MMU2::filament_runout() {
739 932
   }
740 933
 
741 934
   /**
742
-   *
743 935
    * Load filament to nozzle of multimaterial printer
744 936
    *
745 937
    * This function is used only only after T? (user select filament) and M600 (change filament).
@@ -751,7 +943,7 @@ void MMU2::filament_runout() {
751 943
     execute_extruder_sequence((const E_Step *)load_to_nozzle_sequence, COUNT(load_to_nozzle_sequence));
752 944
   }
753 945
 
754
-  bool MMU2::eject_filament(uint8_t index, bool recover) {
946
+  bool MMU2::eject_filament(const uint8_t index, const bool recover) {
755 947
 
756 948
     if (!enabled) return false;
757 949
 
@@ -798,9 +990,7 @@ void MMU2::filament_runout() {
798 990
   }
799 991
 
800 992
   /**
801
-   *
802
-   * unload from hotend and retract to MMU
803
-   *
993
+   * Unload from hotend and retract to MMU
804 994
    */
805 995
   bool MMU2::unload() {
806 996
 

+ 11
- 7
Marlin/src/feature/mmu2/mmu2.h Vedi File

@@ -44,24 +44,24 @@ public:
44 44
   static void init();
45 45
   static void reset();
46 46
   static void mmu_loop();
47
-  static void tool_change(uint8_t index);
47
+  static void tool_change(const uint8_t index);
48 48
   static void tool_change(const char* special);
49 49
   static uint8_t get_current_tool();
50
-  static void set_filament_type(uint8_t index, uint8_t type);
50
+  static void set_filament_type(const uint8_t index, const uint8_t type);
51 51
 
52 52
   #if BOTH(HAS_LCD_MENU, MMU2_MENUS)
53 53
     static bool unload();
54 54
     static void load_filament(uint8_t);
55 55
     static void load_all();
56
-    static bool load_filament_to_nozzle(uint8_t index);
57
-    static bool eject_filament(uint8_t index, bool recover);
56
+    static bool load_filament_to_nozzle(const uint8_t index);
57
+    static bool eject_filament(const uint8_t index, const bool recover);
58 58
   #endif
59 59
 
60 60
 private:
61 61
   static bool rx_str_P(const char* str);
62 62
   static void tx_str_P(const char* str);
63
-  static void tx_printf_P(const char* format, int argument);
64
-  static void tx_printf_P(const char* format, int argument1, int argument2);
63
+  static void tx_printf_P(const char* format, const int argument);
64
+  static void tx_printf_P(const char* format, const int argument1, const int argument2);
65 65
   static void clear_rx_buffer();
66 66
 
67 67
   static bool rx_ok();
@@ -89,6 +89,10 @@ private:
89 89
     FORCE_INLINE static bool load_to_gears() { return true; }
90 90
   #endif
91 91
 
92
+  #if ENABLED(MMU_EXTRUDER_SENSOR)
93
+    static void mmu_continue_loading();
94
+  #endif
95
+
92 96
   static bool enabled, ready, mmu_print_saved;
93 97
 
94 98
   static uint8_t cmd, cmd_arg, last_cmd, extruder;
@@ -96,7 +100,7 @@ private:
96 100
   static volatile int8_t finda;
97 101
   static volatile bool finda_runout_valid;
98 102
   static int16_t version, buildnr;
99
-  static millis_t last_request, next_P0_request;
103
+  static millis_t prev_request, prev_P0_request;
100 104
   static char rx_buffer[MMU_RX_SIZE], tx_buffer[MMU_TX_SIZE];
101 105
 
102 106
   static inline void set_runout_valid(const bool valid) {

+ 7
- 5
Marlin/src/inc/SanityCheck.h Vedi File

@@ -2742,12 +2742,14 @@ static_assert(   _ARR_TEST(3,0) && _ARR_TEST(3,1) && _ARR_TEST(3,2)
2742 2742
  * Prusa MMU2 requirements
2743 2743
  */
2744 2744
 #if ENABLED(PRUSA_MMU2)
2745
-  #if DISABLED(NOZZLE_PARK_FEATURE)
2746
-    #error "PRUSA_MMU2 requires NOZZLE_PARK_FEATURE."
2747
-  #elif EXTRUDERS != 5
2745
+  #if EXTRUDERS != 5
2748 2746
     #error "PRUSA_MMU2 requires EXTRUDERS = 5."
2749
-  #elif ENABLED(PRUSA_MMU2_S_MODE) && DISABLED(FILAMENT_RUNOUT_SENSOR)
2750
-    #error "PRUSA_MMU2_S_MODE requires FILAMENT_RUNOUT_SENSOR. Enable it to continue."
2747
+  #elif DISABLED(NOZZLE_PARK_FEATURE)
2748
+    #error "PRUSA_MMU2 requires NOZZLE_PARK_FEATURE. Enable it to continue."
2749
+  #elif EITHER(PRUSA_MMU2_S_MODE, MMU_EXTRUDER_SENSOR) && DISABLED(FILAMENT_RUNOUT_SENSOR)
2750
+    #error "PRUSA_MMU2_S_MODE or MMU_EXTRUDER_SENSOR requires FILAMENT_RUNOUT_SENSOR. Enable it to continue."
2751
+  #elif BOTH(PRUSA_MMU2_S_MODE, MMU_EXTRUDER_SENSOR)
2752
+    #error "Enable only one of PRUSA_MMU2_S_MODE or MMU_EXTRUDER_SENSOR."
2751 2753
   #elif DISABLED(ADVANCED_PAUSE_FEATURE)
2752 2754
     static_assert(nullptr == strstr(MMU2_FILAMENT_RUNOUT_SCRIPT, "M600"), "ADVANCED_PAUSE_FEATURE is required to use M600 with PRUSA_MMU2.");
2753 2755
   #endif

+ 6
- 5
Marlin/src/lcd/language/language_fr.h Vedi File

@@ -476,15 +476,16 @@ namespace Language_fr {
476 476
   PROGMEM Language_Str MSG_LCD_PROBING_FAILED              = _UxGT("Echec sonde");
477 477
   PROGMEM Language_Str MSG_M600_TOO_COLD                   = _UxGT("M600: Trop froid");
478 478
 
479
+  PROGMEM Language_Str MSG_KILL_MMU2_FIRMWARE              = _UxGT("MAJ firmware MMU!!");
479 480
   PROGMEM Language_Str MSG_MMU2_CHOOSE_FILAMENT_HEADER     = _UxGT("CHOISIR FILAMENT");
480 481
   PROGMEM Language_Str MSG_MMU2_MENU                       = _UxGT("MMU");
481 482
   PROGMEM Language_Str MSG_MMU2_NOT_RESPONDING             = _UxGT("MMU ne répond plus");
482
-  PROGMEM Language_Str MSG_MMU2_RESUME                     = _UxGT("Continuer impr.");
483
-  PROGMEM Language_Str MSG_MMU2_RESUMING                   = _UxGT("Reprise...");
484
-  PROGMEM Language_Str MSG_MMU2_LOAD_FILAMENT              = _UxGT("Charger filament");
485
-  PROGMEM Language_Str MSG_MMU2_LOAD_ALL                   = _UxGT("Charger tous");
483
+  PROGMEM Language_Str MSG_MMU2_RESUME                     = _UxGT("Continuer Imp. MMU");
484
+  PROGMEM Language_Str MSG_MMU2_RESUMING                   = _UxGT("Reprise MMU...");
485
+  PROGMEM Language_Str MSG_MMU2_LOAD_FILAMENT              = _UxGT("Charge dans MMU");
486
+  PROGMEM Language_Str MSG_MMU2_LOAD_ALL                   = _UxGT("Charger tous dans MMU");
486 487
   PROGMEM Language_Str MSG_MMU2_LOAD_TO_NOZZLE             = _UxGT("Charger dans buse");
487
-  PROGMEM Language_Str MSG_MMU2_EJECT_FILAMENT             = _UxGT("Ejecter filament");
488
+  PROGMEM Language_Str MSG_MMU2_EJECT_FILAMENT             = _UxGT("Ejecter fil. du MMU");
488 489
   PROGMEM Language_Str MSG_MMU2_EJECT_FILAMENT_N           = _UxGT("Ejecter fil. ~");
489 490
   PROGMEM Language_Str MSG_MMU2_UNLOAD_FILAMENT            = _UxGT("Retrait filament");
490 491
   PROGMEM Language_Str MSG_MMU2_LOADING_FILAMENT           = _UxGT("Chargem. fil. %i...");

Loading…
Annulla
Salva