|
@@ -91,7 +91,7 @@ MMU2::MMU2()
|
|
|
, resume_hotend_temp(0)
|
|
|
, logicStepLastStatus(StepStatus::Finished)
|
|
|
, state(xState::Stopped)
|
|
|
- , mmu_print_saved(false)
|
|
|
+ , mmu_print_saved(SavedState::None)
|
|
|
, loadFilamentStarted(false)
|
|
|
, loadingToNozzle(false)
|
|
|
{
|
|
@@ -458,15 +458,14 @@ void MMU2::Home(uint8_t mode){
|
|
|
}
|
|
|
|
|
|
void MMU2::SaveAndPark(bool move_axes, bool turn_off_nozzle) {
|
|
|
- if (!mmu_print_saved) { // First occurrence. Save current position, park print head, disable nozzle heater.
|
|
|
+ if (mmu_print_saved == SavedState::None) { // First occurrence. Save current position, park print head, disable nozzle heater.
|
|
|
LogEchoEvent("Saving and parking");
|
|
|
st_synchronize();
|
|
|
-
|
|
|
- mmu_print_saved = true;
|
|
|
-
|
|
|
+
|
|
|
resume_hotend_temp = degTargetHotend(active_extruder);
|
|
|
|
|
|
if (move_axes){
|
|
|
+ mmu_print_saved |= SavedState::ParkExtruder;
|
|
|
// save current pos
|
|
|
for(uint8_t i = 0; i < 3; ++i){
|
|
|
resume_position.xyz[i] = current_position[i];
|
|
@@ -487,6 +486,7 @@ void MMU2::SaveAndPark(bool move_axes, bool turn_off_nozzle) {
|
|
|
}
|
|
|
|
|
|
if (turn_off_nozzle){
|
|
|
+ mmu_print_saved |= SavedState::Cooldown;
|
|
|
LogEchoEvent("Heater off");
|
|
|
setAllTargetHotends(0);
|
|
|
}
|
|
@@ -496,35 +496,37 @@ void MMU2::SaveAndPark(bool move_axes, bool turn_off_nozzle) {
|
|
|
// gcode.reset_stepper_timeout();
|
|
|
}
|
|
|
|
|
|
-void MMU2::ResumeAndUnPark(bool move_axes, bool turn_off_nozzle) {
|
|
|
- if (mmu_print_saved) {
|
|
|
- LogEchoEvent("Resuming print");
|
|
|
-
|
|
|
- if (turn_off_nozzle && resume_hotend_temp) {
|
|
|
- MMU2_ECHO_MSG("Restoring hotend temperature ");
|
|
|
- SERIAL_ECHOLN(resume_hotend_temp);
|
|
|
- setTargetHotend(resume_hotend_temp, active_extruder);
|
|
|
- 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");
|
|
|
- lcd_update_enable(true); // temporary hack to stop this locking the printer...
|
|
|
- }
|
|
|
+void MMU2::ResumeHotendTemp() {
|
|
|
+ if ((mmu_print_saved & SavedState::Cooldown) && resume_hotend_temp) {
|
|
|
+ LogEchoEvent("Resuming Temp");
|
|
|
+ MMU2_ECHO_MSG("Restoring hotend temperature ");
|
|
|
+ SERIAL_ECHOLN(resume_hotend_temp);
|
|
|
+ setTargetHotend(resume_hotend_temp, active_extruder);
|
|
|
+ lcd_display_message_fullscreen_P(_i("MMU OK. Resuming temperature...")); // better report the event and let the GUI do its work somewhere else
|
|
|
+ ReportErrorHookSensorLineRender();
|
|
|
+ waitForHotendTargetTemp(1000, []{
|
|
|
+ ReportErrorHookDynamicRender();
|
|
|
+ });
|
|
|
+ LogEchoEvent("Hotend temperature reached");
|
|
|
+ lcd_update_enable(true); // temporary hack to stop this locking the printer...
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
- if (move_axes) {
|
|
|
- LogEchoEvent("Resuming XYZ");
|
|
|
+void MMU2::ResumeUnpark()
|
|
|
+{
|
|
|
+ if (mmu_print_saved & SavedState::ParkExtruder) {
|
|
|
+ LogEchoEvent("Resuming XYZ");
|
|
|
|
|
|
- current_position[X_AXIS] = resume_position.xyz[X_AXIS];
|
|
|
- current_position[Y_AXIS] = resume_position.xyz[Y_AXIS];
|
|
|
- plan_buffer_line_curposXYZE(NOZZLE_PARK_XY_FEEDRATE);
|
|
|
- st_synchronize();
|
|
|
-
|
|
|
- current_position[Z_AXIS] = resume_position.xyz[Z_AXIS];
|
|
|
- plan_buffer_line_curposXYZE(NOZZLE_PARK_Z_FEEDRATE);
|
|
|
- st_synchronize();
|
|
|
- } else {
|
|
|
- LogEchoEvent("NOT resuming XYZ");
|
|
|
- }
|
|
|
+ current_position[X_AXIS] = resume_position.xyz[X_AXIS];
|
|
|
+ current_position[Y_AXIS] = resume_position.xyz[Y_AXIS];
|
|
|
+ plan_buffer_line_curposXYZE(NOZZLE_PARK_XY_FEEDRATE);
|
|
|
+ st_synchronize();
|
|
|
+
|
|
|
+ current_position[Z_AXIS] = resume_position.xyz[Z_AXIS];
|
|
|
+ plan_buffer_line_curposXYZE(NOZZLE_PARK_Z_FEEDRATE);
|
|
|
+ st_synchronize();
|
|
|
+ } else {
|
|
|
+ LogEchoEvent("NOT resuming XYZ");
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -534,6 +536,7 @@ void MMU2::CheckUserInput(){
|
|
|
case Left:
|
|
|
case Middle:
|
|
|
case Right:
|
|
|
+ ResumeHotendTemp(); // Recover the hotend temp before we attempt to do anything else...
|
|
|
Button(btn);
|
|
|
break;
|
|
|
case RestartMMU:
|
|
@@ -559,7 +562,7 @@ void MMU2::CheckUserInput(){
|
|
|
/// But - in case of an error, the command is not yet finished, but we must react accordingly - move the printhead elsewhere, stop heating, eat a cat or so.
|
|
|
/// That's what's being done here...
|
|
|
void MMU2::manage_response(const bool move_axes, const bool turn_off_nozzle) {
|
|
|
- mmu_print_saved = false;
|
|
|
+ mmu_print_saved = SavedState::None;
|
|
|
|
|
|
KEEPALIVE_STATE(PAUSED_FOR_USER);
|
|
|
|
|
@@ -577,7 +580,7 @@ void MMU2::manage_response(const bool move_axes, const bool turn_off_nozzle) {
|
|
|
case Finished:
|
|
|
// command/operation completed, let Marlin continue its work
|
|
|
// the E may have some more moves to finish - wait for them
|
|
|
- ResumeAndUnPark(move_axes, turn_off_nozzle); // This is needed here otherwise recovery doesn't work.
|
|
|
+ ResumeUnpark(); // We can now travel back to the tower or wherever we were when we saved.
|
|
|
st_synchronize();
|
|
|
return;
|
|
|
case VersionMismatch: // this basically means the MMU will be disabled until reconnected
|
|
@@ -591,7 +594,8 @@ void MMU2::manage_response(const bool move_axes, const bool turn_off_nozzle) {
|
|
|
break;
|
|
|
case CommunicationRecovered: // @@TODO communication recovered and may be an error recovered as well
|
|
|
// may be the logic layer can detect the change of state a respond with one "Recovered" to be handled here
|
|
|
- ResumeAndUnPark(move_axes, turn_off_nozzle);
|
|
|
+ ResumeHotendTemp();
|
|
|
+ ResumeUnpark();
|
|
|
break;
|
|
|
case Processing: // wait for the MMU to respond
|
|
|
default:
|