From bf1a55ab02b7e6f7e516f91c1850461313398263 Mon Sep 17 00:00:00 2001 From: Marek Bel Date: Thu, 4 Apr 2019 18:15:37 +0200 Subject: [PATCH 1/5] Add mmu_continue_loading blocking variant and use it for usb printing, so that "ok" is not returned to the controller in case MMU load failed. Known limitation: MMU load failed is not handled properly if it happens again after user clicked printer button to continue print. --- Firmware/Marlin_main.cpp | 5 +++-- Firmware/mmu.cpp | 34 ++++++++++++++++++++++++++++------ Firmware/mmu.h | 2 +- 3 files changed, 32 insertions(+), 9 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 45a1d4012..f199df2ae 100644 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -7014,7 +7014,7 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE)) if (mmu_enabled) { st_synchronize(); - mmu_continue_loading(); + mmu_continue_loading(is_usb_printing); mmu_extruder = tmp_extruder; //filament change is finished mmu_load_to_nozzle(); } @@ -7052,7 +7052,8 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE)) mmu_command(MmuCmd::T0 + tmp_extruder); manage_response(true, true, MMU_TCODE_MOVE); - mmu_continue_loading(); + mmu_continue_loading(is_usb_printing); + mmu_extruder = tmp_extruder; //filament change is finished if (load_to_nozzle)// for single material usage with mmu diff --git a/Firmware/mmu.cpp b/Firmware/mmu.cpp index dad00f8ee..1c671cfa3 100644 --- a/Firmware/mmu.cpp +++ b/Firmware/mmu.cpp @@ -878,7 +878,7 @@ void mmu_M600_load_filament(bool automatic, float nozzle_temp) mmu_command(MmuCmd::T0 + tmp_extruder); manage_response(false, true, MMU_LOAD_MOVE); - mmu_continue_loading(); + mmu_continue_loading(is_usb_printing); mmu_extruder = tmp_extruder; //filament change is finished mmu_load_to_nozzle(); @@ -1363,7 +1363,7 @@ bFilamentAction=false; // NOT in "mmu_load_to_nozzle_ lcd_print(tmp_extruder + 1); mmu_command(MmuCmd::T0 + tmp_extruder); manage_response(true, true, MMU_TCODE_MOVE); - mmu_continue_loading(); + mmu_continue_loading(false); mmu_extruder = tmp_extruder; //filament change is finished mmu_load_to_nozzle(); load_filament_final_feed(); @@ -1464,7 +1464,10 @@ static void load_more() st_synchronize(); } -void mmu_continue_loading() +//! @par blocking +//! * true blocking +//! * false non-blocking +void mmu_continue_loading(bool blocking) { if (ir_sensor_detected) { @@ -1510,9 +1513,28 @@ void mmu_continue_loading() setAllTargetHotends(0); lcd_setstatuspgm(_i("MMU load failed "));////MSG_RECOVERING_PRINT c=20 r=1 - mmu_fil_loaded = false; //so we can retry same T-code again - isPrintPaused = true; - mmu_command(MmuCmd::W0); + + if (blocking) + { + KEEPALIVE_STATE(PAUSED_FOR_USER); + lcd_consume_click(); + while(!lcd_clicked()){ + manage_heater(); + manage_inactivity(true); + lcd_update(0); + } + KEEPALIVE_STATE(IN_HANDLER); + restore_print_from_ram_and_continue(0); + mmu_command(MmuCmd::T0 + tmp_extruder); + manage_response(true, true, MMU_TCODE_MOVE); + load_more(); + } + else + { + mmu_fil_loaded = false; //so we can retry same T-code again + isPrintPaused = true; + mmu_command(MmuCmd::W0); + } } } } diff --git a/Firmware/mmu.h b/Firmware/mmu.h index 41e0ba1f4..f0fc0deb0 100644 --- a/Firmware/mmu.h +++ b/Firmware/mmu.h @@ -134,7 +134,7 @@ extern void mmu_eject_filament(uint8_t filament, bool recover); #ifdef MMU_HAS_CUTTER extern void mmu_cut_filament(uint8_t filament_nr); #endif //MMU_HAS_CUTTER -extern void mmu_continue_loading(); +extern void mmu_continue_loading(bool blocking); extern void mmu_filament_ramming(); extern void mmu_wait_for_heater_blocking(); extern void mmu_load_step(bool synchronize = true); From 4bfa3d7e0bb05aa54564baa242205f6c492595c3 Mon Sep 17 00:00:00 2001 From: Marek Bel Date: Thu, 4 Apr 2019 19:04:15 +0200 Subject: [PATCH 2/5] Reporty busy: paused for user in case MMU is not responding. --- Firmware/mmu.cpp | 2 ++ Firmware/tmc2130.cpp | 3 +++ 2 files changed, 5 insertions(+) diff --git a/Firmware/mmu.cpp b/Firmware/mmu.cpp index 1c671cfa3..c7d1f2c93 100644 --- a/Firmware/mmu.cpp +++ b/Firmware/mmu.cpp @@ -679,6 +679,7 @@ void manage_response(bool move_axes, bool turn_off_nozzle, uint8_t move) st_synchronize(); mmu_print_saved = true; printf_P(PSTR("MMU not responding\n")); + KEEPALIVE_STATE(PAUSED_FOR_USER); hotend_temp_bckp = degTargetHotend(active_extruder); if (move_axes) { z_position_bckp = current_position[Z_AXIS]; @@ -735,6 +736,7 @@ void manage_response(bool move_axes, bool turn_off_nozzle, uint8_t move) } else if (mmu_print_saved) { printf_P(PSTR("MMU starts responding\n")); + KEEPALIVE_STATE(IN_HANDLER); mmu_loading_flag = false; if (turn_off_nozzle) { diff --git a/Firmware/tmc2130.cpp b/Firmware/tmc2130.cpp index 8cd3422a9..05ea2ab6a 100644 --- a/Firmware/tmc2130.cpp +++ b/Firmware/tmc2130.cpp @@ -715,6 +715,9 @@ uint8_t tmc2130_get_pwr(uint8_t axis) return 0; } +//! @par pwr motor power +//! * 0 disabled +//! * non-zero enabled void tmc2130_set_pwr(uint8_t axis, uint8_t pwr) { switch (axis) From bf57a59147f18e9d5485b6dfa808bac6786f6e51 Mon Sep 17 00:00:00 2001 From: Marek Bel Date: Fri, 5 Apr 2019 13:47:17 +0200 Subject: [PATCH 3/5] Extract duplicate code into function. Saves 106B flash. --- Firmware/Marlin.h | 1 + Firmware/Marlin_main.cpp | 26 +++++++++++++++++++------- Firmware/mmu.cpp | 9 +-------- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/Firmware/Marlin.h b/Firmware/Marlin.h index 1a278013b..fd6121a06 100644 --- a/Firmware/Marlin.h +++ b/Firmware/Marlin.h @@ -497,3 +497,4 @@ void M600_load_filament_movements(); void M600_wait_for_user(float HotendTempBckp); void M600_check_state(float nozzle_temp); void load_filament_final_feed(); +void marlin_wait_for_click(); diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index f199df2ae..b4aeef150 100644 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -4962,13 +4962,7 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE)) KEEPALIVE_STATE(IN_HANDLER); lcd_ignore_click(false); }else{ - KEEPALIVE_STATE(PAUSED_FOR_USER); - while(!lcd_clicked()){ - manage_heater(); - manage_inactivity(true); - lcd_update(0); - } - KEEPALIVE_STATE(IN_HANDLER); + marlin_wait_for_click(); } if (IS_SD_PRINTING) LCD_MESSAGERPGM(_T(MSG_RESUMING_PRINT)); @@ -9615,4 +9609,22 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE)) lcd_update_enable(false); } + +//! @brief Wait for click +//! +//! Set +void marlin_wait_for_click() +{ + int busy_state_backup = busy_state; + KEEPALIVE_STATE(PAUSED_FOR_USER); + lcd_consume_click(); + while(!lcd_clicked()) + { + manage_heater(); + manage_inactivity(true); + lcd_update(0); + } + KEEPALIVE_STATE(busy_state); +} + #define FIL_LOAD_LENGTH 60 diff --git a/Firmware/mmu.cpp b/Firmware/mmu.cpp index c7d1f2c93..754ad3f74 100644 --- a/Firmware/mmu.cpp +++ b/Firmware/mmu.cpp @@ -1518,14 +1518,7 @@ void mmu_continue_loading(bool blocking) if (blocking) { - KEEPALIVE_STATE(PAUSED_FOR_USER); - lcd_consume_click(); - while(!lcd_clicked()){ - manage_heater(); - manage_inactivity(true); - lcd_update(0); - } - KEEPALIVE_STATE(IN_HANDLER); + marlin_wait_for_click(); restore_print_from_ram_and_continue(0); mmu_command(MmuCmd::T0 + tmp_extruder); manage_response(true, true, MMU_TCODE_MOVE); From 84cabd38366c610e7bfded2395f87cbc3d290752 Mon Sep 17 00:00:00 2001 From: Marek Bel Date: Fri, 5 Apr 2019 15:19:53 +0200 Subject: [PATCH 4/5] Change busy_state type, save 340B of flash --- Firmware/Marlin.h | 2 +- Firmware/Marlin_main.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Firmware/Marlin.h b/Firmware/Marlin.h index fd6121a06..08f7b4f22 100644 --- a/Firmware/Marlin.h +++ b/Firmware/Marlin.h @@ -469,7 +469,7 @@ extern uint8_t calc_percent_done(); #define KEEPALIVE_STATE(n) do { busy_state = n;} while (0) extern void host_keepalive(); //extern MarlinBusyState busy_state; -extern int busy_state; +extern int8_t busy_state; #ifdef TMC2130 diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index b4aeef150..4ca05d182 100644 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -303,7 +303,7 @@ int fanSpeed=0; bool cancel_heatup = false ; -int busy_state = NOT_BUSY; +int8_t busy_state = NOT_BUSY; static long prev_busy_signal_ms = -1; uint8_t host_keepalive_interval = HOST_KEEPALIVE_INTERVAL; @@ -9615,7 +9615,7 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE)) //! Set void marlin_wait_for_click() { - int busy_state_backup = busy_state; + int8_t busy_state_backup = busy_state; KEEPALIVE_STATE(PAUSED_FOR_USER); lcd_consume_click(); while(!lcd_clicked()) From c7d403733a726ada83343e2dda23eb14b38a633b Mon Sep 17 00:00:00 2001 From: Marek Bel Date: Tue, 9 Apr 2019 20:50:29 +0200 Subject: [PATCH 5/5] Allow load filament retry after button push unlimited times in case mmu_continue_loading() is in blocking mode. --- Firmware/mmu.cpp | 147 +++++++++++++++++++++++++++++------------------ Firmware/mmu.h | 2 +- 2 files changed, 92 insertions(+), 57 deletions(-) diff --git a/Firmware/mmu.cpp b/Firmware/mmu.cpp index 754ad3f74..ef5b021c9 100644 --- a/Firmware/mmu.cpp +++ b/Firmware/mmu.cpp @@ -1466,74 +1466,109 @@ static void load_more() st_synchronize(); } +static void increment_load_fail() +{ + uint8_t mmu_load_fail = eeprom_read_byte((uint8_t*)EEPROM_MMU_LOAD_FAIL); + uint16_t mmu_load_fail_tot = eeprom_read_word((uint16_t*)EEPROM_MMU_LOAD_FAIL_TOT); + if(mmu_load_fail < 255) eeprom_update_byte((uint8_t*)EEPROM_MMU_LOAD_FAIL, mmu_load_fail + 1); + if(mmu_load_fail_tot < 65535) eeprom_update_word((uint16_t*)EEPROM_MMU_LOAD_FAIL_TOT, mmu_load_fail_tot + 1); +} + +//! @brief continue loading filament //! @par blocking -//! * true blocking -//! * false non-blocking +//! * true blocking - do not return until successful load +//! * false non-blocking - pause print and return on load failure +//! +//! @startuml +//! [*] --> [*] : !ir_sensor_detected /\n send MmuCmd::C0 +//! [*] --> LoadMore +//! LoadMore --> [*] : filament \ndetected +//! LoadMore --> Retry : !filament detected /\n increment load fail +//! Retry --> [*] : filament \ndetected +//! Retry --> Unload : !filament \ndetected +//! Unload --> [*] : non-blocking +//! Unload --> Retry : button \nclicked +//! +//! Retry : Cut filament if enabled +//! Retry : repeat last T-code +//! Unload : unload filament +//! Unload : pause print +//! Unload : show error message +//! +//! @enduml void mmu_continue_loading(bool blocking) { - if (ir_sensor_detected) + if (!ir_sensor_detected) { - load_more(); + mmu_command(MmuCmd::C0); + return; + } - if (PIN_GET(IR_SENSOR_PIN) != 0) { - uint8_t mmu_load_fail = eeprom_read_byte((uint8_t*)EEPROM_MMU_LOAD_FAIL); - uint16_t mmu_load_fail_tot = eeprom_read_word((uint16_t*)EEPROM_MMU_LOAD_FAIL_TOT); - if(mmu_load_fail < 255) eeprom_update_byte((uint8_t*)EEPROM_MMU_LOAD_FAIL, mmu_load_fail + 1); - if(mmu_load_fail_tot < 65535) eeprom_update_word((uint16_t*)EEPROM_MMU_LOAD_FAIL_TOT, mmu_load_fail_tot + 1); + load_more(); + enum class Ls : uint_least8_t + { + enter, + retry, + unload, + }; + Ls state = Ls::enter; + + while (PIN_GET(IR_SENSOR_PIN) != 0) + { + switch (state) + { + case Ls::enter: + increment_load_fail(); + // no break + case Ls::retry: #ifdef MMU_HAS_CUTTER - if (1 == eeprom_read_byte((uint8_t*)EEPROM_MMU_CUTTER_ENABLED)) - { - mmu_command(MmuCmd::K0 + tmp_extruder); - manage_response(true, true, MMU_UNLOAD_MOVE); - } + if (1 == eeprom_read_byte((uint8_t*)EEPROM_MMU_CUTTER_ENABLED)) + { + mmu_command(MmuCmd::K0 + tmp_extruder); + manage_response(true, true, MMU_UNLOAD_MOVE); + } #endif //MMU_HAS_CUTTER - mmu_command(MmuCmd::T0 + tmp_extruder); manage_response(true, true, MMU_TCODE_MOVE); load_more(); + state = Ls::unload; + break; + case Ls::unload: + stop_and_save_print_to_ram(0, 0); - if (PIN_GET(IR_SENSOR_PIN) != 0) + //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(); + + //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(); + + mmu_command(MmuCmd::U0); + manage_response(false, true, MMU_UNLOAD_MOVE); + + setAllTargetHotends(0); + lcd_setstatuspgm(_i("MMU load failed "));////c=20 r=1 + + if (blocking) { - //pause print, show error message and then repeat last T-code - stop_and_save_print_to_ram(0, 0); - - //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(); - - //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(); - - mmu_command(MmuCmd::U0); - manage_response(false, true, MMU_UNLOAD_MOVE); - - setAllTargetHotends(0); - lcd_setstatuspgm(_i("MMU load failed "));////MSG_RECOVERING_PRINT c=20 r=1 - - if (blocking) - { - marlin_wait_for_click(); - restore_print_from_ram_and_continue(0); - mmu_command(MmuCmd::T0 + tmp_extruder); - manage_response(true, true, MMU_TCODE_MOVE); - load_more(); - } - else - { - mmu_fil_loaded = false; //so we can retry same T-code again - isPrintPaused = true; - mmu_command(MmuCmd::W0); - } + marlin_wait_for_click(); + restore_print_from_ram_and_continue(0); + state = Ls::retry; } - } - } - else { //mmu_ir_sensor_detected == false - mmu_command(MmuCmd::C0); - } + else + { + mmu_fil_loaded = false; //so we can retry same T-code again + isPrintPaused = true; + mmu_command(MmuCmd::W0); + return; + } + break; + } + } } diff --git a/Firmware/mmu.h b/Firmware/mmu.h index f0fc0deb0..a7da0c2d9 100644 --- a/Firmware/mmu.h +++ b/Firmware/mmu.h @@ -58,7 +58,7 @@ enum class MmuCmd : uint_least8_t K4, R0, S3, - W0, + W0, //!< Wait and signal load error }; inline MmuCmd operator+ (MmuCmd cmd, uint8_t filament)