TM: Handle UVDL set/load/report/upgrade
- Expose TEMP_MODEL_fS and TEMP_MODEL_LAG as D and L respectively, initializing the default values based on the previous hard-coded values. - Always round L to the effective sample lag to future-proof model upgrades or changes (the stored value _is_ the effective value). - Introduce UV as a new linear term for PTC heaters, defaulting to an identity for model backward-compatibility.
This commit is contained in:
parent
5a1ed1519c
commit
70fd9a336b
@ -7586,7 +7586,8 @@ Sigma_Exit:
|
||||
M310 [ A ] [ F ] ; autotune
|
||||
M310 [ S ] ; set 0=disable 1=enable
|
||||
M310 [ I ] [ R ] ; set resistance at index
|
||||
M310 [ P | C ] ; set power, capacitance
|
||||
M310 [ P | U | V | C ] ; set power, temperature coefficient, intercept, capacitance
|
||||
M310 [ D | L ] ; set simulation filter, lag
|
||||
M310 [ B | E | W ] ; set beeper, warning and error threshold
|
||||
M310 [ T ] ; set ambient temperature correction
|
||||
|
||||
@ -7594,7 +7595,11 @@ Sigma_Exit:
|
||||
- `I` - resistance index position (0-15)
|
||||
- `R` - resistance value at index (K/W; requires `I`)
|
||||
- `P` - power (W)
|
||||
- `U` - linear temperature coefficient (W/K/power)
|
||||
- `V` - linear temperature intercept (W/power)
|
||||
- `C` - capacitance (J/K)
|
||||
- `D` - sim. 1st order IIR filter factor (f=100/27)
|
||||
- `L` - sim. response lag (ms, 0-2160)
|
||||
- `S` - set 0=disable 1=enable
|
||||
- `B` - beep and warn when reaching warning threshold 0=disable 1=enable (default: 1)
|
||||
- `E` - error threshold (K/s; default in variant)
|
||||
@ -7606,31 +7611,39 @@ Sigma_Exit:
|
||||
case 310:
|
||||
{
|
||||
// parse all parameters
|
||||
float P = NAN, C = NAN, R = NAN, E = NAN, W = NAN, T = NAN;
|
||||
float R = NAN, P = NAN, U = NAN, V = NAN, C = NAN, D = NAN, T = NAN, W = NAN, E = NAN;
|
||||
int8_t I = -1, S = -1, B = -1, F = -1;
|
||||
int16_t A = -1;
|
||||
if(code_seen('C')) C = code_value();
|
||||
if(code_seen('P')) P = code_value();
|
||||
int16_t A = -1, L = -1;
|
||||
if(code_seen('I')) I = code_value_short();
|
||||
if(code_seen('R')) R = code_value();
|
||||
if(code_seen('P')) P = code_value();
|
||||
if(code_seen('U')) U = code_value();
|
||||
if(code_seen('V')) V = code_value();
|
||||
if(code_seen('C')) C = code_value();
|
||||
if(code_seen('D')) D = code_value();
|
||||
if(code_seen('L')) L = code_value_short();
|
||||
if(code_seen('S')) S = code_value_short();
|
||||
if(code_seen('B')) B = code_value_short();
|
||||
if(code_seen('T')) T = code_value();
|
||||
if(code_seen('E')) E = code_value();
|
||||
if(code_seen('W')) W = code_value();
|
||||
if(code_seen('T')) T = code_value();
|
||||
if(code_seen('A')) A = code_value_short();
|
||||
if(code_seen('F')) F = code_value_short();
|
||||
|
||||
// report values if nothing has been requested
|
||||
if(isnan(C) && isnan(P) && isnan(R) && isnan(E) && isnan(W) && isnan(T) && I < 0 && S < 0 && B < 0 && A < 0) {
|
||||
if(isnan(R) && isnan(P) && isnan(U) && isnan(V) && isnan(C) && isnan(D) && isnan(T) && isnan(W) && isnan(E)
|
||||
&& I < 0 && S < 0 && B < 0 && A < 0 && L < 0) {
|
||||
temp_model_report_settings();
|
||||
break;
|
||||
}
|
||||
|
||||
// update all parameters
|
||||
if(B >= 0) temp_model_set_warn_beep(B);
|
||||
if(!isnan(C) || !isnan(P) || !isnan(T) || !isnan(W) || !isnan(E)) temp_model_set_params(C, P, T, W, E);
|
||||
if(I >= 0 && !isnan(R)) temp_model_set_resistance(I, R);
|
||||
if(B >= 0)
|
||||
temp_model_set_warn_beep(B);
|
||||
if(!isnan(P) || !isnan(U) || !isnan(V) || !isnan(C) || !isnan(D) || (L >= 0) || !isnan(T) || !isnan(W) || !isnan(E))
|
||||
temp_model_set_params(P, U, V, C, D, L, T, W, E);
|
||||
if(I >= 0 && !isnan(R))
|
||||
temp_model_set_resistance(I, R);
|
||||
|
||||
// enable the model last, if requested
|
||||
if(S >= 0) temp_model_set_enabled(S);
|
||||
|
@ -7,11 +7,10 @@
|
||||
|
||||
constexpr uint8_t TEMP_MODEL_CAL_S = 60; // Maximum recording lenght during calibration (s)
|
||||
constexpr uint8_t TEMP_MODEL_CAL_R_STEP = 4; // Fan interpolation steps during calibration
|
||||
constexpr float TEMP_MODEL_fS = 0.065; // simulation filter (1st-order IIR factor)
|
||||
constexpr float TEMP_MODEL_fE = 0.05; // error filter (1st-order IIR factor)
|
||||
|
||||
// transport delay buffer size (samples)
|
||||
constexpr uint8_t TEMP_MODEL_LAG_SIZE = (TEMP_MODEL_LAG / TEMP_MGR_INTV + 0.5);
|
||||
constexpr uint8_t TEMP_MODEL_MAX_LAG_SIZE = 8; // * TEMP_MGR_INTV = 2160
|
||||
|
||||
// resistance values for all fan levels
|
||||
constexpr uint8_t TEMP_MODEL_R_SIZE = (1 << FAN_SOFT_PWM_BITS);
|
||||
@ -22,14 +21,18 @@ namespace temp_model {
|
||||
struct model_data
|
||||
{
|
||||
// temporary buffers
|
||||
float dT_lag_buf[TEMP_MODEL_LAG_SIZE]; // transport delay buffer
|
||||
uint8_t dT_lag_idx = 0; // transport delay buffer index
|
||||
float dT_err_prev = 0; // previous temperature delta error
|
||||
float T_prev = 0; // last temperature extruder
|
||||
float dT_lag_buf[TEMP_MODEL_MAX_LAG_SIZE]; // transport delay buffer
|
||||
uint8_t dT_lag_idx = 0; // transport delay buffer index
|
||||
float dT_err_prev = 0; // previous temperature delta error
|
||||
float T_prev = 0; // last temperature extruder
|
||||
|
||||
// configurable parameters
|
||||
float P; // heater power (W)
|
||||
float U; // linear temperature coefficient (W/K/W)
|
||||
float V; // linear temperature intercept (W/W)
|
||||
float C; // heatblock capacitance (J/K)
|
||||
float fS; // sim. 1st order IIR filter factor (f=100/27)
|
||||
uint16_t L; // sim. response lag (ms)
|
||||
float R[TEMP_MODEL_R_SIZE]; // heatblock resistance for all fan levels (K/W)
|
||||
float Ta_corr; // ambient temperature correction (K)
|
||||
|
||||
|
@ -2540,15 +2540,27 @@ void temp_model_set_warn_beep(bool enabled)
|
||||
temp_model::warn_beep = enabled;
|
||||
}
|
||||
|
||||
void temp_model_set_params(float C, float P, float Ta_corr, float warn, float err)
|
||||
// set the model lag rounding to the effective sample resolution, ensuring the reported/stored lag
|
||||
// matches the current model constraints (future-proofing for model changes)
|
||||
static void temp_model_set_lag(uint16_t ms)
|
||||
{
|
||||
static const uint16_t intv_ms = (uint16_t)(TEMP_MGR_INTV * 1000);
|
||||
temp_model::data.L = ((ms + intv_ms/2) / intv_ms) * intv_ms;
|
||||
}
|
||||
|
||||
void temp_model_set_params(float P, float U, float V, float C, float D, int16_t L, float Ta_corr, float warn, float err)
|
||||
{
|
||||
TempMgrGuard temp_mgr_guard;
|
||||
|
||||
if(!isnan(C) && C > 0) temp_model::data.C = C;
|
||||
if(!isnan(P) && P > 0) temp_model::data.P = P;
|
||||
if(!isnan(U)) temp_model::data.U = U;
|
||||
if(!isnan(V)) temp_model::data.V = V;
|
||||
if(!isnan(C) && C > 0) temp_model::data.C = C;
|
||||
if(!isnan(D)) temp_model::data.fS = D;
|
||||
if(L >= 0) temp_model_set_lag(L);
|
||||
if(!isnan(Ta_corr)) temp_model::data.Ta_corr = Ta_corr;
|
||||
if(!isnan(err) && err > 0) temp_model::data.err = err;
|
||||
if(!isnan(warn) && warn > 0) temp_model::data.warn = warn;
|
||||
if(!isnan(err) && err > 0) temp_model::data.err = err;
|
||||
|
||||
// ensure warn <= err
|
||||
if (temp_model::data.warn > temp_model::data.err)
|
||||
@ -2573,8 +2585,9 @@ void temp_model_report_settings()
|
||||
SERIAL_ECHOLNPGM("Temperature Model settings:");
|
||||
for(uint8_t i = 0; i != TEMP_MODEL_R_SIZE; ++i)
|
||||
printf_P(PSTR("%S M310 I%u R%.2f\n"), echomagic, (unsigned)i, (double)temp_model::data.R[i]);
|
||||
printf_P(PSTR("%S M310 P%.2f C%.2f S%u B%u E%.2f W%.2f T%.2f\n"),
|
||||
echomagic, (double)temp_model::data.P, (double)temp_model::data.C,
|
||||
printf_P(PSTR("%S M310 P%.2f U%.4f V%.2f C%.2f D%.4f L%u S%u B%u E%.2f W%.2f T%.2f\n"),
|
||||
echomagic, (double)temp_model::data.P, (double)temp_model::data.U, (double)temp_model::data.V,
|
||||
(double)temp_model::data.C, (double)temp_model::data.fS, (unsigned)temp_model::data.L,
|
||||
(unsigned)temp_model::enabled, (unsigned)temp_model::warn_beep,
|
||||
(double)temp_model::data.err, (double)temp_model::data.warn,
|
||||
(double)temp_model::data.Ta_corr);
|
||||
@ -2585,7 +2598,11 @@ void temp_model_reset_settings()
|
||||
TempMgrGuard temp_mgr_guard;
|
||||
|
||||
temp_model::data.P = TEMP_MODEL_P;
|
||||
temp_model::data.U = TEMP_MODEL_U;
|
||||
temp_model::data.V = TEMP_MODEL_V;
|
||||
temp_model::data.C = TEMP_MODEL_C;
|
||||
temp_model::data.fS = TEMP_MODEL_fS;
|
||||
temp_model::data.L = (uint16_t)(TEMP_MODEL_LAG / (TEMP_MGR_INTV * 1000) + 0.5) * (uint16_t)(TEMP_MGR_INTV * 1000);
|
||||
for(uint8_t i = 0; i != TEMP_MODEL_R_SIZE; ++i)
|
||||
temp_model::data.R[i] = pgm_read_float(TEMP_MODEL_R_DEFAULT + i);
|
||||
temp_model::data.Ta_corr = TEMP_MODEL_Ta_corr;
|
||||
@ -2601,9 +2618,21 @@ void temp_model_load_settings()
|
||||
static_assert(TEMP_MODEL_R_SIZE == 16); // ensure we don't desync with the eeprom table
|
||||
TempMgrGuard temp_mgr_guard;
|
||||
|
||||
// handle upgrade from a model without UVDL (FW<3.13)
|
||||
// WARNING: this only works as long as UVDL are the same constants/model type as FW 3.12,
|
||||
// it needs to consider the upgrading FW version otherwise!
|
||||
eeprom_init_default_float((float*)EEPROM_TEMP_MODEL_U, TEMP_MODEL_U);
|
||||
eeprom_init_default_float((float*)EEPROM_TEMP_MODEL_V, TEMP_MODEL_V);
|
||||
eeprom_init_default_float((float*)EEPROM_TEMP_MODEL_D, TEMP_MODEL_fS);
|
||||
eeprom_init_default_word((uint16_t*)EEPROM_TEMP_MODEL_L, TEMP_MODEL_LAG);
|
||||
|
||||
temp_model::enabled = eeprom_read_byte((uint8_t*)EEPROM_TEMP_MODEL_ENABLE);
|
||||
temp_model::data.P = eeprom_read_float((float*)EEPROM_TEMP_MODEL_P);
|
||||
temp_model::data.U = eeprom_read_float((float*)EEPROM_TEMP_MODEL_U);
|
||||
temp_model::data.V = eeprom_read_float((float*)EEPROM_TEMP_MODEL_V);
|
||||
temp_model::data.C = eeprom_read_float((float*)EEPROM_TEMP_MODEL_C);
|
||||
temp_model::data.fS = eeprom_read_float((float*)EEPROM_TEMP_MODEL_D);
|
||||
temp_model_set_lag(eeprom_read_word((uint16_t*)EEPROM_TEMP_MODEL_L));
|
||||
for(uint8_t i = 0; i != TEMP_MODEL_R_SIZE; ++i)
|
||||
temp_model::data.R[i] = eeprom_read_float((float*)EEPROM_TEMP_MODEL_R + i);
|
||||
temp_model::data.Ta_corr = eeprom_read_float((float*)EEPROM_TEMP_MODEL_Ta_corr);
|
||||
@ -2621,7 +2650,11 @@ void temp_model_save_settings()
|
||||
{
|
||||
eeprom_update_byte((uint8_t*)EEPROM_TEMP_MODEL_ENABLE, temp_model::enabled);
|
||||
eeprom_update_float((float*)EEPROM_TEMP_MODEL_P, temp_model::data.P);
|
||||
eeprom_update_float((float*)EEPROM_TEMP_MODEL_U, temp_model::data.U);
|
||||
eeprom_update_float((float*)EEPROM_TEMP_MODEL_V, temp_model::data.V);
|
||||
eeprom_update_float((float*)EEPROM_TEMP_MODEL_C, temp_model::data.C);
|
||||
eeprom_update_float((float*)EEPROM_TEMP_MODEL_D, temp_model::data.fS);
|
||||
eeprom_update_word((uint16_t*)EEPROM_TEMP_MODEL_L, temp_model::data.L);
|
||||
for(uint8_t i = 0; i != TEMP_MODEL_R_SIZE; ++i)
|
||||
eeprom_update_float((float*)EEPROM_TEMP_MODEL_R + i, temp_model::data.R[i]);
|
||||
eeprom_update_float((float*)EEPROM_TEMP_MODEL_Ta_corr, temp_model::data.Ta_corr);
|
||||
|
@ -220,7 +220,8 @@ void PID_autotune(float temp, int extruder, int ncycles);
|
||||
bool temp_model_enabled(); // return temperature model state
|
||||
void temp_model_set_enabled(bool enabled);
|
||||
void temp_model_set_warn_beep(bool enabled);
|
||||
void temp_model_set_params(float C = NAN, float P = NAN, float Ta_corr = NAN, float warn = NAN, float err = NAN);
|
||||
void temp_model_set_params(float P=NAN, float U=NAN, float V=NAN, float C=NAN, float D=NAN,
|
||||
int16_t L=-1, float Ta_corr=NAN, float warn=NAN, float err=NAN);
|
||||
void temp_model_set_resistance(uint8_t index, float R);
|
||||
|
||||
void temp_model_report_settings();
|
||||
|
@ -415,6 +415,8 @@
|
||||
#define TEMP_MODEL_DEBUG 1 // extended runtime logging
|
||||
|
||||
#define TEMP_MODEL_P 38. // heater power (W)
|
||||
#define TEMP_MODEL_U 1. // linear temperature coefficient (W/K/power)
|
||||
#define TEMP_MODEL_V 0. // linear temperature intercept (W/power)
|
||||
|
||||
#define TEMP_MODEL_C 12.1 // initial guess for heatblock capacitance (J/K)
|
||||
#define TEMP_MODEL_Cl 5 // C estimation lower limit
|
||||
@ -422,6 +424,9 @@
|
||||
#define TEMP_MODEL_C_thr 0.01 // C estimation iteration threshold
|
||||
#define TEMP_MODEL_C_itr 30 // C estimation iteration limit
|
||||
|
||||
#define TEMP_MODEL_fS 0.065 // sim. 1st order IIR filter factor (f=100/27)
|
||||
#define TEMP_MODEL_LAG 2100 // sim. response lag (ms, 0-2160)
|
||||
|
||||
#define TEMP_MODEL_R 20.5 // initial guess for heatblock resistance (K/W)
|
||||
#define TEMP_MODEL_Rl 5 // R estimation lower limit
|
||||
#define TEMP_MODEL_Rh 50 // R estimation upper limit
|
||||
@ -429,8 +434,6 @@
|
||||
#define TEMP_MODEL_R_itr 30 // R estimation iteration limit
|
||||
|
||||
#define TEMP_MODEL_Ta_corr -7 // Default ambient temperature correction
|
||||
#define TEMP_MODEL_LAG 2.1 // Temperature transport delay (s)
|
||||
|
||||
#define TEMP_MODEL_W 1.2 // Default warning threshold (K/s)
|
||||
#define TEMP_MODEL_E 1.74 // Default error threshold (K/s)
|
||||
|
||||
|
@ -419,6 +419,8 @@
|
||||
#define TEMP_MODEL_DEBUG 1 // extended runtime logging
|
||||
|
||||
#define TEMP_MODEL_P 38. // heater power (W)
|
||||
#define TEMP_MODEL_U 1. // linear temperature coefficient (W/K/power)
|
||||
#define TEMP_MODEL_V 0. // linear temperature intercept (W/power)
|
||||
|
||||
#define TEMP_MODEL_C 12.1 // initial guess for heatblock capacitance (J/K)
|
||||
#define TEMP_MODEL_Cl 5 // C estimation lower limit
|
||||
@ -426,6 +428,9 @@
|
||||
#define TEMP_MODEL_C_thr 0.01 // C estimation iteration threshold
|
||||
#define TEMP_MODEL_C_itr 30 // C estimation iteration limit
|
||||
|
||||
#define TEMP_MODEL_fS 0.065 // sim. 1st order IIR filter factor (f=100/27)
|
||||
#define TEMP_MODEL_LAG 2100 // sim. response lag (ms, 0-2160)
|
||||
|
||||
#define TEMP_MODEL_R 20.5 // initial guess for heatblock resistance (K/W)
|
||||
#define TEMP_MODEL_Rl 5 // R estimation lower limit
|
||||
#define TEMP_MODEL_Rh 50 // R estimation upper limit
|
||||
@ -433,8 +438,6 @@
|
||||
#define TEMP_MODEL_R_itr 30 // R estimation iteration limit
|
||||
|
||||
#define TEMP_MODEL_Ta_corr -7 // Default ambient temperature correction
|
||||
#define TEMP_MODEL_LAG 2.1 // Temperature transport delay (s)
|
||||
|
||||
#define TEMP_MODEL_W 1.2 // Default warning threshold (K/s)
|
||||
#define TEMP_MODEL_E 1.74 // Default error threshold (K/s)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user