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 <drracer@drracer.eu>
This commit is contained in:
Marek Bel 2021-04-23 16:06:28 +02:00 committed by GitHub
parent b762a98c38
commit aa45091400
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 122 additions and 41 deletions

View File

@ -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 <a href="https://reprap.org/wiki/G-code#M907:_Set_digital_trimpot_motor">M907: Set digital trimpot motor</a>
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<NUM_AXIS;i++) if(code_seen(axis_codes[i])) st_current_set(i,code_value());
@ -8675,7 +8682,7 @@ Sigma_Exit:
case 350:
{
#ifdef TMC2130
for (int i=0; i<NUM_AXIS; i++)
for (uint_least8_t i=0; i<NUM_AXIS; i++)
{
if(code_seen(axis_codes[i]))
{
@ -11961,7 +11968,7 @@ void disable_force_z()
#ifdef TMC2130
tmc2130_mode=TMC2130_MODE_SILENT;
update_mode_profile();
tmc2130_init(true);
tmc2130_init(TMCInitParams(true, FarmOrUserECool()));
#endif // TMC2130
}
@ -11975,7 +11982,7 @@ bEnableForce_z=true;
#ifdef TMC2130
tmc2130_mode=eeprom_read_byte((uint8_t*)EEPROM_SILENT)?TMC2130_MODE_SILENT:TMC2130_MODE_NORMAL;
update_mode_profile();
tmc2130_init(true);
tmc2130_init(TMCInitParams(true, FarmOrUserECool()));
#endif // TMC2130
WRITE(Z_ENABLE_PIN,Z_ENABLE_ON); // slightly redundant ;-p

View File

@ -325,6 +325,8 @@ static_assert(sizeof(Sheets) == EEPROM_SHEETS_SIZEOF, "Sizeof(Sheets) is not EEP
| 0x0D0D 3341 | float | EEPROM_UVLO_RETRACT_ACCELL | ??? | ff ff ff ffh | Power panic saved retract acceleration | ??? | D3 Ax0d0d C4
| 0x0D09 3337 | float | EEPROM_UVLO_TRAVEL_ACCELL | ??? | ff ff ff ffh | Power panic saved travel acceleration | ??? | D3 Ax0d09 C4
| 0x0D05 3333 | uint32_t | EEPROM_JOB_ID | ??? | 00 00 00 00h | Job ID used by host software | D3 only | D3 Ax0d05 C4
| 0x0D01 3329 | uint8_t | EEPROM_ECOOL_ENABLE | ffh 255 | ^ | Disable extruder motor scaling for non-farm print | LCD menu | D3 Ax0d01 FF
| ^ | ^ | ^ | 2ah 42 | ^ | Enable extruder motor scaling for non-farm print | ^ | D3 Ax0d01 42
| Address begin | Bit/Type | Name | Valid values | Default/FactoryReset | Description | Gcode/Function| Debug code
| :--: | :--: | :--: | :--: | :--: | :--: | :--: | :--:
@ -538,8 +540,10 @@ static Sheets * const EEPROM_Sheets_base = (Sheets*)(EEPROM_SHEETS_BASE);
#define EEPROM_JOB_ID (EEPROM_UVLO_TRAVEL_ACCELL-4) //uint32_t
#define EEPROM_ECOOL_ENABLE (EEPROM_JOB_ID-1) // uint8_t
//This is supposed to point to last item to allow EEPROM overrun check. Please update when adding new items.
#define EEPROM_LAST_ITEM EEPROM_JOB_ID
#define EEPROM_LAST_ITEM EEPROM_ECOOL_ENABLE
// !!!!!
// !!!!! this is end of EEPROM section ... all updates MUST BE inserted before this mark !!!!!
// !!!!!
@ -555,6 +559,7 @@ static Sheets * const EEPROM_Sheets_base = (Sheets*)(EEPROM_SHEETS_BASE);
#define EEPROM_FIRMWARE_VERSION_MAJOR FW_PRUSA3D_MAGIC_LEN
// Magic string, indicating that the current or the previous firmware running was the Prusa3D firmware.
#define EEPROM_FIRMWARE_PRUSA_MAGIC 0
#define EEPROM_ECOOL_MAGIC_NUMBER 42
#ifdef __cplusplus
#include "ConfigurationStore.h"

View File

@ -1100,7 +1100,7 @@ FORCE_INLINE void advance_isr_scheduler() {
void st_init()
{
#ifdef TMC2130
tmc2130_init();
tmc2130_init(TMCInitParams(false, FarmOrUserECool()));
#endif //TMC2130
st_current_init(); //Initialize Digipot Motor Current

View File

@ -9,8 +9,6 @@
#include "language.h"
#include "spi.h"
#define TMC2130_GCONF_NORMAL 0x00000000 // spreadCycle
#define TMC2130_GCONF_SGSENS 0x00003180 // spreadCycle with stallguard (stall activates DIAG0 and DIAG1 [pushpull])
#define TMC2130_GCONF_SILENT 0x00000004 // stealthChop
@ -18,7 +16,6 @@
//mode
uint8_t tmc2130_mode = TMC2130_MODE_NORMAL;
//holding currents
uint8_t tmc2130_current_h[4] = TMC2130_CURRENTS_H;
//running currents
uint8_t tmc2130_current_r[4] = TMC2130_CURRENTS_R;
@ -45,6 +42,8 @@ uint8_t tmc2130_sg_thr_home[4] = TMC2130_SG_THRS_HOME;
uint8_t tmc2130_sg_homing_axes_mask = 0x00;
const char eMotorCurrentScalingEnabled[] PROGMEM = "E-motor current scaling enabled";
uint8_t tmc2130_sg_meassure = 0xff;
uint32_t tmc2130_sg_meassure_cnt = 0;
uint32_t tmc2130_sg_meassure_val = 0;
@ -145,11 +144,7 @@ uint16_t __tcoolthrs(uint8_t axis)
}
return 0;
}
#ifdef PSU_Delta
void tmc2130_init(bool bSupressFlag)
#else
void tmc2130_init()
#endif
void tmc2130_init(TMCInitParams params)
{
// DBG(_n("tmc2130_init(), mode=%S\n"), tmc2130_mode?_n("STEALTH"):_n("NORMAL"));
WRITE(X_TMC2130_CS, HIGH);
@ -194,7 +189,16 @@ void tmc2130_init()
tmc2130_setup_chopper(axis, tmc2130_mres[axis], tmc2130_current_h[axis], tmc2130_current_r[axis]);
tmc2130_wr(axis, TMC2130_REG_TPOWERDOWN, 0x00000000);
#ifndef TMC2130_STEALTH_E
tmc2130_wr(axis, TMC2130_REG_GCONF, TMC2130_GCONF_SGSENS);
if( ! params.enableECool ){
tmc2130_wr(axis, TMC2130_REG_GCONF, TMC2130_GCONF_SGSENS);
} else {
tmc2130_wr(axis, TMC2130_REG_COOLCONF, (((uint32_t)tmc2130_sg_thr[axis]) << 16));
tmc2130_wr(axis, TMC2130_REG_TCOOLTHRS, 0);
tmc2130_wr(axis, TMC2130_REG_GCONF, TMC2130_GCONF_SILENT);
tmc2130_wr_PWMCONF(axis, TMC2130_PWM_AMPL_Ecool, TMC2130_PWM_GRAD_Ecool, tmc2130_pwm_freq[axis], TMC2130_PWM_AUTO_Ecool, 0, 0);
tmc2130_wr_TPWMTHRS(axis, TMC2130_TPWMTHRS_E);
SERIAL_ECHOLNRPGM(eMotorCurrentScalingEnabled);
}
#else //TMC2130_STEALTH_E
tmc2130_wr(axis, TMC2130_REG_COOLCONF, (((uint32_t)tmc2130_sg_thr[axis]) << 16));
tmc2130_wr(axis, TMC2130_REG_TCOOLTHRS, 0);
@ -223,7 +227,7 @@ void tmc2130_init()
#endif //TMC2130_LINEARITY_CORRECTION
#ifdef PSU_Delta
if(!bSupressFlag)
if(!params.bSuppressFlag)
check_force_z();
#endif // PSU_Delta

View File

@ -1,10 +1,10 @@
#ifndef TMC2130_H
#define TMC2130_H
#include <stdint.h>
//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)

View File

@ -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();
}

View File

@ -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

View File

@ -2,7 +2,7 @@
#define CONFIGURATION_PRUSA_H
#include <limits.h>
//-//
#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

View File

@ -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