Towards MMU2 without LCD

This commit is contained in:
Scott Lahteine 2020-10-28 00:26:27 -05:00
parent ca34edc5b0
commit 47ad2caab2
3 changed files with 178 additions and 181 deletions

View file

@ -105,23 +105,19 @@ int16_t MMU2::version = -1, MMU2::buildnr = -1;
millis_t MMU2::prev_request, MMU2::prev_P0_request;
char MMU2::rx_buffer[MMU_RX_SIZE], MMU2::tx_buffer[MMU_TX_SIZE];
#if BOTH(HAS_LCD_MENU, MMU2_MENUS)
struct E_Step {
float extrude; //!< extrude distance in mm
feedRate_t feedRate; //!< feed rate in mm/s
};
struct E_Step {
float extrude; //!< extrude distance in mm
feedRate_t feedRate; //!< feed rate in mm/s
};
static constexpr E_Step
ramming_sequence[] PROGMEM = { MMU2_RAMMING_SEQUENCE }
, load_to_nozzle_sequence[] PROGMEM = { MMU2_LOAD_TO_NOZZLE_SEQUENCE }
#if HAS_PRUSA_MMU2S
, can_load_sequence[] PROGMEM = { MMU2_CAN_LOAD_SEQUENCE }
, can_load_increment_sequence[] PROGMEM = { MMU2_CAN_LOAD_INCREMENT_SEQUENCE }
#endif
;
#endif
static constexpr E_Step
ramming_sequence[] PROGMEM = { MMU2_RAMMING_SEQUENCE }
, load_to_nozzle_sequence[] PROGMEM = { MMU2_LOAD_TO_NOZZLE_SEQUENCE }
#if HAS_PRUSA_MMU2S
, can_load_sequence[] PROGMEM = { MMU2_CAN_LOAD_SEQUENCE }
, can_load_increment_sequence[] PROGMEM = { MMU2_CAN_LOAD_INCREMENT_SEQUENCE }
#endif
;
MMU2::MMU2() {
rx_buffer[0] = '\0';
@ -906,162 +902,159 @@ void MMU2::filament_runout() {
DEBUG_ECHOLNPGM(" succeeded.");
return true;
}
#endif
#if BOTH(HAS_LCD_MENU, MMU2_MENUS)
// Load filament into MMU2
void MMU2::load_filament(const uint8_t index) {
if (!enabled) return;
command(MMU_CMD_L0 + index);
manage_response(false, false);
BUZZ(200, 404);
}
// Load filament into MMU2
void MMU2::load_filament(const uint8_t index) {
if (!enabled) return;
command(MMU_CMD_L0 + index);
/**
* Switch material and load to nozzle
*/
bool MMU2::load_filament_to_nozzle(const uint8_t index) {
if (!enabled) return false;
if (thermalManager.tooColdToExtrude(active_extruder)) {
BUZZ(200, 404);
LCD_ALERTMESSAGEPGM(MSG_HOTEND_TOO_COLD);
return false;
}
command(MMU_CMD_T0 + index);
manage_response(true, true);
const bool success = load_to_gears();
if (success) {
mmu_loop();
extruder = index;
active_extruder = 0;
load_to_nozzle();
BUZZ(200, 404);
}
return success;
}
/**
* Load filament to nozzle of multimaterial printer
*
* This function is used only only after T? (user select filament) and M600 (change filament).
* It is not used after T0 .. T4 command (select filament), in such case, gcode is responsible for loading
* filament to nozzle.
*/
void MMU2::load_to_nozzle() {
if (!enabled) return;
execute_extruder_sequence((const E_Step *)load_to_nozzle_sequence, COUNT(load_to_nozzle_sequence));
}
bool MMU2::eject_filament(const uint8_t index, const bool recover) {
if (!enabled) return false;
if (thermalManager.tooColdToExtrude(active_extruder)) {
BUZZ(200, 404);
LCD_ALERTMESSAGEPGM(MSG_HOTEND_TOO_COLD);
return false;
}
LCD_MESSAGEPGM(MSG_MMU2_EJECTING_FILAMENT);
ENABLE_AXIS_E0();
current_position.e -= MMU2_FILAMENTCHANGE_EJECT_FEED;
line_to_current_position(MMM_TO_MMS(2500));
planner.synchronize();
command(MMU_CMD_E0 + index);
manage_response(false, false);
if (recover) {
LCD_MESSAGEPGM(MSG_MMU2_EJECT_RECOVER);
BUZZ(200, 404);
TERN_(HOST_PROMPT_SUPPORT, host_prompt_do(PROMPT_USER_CONTINUE, PSTR("MMU2 Eject Recover"), CONTINUE_STR));
TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired_P(PSTR("MMU2 Eject Recover")));
wait_for_user_response();
BUZZ(200, 404);
BUZZ(200, 404);
command(MMU_CMD_R0);
manage_response(false, false);
}
ui.reset_status();
// no active tool
extruder = MMU2_NO_TOOL;
set_runout_valid(false);
BUZZ(200, 404);
DISABLE_AXIS_E0();
return true;
}
/**
* Unload from hotend and retract to MMU
*/
bool MMU2::unload() {
if (!enabled) return false;
if (thermalManager.tooColdToExtrude(active_extruder)) {
BUZZ(200, 404);
LCD_ALERTMESSAGEPGM(MSG_HOTEND_TOO_COLD);
return false;
}
/**
* Switch material and load to nozzle
*/
bool MMU2::load_filament_to_nozzle(const uint8_t index) {
filament_ramming();
if (!enabled) return false;
command(MMU_CMD_U0);
manage_response(false, true);
if (thermalManager.tooColdToExtrude(active_extruder)) {
BUZZ(200, 404);
LCD_ALERTMESSAGEPGM(MSG_HOTEND_TOO_COLD);
return false;
}
BUZZ(200, 404);
command(MMU_CMD_T0 + index);
manage_response(true, true);
// no active tool
extruder = MMU2_NO_TOOL;
const bool success = load_to_gears();
if (success) {
mmu_loop();
extruder = index;
active_extruder = 0;
load_to_nozzle();
BUZZ(200, 404);
}
return success;
}
set_runout_valid(false);
/**
* Load filament to nozzle of multimaterial printer
*
* This function is used only only after T? (user select filament) and M600 (change filament).
* It is not used after T0 .. T4 command (select filament), in such case, gcode is responsible for loading
* filament to nozzle.
*/
void MMU2::load_to_nozzle() {
if (!enabled) return;
execute_extruder_sequence((const E_Step *)load_to_nozzle_sequence, COUNT(load_to_nozzle_sequence));
}
return true;
}
bool MMU2::eject_filament(const uint8_t index, const bool recover) {
/**
* Unload sequence to optimize shape of the tip of the unloaded filament
*/
void MMU2::filament_ramming() {
execute_extruder_sequence((const E_Step *)ramming_sequence, sizeof(ramming_sequence) / sizeof(E_Step));
}
if (!enabled) return false;
void MMU2::execute_extruder_sequence(const E_Step * sequence, int steps) {
if (thermalManager.tooColdToExtrude(active_extruder)) {
BUZZ(200, 404);
LCD_ALERTMESSAGEPGM(MSG_HOTEND_TOO_COLD);
return false;
}
planner.synchronize();
ENABLE_AXIS_E0();
LCD_MESSAGEPGM(MSG_MMU2_EJECTING_FILAMENT);
const E_Step* step = sequence;
ENABLE_AXIS_E0();
current_position.e -= MMU2_FILAMENTCHANGE_EJECT_FEED;
line_to_current_position(2500 / 60);
LOOP_L_N(i, steps) {
const float es = pgm_read_float(&(step->extrude));
const feedRate_t fr_mm_m = pgm_read_float(&(step->feedRate));
DEBUG_ECHO_START();
DEBUG_ECHOLNPAIR("E step ", es, "/", fr_mm_m);
current_position.e += es;
line_to_current_position(MMM_TO_MMS(fr_mm_m));
planner.synchronize();
command(MMU_CMD_E0 + index);
manage_response(false, false);
if (recover) {
LCD_MESSAGEPGM(MSG_MMU2_EJECT_RECOVER);
BUZZ(200, 404);
TERN_(HOST_PROMPT_SUPPORT, host_prompt_do(PROMPT_USER_CONTINUE, PSTR("MMU2 Eject Recover"), CONTINUE_STR));
TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired_P(PSTR("MMU2 Eject Recover")));
wait_for_user_response();
BUZZ(200, 404);
BUZZ(200, 404);
command(MMU_CMD_R0);
manage_response(false, false);
}
ui.reset_status();
// no active tool
extruder = MMU2_NO_TOOL;
set_runout_valid(false);
BUZZ(200, 404);
DISABLE_AXIS_E0();
return true;
step++;
}
/**
* Unload from hotend and retract to MMU
*/
bool MMU2::unload() {
if (!enabled) return false;
if (thermalManager.tooColdToExtrude(active_extruder)) {
BUZZ(200, 404);
LCD_ALERTMESSAGEPGM(MSG_HOTEND_TOO_COLD);
return false;
}
filament_ramming();
command(MMU_CMD_U0);
manage_response(false, true);
BUZZ(200, 404);
// no active tool
extruder = MMU2_NO_TOOL;
set_runout_valid(false);
return true;
}
/**
* Unload sequence to optimize shape of the tip of the unloaded filament
*/
void MMU2::filament_ramming() {
execute_extruder_sequence((const E_Step *)ramming_sequence, sizeof(ramming_sequence) / sizeof(E_Step));
}
void MMU2::execute_extruder_sequence(const E_Step * sequence, int steps) {
planner.synchronize();
ENABLE_AXIS_E0();
const E_Step* step = sequence;
LOOP_L_N(i, steps) {
const float es = pgm_read_float(&(step->extrude));
const feedRate_t fr_mm_m = pgm_read_float(&(step->feedRate));
DEBUG_ECHO_START();
DEBUG_ECHOLNPAIR("E step ", es, "/", fr_mm_m);
current_position.e += es;
line_to_current_position(MMM_TO_MMS(fr_mm_m));
planner.synchronize();
step++;
}
DISABLE_AXIS_E0();
}
#endif // HAS_LCD_MENU && MMU2_MENUS
DISABLE_AXIS_E0();
}
#endif // HAS_PRUSA_MMU2

View file

@ -49,13 +49,11 @@ public:
static uint8_t get_current_tool();
static void set_filament_type(const uint8_t index, const uint8_t type);
#if BOTH(HAS_LCD_MENU, MMU2_MENUS)
static bool unload();
static void load_filament(uint8_t);
static void load_all();
static bool load_filament_to_nozzle(const uint8_t index);
static bool eject_filament(const uint8_t index, const bool recover);
#endif
static bool unload();
static void load_filament(uint8_t);
static void load_all();
static bool load_filament_to_nozzle(const uint8_t index);
static bool eject_filament(const uint8_t index, const bool recover);
private:
static bool rx_str_P(const char* str);
@ -72,11 +70,9 @@ private:
static bool get_response();
static void manage_response(const bool move_axes, const bool turn_off_nozzle);
#if BOTH(HAS_LCD_MENU, MMU2_MENUS)
static void load_to_nozzle();
static void filament_ramming();
static void execute_extruder_sequence(const E_Step * sequence, int steps);
#endif
static void load_to_nozzle();
static void filament_ramming();
static void execute_extruder_sequence(const E_Step * sequence, int steps);
static void filament_runout();

View file

@ -874,6 +874,31 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
#error "INDIVIDUAL_AXIS_HOMING_MENU is incompatible with DELTA kinematics."
#endif
/**
* Multi-Material-Unit requirements
*/
#if HAS_PRUSA_MMU2
#if EXTRUDERS != 5
#undef SINGLENOZZLE
#error "PRUSA_MMU2(S) requires exactly 5 EXTRUDERS. Please update your Configuration."
#elif DISABLED(NOZZLE_PARK_FEATURE)
#error "PRUSA_MMU2(S) requires NOZZLE_PARK_FEATURE. Enable it to continue."
#elif ENABLED(HAS_PRUSA_MMU2S) && DISABLED(FILAMENT_RUNOUT_SENSOR)
#error "PRUSA_MMU2S requires FILAMENT_RUNOUT_SENSOR. Enable it to continue."
#elif ENABLED(MMU_EXTRUDER_SENSOR) && DISABLED(FILAMENT_RUNOUT_SENSOR)
#error "MMU_EXTRUDER_SENSOR requires FILAMENT_RUNOUT_SENSOR. Enable it to continue."
#elif HAS_PRUSA_MMU2S && !HAS_LCD_MENU
#error "PRUSA_MMU2S requires an LCD supporting MarlinUI to be enabled."
#elif ENABLED(MMU_EXTRUDER_SENSOR) && !HAS_LCD_MENU
#error "MMU_EXTRUDER_SENSOR requires an LCD supporting MarlinUI to be enabled."
#elif DISABLED(ADVANCED_PAUSE_FEATURE)
static_assert(nullptr == strstr(MMU2_FILAMENT_RUNOUT_SCRIPT, "M600"), "ADVANCED_PAUSE_FEATURE is required to use M600 with PRUSA_MMU2(S) / SMUFF_EMU_MMU2(S).");
#endif
#endif
#if HAS_SMUFF && EXTRUDERS > 15
#error "Too many extruders for SMUFF_EMU_MMU2(S). (15 maximum)."
#endif
/**
* Options only for EXTRUDERS > 1
*/
@ -2958,23 +2983,6 @@ static_assert( _ARR_TEST(3,0) && _ARR_TEST(3,1) && _ARR_TEST(3,2)
#endif
#endif
/**
* Multi-Material-Unit requirements
*/
#if HAS_SMUFF && EXTRUDERS > 15
#error "Too many extruders for SMUFF_EMU_MMU2(S). (15 maximum)."
#elif HAS_PRUSA_MMU2
#if EXTRUDERS != 5
#error "PRUSA_MMU2 / PRUSA_MMU2S requires EXTRUDERS = 5."
#elif DISABLED(NOZZLE_PARK_FEATURE)
#error "PRUSA_MMU2 / PRUSA_MMU2S requires NOZZLE_PARK_FEATURE. Enable it to continue."
#elif EITHER(HAS_PRUSA_MMU2S, MMU_EXTRUDER_SENSOR) && DISABLED(FILAMENT_RUNOUT_SENSOR)
#error "PRUSA_MMU2S or MMU_EXTRUDER_SENSOR requires FILAMENT_RUNOUT_SENSOR. Enable it to continue."
#elif DISABLED(ADVANCED_PAUSE_FEATURE)
static_assert(nullptr == strstr(MMU2_FILAMENT_RUNOUT_SCRIPT, "M600"), "ADVANCED_PAUSE_FEATURE is required to use M600 with PRUSA_MMU2(S) / SMUFF_EMU_MMU2(S).");
#endif
#endif
/**
* Advanced PRINTCOUNTER settings
*/