diff --git a/Firmware/Marlin.h b/Firmware/Marlin.h index 625e079e..ee7f15d8 100755 --- a/Firmware/Marlin.h +++ b/Firmware/Marlin.h @@ -376,6 +376,10 @@ extern char dir_names[3][9]; extern int8_t lcd_change_fil_state; // save/restore printing extern bool saved_printing; +extern uint8_t saved_printing_type; +#define PRINTING_TYPE_SD 0 +#define PRINTING_TYPE_USB 1 +#define PRINTING_TYPE_NONE 2 //save/restore printing in case that mmu is not responding extern bool mmu_print_saved; diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 970b855f..fdb86da9 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -142,10 +142,6 @@ //Macro for print fan speed #define FAN_PULSE_WIDTH_LIMIT ((fanSpeed > 100) ? 3 : 4) //time in ms -#define PRINTING_TYPE_SD 0 -#define PRINTING_TYPE_USB 1 -#define PRINTING_TYPE_NONE 2 - //filament types #define FILAMENT_DEFAULT 0 #define FILAMENT_FLEX 1 @@ -378,7 +374,7 @@ boolean chdkActive = false; //! @{ bool saved_printing = false; //!< Print is paused and saved in RAM static uint32_t saved_sdpos = 0; //!< SD card position, or line number in case of USB printing -static uint8_t saved_printing_type = PRINTING_TYPE_SD; +uint8_t saved_printing_type = PRINTING_TYPE_SD; static float saved_pos[4] = { 0, 0, 0, 0 }; //! Feedrate hopefully derived from an active block of the planner at the time the print has been canceled, in mm/min. static float saved_feedrate2 = 0; @@ -623,7 +619,7 @@ void crashdet_cancel() if (saved_printing_type == PRINTING_TYPE_SD) { lcd_print_stop(); }else if(saved_printing_type == PRINTING_TYPE_USB){ - SERIAL_ECHOLNPGM("// action:cancel"); //for Octoprint: works the same as clicking "Abort" button in Octoprint GUI + SERIAL_ECHOLNRPGM(MSG_OCTOPRINT_CANCEL); //for Octoprint: works the same as clicking "Abort" button in Octoprint GUI SERIAL_PROTOCOLLNRPGM(MSG_OK); } } @@ -1751,12 +1747,25 @@ void loop() { is_usb_printing = false; } + if (isPrintPaused && saved_printing_type == PRINTING_TYPE_USB) //keep believing that usb is being printed. Prevents accessing dangerous menus while pausing. + { + is_usb_printing = true; + } + +#ifdef FANCHECK + if (fan_check_error && isPrintPaused) + { + KEEPALIVE_STATE(PAUSED_FOR_USER); + host_keepalive(); //prevent timeouts since usb processing is disabled until print is resumed. This is for a crude way of pausing a print on all hosts. + } +#endif if (prusa_sd_card_upload) { //we read byte-by byte serial_read_stream(); - } else + } + else { get_command(); @@ -3450,22 +3459,16 @@ extern uint8_t st_backlash_y; void process_commands() { - #ifdef FANCHECK - if (fan_check_error){ - if( fan_check_error == EFCE_DETECTED ){ - fan_check_error = EFCE_REPORTED; - - if(is_usb_printing){ - SERIAL_PROTOCOLLNRPGM(MSG_OCTOPRINT_PAUSE); - } - else{ - lcd_pause_print(); - } - - } // otherwise it has already been reported, so just ignore further processing - return; - } - #endif +#ifdef FANCHECK + if(fan_check_error){ + if(fan_check_error == EFCE_DETECTED){ + fan_check_error = EFCE_REPORTED; + // SERIAL_PROTOCOLLNRPGM(MSG_OCTOPRINT_PAUSED); + lcd_pause_print(); + } // otherwise it has already been reported, so just ignore further processing + return; //ignore usb stream. It is reenabled by selecting resume from the lcd. + } +#endif if (!buflen) return; //empty command #ifdef FILAMENT_RUNOUT_SUPPORT @@ -10155,7 +10158,8 @@ void restore_print_from_ram_and_continue(float e_move) #ifdef FANCHECK // Do not allow resume printing if fans are still not ok - if( fan_check_error != EFCE_OK )return; + if ((fan_check_error != EFCE_OK) && (fan_check_error != EFCE_FIXED)) return; + if (fan_check_error == EFCE_FIXED) fan_check_error = EFCE_OK; //reenable serial stream processing if printing from usb #endif // for (int axis = X_AXIS; axis <= E_AXIS; axis++) @@ -10209,6 +10213,7 @@ void restore_print_from_ram_and_continue(float e_move) } SERIAL_PROTOCOLLNRPGM(MSG_OK); //dummy response because of octoprint is waiting for this lcd_setstatuspgm(_T(WELCOME_MSG)); + saved_printing_type = PRINTING_TYPE_NONE; saved_printing = false; } diff --git a/Firmware/messages.c b/Firmware/messages.c index 1c36e43c..c0c3cfc3 100644 --- a/Firmware/messages.c +++ b/Firmware/messages.c @@ -129,4 +129,8 @@ const char MSG_ENDSTOP_OPEN[] PROGMEM_N1 = "open"; //// const char MSG_POWERUP[] PROGMEM_N1 = "PowerUp"; //// const char MSG_ERR_STOPPED[] PROGMEM_N1 = "Printer stopped due to errors. Fix the error and use M999 to restart. (Temperature is reset. Set it after restarting)"; //// const char MSG_ENDSTOP_HIT[] PROGMEM_N1 = "TRIGGERED"; //// -const char MSG_OCTOPRINT_PAUSE[] PROGMEM_N1 = "// action:pause"; //// +const char MSG_OCTOPRINT_PAUSED[] PROGMEM_N1 = "// action:paused"; //// +const char MSG_OCTOPRINT_RESUMED[] PROGMEM_N1 = "// action:resumed"; //// +const char MSG_OCTOPRINT_CANCEL[] PROGMEM_N1 = "// action:cancel"; //// +const char MSG_FANCHECK_EXTRUDER[] PROGMEM_N1 = "Err: EXTR. FAN ERROR"; ////c=20 +const char MSG_FANCHECK_PRINT[] PROGMEM_N1 = "Err: PRINT FAN ERROR"; ////c=20 diff --git a/Firmware/messages.h b/Firmware/messages.h index b48337ef..525b7c5b 100644 --- a/Firmware/messages.h +++ b/Firmware/messages.h @@ -130,7 +130,11 @@ extern const char MSG_ERR_STOPPED[]; extern const char MSG_ENDSTOP_HIT[]; extern const char MSG_EJECT_FILAMENT[]; extern const char MSG_CUT_FILAMENT[]; -extern const char MSG_OCTOPRINT_PAUSE[]; +extern const char MSG_OCTOPRINT_PAUSED[]; +extern const char MSG_OCTOPRINT_RESUMED[]; +extern const char MSG_OCTOPRINT_CANCEL[]; +extern const char MSG_FANCHECK_EXTRUDER[]; +extern const char MSG_FANCHECK_PRINT[]; #if defined(__cplusplus) } diff --git a/Firmware/temperature.cpp b/Firmware/temperature.cpp index 3c7f5fbc..5a1b9c8c 100755 --- a/Firmware/temperature.cpp +++ b/Firmware/temperature.cpp @@ -503,14 +503,14 @@ void checkFanSpeed() // drop the fan_check_error flag when both fans are ok if( fan_speed_errors[0] == 0 && fan_speed_errors[1] == 0 && fan_check_error == EFCE_REPORTED){ // we may even send some info to the LCD from here - fan_check_error = EFCE_OK; + fan_check_error = EFCE_FIXED; } - if ((fan_speed_errors[0] > max_extruder_fan_errors) && fans_check_enabled) { + if ((fan_speed_errors[0] > max_extruder_fan_errors) && fans_check_enabled && (fan_check_error == EFCE_OK)) { fan_speed_errors[0] = 0; fanSpeedError(0); //extruder fan } - if ((fan_speed_errors[1] > max_print_fan_errors) && fans_check_enabled) { + if ((fan_speed_errors[1] > max_print_fan_errors) && fans_check_enabled && (fan_check_error == EFCE_OK)) { fan_speed_errors[1] = 0; fanSpeedError(1); //print fan } @@ -529,31 +529,31 @@ static void fanSpeedErrorBeep(const char *serialMsg, const char *lcdMsg){ } void fanSpeedError(unsigned char _fan) { - if (get_message_level() != 0 && isPrintPaused) return; - //to ensure that target temp. is not set to zero in case taht we are resuming print + if (get_message_level() != 0 && isPrintPaused) return; + //to ensure that target temp. is not set to zero in case that we are resuming print if (card.sdprinting || is_usb_printing) { if (heating_status != 0) { lcd_print_stop(); } else { - fan_check_error = EFCE_DETECTED; + fan_check_error = EFCE_DETECTED; //plans error for next processed command } } else { - SERIAL_PROTOCOLLNRPGM(MSG_OCTOPRINT_PAUSE); //for octoprint - setTargetHotend0(0); - heating_status = 0; - fan_check_error = EFCE_REPORTED; + // SERIAL_PROTOCOLLNRPGM(MSG_OCTOPRINT_PAUSED); //Why pause octoprint? is_usb_printing would be true in that case, so there is no need for this. + setTargetHotend0(0); + heating_status = 0; + fan_check_error = EFCE_REPORTED; } switch (_fan) { case 0: // extracting the same code from case 0 and case 1 into a function saves 72B - fanSpeedErrorBeep(PSTR("Extruder fan speed is lower than expected"), PSTR("Err: EXTR. FAN ERROR") ); + fanSpeedErrorBeep(PSTR("Extruder fan speed is lower than expected"), MSG_FANCHECK_EXTRUDER); break; case 1: - fanSpeedErrorBeep(PSTR("Print fan speed is lower than expected"), PSTR("Err: PRINT FAN ERROR") ); + fanSpeedErrorBeep(PSTR("Print fan speed is lower than expected"), MSG_FANCHECK_PRINT); break; } - SERIAL_PROTOCOLLNRPGM(MSG_OK); + // SERIAL_PROTOCOLLNRPGM(MSG_OK); //This ok messes things up with octoprint. } #endif //(defined(TACH_0) && TACH_0 >-1) || (defined(TACH_1) && TACH_1 > -1) diff --git a/Firmware/temperature.h b/Firmware/temperature.h index 7f4daa2e..7c40eae6 100755 --- a/Firmware/temperature.h +++ b/Firmware/temperature.h @@ -241,6 +241,7 @@ void checkExtruderAutoFans(); enum { EFCE_OK = 0, //!< normal operation, both fans are ok + EFCE_FIXED, //!< previous fan error was fixed EFCE_DETECTED, //!< fan error detected, but not reported yet EFCE_REPORTED //!< fan error detected and reported to LCD and serial }; diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 77af6d5f..86e6296d 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -1658,7 +1658,7 @@ void lcd_pause_print() { lcd_commands_type = LcdCommands::LongPause; } - SERIAL_PROTOCOLLNRPGM(MSG_OCTOPRINT_PAUSE); //pause for octoprint + SERIAL_PROTOCOLLNRPGM(MSG_OCTOPRINT_PAUSED); //pause for octoprint } @@ -6578,19 +6578,61 @@ static void lcd_test_menu() } #endif //LCD_TEST +static bool fan_error_selftest() +{ +#ifdef FANCHECK + + fanSpeed = 255; +#ifdef FAN_SOFT_PWM + fanSpeedSoftPwm = 255; +#endif //FAN_SOFT_PWM + manage_heater(); //enables print fan + setExtruderAutoFanState(EXTRUDER_0_AUTO_FAN_PIN, 1); //force enables the extruder fan untill the first manage_heater() call. +#ifdef FAN_SOFT_PWM + extruder_autofan_last_check = _millis(); + fan_measuring = true; +#endif //FAN_SOFT_PWM + _delay(1000); //delay_keep_alive would turn off extruder fan, because temerature is too low (maybe) + manage_heater(); + fanSpeed = 0; +#ifdef FAN_SOFT_PWM + fanSpeedSoftPwm = 0; +#endif //FAN_SOFT_PWM + manage_heater(); +#ifdef TACH_0 + if (fan_speed[0] <= 20) { //extruder fan error + LCD_ALERTMESSAGERPGM(MSG_FANCHECK_EXTRUDER); + return 1; + } +#endif +#ifdef TACH_1 + if (fan_speed[1] <= 20) { //print fan error + LCD_ALERTMESSAGERPGM(MSG_FANCHECK_PRINT); + return 1; + } +#endif + return 0; + +#endif //FANCHECK +} + //! @brief Resume paused print //! @todo It is not good to call restore_print_from_ram_and_continue() from function called by lcd_update(), //! as restore_print_from_ram_and_continue() calls lcd_update() internally. void lcd_resume_print() { lcd_return_to_status(); - lcd_reset_alert_level(); + lcd_reset_alert_level(); lcd_setstatuspgm(_T(MSG_RESUMING_PRINT)); lcd_reset_alert_level(); //for fan speed error + + if (fan_error_selftest()) return; //abort if error persists + restore_print_from_ram_and_continue(0.0); pause_time += (_millis() - start_pause_print); //accumulate time when print is paused for correct statistics calculation refresh_cmd_timeout(); isPrintPaused = false; + SERIAL_PROTOCOLLNRPGM(MSG_OCTOPRINT_RESUMED); //resume octoprint } static void change_sheet() @@ -6723,6 +6765,10 @@ static void lcd_main_menu() } +#ifdef FANCHECK + if((fan_check_error == EFCE_FIXED) && (saved_printing_type == PRINTING_TYPE_USB)) + MENU_ITEM_SUBMENU_P(_i("Resume print"), lcd_resume_print);////MSG_RESUME_PRINT +#endif #ifdef SDSUPPORT if (card.cardOK || lcd_commands_type == LcdCommands::Layer1Cal) @@ -6737,9 +6783,8 @@ static void lcd_main_menu() else { #ifdef FANCHECK - checkFanSpeed(); //Check manually to get most recent fan speed status - if(fan_check_error == EFCE_OK) - MENU_ITEM_SUBMENU_P(_i("Resume print"), lcd_resume_print);////MSG_RESUME_PRINT + if((fan_check_error == EFCE_FIXED) || (fan_check_error == EFCE_OK)) + MENU_ITEM_SUBMENU_P(_i("Resume print"), lcd_resume_print);////MSG_RESUME_PRINT #else MENU_ITEM_SUBMENU_P(_i("Resume print"), lcd_resume_print);////MSG_RESUME_PRINT #endif @@ -7101,9 +7146,10 @@ void lcd_print_stop() //-// if(!card.sdprinting) { - SERIAL_ECHOLNPGM("// action:cancel"); // for Octoprint + SERIAL_ECHOLNRPGM(MSG_OCTOPRINT_CANCEL); // for Octoprint } saved_printing = false; + saved_printing_type = PRINTING_TYPE_NONE; cancel_heatup = true; #ifdef MESH_BED_LEVELING mbl.active = false;