diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index d7e2e50d2..b19939865 100644 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -3542,9 +3542,10 @@ static void gcode_M600(bool automatic, float x_position, float y_position, float if (MMU2::mmu2.Enabled()) { if (!automatic) { - if (saved_printing) - MMU2::mmu2.eject_filament(MMU2::mmu2.get_current_tool(), - false); // if M600 was invoked by filament senzor (FINDA) eject filament so user can easily remove it + if (saved_printing){ + // if M600 was invoked by filament senzor (FINDA) eject filament so user can easily remove it + MMU2::mmu2.eject_filament(MMU2::mmu2.get_current_tool(), false); + } //@@TODO mmu_M600_wait_and_beep(); if (saved_printing) { diff --git a/Firmware/Tcodes.cpp b/Firmware/Tcodes.cpp index e94dfe8b1..e61584f52 100644 --- a/Firmware/Tcodes.cpp +++ b/Firmware/Tcodes.cpp @@ -1,13 +1,14 @@ #include "Tcodes.h" +#include "AutoDeplete.h" #include "Marlin.h" +#include "language.h" +#include "messages.h" #include "mmu2.h" #include "stepper.h" +#include "ultralcd.h" #include #include #include -#include "language.h" -#include "messages.h" -#include "ultralcd.h" #include static const char duplicate_Tcode_ignored[] PROGMEM = "Duplicate T-code ignored."; @@ -20,30 +21,6 @@ inline void TCodeInvalid() { SERIAL_ECHOLNPGM("Invalid T code."); } -// load to bondtech gears; if mmu is not present do nothing -void TCodeX() { - if (MMU2::mmu2.Enabled()) { - uint8_t selectedSlot = choose_menu_P(_T(MSG_CHOOSE_FILAMENT), _T(MSG_FILAMENT)); - if ((selectedSlot == MMU2::mmu2.get_current_tool()) /*&& mmu_fil_loaded @@TODO */){ - // dont execute the same T-code twice in a row - puts_P(duplicate_Tcode_ignored); - } else { - st_synchronize(); - MMU2::mmu2.tool_change(selectedSlot); - } - } -} - -// load to from bondtech gears to nozzle (nozzle should be preheated) -void TCodeC() { - if (MMU2::mmu2.Enabled()) { - st_synchronize(); -// @@TODO mmu_continue_loading(usb_timer.running() || (lcd_commands_type == LcdCommands::Layer1Cal)); -// mmu_extruder = selectedSlot; // filament change is finished -// MMU2::mmu2.load_filament_to_nozzle(); - } -} - struct SChooseFromMenu { uint8_t slot:7; uint8_t loadToNozzle:1; @@ -60,32 +37,38 @@ SChooseFromMenu TCodeChooseFromMenu() { } void TCodes(char *const strchr_pointer, uint8_t codeValue) { - uint8_t index; - for (index = 1; strchr_pointer[index] == ' ' || strchr_pointer[index] == '\t'; index++) + uint8_t index = 1; + for ( /*nothing*/ ; strchr_pointer[index] == ' ' || strchr_pointer[index] == '\t'; index++) ; strchr_pointer[index] = tolower(strchr_pointer[index]); - if (IsInvalidTCode(strchr_pointer, index)) + if (IsInvalidTCode(strchr_pointer, index)){ TCodeInvalid(); - else if (strchr_pointer[index] == 'x') - TCodeX(); - else if (strchr_pointer[index] == 'c') - TCodeC(); - else { + } else if (strchr_pointer[index] == 'x'){ + // load to bondtech gears; if mmu is not present do nothing + if (MMU2::mmu2.Enabled()) { + MMU2::mmu2.tool_change(strchr_pointer[index], choose_menu_P(_T(MSG_CHOOSE_EXTRUDER), _T(MSG_EXTRUDER))); + } + } else if (strchr_pointer[index] == 'c'){ + // load from bondtech gears to nozzle (nozzle should be preheated) + if (MMU2::mmu2.Enabled()) { + MMU2::mmu2.tool_change(strchr_pointer[index], 0); + } + } else { SChooseFromMenu selectedSlot; if (strchr_pointer[index] == '?') selectedSlot = TCodeChooseFromMenu(); else { selectedSlot.slot = codeValue; if (MMU2::mmu2.Enabled() && lcd_autoDepleteEnabled()) { -// @@TODO selectedSlot.slot = ad_getAlternative(selectedSlot); + selectedSlot.slot = ad_getAlternative(selectedSlot.slot); } } st_synchronize(); if (MMU2::mmu2.Enabled()) { - if ((selectedSlot.slot == MMU2::mmu2.get_current_tool()) /*&& mmu_fil_loaded @@TODO*/){ + if (selectedSlot.slot == MMU2::mmu2.get_current_tool()){ // don't execute the same T-code twice in a row puts_P(duplicate_Tcode_ignored); } else { @@ -96,8 +79,6 @@ void TCodes(char *const strchr_pointer, uint8_t codeValue) { } #endif // defined(MMU_HAS_CUTTER) && defined(MMU_ALWAYS_CUT) MMU2::mmu2.tool_change(selectedSlot.slot); -// @@TODO mmu_continue_loading(usb_timer.running() || (lcd_commands_type == LcdCommands::Layer1Cal)); - if (selectedSlot.loadToNozzle){ // for single material usage with mmu MMU2::mmu2.load_filament_to_nozzle(selectedSlot.slot); } diff --git a/Firmware/mmu2.cpp b/Firmware/mmu2.cpp index e3ea2e0af..81a1f2175 100644 --- a/Firmware/mmu2.cpp +++ b/Firmware/mmu2.cpp @@ -13,8 +13,8 @@ #include "stepper.h" #include "strlen_cx.h" #include "temperature.h" +#include "ultralcd.h" -// @@TODO remove this and enable it in the configuration files // Settings for filament load / unload from the LCD menu. // This is for Prusa MK3-style extruders. Customize for your hardware. #define MMU2_FILAMENTCHANGE_EJECT_FEED 80.0 @@ -70,6 +70,18 @@ namespace MMU2 { void execute_extruder_sequence(const E_Step *sequence, int steps); +template +void waitForHotendTargetTemp(uint16_t delay, F f){ + while (((degTargetHotend(active_extruder) - degHotend(active_extruder)) > 5)) { + f(); + delay_keep_alive(delay); + } +} + +void WaitForHotendTargetTempBeep(){ + waitForHotendTargetTemp(3000, []{ Sound_MakeSound(e_SOUND_TYPE_StandardPrompt); } ); +} + MMU2 mmu2; MMU2::MMU2() @@ -209,41 +221,32 @@ bool MMU2::tool_change(uint8_t index) { ///- T? Gcode to extrude shouldn't have to follow, load to extruder wheels is done automatically ///- 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. ///- Tc Load to nozzle after filament was prepared by Tx and extruder nozzle is already heated. -bool MMU2::tool_change(const char *special) { +bool MMU2::tool_change(char code, uint8_t slot) { if( ! WaitForMMUReady()) return false; -#if 0 //@@TODO BlockRunoutRAII blockRunout; - switch (*special) { + switch (code) { case '?': { - uint8_t index = 0; // mmu2_choose_filament(); //@@TODO GUI - user selects - while (!thermalManager.wait_for_hotend(active_extruder, false)) - safe_delay(100); - load_filament_to_nozzle(index); + waitForHotendTargetTemp(100, []{}); + load_filament_to_nozzle(slot); } break; case 'x': { - planner.synchronize(); - uint8_t index = 0; //mmu2_choose_filament(); //@@TODO GUI - user selects - disable_E0(); - logic.ToolChange(index); - manage_response(false, false); // true, true); - - enable_E0(); - extruder = index; + st_synchronize(); + logic.ToolChange(slot); + manage_response(false, false); + extruder = slot; SetActiveExtruder(0); } break; case 'c': { - while (!thermalManager.wait_for_hotend(active_extruder, false)) - safe_delay(100); - execute_extruder_sequence((const E_Step *)load_to_nozzle_sequence, COUNT(load_to_nozzle_sequence)); + waitForHotendTargetTemp(100, []{}); + execute_extruder_sequence((const E_Step *)load_to_nozzle_sequence, sizeof(load_to_nozzle_sequence) / sizeof (load_to_nozzle_sequence[0])); } break; } -#endif return true; } @@ -268,12 +271,7 @@ bool MMU2::unload() { if( ! WaitForMMUReady()) return false; - // @@TODO -// if (thermalManager.tooColdToExtrude(active_extruder)) { -// Sound_MakeSound(e_SOUND_TYPE_Prompt); -// LCD_ALERTMESSAGEPGM(MSG_HOTEND_TOO_COLD); -// return false; -// } + WaitForHotendTargetTempBeep(); { ReportingRAII rep(CommandInProgress::UnloadFilament); @@ -328,12 +326,9 @@ bool MMU2::load_filament_to_nozzle(uint8_t index) { LoadingToNozzleRAII ln(*this); - // @@TODO how is this supposed to be done in 8bit FW? -/* if (thermalManager.tooColdToExtrude(active_extruder)) { - Sound_MakeSound(e_SOUND_TYPE_Prompt); - LCD_ALERTMESSAGEPGM(MSG_HOTEND_TOO_COLD); - return false; - } else*/ { + WaitForHotendTargetTempBeep(); + + { // used for MMU-menu operation "Load to Nozzle" ReportingRAII rep(CommandInProgress::ToolChange); BlockRunoutRAII blockRunout; @@ -360,12 +355,7 @@ bool MMU2::eject_filament(uint8_t index, bool recover) { if( ! WaitForMMUReady()) return false; - //@@TODO -// if (thermalManager.tooColdToExtrude(active_extruder)) { -// Sound_MakeSound(e_SOUND_TYPE_Prompt); -// LCD_ALERTMESSAGEPGM(MSG_HOTEND_TOO_COLD); -// return false; -// } + WaitForHotendTargetTempBeep(); ReportingRAII rep(CommandInProgress::EjectFilament); current_position[E_AXIS] -= MMU2_FILAMENTCHANGE_EJECT_FEED; @@ -456,11 +446,9 @@ void MMU2::ResumeAndUnPark(bool move_axes, bool turn_off_nozzle) { MMU2_ECHO_MSG("Restoring hotend temperature "); SERIAL_ECHOLN(resume_hotend_temp); setTargetHotend(resume_hotend_temp, active_extruder); - - if (((degTargetHotend(active_extruder) - degHotend(active_extruder)) > 5)) { - // @@TODO lcd_display_message_fullscreen_P(_i("MMU OK. Resuming temperature...")); // better report the event and let the GUI do its work somewhere else - delay_keep_alive(3000); - } + waitForHotendTargetTemp(3000, []{ + lcd_display_message_fullscreen_P(_i("MMU OK. Resuming temperature...")); // better report the event and let the GUI do its work somewhere else + }); LogEchoEvent("Hotend temperature reached"); } diff --git a/Firmware/mmu2.h b/Firmware/mmu2.h index 58632597b..b87d8ab97 100644 --- a/Firmware/mmu2.h +++ b/Firmware/mmu2.h @@ -77,7 +77,7 @@ public: bool tool_change(uint8_t index); /// Handling of special Tx, Tc, T? commands - bool tool_change(const char *special); + bool tool_change(char code, uint8_t slot); /// Unload of filament in collaboration with the MMU. /// That includes rotating the printer's extruder in order to release filament. @@ -196,6 +196,8 @@ private: /// true in case we are doing the LoadToNozzle operation - that means the filament shall be loaded all the way down to the nozzle /// unlike the mid-print ToolChange commands, which only load the first ~30mm and then the G-code takes over. bool loadingToNozzle; + + }; /// following Marlin's way of doing stuff - one and only instance of MMU implementation in the code base