Browse Source

Add Prusa MMU2S settings - beta (#17523)

Toni 4 years ago
parent
commit
21067ab062
No account linked to committer's email address

+ 19
- 0
Marlin/Configuration_adv.h View File

@@ -3267,6 +3267,25 @@
3267 3267
       {  10.0,  700 }, \
3268 3268
       { -10.0,  400 }, \
3269 3269
       { -50.0, 2000 }
3270
+  #endif
3271
+
3272
+  // Using a sensor like the MMU2S
3273
+  //#define PRUSA_MMU2_S_MODE
3274
+  #if ENABLED(PRUSA_MMU2_S_MODE)
3275
+    #define MMU2_C0_RETRY   5             // Number of retries (total time = timeout*retries)
3276
+
3277
+    #define MMU2_CAN_LOAD_FEEDRATE 800    // (mm/m)
3278
+    #define MMU2_CAN_LOAD_SEQUENCE \
3279
+      {  0.1, MMU2_CAN_LOAD_FEEDRATE }, \
3280
+      {  60.0, MMU2_CAN_LOAD_FEEDRATE }, \
3281
+      { -52.0, MMU2_CAN_LOAD_FEEDRATE }
3282
+
3283
+    #define MMU2_CAN_LOAD_RETRACT   6.0   // (mm) Keep under the distance between Load Sequence values
3284
+    #define MMU2_CAN_LOAD_DEVIATION 0.8   // (mm) Acceptable deviation
3285
+
3286
+    #define MMU2_CAN_LOAD_INCREMENT 0.2   // (mm) To reuse within MMU2 module
3287
+    #define MMU2_CAN_LOAD_INCREMENT_SEQUENCE \
3288
+      { -MMU2_CAN_LOAD_INCREMENT, MMU2_CAN_LOAD_FEEDRATE }
3270 3289
 
3271 3290
   #endif
3272 3291
 

+ 97
- 31
Marlin/src/feature/mmu2/mmu2.cpp View File

@@ -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
   /**

+ 10
- 0
Marlin/src/feature/mmu2/mmu2.h View File

@@ -80,7 +80,17 @@ private:
80 80
 
81 81
   static void filament_runout();
82 82
 
83
+  #if ENABLED(PRUSA_MMU2_S_MODE)
84
+    static bool mmu2s_triggered;
85
+    static void check_filament();
86
+    static bool can_load();
87
+    static bool load_to_gears();
88
+  #else
89
+    FORCE_INLINE static bool load_to_gears() { return true; }
90
+  #endif
91
+
83 92
   static bool enabled, ready, mmu_print_saved;
93
+
84 94
   static uint8_t cmd, cmd_arg, last_cmd, extruder;
85 95
   static int8_t state;
86 96
   static volatile int8_t finda;

+ 2
- 0
Marlin/src/inc/SanityCheck.h View File

@@ -2740,6 +2740,8 @@ static_assert(   _ARR_TEST(3,0) && _ARR_TEST(3,1) && _ARR_TEST(3,2)
2740 2740
     #error "PRUSA_MMU2 requires NOZZLE_PARK_FEATURE."
2741 2741
   #elif EXTRUDERS != 5
2742 2742
     #error "PRUSA_MMU2 requires EXTRUDERS = 5."
2743
+  #elif ENABLED(PRUSA_MMU2_S_MODE) && DISABLED(FILAMENT_RUNOUT_SENSOR)
2744
+    #error "PRUSA_MMU2_S_MODE requires FILAMENT_RUNOUT_SENSOR. Enable it to continue."
2743 2745
   #elif DISABLED(ADVANCED_PAUSE_FEATURE)
2744 2746
     static_assert(nullptr == strstr(MMU2_FILAMENT_RUNOUT_SCRIPT, "M600"), "ADVANCED_PAUSE_FEATURE is required to use M600 with PRUSA_MMU2.");
2745 2747
   #endif

+ 9
- 9
Marlin/src/lcd/language/language_en.h View File

@@ -528,21 +528,21 @@ namespace Language_en {
528 528
   PROGMEM Language_Str MSG_MMU2_MENU                       = _UxGT("MMU");
529 529
   PROGMEM Language_Str MSG_KILL_MMU2_FIRMWARE              = _UxGT("Update MMU Firmware!");
530 530
   PROGMEM Language_Str MSG_MMU2_NOT_RESPONDING             = _UxGT("MMU Needs Attention.");
531
-  PROGMEM Language_Str MSG_MMU2_RESUME                     = _UxGT("Resume Print");
532
-  PROGMEM Language_Str MSG_MMU2_RESUMING                   = _UxGT("Resuming...");
533
-  PROGMEM Language_Str MSG_MMU2_LOAD_FILAMENT              = _UxGT("Load Filament");
534
-  PROGMEM Language_Str MSG_MMU2_LOAD_ALL                   = _UxGT("Load All");
535
-  PROGMEM Language_Str MSG_MMU2_LOAD_TO_NOZZLE             = _UxGT("Load to Nozzle");
536
-  PROGMEM Language_Str MSG_MMU2_EJECT_FILAMENT             = _UxGT("Eject Filament");
537
-  PROGMEM Language_Str MSG_MMU2_EJECT_FILAMENT_N           = _UxGT("Eject Filament ~");
538
-  PROGMEM Language_Str MSG_MMU2_UNLOAD_FILAMENT            = _UxGT("Unload Filament");
531
+  PROGMEM Language_Str MSG_MMU2_RESUME                     = _UxGT("MMU Resume");
532
+  PROGMEM Language_Str MSG_MMU2_RESUMING                   = _UxGT("MMU Resuming...");
533
+  PROGMEM Language_Str MSG_MMU2_LOAD_FILAMENT              = _UxGT("MMU Load");
534
+  PROGMEM Language_Str MSG_MMU2_LOAD_ALL                   = _UxGT("MMU Load All");
535
+  PROGMEM Language_Str MSG_MMU2_LOAD_TO_NOZZLE             = _UxGT("MMU Load to Nozzle");
536
+  PROGMEM Language_Str MSG_MMU2_EJECT_FILAMENT             = _UxGT("MMU Eject");
537
+  PROGMEM Language_Str MSG_MMU2_EJECT_FILAMENT_N           = _UxGT("MMU Eject ~");
538
+  PROGMEM Language_Str MSG_MMU2_UNLOAD_FILAMENT            = _UxGT("MMU Unload");
539 539
   PROGMEM Language_Str MSG_MMU2_LOADING_FILAMENT           = _UxGT("Loading Fil. %i...");
540 540
   PROGMEM Language_Str MSG_MMU2_EJECTING_FILAMENT          = _UxGT("Ejecting Fil. ...");
541 541
   PROGMEM Language_Str MSG_MMU2_UNLOADING_FILAMENT         = _UxGT("Unloading Fil....");
542 542
   PROGMEM Language_Str MSG_MMU2_ALL                        = _UxGT("All");
543 543
   PROGMEM Language_Str MSG_MMU2_FILAMENT_N                 = _UxGT("Filament ~");
544 544
   PROGMEM Language_Str MSG_MMU2_RESET                      = _UxGT("Reset MMU");
545
-  PROGMEM Language_Str MSG_MMU2_RESETTING                  = _UxGT("Resetting MMU...");
545
+  PROGMEM Language_Str MSG_MMU2_RESETTING                  = _UxGT("MMU Resetting...");
546 546
   PROGMEM Language_Str MSG_MMU2_EJECT_RECOVER              = _UxGT("Remove, click");
547 547
 
548 548
   PROGMEM Language_Str MSG_MIX                             = _UxGT("Mix");

+ 1
- 1
buildroot/share/tests/mega2560-tests View File

@@ -71,7 +71,7 @@ opt_set NUM_SERVOS 1
71 71
 opt_enable ZONESTAR_LCD Z_PROBE_SERVO_NR Z_SERVO_ANGLES DEACTIVATE_SERVOS_AFTER_MOVE BOOT_MARLIN_LOGO_ANIMATED \
72 72
            AUTO_BED_LEVELING_3POINT DEBUG_LEVELING_FEATURE EEPROM_SETTINGS EEPROM_CHITCHAT M114_DETAIL \
73 73
            NO_VOLUMETRICS EXTENDED_CAPABILITIES_REPORT AUTO_REPORT_TEMPERATURES AUTOTEMP G38_PROBE_TARGET JOYSTICK \
74
-           PRUSA_MMU2 MMU2_MENUS NOZZLE_PARK_FEATURE ADVANCED_PAUSE_FEATURE Z_SAFE_HOMING
74
+           PRUSA_MMU2 MMU2_MENUS PRUSA_MMU2_S_MODE FILAMENT_RUNOUT_SENSOR NOZZLE_PARK_FEATURE ADVANCED_PAUSE_FEATURE Z_SAFE_HOMING
75 75
 exec_test $1 $2 "RAMPS | ZONESTAR_LCD | MMU2 | Servo Probe | ABL 3-Pt | Debug Leveling | EEPROM | G38 ..."
76 76
 
77 77
 #

Loading…
Cancel
Save