diff --git a/Firmware/Marlin.h b/Firmware/Marlin.h index 157a1df9c..d8ccc92ec 100644 --- a/Firmware/Marlin.h +++ b/Firmware/Marlin.h @@ -354,6 +354,9 @@ extern char dir_names[3][9]; // save/restore printing extern bool saved_printing; +//save/restore printing in case that mmu is not responding +extern bool mmu_print_saved; + //estimated time to end of the print extern uint8_t print_percent_done_normal; extern uint16_t print_time_remaining_normal; @@ -361,7 +364,7 @@ extern uint8_t print_percent_done_silent; extern uint16_t print_time_remaining_silent; #define PRINT_TIME_REMAINING_INIT 65535 #define PRINT_PERCENT_DONE_INIT 255 -#define PRINTER_ACTIVE (IS_SD_PRINTING || is_usb_printing || isPrintPaused || (custom_message_type == 4) || saved_printing || (lcd_commands_type == LCD_COMMAND_V2_CAL) || card.paused) +#define PRINTER_ACTIVE (IS_SD_PRINTING || is_usb_printing || isPrintPaused || (custom_message_type == 4) || saved_printing || (lcd_commands_type == LCD_COMMAND_V2_CAL) || card.paused || mmu_print_saved) extern void calculate_extruder_multipliers(); @@ -464,9 +467,12 @@ void gcode_M701(); void proc_commands(); -bool mmu_get_reponse(bool timeout); +void manage_response(); +bool mmu_get_response(bool timeout); void mmu_not_responding(); void mmu_load_to_nozzle(); void M600_load_filament(); -void mmu_M600_load_filament(); -void M600_load_filament_movements(); \ No newline at end of file +void mmu_M600_load_filament(bool automatic); +void M600_load_filament_movements(); +void M600_wait_for_user(); +void M600_check_state(); \ No newline at end of file diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 78e5c03dd..cdea9962c 100644 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -319,7 +319,7 @@ unsigned long kicktime = millis()+100000; unsigned int usb_printing_counter; -int lcd_change_fil_state = 0; +int8_t lcd_change_fil_state = 0; int feedmultiplyBckp = 100; float HotendTempBckp = 0; @@ -462,6 +462,9 @@ uint8_t saved_filament_type; // save/restore printing bool saved_printing = false; +// save/restore printing in case that mmu was not responding +bool mmu_print_saved = false; + // storing estimated time to end of print counted by slicer uint8_t print_percent_done_normal = PRINT_PERCENT_DONE_INIT; uint16_t print_time_remaining_normal = PRINT_TIME_REMAINING_INIT; //estimated remaining print time in minutes @@ -3073,6 +3076,112 @@ void gcode_M114() SERIAL_PROTOCOLLN(""); } +void gcode_M600(bool automatic, float x_position, float y_position, float z_shift, float e_shift, float e_shift_late) { + st_synchronize(); + float lastpos[4]; + + if (farm_mode) + { + prusa_statistics(22); + } + + //First backup current position and settings + feedmultiplyBckp=feedmultiply; + float HotendTempBckp = degTargetHotend(active_extruder); + int fanSpeedBckp = fanSpeed; + lastpos[X_AXIS]=current_position[X_AXIS]; + lastpos[Y_AXIS]=current_position[Y_AXIS]; + lastpos[Z_AXIS]=current_position[Z_AXIS]; + lastpos[E_AXIS]=current_position[E_AXIS]; + + //Retract E + current_position[E_AXIS]+= e_shift; + plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], FILAMENTCHANGE_RFEED, active_extruder); + st_synchronize(); + + //Lift Z + current_position[Z_AXIS]+= z_shift; + plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], FILAMENTCHANGE_ZFEED, active_extruder); + st_synchronize(); + + //Move XY to side + current_position[X_AXIS]= x_position; + current_position[Y_AXIS]= y_position; + plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], FILAMENTCHANGE_XYFEED, active_extruder); + st_synchronize(); + + //Beep, manage nozzle heater and wait for user to start unload filament + if(!automatic) M600_wait_for_user(); + + lcd_change_fil_state = 0; + + // Unload filament +#if defined (SNMM) || defined (SNMM_V2) + extr_unload(); //unload just current filament +#else + unload_filament(); //unload filament fopr single material (used also in M702) +#endif + //finish moves + st_synchronize(); + + +#if !defined(SNMM_V2) && !defined(SNMM) + KEEPALIVE_STATE(PAUSED_FOR_USER); + lcd_change_fil_state = lcd_show_fullscreen_message_yes_no_and_wait_P(_i("Was filament unload successful?"), false, true);////MSG_UNLOAD_SUCCESSFUL c=20 r=2 + if (lcd_change_fil_state == 0) lcd_show_fullscreen_message_and_wait_P(_i("Please open idler and remove filament manually."));////MSG_CHECK_IDLER c=20 r=4 + + lcd_update_enable(true); + } +#endif + +#ifdef SNMM_V2 + mmu_M600_load_filament(automatic); +#else + M600_load_filament(); +#endif + + if(!automatic) M600_check_state(); + + //Not let's go back to print + fanSpeed = fanSpeedBckp; + + //Feed a little of filament to stabilize pressure + if (!automatic) { + current_position[E_AXIS] += FILAMENTCHANGE_RECFEED; + plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], FILAMENTCHANGE_EXFEED, active_extruder); + } + + //Move XY back + plan_buffer_line(lastpos[X_AXIS], lastpos[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], FILAMENTCHANGE_XYFEED, active_extruder); + st_synchronize(); + //Move Z back + plan_buffer_line(lastpos[X_AXIS], lastpos[Y_AXIS], lastpos[Z_AXIS], current_position[E_AXIS], FILAMENTCHANGE_ZFEED, active_extruder); + st_synchronize(); + + //Unretract + current_position[E_AXIS]= current_position[E_AXIS] - FILAMENTCHANGE_FIRSTRETRACT; + plan_buffer_line(lastpos[X_AXIS], lastpos[Y_AXIS], lastpos[Z_AXIS], current_position[E_AXIS], FILAMENTCHANGE_RFEED, active_extruder); + st_synchronize(); + + //Set E position to original + plan_set_e_position(lastpos[E_AXIS]); + + memcpy(current_position, lastpos, sizeof(lastpos)); + memcpy(destination, current_position, sizeof(current_position)); + + //Recover feed rate + feedmultiply=feedmultiplyBckp; + char cmd[9]; + sprintf_P(cmd, PSTR("M220 S%i"), feedmultiplyBckp); + enquecommand(cmd); + + lcd_setstatuspgm(_T(WELCOME_MSG)); + custom_message = false; + custom_message_type = 0; + +} + + void gcode_M701() { printf_P(PSTR("gcode_M701 begin\n")); @@ -6253,359 +6362,83 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE)) #ifdef FILAMENTCHANGEENABLE case 600: //Pause for filament change X[pos] Y[pos] Z[relative lift] E[initial retract] L[later retract distance for removal] - { - + { st_synchronize(); - float lastpos[4]; - if (farm_mode) - - { - - prusa_statistics(22); - - } - - feedmultiplyBckp=feedmultiply; - - float HotendTempBckp = degTargetHotend(active_extruder); - int fanSpeedBckp = fanSpeed; - lastpos[X_AXIS]=current_position[X_AXIS]; - lastpos[Y_AXIS]=current_position[Y_AXIS]; - lastpos[Z_AXIS]=current_position[Z_AXIS]; - lastpos[E_AXIS]=current_position[E_AXIS]; - - //Restract extruder + float x_position = current_position[X_AXIS]; + float y_position = current_position[Y_AXIS]; + float z_shift = 0; + float e_shift_init = 0; + float e_shift_late = 0; + bool automatic = false; + + //Retract extruder if(code_seen('E')) { - current_position[E_AXIS]+= code_value(); + e_shift_init = code_value(); } else { #ifdef FILAMENTCHANGE_FIRSTRETRACT - current_position[E_AXIS]+= FILAMENTCHANGE_FIRSTRETRACT ; + e_shift_init = FILAMENTCHANGE_FIRSTRETRACT ; #endif } - plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], FILAMENTCHANGE_RFEED, active_extruder); + + //currently don't work as we are using the same unload sequence as in M702, needs re-work + if (code_seen('L')) + { + e_shift_late = code_value(); + } + else + { + #ifdef FILAMENTCHANGE_FINALRETRACT + e_shift_late = FILAMENTCHANGE_FINALRETRACT; + #endif + } //Lift Z if(code_seen('Z')) { - current_position[Z_AXIS]+= code_value(); + z_shift = code_value(); } else { #ifdef FILAMENTCHANGE_ZADD - current_position[Z_AXIS]+= FILAMENTCHANGE_ZADD ; - if(current_position[Z_AXIS] < 10){ - current_position[Z_AXIS]+= 10 ; - } + z_shift= FILAMENTCHANGE_ZADD ; + if(current_position[Z_AXIS] < 25) z_shift+= 25 ; #endif - - } - plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], FILAMENTCHANGE_ZFEED, active_extruder); - - //Move XY to side + //Move XY to side if(code_seen('X')) { - current_position[X_AXIS]+= code_value(); + x_position = code_value(); } else { #ifdef FILAMENTCHANGE_XPOS - current_position[X_AXIS]= FILAMENTCHANGE_XPOS ; + x_position = FILAMENTCHANGE_XPOS; #endif } if(code_seen('Y')) { - current_position[Y_AXIS]= code_value(); + y_position = code_value(); } else { #ifdef FILAMENTCHANGE_YPOS - current_position[Y_AXIS]= FILAMENTCHANGE_YPOS ; + y_position = FILAMENTCHANGE_YPOS ; #endif } - plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], FILAMENTCHANGE_XYFEED, active_extruder); - st_synchronize(); - KEEPALIVE_STATE(PAUSED_FOR_USER); - - int counterBeep = 0; - fanSpeed = 0; - unsigned long waiting_start_time = millis(); - uint8_t wait_for_user_state = 0; - lcd_display_message_fullscreen_P(_T(MSG_PRESS_TO_UNLOAD)); - bool bFirst=true; - while (!(wait_for_user_state == 0 && lcd_clicked())){ - - manage_heater(); - manage_inactivity(true); - -#if BEEPER > 0 - if (counterBeep == 500) { - counterBeep = 0; - } - SET_OUTPUT(BEEPER); - if (counterBeep == 0) { - if((eSoundMode==e_SOUND_MODE_LOUD)||((eSoundMode==e_SOUND_MODE_ONCE)&&bFirst)) { - bFirst=false; - WRITE(BEEPER, HIGH); - } - } - if (counterBeep == 20) { - WRITE(BEEPER, LOW); - } - - counterBeep++; -#endif - - switch (wait_for_user_state) { - case 0: - delay_keep_alive(4); - - if (millis() > waiting_start_time + (unsigned long)M600_TIMEOUT * 1000) { - lcd_display_message_fullscreen_P(_i("Press knob to preheat nozzle and continue."));////MSG_PRESS_TO_PREHEAT c=20 r=4 - wait_for_user_state = 1; - setAllTargetHotends(0); - st_synchronize(); - disable_e0(); - disable_e1(); - disable_e2(); - } - break; - case 1: - delay_keep_alive(4); - - if (lcd_clicked()) { - setTargetHotend(HotendTempBckp, active_extruder); - lcd_wait_for_heater(); - - wait_for_user_state = 2; - } - break; - case 2: - - if (abs(degTargetHotend(active_extruder) - degHotend(active_extruder)) < 1) { - lcd_display_message_fullscreen_P(_T(MSG_PRESS_TO_UNLOAD)); - waiting_start_time = millis(); - wait_for_user_state = 0; - } - else { - counterBeep = 20; //beeper will be inactive during waiting for nozzle preheat - lcd_set_cursor(1, 4); - lcd_print(ftostr3(degHotend(active_extruder))); - } - break; - - } +#ifdef SNMM_V2 + if (code_seen("AUTO")) { + automatic = true; } - WRITE(BEEPER, LOW); - - lcd_change_fil_state = 0; - +#endif //SNMM_V2 - // Unload filament - lcd_display_message_fullscreen_P(_T(MSG_UNLOADING_FILAMENT)); - KEEPALIVE_STATE(IN_HANDLER); - custom_message = true; - lcd_setstatuspgm(_T(MSG_UNLOADING_FILAMENT)); - - if (code_seen('L')) - { - current_position[E_AXIS] += code_value(); - } - else - { -#ifdef SNMM - -#else -#ifdef FILAMENTCHANGE_FINALRETRACT - current_position[E_AXIS] += FILAMENTCHANGE_FINALRETRACT; -#endif -#endif // SNMM - } - -#ifdef SNMM - current_position[E_AXIS] += 12; - plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 3500, active_extruder); - current_position[E_AXIS] += 6; - plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 5000, active_extruder); - current_position[E_AXIS] += (FIL_LOAD_LENGTH * -1); - plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 5000, active_extruder); - st_synchronize(); - current_position[E_AXIS] += (FIL_COOLING); - plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 50, active_extruder); - current_position[E_AXIS] += (FIL_COOLING*-1); - plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 50, active_extruder); - current_position[E_AXIS] += (bowden_length[snmm_extruder] * -1); - plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 3000, active_extruder); - st_synchronize(); - -#else - // plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], FILAMENTCHANGE_RFEED, active_extruder); - //plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 3500 / 60, active_extruder); - - current_position[E_AXIS] -= FILAMENTCHANGE_FINALRETRACT; - st_synchronize(); -#ifdef TMC2130 - uint8_t tmc2130_current_r_bckp = tmc2130_current_r[E_AXIS]; - tmc2130_set_current_r(E_AXIS, TMC2130_UNLOAD_CURRENT_R); -#else - - st_current_set(2, 200); //set lower E motor current for unload to protect filament sensor and ptfe tube - float tmp_motor[3] = DEFAULT_PWM_MOTOR_CURRENT; - float tmp_motor_loud[3] = DEFAULT_PWM_MOTOR_CURRENT_LOUD; - -#endif //TMC2130 - - current_position[E_AXIS] -= 45; - plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 5200 / 60, active_extruder); - st_synchronize(); - current_position[E_AXIS] -= 15; - plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 1000 / 60, active_extruder); - st_synchronize(); - current_position[E_AXIS] -= 20; - plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 1000 / 60, active_extruder); - st_synchronize(); - -#ifdef TMC2130 - tmc2130_set_current_r(E_AXIS, tmc2130_current_r_bckp); -#else - uint8_t silentMode = eeprom_read_byte((uint8_t*)EEPROM_SILENT); - if(silentMode != SILENT_MODE_POWER) st_current_set(2, tmp_motor[2]); //set E back to normal operation currents - else st_current_set(2, tmp_motor_loud[2]); -#endif //TMC2130 - -#endif // SNMM - - - //finish moves - st_synchronize(); - - //disable extruder steppers so filament can be removed - disable_e0(); - disable_e1(); - disable_e2(); - delay(100); - -#ifdef SNMM_V2 - fprintf_P(uart2io, PSTR("U0\n")); - - // get response - bool response = mmu_get_reponse(false); - if (!response) mmu_not_responding(); -#else - lcd_display_message_fullscreen_P(_T(MSG_PULL_OUT_FILAMENT)); - - - - -if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE)) - WRITE(BEEPER, HIGH); - counterBeep = 0; - while(!lcd_clicked() && (counterBeep < 50)) { - if(counterBeep > 5) WRITE(BEEPER, LOW); - delay_keep_alive(100); - counterBeep++; - } - WRITE(BEEPER, LOW); -#endif - - KEEPALIVE_STATE(PAUSED_FOR_USER); - lcd_change_fil_state = lcd_show_fullscreen_message_yes_no_and_wait_P(_i("Was filament unload successful?"), false, true);////MSG_UNLOAD_SUCCESSFUL c=20 r=2 - if (lcd_change_fil_state == 0) lcd_show_fullscreen_message_and_wait_P(_i("Please open idler and remove filament manually."));////MSG_CHECK_IDLER c=20 r=4 - //lcd_return_to_status(); - lcd_update_enable(true); - - -#ifdef SNMM_V2 - mmu_M600_load_filament(); -#else - M600_load_filament(); -#endif - - //Wait for user to check the state - lcd_change_fil_state = 0; - - while ((lcd_change_fil_state == 0)||(lcd_change_fil_state != 1)){ - lcd_change_fil_state = 0; - KEEPALIVE_STATE(PAUSED_FOR_USER); - lcd_alright(); - KEEPALIVE_STATE(IN_HANDLER); - switch(lcd_change_fil_state){ - - // Filament failed to load so load it again - case 2: -#ifdef SNMM_V2 - mmu_M600_load_filament(); //change to "wrong filament loaded" option? -#else - M600_load_filament_movements(); -#endif - break; - - // Filament loaded properly but color is not clear - case 3: - current_position[E_AXIS]+= FILAMENTCHANGE_FINALFEED ; - plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 2, active_extruder); - lcd_loading_color(); - break; - - // Everything good - default: - lcd_change_success(); - lcd_update_enable(true); - break; - } - - } - - - //Not let's go back to print - fanSpeed = fanSpeedBckp; - - //Feed a little of filament to stabilize pressure - current_position[E_AXIS]+= FILAMENTCHANGE_RECFEED; - plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], FILAMENTCHANGE_EXFEED, active_extruder); - - //Retract - current_position[E_AXIS]+= FILAMENTCHANGE_FIRSTRETRACT; - plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], FILAMENTCHANGE_RFEED, active_extruder); - - - - //plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 70, active_extruder); //should do nothing - - //Move XY back - plan_buffer_line(lastpos[X_AXIS], lastpos[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], FILAMENTCHANGE_XYFEED, active_extruder); - - //Move Z back - plan_buffer_line(lastpos[X_AXIS], lastpos[Y_AXIS], lastpos[Z_AXIS], current_position[E_AXIS], FILAMENTCHANGE_ZFEED, active_extruder); - - - current_position[E_AXIS]= current_position[E_AXIS] - FILAMENTCHANGE_FIRSTRETRACT; - - //Unretract - plan_buffer_line(lastpos[X_AXIS], lastpos[Y_AXIS], lastpos[Z_AXIS], current_position[E_AXIS], FILAMENTCHANGE_RFEED, active_extruder); - - //Set E position to original - plan_set_e_position(lastpos[E_AXIS]); - - memcpy(current_position, lastpos, sizeof(lastpos)); - memcpy(destination, current_position, sizeof(current_position)); - - //Recover feed rate - feedmultiply=feedmultiplyBckp; - char cmd[9]; - sprintf_P(cmd, PSTR("M220 S%i"), feedmultiplyBckp); - enquecommand(cmd); - - lcd_setstatuspgm(_T(WELCOME_MSG)); - custom_message = false; - custom_message_type = 0; - - } + gcode_M600(automatic, x_position, y_position, z_shift, e_shift_init, e_shift_late); + + } break; #endif //FILAMENTCHANGEENABLE case 601: { @@ -6926,47 +6759,10 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE)) extr_unload(); //unload just current filament } else { - extr_unload_all(); //unload all filaments + extr_unload_all(); //unload all filaments } #else - custom_message = true; - custom_message_type = 2; - lcd_setstatuspgm(_T(MSG_UNLOADING_FILAMENT)); - -// extr_unload2(); - - current_position[E_AXIS] -= 45; - plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 5200 / 60, active_extruder); - st_synchronize(); - current_position[E_AXIS] -= 15; - plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 1000 / 60, active_extruder); - st_synchronize(); - current_position[E_AXIS] -= 20; - plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 1000 / 60, active_extruder); - st_synchronize(); - - lcd_display_message_fullscreen_P(_T(MSG_PULL_OUT_FILAMENT)); - - //disable extruder steppers so filament can be removed - disable_e0(); - disable_e1(); - disable_e2(); - delay(100); - - Sound_MakeSound(e_SOUND_CLASS_Prompt,e_SOUND_TYPE_StandardPrompt); - uint8_t counterBeep = 0; - while (!lcd_clicked() && (counterBeep < 50)) { - delay_keep_alive(100); - counterBeep++; - } - st_synchronize(); - while (lcd_clicked()) delay_keep_alive(100); - - lcd_update_enable(true); - - lcd_setstatuspgm(_T(WELCOME_MSG)); - custom_message = false; - custom_message_type = 0; + unload_filament(); #endif } break; @@ -7007,8 +6803,7 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE)) printf_P(PSTR("T code: %d \n"), tmp_extruder); fprintf_P(uart2io, PSTR("T%d\n"), tmp_extruder); - bool response = mmu_get_reponse(false); - if (!response) mmu_not_responding(); + manage_response(); snmm_extruder = tmp_extruder; //filament change is finished @@ -9043,7 +8838,7 @@ static void print_time_remaining_init() { print_percent_done_silent = PRINT_PERCENT_DONE_INIT; } -bool mmu_get_reponse(bool timeout) { +bool mmu_get_response(bool timeout) { bool response = true; LongTimer mmu_get_reponse_timeout; uart2_rx_clr(); @@ -9052,7 +8847,7 @@ bool mmu_get_reponse(bool timeout) { while (!uart2_rx_ok()) { delay_keep_alive(100); - if (timeout && mmu_get_reponse_timeout.expired(180 * 1000ul)) { //3 minutes timeout + if (timeout && mmu_get_reponse_timeout.expired(5 * 60 * 1000ul)) { //5 minutes timeout response = false; break; } @@ -9060,8 +8855,66 @@ bool mmu_get_reponse(bool timeout) { return response; } -void mmu_not_responding() { - printf_P(PSTR("MMU not responding")); + +void manage_response() { + bool response = false; + mmu_print_saved = false; + bool lcd_update_was_enabled = false; + float hotend_temp_bckp; + float z_position_bckp, x_position_bckp, y_position_bckp; + while(!response) { + response = mmu_get_response(true); + if (!response) { + if (!mmu_print_saved) { //first occurence + if (lcd_update_enabled) { + lcd_update_was_enabled = true; + lcd_update_enable(false); + } + st_synchronize(); + mmu_print_saved = true; + + hotend_temp_bckp = degTargetHotend(active_extruder); + z_position_bckp = current_position[Z_AXIS]; + x_position_bckp = current_position[X_AXIS]; + y_position_bckp = current_position[Y_AXIS]; + + //lift z + current_position[Z_AXIS] += Z_PAUSE_LIFT; + if (current_position[Z_AXIS] > Z_MAX_POS) current_position[Z_AXIS] = Z_MAX_POS; + plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 15, active_extruder); + st_synchronize(); + //set nozzle target temperature to 0 + setAllTargetHotends(0); + + //Move XY to side + current_position[X_AXIS] = X_PAUSE_POS; + current_position[Y_AXIS] = Y_PAUSE_POS; + plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 50, active_extruder); + st_synchronize(); + } + printf_P(PSTR("MMU not responding\n")); + lcd_show_fullscreen_message_and_wait_P(_i("MMU needs user attention. Please press knob to resume nozzle target temperature.")); + setTargetHotend(hotend_temp_bckp, active_extruder); + while ((degTargetHotend(active_extruder) - degHotend(active_extruder)) > 5) { + delay_keep_alive(1000); + lcd_wait_for_heater(); + } + lcd_display_message_fullscreen_P(_i("Now check MMU. Fix the issue and then press knob on MMU unit.")); + } + else if (mmu_print_saved) { + printf_P(PSTR("MMU start responding\n")); + lcd_clear(); + lcd_display_message_fullscreen_P(_i("MMU OK. Resuming...")); + current_position[X_AXIS] = x_position_bckp; + current_position[Y_AXIS] = y_position_bckp; + plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 50, active_extruder); + st_synchronize(); + current_position[Z_AXIS] = z_position_bckp; + plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 15, active_extruder); + st_synchronize(); + } + } + if (lcd_update_was_enabled) lcd_update_enable(true); } void mmu_load_to_nozzle() { @@ -9103,21 +8956,144 @@ void mmu_switch_extruder(uint8_t extruder) { } -void mmu_M600_load_filament() { +void M600_check_state() { + //Wait for user to check the state + lcd_change_fil_state = 0; + + while ((lcd_change_fil_state == 0)||(lcd_change_fil_state != 1)){ + lcd_change_fil_state = 0; + KEEPALIVE_STATE(PAUSED_FOR_USER); + lcd_alright(); + KEEPALIVE_STATE(IN_HANDLER); + switch(lcd_change_fil_state){ + // Filament failed to load so load it again + case 2: + #ifdef SNMM_V2 + mmu_M600_load_filament(false); //nonautomatic load; change to "wrong filament loaded" option? + #else + M600_load_filament_movements(); + #endif + break; + + // Filament loaded properly but color is not clear + case 3: + current_position[E_AXIS]+= FILAMENTCHANGE_FINALFEED ; + plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 2, active_extruder); + lcd_loading_color(); + break; + + // Everything good + default: + lcd_change_success(); + lcd_update_enable(true); + break; + } + } +} + +void M600_wait_for_user() { + KEEPALIVE_STATE(PAUSED_FOR_USER); + + int counterBeep = 0; + + unsigned long waiting_start_time = millis(); + uint8_t wait_for_user_state = 0; + lcd_display_message_fullscreen_P(_T(MSG_PRESS_TO_UNLOAD)); + //-// + bool bFirst=true; + + + while (!(wait_for_user_state == 0 && lcd_clicked())){ + + manage_heater(); + manage_inactivity(true); + + #if BEEPER > 0 + if (counterBeep == 500) { + counterBeep = 0; + } + SET_OUTPUT(BEEPER); + if (counterBeep == 0) { + //-// + //if(eSoundMode==e_SOUND_MODE_LOUD) + if((eSoundMode==e_SOUND_MODE_LOUD)||((eSoundMode==e_SOUND_MODE_ONCE)&&bFirst)) + { + bFirst=false; + WRITE(BEEPER, HIGH); + } + } + if (counterBeep == 20) { + WRITE(BEEPER, LOW); + } + + counterBeep++; +#endif + + switch (wait_for_user_state) { + case 0: + delay_keep_alive(4); + + if (millis() > waiting_start_time + (unsigned long)M600_TIMEOUT * 1000) { + lcd_display_message_fullscreen_P(_i("Press knob to preheat nozzle and continue."));////MSG_PRESS_TO_PREHEAT c=20 r=4 + wait_for_user_state = 1; + setTargetHotend(0, 0); + setTargetHotend(0, 1); + setTargetHotend(0, 2); + st_synchronize(); + disable_e0(); + disable_e1(); + disable_e2(); + } + break; + case 1: + delay_keep_alive(4); + + if (lcd_clicked()) { + setTargetHotend(HotendTempBckp, active_extruder); + lcd_wait_for_heater(); + + wait_for_user_state = 2; + } + break; + case 2: + + if (abs(degTargetHotend(active_extruder) - degHotend(active_extruder)) < 1) { + lcd_display_message_fullscreen_P(_T(MSG_PRESS_TO_UNLOAD)); + waiting_start_time = millis(); + wait_for_user_state = 0; + } + else { + counterBeep = 20; //beeper will be inactive during waiting for nozzle preheat + lcd_set_cursor(1, 4); + lcd_print(ftostr3(degHotend(active_extruder))); + } + break; + + } + + } + WRITE(BEEPER, LOW); +} + +void mmu_M600_load_filament(bool automatic) { #ifdef SNMM_V2 bool response = false; - tmp_extruder = choose_extruder_menu(); + if (!automatic) { + tmp_extruder = choose_extruder_menu(); + } + else { + tmp_extruder = (tmp_extruder+1)%5; + } lcd_update_enable(false); lcd_clear(); lcd_set_cursor(0, 1); lcd_puts_P(_T(MSG_LOADING_FILAMENT)); lcd_print(" "); - lcd_print(snmm_extruder + 1); + lcd_print(tmp_extruder + 1); snmm_filaments_used |= (1 << tmp_extruder); //for stop print printf_P(PSTR("T code: %d \n"), tmp_extruder); fprintf_P(uart2io, PSTR("T%d\n"), tmp_extruder); - response = mmu_get_reponse(false); - if (!response) mmu_not_responding(); + manage_response(); snmm_extruder = tmp_extruder; //filament change is finished mmu_load_to_nozzle(); diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 3e35c693f..0b9de32eb 100644 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -5308,8 +5308,8 @@ void extr_adj(int extruder) //loading filament for SNMM lcd_print(snmm_extruder + 1); // get response - bool response = mmu_get_reponse(false); - if (!response) mmu_not_responding(); + manage_response(); + lcd_update_enable(true); @@ -5381,8 +5381,7 @@ void extr_unload() { //unloads filament fprintf_P(uart2io, PSTR("U0\n")); // get response - bool response = mmu_get_reponse(false); - if (!response) mmu_not_responding(); + manage_response(); lcd_update_enable(true); #else //SNMM_V2 @@ -5552,7 +5551,6 @@ void extr_unload_all() { } //unloading just used filament (for snmm) - void extr_unload_used() { if (degHotend0() > EXTRUDE_MINTEMP) { for (int i = 0; i < 4; i++) { @@ -5598,6 +5596,48 @@ static void extr_unload_4() { extr_unload(); } +//unload filament for single material printer (used in M702 gcode) +void unload_filament() { + custom_message = true; + custom_message_type = 2; + lcd_setstatuspgm(_T(MSG_UNLOADING_FILAMENT)); + + // extr_unload2(); + + current_position[E_AXIS] -= 45; + plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 5200 / 60, active_extruder); + st_synchronize(); + current_position[E_AXIS] -= 15; + plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 1000 / 60, active_extruder); + st_synchronize(); + current_position[E_AXIS] -= 20; + plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], 1000 / 60, active_extruder); + st_synchronize(); + + lcd_display_message_fullscreen_P(_T(MSG_PULL_OUT_FILAMENT)); + + //disable extruder steppers so filament can be removed + disable_e0(); + disable_e1(); + disable_e2(); + delay(100); + + Sound_MakeSound(e_SOUND_CLASS_Prompt, e_SOUND_TYPE_StandardPrompt); + uint8_t counterBeep = 0; + while (!lcd_clicked() && (counterBeep < 50)) { + delay_keep_alive(100); + counterBeep++; + } + st_synchronize(); + while (lcd_clicked()) delay_keep_alive(100); + + lcd_update_enable(true); + + lcd_setstatuspgm(_T(WELCOME_MSG)); + custom_message = false; + custom_message_type = 0; + +} static void fil_load_menu() { diff --git a/Firmware/ultralcd.h b/Firmware/ultralcd.h index 1c61032dd..323c23319 100644 --- a/Firmware/ultralcd.h +++ b/Firmware/ultralcd.h @@ -120,6 +120,8 @@ void extr_unload_all(); void extr_unload_used(); void extr_unload(); +void unload_filament(); + void stack_error(); void lcd_printer_connected(); void lcd_ping(); diff --git a/Firmware/variants/1_75mm_MK3-MMU-EINSy10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK3-MMU-EINSy10a-E3Dv6full.h index ce94e3d8c..ed6d0c3dc 100644 --- a/Firmware/variants/1_75mm_MK3-MMU-EINSy10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK3-MMU-EINSy10a-E3Dv6full.h @@ -134,7 +134,7 @@ // Filament sensor #define PAT9125 -#define FILAMENT_SENSOR +//#define FILAMENT_SENSOR // Backlash - //#define BACKLASH_X