diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp old mode 100644 new mode 100755 index f75b141ff..711c428b9 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -3001,6 +3001,32 @@ void gcode_M114() SERIAL_PROTOCOLLN(""); } +//! extracted code to compute z_shift for M600 in case of filament change operation +//! requested from fsensors. +//! The function ensures, that the printhead lifts to at least 25mm above the heat bed +//! unlike the previous implementation, which was adding 25mm even when the head was +//! printing at e.g. 24mm height. +//! A safety margin of FILAMENTCHANGE_ZADD is added in all cases to avoid touching +//! the printout. +//! This function is templated to enable fast change of computation data type. +//! @return new z_shift value +template +static T gcode_M600_filament_change_z_shift() +{ +#ifdef FILAMENTCHANGE_ZADD + static_assert(Z_MAX_POS < (255 - FILAMENTCHANGE_ZADD), "Z-range too high, change the T type from uint8_t to uint16_t"); + // avoid floating point arithmetics when not necessary - results in shorter code + T ztmp = T( current_position[Z_AXIS] ); + T z_shift = 0; + if(ztmp < T(25)){ + z_shift = T(25) - ztmp; // make sure to be at least 25mm above the heat bed + } + return z_shift + T(FILAMENTCHANGE_ZADD); // always move above printout +#else + return T(0); +#endif +} + static void gcode_M600(bool automatic, float x_position, float y_position, float z_shift, float e_shift, float /*e_shift_late*/) { st_synchronize(); @@ -3390,8 +3416,10 @@ void process_commands() { #ifdef FANCHECK if (fan_check_error){ - fan_check_error = false; - lcd_pause_print(); + if( fan_check_error == EFCE_DETECTED ){ + fan_check_error = EFCE_REPORTED; + lcd_pause_print(); + } // otherwise it has already been reported, so just ignore further processing return; } #endif @@ -3552,10 +3580,6 @@ void process_commands() enquecommand_P(PSTR("M24")); } #ifdef FILAMENT_SENSOR - else if (code_seen("fsensor_recover_IR")) //! PRUSA fsensor_recover_IR - { - fsensor_restore_print_and_continue_IR(); - } else if (code_seen("fsensor_recover")) //! PRUSA fsensor_recover { fsensor_restore_print_and_continue(); @@ -6590,7 +6614,7 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE)) float x_position = current_position[X_AXIS]; float y_position = current_position[Y_AXIS]; - float z_shift = 0; + float z_shift = 0; // is it necessary to be a float? float e_shift_init = 0; float e_shift_late = 0; bool automatic = false; @@ -6626,10 +6650,7 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE)) } else { - #ifdef FILAMENTCHANGE_ZADD - z_shift= FILAMENTCHANGE_ZADD ; - if(current_position[Z_AXIS] < 25) z_shift+= 25 ; - #endif + z_shift = gcode_M600_filament_change_z_shift(); } //Move XY to side if(code_seen('X')) @@ -9307,22 +9328,20 @@ void stop_and_save_print_to_ram(float z_move, float e_move) // First unretract (relative extrusion) if(!saved_extruder_relative_mode){ - strcpy_P(buf, PSTR("M83")); - enquecommand(buf, false); + enquecommand(PSTR("M83"), true); } //retract 45mm/s - strcpy_P(buf, PSTR("G1 E")); - dtostrf(e_move, 6, 3, buf + strlen(buf)); - strcat_P(buf, PSTR(" F")); - dtostrf(2700, 8, 3, buf + strlen(buf)); + // A single sprintf may not be faster, but is definitely 20B shorter + // than a sequence of commands building the string piece by piece + // A snprintf would have been a safer call, but since it is not used + // in the whole program, its implementation would bring more bytes to the total size + // The behavior of dtostrf 8,3 should be roughly the same as %-0.3 + sprintf_P(buf, PSTR("G1 E%-0.3f F2700"), e_move); enquecommand(buf, false); // Then lift Z axis - strcpy_P(buf, PSTR("G1 Z")); - dtostrf(saved_pos[Z_AXIS] + z_move, 8, 3, buf + strlen(buf)); - strcat_P(buf, PSTR(" F")); - dtostrf(homing_feedrate[Z_AXIS], 8, 3, buf + strlen(buf)); + sprintf_P(buf, PSTR("G1 Z%-0.3f F%-0.3f"), saved_pos[Z_AXIS] + z_move, homing_feedrate[Z_AXIS]); // At this point the command queue is empty. enquecommand(buf, false); // If this call is invoked from the main Arduino loop() function, let the caller know that the command @@ -9348,6 +9367,12 @@ void stop_and_save_print_to_ram(float z_move, float e_move) void restore_print_from_ram_and_continue(float e_move) { if (!saved_printing) return; + +#ifdef FANCHECK + // Do not allow resume printing if fans are still not ok + if( fan_check_error != EFCE_OK )return; +#endif + // for (int axis = X_AXIS; axis <= E_AXIS; axis++) // current_position[axis] = st_get_position_mm(axis); active_extruder = saved_active_extruder; //restore active_extruder diff --git a/Firmware/fsensor.cpp b/Firmware/fsensor.cpp old mode 100644 new mode 100755 index f9ca89099..fd7936ee9 --- a/Firmware/fsensor.cpp +++ b/Firmware/fsensor.cpp @@ -123,17 +123,12 @@ void fsensor_stop_and_save_print(void) stop_and_save_print_to_ram(0, 0); //XYZE - no change } -void fsensor_restore_print_and_continue_IR(void) -{ - fsensor_watch_runout = true; - fsensor_err_cnt = 0; - fsensor_m600_enqueued = false; -} - void fsensor_restore_print_and_continue(void) { printf_P(PSTR("fsensor_restore_print_and_continue\n")); - fsensor_restore_print_and_continue_IR(); + fsensor_watch_runout = true; + fsensor_err_cnt = 0; + fsensor_m600_enqueued = false; restore_print_from_ram_and_continue(0); //XYZ = orig, E - no change } @@ -527,6 +522,47 @@ void fsensor_st_block_chunk(block_t* bl, int cnt) } } +//! This ensures generating z-position at least 25mm above the heat bed. +//! Making this a template enables changing the computation data type easily at all spots where necessary. +//! @param current_z current z-position +//! @return z-position at least 25mm above the heat bed plus FILAMENTCHANGE_ZADD +template +inline T fsensor_clamp_z(float current_z){ + T z( current_z ); + if(z < T(25)){ // make sure the compiler understands, that the constant 25 is of correct type + // - necessary for uint8_t -> results in shorter code + z = T(25); // move to at least 25mm above heat bed + } + return z + T(FILAMENTCHANGE_ZADD); // always move above the printout by FILAMENTCHANGE_ZADD (default 2mm) +} + +//! Common code for enqueing M600 and supplemental codes into the command queue. +//! Used both for the IR sensor and the PAT9125 +void fsensor_enque_M600(){ + printf_P(PSTR("fsensor_update - M600\n")); + eeprom_update_byte((uint8_t*)EEPROM_FERROR_COUNT, eeprom_read_byte((uint8_t*)EEPROM_FERROR_COUNT) + 1); + eeprom_update_word((uint16_t*)EEPROM_FERROR_COUNT_TOT, eeprom_read_word((uint16_t*)EEPROM_FERROR_COUNT_TOT) + 1); + enquecommand_front_P(PSTR("PRUSA fsensor_recover")); + fsensor_m600_enqueued = true; + enquecommand_front_P((PSTR("M600"))); +#define xstr(a) str(a) +#define str(a) #a + static const char gcodeMove[] PROGMEM = + "G1 X" xstr(FILAMENTCHANGE_XPOS) + " Y" xstr(FILAMENTCHANGE_YPOS) + " Z%u"; +#undef str +#undef xstr + char buf[32]; + // integer arithmetics is far shorter, I don't need a precise float position here, just move a bit above + // 8bit arithmetics in fsensor_clamp_z is 10B shorter than 16bit (not talking about float ;) ) + // The compile-time static_assert here ensures, that the computation gets enough bits in case of Z-range too high, + // i.e. makes the user change the data type, which also results in larger code + static_assert(Z_MAX_POS < (255 - FILAMENTCHANGE_ZADD), "Z-range too high, change fsensor_clamp_z to "); + sprintf_P(buf, gcodeMove, fsensor_clamp_z(current_position[Z_AXIS]) ); + enquecommand_front(buf, false); +} + //! @brief filament sensor update (perform M600 on filament runout) //! //! Works only if filament sensor is enabled. @@ -535,7 +571,7 @@ void fsensor_st_block_chunk(block_t* bl, int cnt) void fsensor_update(void) { #ifdef PAT9125 - if (fsensor_enabled && fsensor_watch_runout && (fsensor_err_cnt > FSENSOR_ERR_MAX)) + if (fsensor_enabled && fsensor_watch_runout && (fsensor_err_cnt > FSENSOR_ERR_MAX) && ( ! fsensor_m600_enqueued) ) { bool autoload_enabled_tmp = fsensor_autoload_enabled; fsensor_autoload_enabled = false; @@ -575,11 +611,7 @@ void fsensor_update(void) } else { - printf_P(PSTR("fsensor_update - M600\n")); - eeprom_update_byte((uint8_t*)EEPROM_FERROR_COUNT, eeprom_read_byte((uint8_t*)EEPROM_FERROR_COUNT) + 1); - eeprom_update_word((uint16_t*)EEPROM_FERROR_COUNT_TOT, eeprom_read_word((uint16_t*)EEPROM_FERROR_COUNT_TOT) + 1); - enquecommand_front_P(PSTR("PRUSA fsensor_recover")); - enquecommand_front_P((PSTR("M600"))); + fsensor_enque_M600(); fsensor_watch_runout = false; } fsensor_autoload_enabled = autoload_enabled_tmp; @@ -587,14 +619,9 @@ void fsensor_update(void) } #else //PAT9125 if ((digitalRead(IR_SENSOR_PIN) == 1) && CHECK_FSENSOR && fsensor_enabled && ir_sensor_detected && ( ! fsensor_m600_enqueued) ) - { // just plan a simple M600 without any additional position save/restore, - // which caused weird heating issues standing directly over the print - printf_P(PSTR("fsensor_update - M600\n")); - eeprom_update_byte((uint8_t*)EEPROM_FERROR_COUNT, eeprom_read_byte((uint8_t*)EEPROM_FERROR_COUNT) + 1); - eeprom_update_word((uint16_t*)EEPROM_FERROR_COUNT_TOT, eeprom_read_word((uint16_t*)EEPROM_FERROR_COUNT_TOT) + 1); - enquecommand_front_P(PSTR("PRUSA fsensor_recover_IR")); - fsensor_m600_enqueued = true; - enquecommand_front_P((PSTR("M600"))); + { + fsensor_stop_and_save_print(); + fsensor_enque_M600(); } #endif //PAT9125 } diff --git a/Firmware/fsensor.h b/Firmware/fsensor.h old mode 100644 new mode 100755 index 421eee439..fa7ab5854 --- a/Firmware/fsensor.h +++ b/Firmware/fsensor.h @@ -18,9 +18,7 @@ extern bool fsensor_oq_meassure_enabled; //! @name save restore printing //! @{ extern void fsensor_stop_and_save_print(void); -//! special handling for the IR sensor (no restore position and heating, since this is already correctly handled in the M600 itself) -extern void fsensor_restore_print_and_continue_IR(void); -//! legacy restore print - restore position and heatup to original temperature - for the MMU and the optical fsensor +//! restore print - restore position and heatup to original temperature extern void fsensor_restore_print_and_continue(void); //! @} diff --git a/Firmware/pins_Einsy_1_0.h b/Firmware/pins_Einsy_1_0.h index 2e05d3263..33363388a 100755 --- a/Firmware/pins_Einsy_1_0.h +++ b/Firmware/pins_Einsy_1_0.h @@ -99,8 +99,7 @@ //#define KILL_PIN 32 -// LCD backlight pin may interfere with something, this is yet to be found out correctly -#define LCD_BL_PIN 5 //backlight control pin +//#define LCD_BL_PIN 5 //backlight control pin #define BEEPER 84 // Beeper on AUX-4 #define LCD_PINS_RS 82 #define LCD_PINS_ENABLE 61 // !!! changed from 18 (EINY03) diff --git a/Firmware/temperature.cpp b/Firmware/temperature.cpp index b245b23ba..9c49cf79c 100755 --- a/Firmware/temperature.cpp +++ b/Firmware/temperature.cpp @@ -95,7 +95,7 @@ float current_temperature_bed = 0.0; #endif #ifdef FANCHECK - volatile bool fan_check_error = false; + volatile uint8_t fan_check_error = EFCE_OK; #endif unsigned char soft_pwm_bed; @@ -512,6 +512,12 @@ void checkFanSpeed() else fan_speed_errors[1] = 0; #endif + // 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; + } + if ((fan_speed_errors[0] > max_extruder_fan_errors) && fans_check_enabled) { fan_speed_errors[0] = 0; fanSpeedError(0); //extruder fan @@ -522,6 +528,23 @@ void checkFanSpeed() } } +//! Prints serialMsg to serial port, displays lcdMsg onto the LCD and beeps. +//! Extracted from fanSpeedError to save some space. +//! @param serialMsg pointer into PROGMEM, this text will be printed to the serial port +//! @param lcdMsg pointer into PROGMEM, this text will be printed onto the LCD +static void fanSpeedErrorBeep(const char *serialMsg, const char *lcdMsg){ + SERIAL_ECHOLNRPGM(serialMsg); + if (get_message_level() == 0) { + if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE)||(eSoundMode==e_SOUND_MODE_SILENT)){ + WRITE(BEEPER, HIGH); + delayMicroseconds(200); + WRITE(BEEPER, LOW); + delayMicroseconds(100); // what is this wait for? + } + LCD_ALERTMESSAGERPGM(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 @@ -530,7 +553,8 @@ void fanSpeedError(unsigned char _fan) { lcd_print_stop(); } else { - fan_check_error = true; + fan_check_error = EFCE_DETECTED; + } } else { @@ -538,27 +562,11 @@ void fanSpeedError(unsigned char _fan) { SERIAL_ECHOLNPGM("// action:pause"); //for octoprint } switch (_fan) { - case 0: - SERIAL_ECHOLNPGM("Extruder fan speed is lower then expected"); - if (get_message_level() == 0) { -if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE)||(eSoundMode==e_SOUND_MODE_SILENT)) - WRITE(BEEPER, HIGH); - delayMicroseconds(200); - WRITE(BEEPER, LOW); - delayMicroseconds(100); - LCD_ALERTMESSAGEPGM("Err: EXTR. FAN ERROR"); - } + 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") ); break; case 1: - SERIAL_ECHOLNPGM("Print fan speed is lower then expected"); - if (get_message_level() == 0) { -if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE)||(eSoundMode==e_SOUND_MODE_SILENT)) - WRITE(BEEPER, HIGH); - delayMicroseconds(200); - WRITE(BEEPER, LOW); - delayMicroseconds(100); - LCD_ALERTMESSAGEPGM("Err: PRINT FAN ERROR"); - } + fanSpeedErrorBeep(PSTR("Print fan speed is lower than expected"), PSTR("Err: PRINT FAN ERROR") ); break; } } diff --git a/Firmware/temperature.h b/Firmware/temperature.h old mode 100644 new mode 100755 index 31ab8d9f5..27a7e713d --- a/Firmware/temperature.h +++ b/Firmware/temperature.h @@ -238,7 +238,12 @@ void checkExtruderAutoFans(); #if (defined(FANCHECK) && defined(TACH_0) && (TACH_0 > -1)) -extern volatile bool fan_check_error; +enum { + EFCE_OK = 0, //!< normal operation, both fans are ok + EFCE_DETECTED, //!< fan error detected, but not reported yet + EFCE_REPORTED //!< fan error detected and reported to LCD and serial +}; +extern volatile uint8_t fan_check_error; void countFanSpeed(); void checkFanSpeed(); diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index 3b2be088a..f69efbbc3 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -5972,7 +5972,7 @@ static void fil_load_menu() if (mmu_enabled) { - MENU_ITEM_FUNCTION_NR_P(_T(MSG_LOAD_FILAMENT), '5', extr_adj, 3); + MENU_ITEM_FUNCTION_NR_P(_T(MSG_LOAD_FILAMENT), '5', extr_adj, 4); } MENU_END(); }