Browse Source

Add Prusa MMU2S settings - beta (#17523)

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

+ 19
- 0
Marlin/Configuration_adv.h View File

3267
       {  10.0,  700 }, \
3267
       {  10.0,  700 }, \
3268
       { -10.0,  400 }, \
3268
       { -10.0,  400 }, \
3269
       { -50.0, 2000 }
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
   #endif
3290
   #endif
3272
 
3291
 

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

91
 #define mmuSerial   MMU2_SERIAL
91
 #define mmuSerial   MMU2_SERIAL
92
 
92
 
93
 bool MMU2::enabled, MMU2::ready, MMU2::mmu_print_saved;
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
 uint8_t MMU2::cmd, MMU2::cmd_arg, MMU2::last_cmd, MMU2::extruder;
97
 uint8_t MMU2::cmd, MMU2::cmd_arg, MMU2::last_cmd, MMU2::extruder;
95
 int8_t MMU2::state = 0;
98
 int8_t MMU2::state = 0;
96
 volatile int8_t MMU2::finda = 1;
99
 volatile int8_t MMU2::finda = 1;
106
     feedRate_t feedRate;  //!< feed rate in mm/s
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
 #endif // MMU2_MENUS
121
 #endif // MMU2_MENUS
113
 
122
 
228
 
237
 
229
         enabled = true;
238
         enabled = true;
230
         state = 1;
239
         state = 1;
240
+        TERN_(PRUSA_MMU2_S_MODE, mmu2s_triggered = false);
231
       }
241
       }
232
       break;
242
       break;
233
 
243
 
291
         tx_str_P(PSTR("P0\n"));
301
         tx_str_P(PSTR("P0\n"));
292
         state = 2; // wait for response
302
         state = 2; // wait for response
293
       }
303
       }
304
+      
305
+      TERN_(PRUSA_MMU2_S_MODE, check_filament());
294
       break;
306
       break;
295
 
307
 
296
     case 2:   // response to command P0
308
     case 2:   // response to command P0
309
       else if (ELAPSED(millis(), last_request + MMU_P0_TIMEOUT)) // Resend request after timeout (3s)
321
       else if (ELAPSED(millis(), last_request + MMU_P0_TIMEOUT)) // Resend request after timeout (3s)
310
         state = 1;
322
         state = 1;
311
 
323
 
324
+      TERN_(PRUSA_MMU2_S_MODE, check_filament());
312
       break;
325
       break;
313
 
326
 
314
     case 3:   // response to mmu commands
327
     case 3:   // response to mmu commands
327
         }
340
         }
328
         state = 1;
341
         state = 1;
329
       }
342
       }
343
+      TERN_(PRUSA_MMU2_S_MODE, check_filament());
330
       break;
344
       break;
331
   }
345
   }
332
 }
346
 }
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
  * Handle tool change
482
  * Handle tool change
442
  */
483
  */
452
     ui.status_printf_P(0, GET_TEXT(MSG_MMU2_LOADING_FILAMENT), int(index + 1));
493
     ui.status_printf_P(0, GET_TEXT(MSG_MMU2_LOADING_FILAMENT), int(index + 1));
453
 
494
 
454
     command(MMU_CMD_T0 + index);
495
     command(MMU_CMD_T0 + index);
455
-
456
     manage_response(true, true);
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
     ui.reset_status();
505
     ui.reset_status();
468
   }
506
   }
469
 
507
 
500
         DISABLE_AXIS_E0();
538
         DISABLE_AXIS_E0();
501
         command(MMU_CMD_T0 + index);
539
         command(MMU_CMD_T0 + index);
502
         manage_response(true, true);
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
       } break;
548
       } break;
510
 
549
 
511
       case 'c': {
550
       case 'c': {
579
 
618
 
580
         if (turn_off_nozzle) thermalManager.setTargetHotend(0, active_extruder);
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
     else if (mmu_print_saved) {
624
     else if (mmu_print_saved) {
632
   planner.synchronize();
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
 #if BOTH(HAS_LCD_MENU, MMU2_MENUS)
702
 #if BOTH(HAS_LCD_MENU, MMU2_MENUS)
636
 
703
 
637
   // Load filament into MMU2
704
   // Load filament into MMU2
656
       LCD_ALERTMESSAGEPGM(MSG_HOTEND_TOO_COLD);
723
       LCD_ALERTMESSAGEPGM(MSG_HOTEND_TOO_COLD);
657
       return false;
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
       extruder = index;
733
       extruder = index;
666
       active_extruder = 0;
734
       active_extruder = 0;
667
-
668
       load_to_nozzle();
735
       load_to_nozzle();
669
-
670
       BUZZ(200, 404);
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
 
80
 
81
   static void filament_runout();
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
   static bool enabled, ready, mmu_print_saved;
92
   static bool enabled, ready, mmu_print_saved;
93
+
84
   static uint8_t cmd, cmd_arg, last_cmd, extruder;
94
   static uint8_t cmd, cmd_arg, last_cmd, extruder;
85
   static int8_t state;
95
   static int8_t state;
86
   static volatile int8_t finda;
96
   static volatile int8_t finda;

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

2740
     #error "PRUSA_MMU2 requires NOZZLE_PARK_FEATURE."
2740
     #error "PRUSA_MMU2 requires NOZZLE_PARK_FEATURE."
2741
   #elif EXTRUDERS != 5
2741
   #elif EXTRUDERS != 5
2742
     #error "PRUSA_MMU2 requires EXTRUDERS = 5."
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
   #elif DISABLED(ADVANCED_PAUSE_FEATURE)
2745
   #elif DISABLED(ADVANCED_PAUSE_FEATURE)
2744
     static_assert(nullptr == strstr(MMU2_FILAMENT_RUNOUT_SCRIPT, "M600"), "ADVANCED_PAUSE_FEATURE is required to use M600 with PRUSA_MMU2.");
2746
     static_assert(nullptr == strstr(MMU2_FILAMENT_RUNOUT_SCRIPT, "M600"), "ADVANCED_PAUSE_FEATURE is required to use M600 with PRUSA_MMU2.");
2745
   #endif
2747
   #endif

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

528
   PROGMEM Language_Str MSG_MMU2_MENU                       = _UxGT("MMU");
528
   PROGMEM Language_Str MSG_MMU2_MENU                       = _UxGT("MMU");
529
   PROGMEM Language_Str MSG_KILL_MMU2_FIRMWARE              = _UxGT("Update MMU Firmware!");
529
   PROGMEM Language_Str MSG_KILL_MMU2_FIRMWARE              = _UxGT("Update MMU Firmware!");
530
   PROGMEM Language_Str MSG_MMU2_NOT_RESPONDING             = _UxGT("MMU Needs Attention.");
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
   PROGMEM Language_Str MSG_MMU2_LOADING_FILAMENT           = _UxGT("Loading Fil. %i...");
539
   PROGMEM Language_Str MSG_MMU2_LOADING_FILAMENT           = _UxGT("Loading Fil. %i...");
540
   PROGMEM Language_Str MSG_MMU2_EJECTING_FILAMENT          = _UxGT("Ejecting Fil. ...");
540
   PROGMEM Language_Str MSG_MMU2_EJECTING_FILAMENT          = _UxGT("Ejecting Fil. ...");
541
   PROGMEM Language_Str MSG_MMU2_UNLOADING_FILAMENT         = _UxGT("Unloading Fil....");
541
   PROGMEM Language_Str MSG_MMU2_UNLOADING_FILAMENT         = _UxGT("Unloading Fil....");
542
   PROGMEM Language_Str MSG_MMU2_ALL                        = _UxGT("All");
542
   PROGMEM Language_Str MSG_MMU2_ALL                        = _UxGT("All");
543
   PROGMEM Language_Str MSG_MMU2_FILAMENT_N                 = _UxGT("Filament ~");
543
   PROGMEM Language_Str MSG_MMU2_FILAMENT_N                 = _UxGT("Filament ~");
544
   PROGMEM Language_Str MSG_MMU2_RESET                      = _UxGT("Reset MMU");
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
   PROGMEM Language_Str MSG_MMU2_EJECT_RECOVER              = _UxGT("Remove, click");
546
   PROGMEM Language_Str MSG_MMU2_EJECT_RECOVER              = _UxGT("Remove, click");
547
 
547
 
548
   PROGMEM Language_Str MSG_MIX                             = _UxGT("Mix");
548
   PROGMEM Language_Str MSG_MIX                             = _UxGT("Mix");

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

71
 opt_enable ZONESTAR_LCD Z_PROBE_SERVO_NR Z_SERVO_ANGLES DEACTIVATE_SERVOS_AFTER_MOVE BOOT_MARLIN_LOGO_ANIMATED \
71
 opt_enable ZONESTAR_LCD Z_PROBE_SERVO_NR Z_SERVO_ANGLES DEACTIVATE_SERVOS_AFTER_MOVE BOOT_MARLIN_LOGO_ANIMATED \
72
            AUTO_BED_LEVELING_3POINT DEBUG_LEVELING_FEATURE EEPROM_SETTINGS EEPROM_CHITCHAT M114_DETAIL \
72
            AUTO_BED_LEVELING_3POINT DEBUG_LEVELING_FEATURE EEPROM_SETTINGS EEPROM_CHITCHAT M114_DETAIL \
73
            NO_VOLUMETRICS EXTENDED_CAPABILITIES_REPORT AUTO_REPORT_TEMPERATURES AUTOTEMP G38_PROBE_TARGET JOYSTICK \
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
 exec_test $1 $2 "RAMPS | ZONESTAR_LCD | MMU2 | Servo Probe | ABL 3-Pt | Debug Leveling | EEPROM | G38 ..."
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