From aa4509140094bea1fa8fa2c162d9dcc1c3ebb53a Mon Sep 17 00:00:00 2001 From: Marek Bel <35807926+mkbel@users.noreply.github.com> Date: Fri, 23 Apr 2021 16:06:28 +0200 Subject: [PATCH] Scale extruder motor current linearly with speed. (#2813) Scale extruder motor current linearly with speed. 49% less heating when running at low speed and standstill, 4% more torque at maximum extrusion rate (15mm^3/s), 15% more torque in high speed movements (un/retractions). StealthChop mode is used for low speeds (below 900mm/min) spreadCycle is used above. Transition speed is well above maximum extrusion rate of 15mm^3/s (275mm/min) so mode transition is not expected to be visible on printed surface. StealthChop is expected to improve printed surface quality (less artifacts). Warning you can burn extruder motor if it is not the same impedance as original Prusa i3 Extruder stepper motor. There is no current feedback in low speed so lower impedance motor can be burned by over current. Even there is no direct current feedback, there is no risk for original motor thermal runaway, as motor resistance increases with temperature, current decreases. Standstill peak phase current is expected to be 500 mA and linearly increase with speed to 970 mA at 900mm/min where spreadCycle constant current regulation takes over and keeps peak current at 805 mA to maximum speed possible. As motor heating increases with current squared, lowering low speed current from 700mA to 500mA decreases heating 49% in thate mode, where motor spends most of the time. Enable E-motor cool mode in farm mode only (and experimental menu) - the experimental menu is visible AND the EEPROM_ECOOL variable has a value of the universal answer to all problems of the universe - i.e. two conditions must be met at the start of the FW to enable the E-cool mode. If the user enables the experimental menu, sets the E-cool mode and disables the menu afterwards, on the next start of the FW the E-cool mode will be DISABLED. This is still subject to discussion how much obscure (security through obscurity) we'd like this option to have . Additional stuff: * Add serial debug msg to verify if E-cool mode is on * Avoid access to E-cool mode switch on machines without TMC2130 * Do not allow only M907 E in case of E-cool mode+warn the user on the serial line that the command was skipped Co-authored-by: D.R.racer --- Firmware/Marlin_main.cpp | 49 +++++++++++-------- Firmware/eeprom.h | 7 ++- Firmware/stepper.cpp | 2 +- Firmware/tmc2130.cpp | 24 +++++---- Firmware/tmc2130.h | 22 +++++++-- Firmware/ultralcd.cpp | 40 +++++++++++++-- Firmware/ultralcd.h | 3 ++ .../variants/1_75mm_MK3-EINSy10a-E3Dv6full.h | 9 +++- .../variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h | 7 +++ 9 files changed, 122 insertions(+), 41 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 8e685d95..1fdfdacb 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -1054,11 +1054,6 @@ void setup() selectedSerialPort = 1; #endif //HAS_SECOND_SERIAL_PORT MYSERIAL.begin(BAUDRATE); -#ifdef TMC2130 - //increased extruder current (PFW363) - tmc2130_current_h[E_AXIS] = 36; - tmc2130_current_r[E_AXIS] = 36; -#endif //TMC2130 #ifdef FILAMENT_SENSOR //disabled filament autoload (PFW360) fsensor_autoload_set(false); @@ -1068,6 +1063,14 @@ void setup() eeprom_update_byte((unsigned char *)EEPROM_FAN_CHECK_ENABLED,true); } +#ifdef TMC2130 + if( FarmOrUserECool() ){ + //increased extruder current (PFW363) + tmc2130_current_h[E_AXIS] = TMC2130_CURRENTS_FARM; + tmc2130_current_r[E_AXIS] = TMC2130_CURRENTS_FARM; + } +#endif //TMC2130 + //saved EEPROM SN is not valid. Try to retrieve it. //SN is valid only if it is NULL terminated. Any other character means either uninitialized or corrupted if (eeprom_read_byte((uint8_t*)EEPROM_PRUSA_SN + 19)) @@ -1337,13 +1340,12 @@ void setup() #endif //TMC2130_VARIABLE_RESOLUTION #endif //TMC2130 - st_init(); // Initialize stepper, this enables interrupts! #ifdef TMC2130 tmc2130_mode = silentMode?TMC2130_MODE_SILENT:TMC2130_MODE_NORMAL; update_mode_profile(); - tmc2130_init(); + tmc2130_init(TMCInitParams(false, FarmOrUserECool() )); #endif //TMC2130 #ifdef PSU_Delta init_force_z(); // ! important for correct Z-axis initialization @@ -2556,7 +2558,7 @@ void force_high_power_mode(bool start_high_power_section) { cli(); tmc2130_mode = (start_high_power_section == true) ? TMC2130_MODE_NORMAL : TMC2130_MODE_SILENT; update_mode_profile(); - tmc2130_init(); + tmc2130_init(TMCInitParams(FarmOrUserECool())); // We may have missed a stepper timer interrupt due to the time spent in the tmc2130_init() routine. // Be safe than sorry, reset the stepper timer before re-enabling interrupts. st_reset_timer(); @@ -8425,6 +8427,7 @@ Sigma_Exit: /*! ### M907 - Set digital trimpot motor current in mA using axis codes M907: Set digital trimpot motor Set digital trimpot motor current using axis codes (X, Y, Z, E, B, S). + M907 has no effect when the experimental Extruder motor current scaling mode is active (that applies to farm printing as well) #### Usage M907 [ X | Y | Z | E | B | S ] @@ -8441,16 +8444,20 @@ Sigma_Exit: { #ifdef TMC2130 // See tmc2130_cur2val() for translation to 0 .. 63 range - for (int i = 0; i < NUM_AXIS; i++) - if(code_seen(axis_codes[i])) - { - long cur_mA = code_value_long(); - uint8_t val = tmc2130_cur2val(cur_mA); - tmc2130_set_current_h(i, val); - tmc2130_set_current_r(i, val); - //if (i == E_AXIS) printf_P(PSTR("E-axis current=%ldmA\n"), cur_mA); - } - + for (uint_least8_t i = 0; i < NUM_AXIS; i++){ + if(code_seen(axis_codes[i])){ + if( i == E_AXIS && FarmOrUserECool() ){ + SERIAL_ECHORPGM(eMotorCurrentScalingEnabled); + SERIAL_ECHOLNPGM(", M907 E ignored"); + continue; + } + long cur_mA = code_value_long(); + uint8_t val = tmc2130_cur2val(cur_mA); + tmc2130_set_current_h(i, val); + tmc2130_set_current_r(i, val); + //if (i == E_AXIS) printf_P(PSTR("E-axis current=%ldmA\n"), cur_mA); + } + } #else //TMC2130 #if defined(DIGIPOTSS_PIN) && DIGIPOTSS_PIN > -1 for(int i=0;i //mode extern uint8_t tmc2130_mode; -//holding and running currents extern uint8_t tmc2130_current_h[4]; extern uint8_t tmc2130_current_r[4]; //microstep resolution (0 means 256usteps, 8 means 1ustep @@ -22,6 +22,8 @@ extern uint32_t tmc2130_sg_meassure_val; extern uint8_t tmc2130_sg_homing_axes_mask; +extern const char eMotorCurrentScalingEnabled[]; + #define TMC2130_MODE_NORMAL 0 #define TMC2130_MODE_SILENT 1 @@ -63,11 +65,23 @@ typedef struct extern tmc2130_chopper_config_t tmc2130_chopper_config[4]; //initialize tmc2130 -#ifdef PSU_Delta -extern void tmc2130_init(bool bSupressFlag=false); + +struct TMCInitParams { + uint8_t bSuppressFlag : 1; // only relevant on MK3S with PSU_Delta + uint8_t enableECool : 1; // experimental support for E-motor cooler operation + inline TMCInitParams():bSuppressFlag(0), enableECool(0) { } + inline explicit TMCInitParams(bool bSuppressFlag, bool enableECool):bSuppressFlag(bSuppressFlag), enableECool(enableECool) { } + inline explicit TMCInitParams(bool enableECool) + : bSuppressFlag( +#ifdef PSU_delta + 1 #else -extern void tmc2130_init(); + 0 #endif + ) + , enableECool(enableECool) { } +}; +extern void tmc2130_init(TMCInitParams params); //check diag pins (called from stepper isr) extern void tmc2130_st_isr(); //update stall guard (called from st_synchronize inside the loop) diff --git a/Firmware/ultralcd.cpp b/Firmware/ultralcd.cpp index b0ba7d34..dec6c71c 100755 --- a/Firmware/ultralcd.cpp +++ b/Firmware/ultralcd.cpp @@ -4295,7 +4295,7 @@ static void lcd_silent_mode_set() { cli(); tmc2130_mode = (SilentModeMenu != SILENT_MODE_NORMAL)?TMC2130_MODE_SILENT:TMC2130_MODE_NORMAL; update_mode_profile(); - tmc2130_init(); + tmc2130_init(TMCInitParams(false, FarmOrUserECool())); // We may have missed a stepper timer interrupt due to the time spent in tmc2130_init. // Be safe than sorry, reset the stepper timer before re-enabling interrupts. st_reset_timer(); @@ -5679,7 +5679,7 @@ static void lcd_settings_linearity_correction_menu_save() changed |= (eeprom_read_byte((uint8_t*)EEPROM_TMC2130_WAVE_Z_FAC) != tmc2130_wave_fac[Z_AXIS]); changed |= (eeprom_read_byte((uint8_t*)EEPROM_TMC2130_WAVE_E_FAC) != tmc2130_wave_fac[E_AXIS]); lcd_ustep_linearity_menu_save(); - if (changed) tmc2130_init(); + if (changed) tmc2130_init(TMCInitParams(false, FarmOrUserECool())); } #endif //TMC2130 @@ -8951,6 +8951,37 @@ void lcd_experimental_toggle() eeprom_update_byte((uint8_t *)EEPROM_EXPERIMENTAL_VISIBILITY, oldVal); } +#ifdef TMC2130 +void UserECool_toggle(){ + // this is only called when the experimental menu is visible, thus the first condition for enabling of the ECool mode is met in this place + // The condition is intentionally inverted as we are toggling the state (i.e. if it was enabled, we are disabling the feature and vice versa) + bool enable = ! UserECoolEnabled(); + + eeprom_update_byte((uint8_t *)EEPROM_ECOOL_ENABLE, enable ? EEPROM_ECOOL_MAGIC_NUMBER : EEPROM_EMPTY_VALUE); + + // @@TODO I don't like this - disabling the experimental menu shall disable ECool mode, but it will not reinit the TMC + // and I don't want to add more code for this experimental feature ... ideally do not reinit the TMC here at all and let the user reset the printer. + tmc2130_init(TMCInitParams(enable)); +} +#endif + +/// Enable experimental support for cooler operation of the extruder motor +/// Beware - REQUIRES original Prusa MK3/S/+ extruder motor with adequate maximal current +/// Therefore we don't want to allow general usage of this feature in public as the community likes to +/// change motors for various reasons and unless the motor is rotating, we cannot verify its properties +/// (which would be obviously too late for an improperly sized motor) +/// For farm printing, the cooler E-motor is enabled by default. +bool UserECoolEnabled(){ + // We enable E-cool mode for non-farm prints IFF the experimental menu is visible AND the EEPROM_ECOOL variable has + // a value of the universal answer to all problems of the universe + return ( eeprom_read_byte((uint8_t *)EEPROM_ECOOL_ENABLE) == EEPROM_ECOOL_MAGIC_NUMBER ) + && ( eeprom_read_byte((uint8_t *)EEPROM_EXPERIMENTAL_VISIBILITY) == 1 ); +} + +bool FarmOrUserECool(){ + return farm_mode || UserECoolEnabled(); +} + void lcd_experimental_menu() { MENU_BEGIN(); @@ -8959,7 +8990,10 @@ void lcd_experimental_menu() #ifdef EXTRUDER_ALTFAN_DETECT MENU_ITEM_TOGGLE_P(_N("ALTFAN det."), altfanOverride_get()?_T(MSG_OFF):_T(MSG_ON), altfanOverride_toggle);////MSG_MENU_ALTFAN c=18 #endif //EXTRUDER_ALTFAN_DETECT - + +#ifdef TMC2130 + MENU_ITEM_TOGGLE_P(_N("E-cool mode"), UserECoolEnabled()?_T(MSG_ON):_T(MSG_OFF), UserECool_toggle);////MSG_MENU_ECOOL c=18 +#endif MENU_END(); } diff --git a/Firmware/ultralcd.h b/Firmware/ultralcd.h index c671326e..3aab932d 100755 --- a/Firmware/ultralcd.h +++ b/Firmware/ultralcd.h @@ -133,6 +133,9 @@ extern uint8_t farm_mode; extern int farm_timer; extern uint8_t farm_status; +extern bool UserECoolEnabled(); +extern bool FarmOrUserECool(); + #ifdef TMC2130 #define SILENT_MODE_NORMAL 0 #define SILENT_MODE_STEALTH 1 diff --git a/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h index 8caaeb32..16fba5d7 100644 --- a/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h @@ -2,7 +2,7 @@ #define CONFIGURATION_PRUSA_H #include -//-// + #include "printers.h" /*------------------------------------ GENERAL SETTINGS @@ -234,6 +234,11 @@ #define TMC2130_PWM_AUTO_E 1 // PWMCONF #define TMC2130_PWM_FREQ_E 2 // PWMCONF +// experimental setting for E-motor cooler operation +#define TMC2130_PWM_GRAD_Ecool 84 // PWMCONF 730mA @ 375mm/min 970mA phase peak at feedrate 900mm/min +#define TMC2130_PWM_AMPL_Ecool 43 // PWMCONF 500mA phase peak at feedrate 10 mm/min +#define TMC2130_PWM_AUTO_Ecool 0 // PWMCONF + #define TMC2130_TOFF_XYZ 3 // CHOPCONF // fchop = 27.778kHz #define TMC2130_TOFF_E 3 // CHOPCONF // fchop = 27.778kHz //#define TMC2130_TOFF_E 4 // CHOPCONF // fchop = 21.429kHz @@ -247,6 +252,7 @@ #define TMC2130_PWM_CLK (2 * TMC2130_FCLK / TMC2130_PWM_DIV) // PWM frequency (23.4kHz, 35.1kHz, 46.9kHz, 58.5kHz for 12MHz fclk) #define TMC2130_TPWMTHRS 0 // TPWMTHRS - Sets the switching speed threshold based on TSTEP from stealthChop to spreadCycle mode +#define TMC2130_TPWMTHRS_E 403 // Switch extruder from StealthChop to SpreadCycle at around 900mm/min #define TMC2130_THIGH 0 // THIGH - unused //#define TMC2130_TCOOLTHRS_X 450 // TCOOLTHRS - coolstep treshold @@ -265,6 +271,7 @@ //new settings is possible for vsense = 1, running current value > 31 set vsense to zero and shift both currents by 1 bit right (Z axis only) #define TMC2130_CURRENTS_H {16, 20, 35, 30} // default holding currents for all axes +#define TMC2130_CURRENTS_FARM 36 // E 805 mA peak for ECool/farm mode #define TMC2130_CURRENTS_R {16, 20, 35, 30} // default running currents for all axes #define TMC2130_CURRENTS_R_HOME {8, 10, 20, 18} // homing running currents for all axes diff --git a/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h b/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h index e9619afc..13fc2a79 100644 --- a/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h +++ b/Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h @@ -236,6 +236,11 @@ #define TMC2130_PWM_AUTO_E 1 // PWMCONF #define TMC2130_PWM_FREQ_E 2 // PWMCONF +// experimental setting for E-motor cooler operation +#define TMC2130_PWM_GRAD_Ecool 84 // PWMCONF 730mA @ 375mm/min 970mA phase peak at feedrate 900mm/min +#define TMC2130_PWM_AMPL_Ecool 43 // PWMCONF 500mA phase peak at feedrate 10 mm/min +#define TMC2130_PWM_AUTO_Ecool 0 // PWMCONF + #define TMC2130_TOFF_XYZ 3 // CHOPCONF // fchop = 27.778kHz #define TMC2130_TOFF_E 3 // CHOPCONF // fchop = 27.778kHz //#define TMC2130_TOFF_E 4 // CHOPCONF // fchop = 21.429kHz @@ -249,6 +254,7 @@ #define TMC2130_PWM_CLK (2 * TMC2130_FCLK / TMC2130_PWM_DIV) // PWM frequency (23.4kHz, 35.1kHz, 46.9kHz, 58.5kHz for 12MHz fclk) #define TMC2130_TPWMTHRS 0 // TPWMTHRS - Sets the switching speed threshold based on TSTEP from stealthChop to spreadCycle mode +#define TMC2130_TPWMTHRS_E 403 // Switch extruder from StealthChop to SpreadCycle at around 900mm/min #define TMC2130_THIGH 0 // THIGH - unused //#define TMC2130_TCOOLTHRS_X 450 // TCOOLTHRS - coolstep treshold @@ -267,6 +273,7 @@ //new settings is possible for vsense = 1, running current value > 31 set vsense to zero and shift both currents by 1 bit right (Z axis only) #define TMC2130_CURRENTS_H {16, 20, 35, 30} // default holding currents for all axes +#define TMC2130_CURRENTS_FARM 36 // E 805 mA peak for ECool/farm mode #define TMC2130_CURRENTS_R {16, 20, 35, 30} // default running currents for all axes #define TMC2130_CURRENTS_R_HOME {8, 10, 20, 18} // homing running currents for all axes