Rename lower case `temp_model` to `thermal_model`

This commit is contained in:
3d-gussner 2023-05-24 08:35:05 +02:00
parent 780f2db3d1
commit dac07d11ba
10 changed files with 168 additions and 312 deletions

View File

@ -104,7 +104,7 @@ void Config_PrintSettings(uint8_t level)
"%SArc Settings: P:Max length(mm) S:Min length (mm) N:Corrections R:Min segments F:Segments/sec.\n%S M214 P%.2f S%.2f N%d R%d F%d\n"), "%SArc Settings: P:Max length(mm) S:Min length (mm) N:Corrections R:Min segments F:Segments/sec.\n%S M214 P%.2f S%.2f N%d R%d F%d\n"),
echomagic, echomagic, cs.mm_per_arc_segment, cs.min_mm_per_arc_segment, cs.n_arc_correction, cs.min_arc_segments, cs.arc_segments_per_sec); echomagic, echomagic, cs.mm_per_arc_segment, cs.min_mm_per_arc_segment, cs.n_arc_correction, cs.min_arc_segments, cs.arc_segments_per_sec);
#ifdef TEMP_MODEL #ifdef TEMP_MODEL
temp_model_report_settings(); thermal_model_report_settings();
#endif #endif
} }
#endif #endif
@ -183,7 +183,7 @@ void Config_StoreSettings()
strcpy_P(cs.version, default_conf.version); strcpy_P(cs.version, default_conf.version);
eeprom_update_block(reinterpret_cast<uint8_t*>(&cs), reinterpret_cast<uint8_t*>(EEPROM_M500_base), sizeof(cs)); eeprom_update_block(reinterpret_cast<uint8_t*>(&cs), reinterpret_cast<uint8_t*>(EEPROM_M500_base), sizeof(cs));
#ifdef TEMP_MODEL #ifdef TEMP_MODEL
temp_model_save_settings(); thermal_model_save_settings();
#endif #endif
SERIAL_ECHO_START; SERIAL_ECHO_START;
@ -247,7 +247,7 @@ bool Config_RetrieveSettings()
// Call updatePID (similar to when we have processed M301) // Call updatePID (similar to when we have processed M301)
updatePID(); updatePID();
#ifdef TEMP_MODEL #ifdef TEMP_MODEL
temp_model_load_settings(); thermal_model_load_settings();
#endif #endif
SERIAL_ECHO_START; SERIAL_ECHO_START;
@ -277,7 +277,7 @@ void Config_ResetDefault()
updatePID(); updatePID();
#endif//PIDTEMP #endif//PIDTEMP
#ifdef TEMP_MODEL #ifdef TEMP_MODEL
temp_model_reset_settings(); thermal_model_reset_settings();
#endif #endif
calculate_extruder_multipliers(); calculate_extruder_multipliers();

View File

@ -1551,7 +1551,7 @@ void setup()
if (!calibration_status_get(CALIBRATION_STATUS_LIVE_ADJUST)) if (!calibration_status_get(CALIBRATION_STATUS_LIVE_ADJUST))
lcd_show_fullscreen_message_and_wait_P(_T(MSG_BABYSTEP_Z_NOT_SET)); lcd_show_fullscreen_message_and_wait_P(_T(MSG_BABYSTEP_Z_NOT_SET));
#ifdef TEMP_MODEL #ifdef TEMP_MODEL
if (!calibration_status_get(CALIBRATION_STATUS_TEMP_MODEL) && temp_model_enabled()) if (!calibration_status_get(CALIBRATION_STATUS_TEMP_MODEL) && thermal_model_enabled())
lcd_show_fullscreen_message_and_wait_P(_T(MSG_TM_NOT_CAL)); lcd_show_fullscreen_message_and_wait_P(_T(MSG_TM_NOT_CAL));
#endif //TEMP_MODEL #endif //TEMP_MODEL
} }
@ -7386,23 +7386,23 @@ Sigma_Exit:
// report values if nothing has been requested // report values if nothing has been requested
if(isnan(R) && isnan(P) && isnan(U) && isnan(V) && isnan(C) && isnan(D) && isnan(T) && isnan(W) && isnan(E) 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) { && I < 0 && S < 0 && B < 0 && A < 0 && L < 0) {
temp_model_report_settings(); thermal_model_report_settings();
break; break;
} }
// update all parameters // update all parameters
if(B >= 0) if(B >= 0)
temp_model_set_warn_beep(B); thermal_model_set_warn_beep(B);
if(!isnan(P) || !isnan(U) || !isnan(V) || !isnan(C) || !isnan(D) || (L >= 0) || !isnan(T) || !isnan(W) || !isnan(E)) 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); thermal_model_set_params(P, U, V, C, D, L, T, W, E);
if(I >= 0 && !isnan(R)) if(I >= 0 && !isnan(R))
temp_model_set_resistance(I, R); thermal_model_set_resistance(I, R);
// enable the model last, if requested // enable the model last, if requested
if(S >= 0) temp_model_set_enabled(S); if(S >= 0) thermal_model_set_enabled(S);
// run autotune // run autotune
if(A >= 0) temp_model_autotune(A, F > 0); if(A >= 0) thermal_model_autotune(A, F > 0);
} }
break; break;
#endif #endif
@ -8890,7 +8890,7 @@ Sigma_Exit:
*/ */
case 70: { case 70: {
if(code_seen('S')) if(code_seen('S'))
temp_model_log_enable(code_value_short()); thermal_model_log_enable(code_value_short());
break; break;
} }
#endif #endif

View File

@ -1,125 +0,0 @@
// model-based temperature safety checker declarations
#ifndef TEMP_MGR_INTV
#error "this file is not a public interface, it should be used *only* within temperature.cpp!"
#endif
#include "planner.h"
// shortcuts to get model defaults
#define __TEMP_MODEL_DEF(MODEL, VAR) TEMP_MODEL_##MODEL##_##VAR
#define _TEMP_MODEL_DEF(MODEL, VAR) __TEMP_MODEL_DEF(MODEL, VAR)
#define TEMP_MODEL_DEF(VAR) _TEMP_MODEL_DEF(TEMP_MODEL_DEFAULT, VAR)
constexpr uint8_t TEMP_MODEL_CAL_S = 60; // Maximum recording length during calibration (s)
constexpr uint8_t TEMP_MODEL_CAL_R_STEP = 4; // Fan interpolation steps during calibration
constexpr float TEMP_MODEL_fE = 0.05; // error filter (1st-order IIR factor)
// transport delay buffer size (samples)
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);
static const float TEMP_MODEL_R_DEFAULT[TEMP_MODEL_R_SIZE] PROGMEM = TEMP_MODEL_DEF(Rv);
namespace temp_model {
struct model_data
{
// temporary buffers
float dT_lag_buf[TEMP_MODEL_MAX_LAG_SIZE]; // transport delay buffer
uint8_t dT_lag_size = 0; // transport delay buffer size
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)
// thresholds
float warn; // warning threshold (K/s)
float err; // error threshold (K/s)
// status flags
union
{
bool flags;
struct
{
bool uninitialized: 1; // model is not initialized
bool error: 1; // error threshold set
bool warning: 1; // warning threshold set
} flag_bits;
};
// pre-computed values (initialized via reset)
float C_i; // heatblock capacitance (precomputed dT/C)
float warn_s; // warning threshold (per sample)
float err_s; // error threshold (per sample)
// simulation functions
void reset(uint8_t heater_pwm, uint8_t fan_pwm, float heater_temp, float ambient_temp);
void step(uint8_t heater_pwm, uint8_t fan_pwm, float heater_temp, float ambient_temp);
};
static bool enabled; // model check enabled
static bool warn_beep = true; // beep on warning threshold
static model_data data; // default heater data
static bool calibrated(); // return calibration/model validity status
static void check(); // check and trigger errors or warnings based on current state
// warning state (updated from from isr context)
volatile static struct
{
float dT_err; // temperature delta error (per sample)
bool warning: 1; // warning condition
bool assert: 1; // warning is still asserted
} warning_state;
static void handle_warning(); // handle warnings from user context
#ifdef TEMP_MODEL_DEBUG
static struct
{
volatile struct
{
uint32_t stamp;
int8_t delta_ms;
uint8_t counter;
uint8_t cur_pwm;
float cur_temp;
float cur_amb;
} entry;
uint8_t serial;
bool enabled;
} log_buf;
static void log_usr(); // user log handler
static void log_isr(); // isr log handler
#endif
} // namespace temp_model
namespace temp_model_cal {
// recording scratch buffer
struct rec_entry
{
float temp; // heater temperature
uint8_t pwm; // heater PWM
};
constexpr uint16_t REC_BUFFER_SIZE = TEMP_MODEL_CAL_S / TEMP_MGR_INTV;
static rec_entry* const rec_buffer = (rec_entry*)block_buffer; // oh-hey, free memory!
static_assert(sizeof(rec_entry[REC_BUFFER_SIZE]) <= sizeof(block_buffer),
"recording length too long to fit within available buffer");
} // namespace temp_model_cal

View File

@ -1,19 +0,0 @@
#pragma once
#define TEMP_MODEL_E3D_V6_VER 1 // model parameters version
#define TEMP_MODEL_E3D_V6_P 38. // heater power (W)
#define TEMP_MODEL_E3D_V6_U 0. // linear temperature coefficient (W/K/power)
#define TEMP_MODEL_E3D_V6_V 1. // linear temperature intercept (W/power)
#define TEMP_MODEL_E3D_V6_C 12.1 // initial guess for heatblock capacitance (J/K)
#define TEMP_MODEL_E3D_V6_R 20.5 // initial guess for heatblock resistance (K/W)
#define TEMP_MODEL_E3D_V6_fS 0.065 // sim. 1st order IIR filter factor (f=100/27)
#define TEMP_MODEL_E3D_V6_LAG 2100 // sim. response lag (ms, 0-2160)
#define TEMP_MODEL_E3D_V6_W 1.2 // Default warning threshold (K/s)
#define TEMP_MODEL_E3D_V6_E 1.74 // Default error threshold (K/s)
// fall-back resistance vector (R0-15)
#define TEMP_MODEL_E3D_V6_Rv {TEMP_MODEL_E3D_V6_R, 18.4, 16.7, 15.2, 14.1, 13.3, 12.7, 12.1, 11.7, 11.3, 11., 10.8, 10.6, 10.4, 10.2, 10.1}

View File

@ -94,7 +94,7 @@
#ifdef TEMP_MODEL #ifdef TEMP_MODEL
// temperature model interface // temperature model interface
#include "temp_model.h" #include "thermal_model.h"
#endif #endif
#include "Filament_sensor.h" #include "Filament_sensor.h"
@ -556,8 +556,8 @@ void manage_heater()
#ifdef TEMP_MODEL #ifdef TEMP_MODEL
// handle model warnings first, so not to override the error handler // handle model warnings first, so not to override the error handler
if(temp_model::warning_state.warning) if(thermal_model::warning_state.warning)
temp_model::handle_warning(); thermal_model::handle_warning();
#endif #endif
// handle temperature errors // handle temperature errors
@ -568,7 +568,7 @@ void manage_heater()
checkFans(); checkFans();
#ifdef TEMP_MODEL_DEBUG #ifdef TEMP_MODEL_DEBUG
temp_model::log_usr(); thermal_model::log_usr();
#endif #endif
} }
@ -1962,9 +1962,9 @@ static void temp_mgr_isr()
check_temp_raw(); // check min/max temp using raw values check_temp_raw(); // check min/max temp using raw values
check_temp_runaway(); // classic temperature hysteresis check check_temp_runaway(); // classic temperature hysteresis check
#ifdef TEMP_MODEL #ifdef TEMP_MODEL
temp_model::check(); // model-based heater check thermal_model::check(); // model-based heater check
#ifdef TEMP_MODEL_DEBUG #ifdef TEMP_MODEL_DEBUG
temp_model::log_isr(); thermal_model::log_isr();
#endif #endif
#endif #endif
@ -2079,7 +2079,7 @@ static void check_temp_raw()
} }
#ifdef TEMP_MODEL #ifdef TEMP_MODEL
namespace temp_model { namespace thermal_model {
void model_data::reset(uint8_t heater_pwm _UNUSED, uint8_t fan_pwm _UNUSED, void model_data::reset(uint8_t heater_pwm _UNUSED, uint8_t fan_pwm _UNUSED,
float heater_temp _UNUSED, float ambient_temp _UNUSED) float heater_temp _UNUSED, float ambient_temp _UNUSED)
@ -2165,7 +2165,7 @@ static bool calibrated()
if(!(data.L > 0)) return false; if(!(data.L > 0)) return false;
if(!(data.Ta_corr != NAN)) return false; if(!(data.Ta_corr != NAN)) return false;
for(uint8_t i = 0; i != TEMP_MODEL_R_SIZE; ++i) { for(uint8_t i = 0; i != TEMP_MODEL_R_SIZE; ++i) {
if(!(temp_model::data.R[i] >= 0)) if(!(thermal_model::data.R[i] >= 0))
return false; return false;
} }
if(!(data.warn != NAN)) return false; if(!(data.warn != NAN)) return false;
@ -2198,7 +2198,7 @@ static void check()
warning_state.assert = data.flag_bits.warning; warning_state.assert = data.flag_bits.warning;
if(warning_state.assert) { if(warning_state.assert) {
warning_state.warning = true; warning_state.warning = true;
warning_state.dT_err = temp_model::data.dT_err_prev; warning_state.dT_err = thermal_model::data.dT_err_prev;
} }
} }
@ -2281,42 +2281,42 @@ static void log_isr()
} }
#endif #endif
} // namespace temp_model } // namespace thermal_model
static void temp_model_reset_enabled(bool enabled) static void thermal_model_reset_enabled(bool enabled)
{ {
TempMgrGuard temp_mgr_guard; TempMgrGuard temp_mgr_guard;
temp_model::enabled = enabled; thermal_model::enabled = enabled;
temp_model::reinitialize(); thermal_model::reinitialize();
} }
bool temp_model_enabled() bool thermal_model_enabled()
{ {
return temp_model::enabled; return thermal_model::enabled;
} }
void temp_model_set_enabled(bool enabled) void thermal_model_set_enabled(bool enabled)
{ {
// set the enabled flag // set the enabled flag
{ {
TempMgrGuard temp_mgr_guard; TempMgrGuard temp_mgr_guard;
temp_model::enabled = enabled; thermal_model::enabled = enabled;
temp_model::setup(); thermal_model::setup();
} }
// verify that the model has been enabled // verify that the model has been enabled
if(enabled && !temp_model::enabled) if(enabled && !thermal_model::enabled)
SERIAL_ECHOLNPGM("TM: invalid parameters, cannot enable"); SERIAL_ECHOLNPGM("TM: invalid parameters, cannot enable");
} }
void temp_model_set_warn_beep(bool enabled) void thermal_model_set_warn_beep(bool enabled)
{ {
temp_model::warn_beep = enabled; thermal_model::warn_beep = enabled;
} }
// set the model lag rounding to the effective sample resolution, ensuring the reported/stored lag // 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) // matches the current model constraints (future-proofing for model changes)
static void temp_model_set_lag(uint16_t ms) static void thermal_model_set_lag(uint16_t ms)
{ {
static const uint16_t intv_ms = (uint16_t)(TEMP_MGR_INTV * 1000); static const uint16_t intv_ms = (uint16_t)(TEMP_MGR_INTV * 1000);
uint16_t samples = ((ms + intv_ms/2) / intv_ms); uint16_t samples = ((ms + intv_ms/2) / intv_ms);
@ -2328,75 +2328,75 @@ static void temp_model_set_lag(uint16_t ms)
samples = TEMP_MODEL_MAX_LAG_SIZE; samples = TEMP_MODEL_MAX_LAG_SIZE;
// round back to ms // round back to ms
temp_model::data.L = samples * intv_ms; thermal_model::data.L = samples * 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) void thermal_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; TempMgrGuard temp_mgr_guard;
if(!isnan(P) && P > 0) temp_model::data.P = P; if(!isnan(P) && P > 0) thermal_model::data.P = P;
if(!isnan(U)) temp_model::data.U = U; if(!isnan(U)) thermal_model::data.U = U;
if(!isnan(V)) temp_model::data.V = V; if(!isnan(V)) thermal_model::data.V = V;
if(!isnan(C) && C > 0) temp_model::data.C = C; if(!isnan(C) && C > 0) thermal_model::data.C = C;
if(!isnan(D)) temp_model::data.fS = D; if(!isnan(D)) thermal_model::data.fS = D;
if(L >= 0) temp_model_set_lag(L); if(L >= 0) thermal_model_set_lag(L);
if(!isnan(Ta_corr)) temp_model::data.Ta_corr = Ta_corr; if(!isnan(Ta_corr)) thermal_model::data.Ta_corr = Ta_corr;
if(!isnan(warn) && warn > 0) temp_model::data.warn = warn; if(!isnan(warn) && warn > 0) thermal_model::data.warn = warn;
if(!isnan(err) && err > 0) temp_model::data.err = err; if(!isnan(err) && err > 0) thermal_model::data.err = err;
// ensure warn <= err // ensure warn <= err
if (temp_model::data.warn > temp_model::data.err) if (thermal_model::data.warn > thermal_model::data.err)
temp_model::data.warn = temp_model::data.err; thermal_model::data.warn = thermal_model::data.err;
temp_model::setup(); thermal_model::setup();
} }
void temp_model_set_resistance(uint8_t index, float R) void thermal_model_set_resistance(uint8_t index, float R)
{ {
if(index >= TEMP_MODEL_R_SIZE || R <= 0) if(index >= TEMP_MODEL_R_SIZE || R <= 0)
return; return;
TempMgrGuard temp_mgr_guard; TempMgrGuard temp_mgr_guard;
temp_model::data.R[index] = R; thermal_model::data.R[index] = R;
temp_model::setup(); thermal_model::setup();
} }
void temp_model_report_settings() void thermal_model_report_settings()
{ {
SERIAL_ECHO_START; SERIAL_ECHO_START;
SERIAL_ECHOLNPGM("Temperature Model settings:"); SERIAL_ECHOLNPGM("Temperature Model settings:");
for(uint8_t i = 0; i != TEMP_MODEL_R_SIZE; ++i) 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 I%u R%.2f\n"), echomagic, (unsigned)i, (double)thermal_model::data.R[i]);
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"), 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, echomagic, (double)thermal_model::data.P, (double)thermal_model::data.U, (double)thermal_model::data.V,
(double)temp_model::data.C, (double)temp_model::data.fS, (unsigned)temp_model::data.L, (double)thermal_model::data.C, (double)thermal_model::data.fS, (unsigned)thermal_model::data.L,
(unsigned)temp_model::enabled, (unsigned)temp_model::warn_beep, (unsigned)thermal_model::enabled, (unsigned)thermal_model::warn_beep,
(double)temp_model::data.err, (double)temp_model::data.warn, (double)thermal_model::data.err, (double)thermal_model::data.warn,
(double)temp_model::data.Ta_corr); (double)thermal_model::data.Ta_corr);
} }
void temp_model_reset_settings() void thermal_model_reset_settings()
{ {
TempMgrGuard temp_mgr_guard; TempMgrGuard temp_mgr_guard;
temp_model::data.P = TEMP_MODEL_DEF(P); thermal_model::data.P = TEMP_MODEL_DEF(P);
temp_model::data.U = TEMP_MODEL_DEF(U); thermal_model::data.U = TEMP_MODEL_DEF(U);
temp_model::data.V = TEMP_MODEL_DEF(V); thermal_model::data.V = TEMP_MODEL_DEF(V);
temp_model::data.C = TEMP_MODEL_DEF(C); thermal_model::data.C = TEMP_MODEL_DEF(C);
temp_model::data.fS = TEMP_MODEL_DEF(fS); thermal_model::data.fS = TEMP_MODEL_DEF(fS);
temp_model::data.L = (uint16_t)(TEMP_MODEL_DEF(LAG) / (TEMP_MGR_INTV * 1000) + 0.5) * (uint16_t)(TEMP_MGR_INTV * 1000); thermal_model::data.L = (uint16_t)(TEMP_MODEL_DEF(LAG) / (TEMP_MGR_INTV * 1000) + 0.5) * (uint16_t)(TEMP_MGR_INTV * 1000);
for(uint8_t i = 0; i != TEMP_MODEL_R_SIZE; ++i) for(uint8_t i = 0; i != TEMP_MODEL_R_SIZE; ++i)
temp_model::data.R[i] = pgm_read_float(TEMP_MODEL_R_DEFAULT + i); thermal_model::data.R[i] = pgm_read_float(TEMP_MODEL_R_DEFAULT + i);
temp_model::data.Ta_corr = TEMP_MODEL_Ta_corr; thermal_model::data.Ta_corr = TEMP_MODEL_Ta_corr;
temp_model::data.warn = TEMP_MODEL_DEF(W); thermal_model::data.warn = TEMP_MODEL_DEF(W);
temp_model::data.err = TEMP_MODEL_DEF(E); thermal_model::data.err = TEMP_MODEL_DEF(E);
temp_model::warn_beep = true; thermal_model::warn_beep = true;
temp_model::enabled = true; thermal_model::enabled = true;
temp_model::reinitialize(); thermal_model::reinitialize();
} }
void temp_model_load_settings() void thermal_model_load_settings()
{ {
static_assert(TEMP_MODEL_R_SIZE == 16); // ensure we don't desync with the eeprom table static_assert(TEMP_MODEL_R_SIZE == 16); // ensure we don't desync with the eeprom table
TempMgrGuard temp_mgr_guard; TempMgrGuard temp_mgr_guard;
@ -2409,43 +2409,43 @@ void temp_model_load_settings()
eeprom_init_default_word((uint16_t*)EEPROM_TEMP_MODEL_L, TEMP_MODEL_DEF(LAG)); eeprom_init_default_word((uint16_t*)EEPROM_TEMP_MODEL_L, TEMP_MODEL_DEF(LAG));
eeprom_init_default_byte((uint8_t*)EEPROM_TEMP_MODEL_VER, TEMP_MODEL_DEF(VER)); eeprom_init_default_byte((uint8_t*)EEPROM_TEMP_MODEL_VER, TEMP_MODEL_DEF(VER));
temp_model::enabled = eeprom_read_byte((uint8_t*)EEPROM_TEMP_MODEL_ENABLE); thermal_model::enabled = eeprom_read_byte((uint8_t*)EEPROM_TEMP_MODEL_ENABLE);
temp_model::data.P = eeprom_read_float((float*)EEPROM_TEMP_MODEL_P); thermal_model::data.P = eeprom_read_float((float*)EEPROM_TEMP_MODEL_P);
temp_model::data.U = eeprom_read_float((float*)EEPROM_TEMP_MODEL_U); thermal_model::data.U = eeprom_read_float((float*)EEPROM_TEMP_MODEL_U);
temp_model::data.V = eeprom_read_float((float*)EEPROM_TEMP_MODEL_V); thermal_model::data.V = eeprom_read_float((float*)EEPROM_TEMP_MODEL_V);
temp_model::data.C = eeprom_read_float((float*)EEPROM_TEMP_MODEL_C); thermal_model::data.C = eeprom_read_float((float*)EEPROM_TEMP_MODEL_C);
temp_model::data.fS = eeprom_read_float((float*)EEPROM_TEMP_MODEL_D); thermal_model::data.fS = eeprom_read_float((float*)EEPROM_TEMP_MODEL_D);
temp_model_set_lag(eeprom_read_word((uint16_t*)EEPROM_TEMP_MODEL_L)); thermal_model_set_lag(eeprom_read_word((uint16_t*)EEPROM_TEMP_MODEL_L));
for(uint8_t i = 0; i != TEMP_MODEL_R_SIZE; ++i) 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); thermal_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); thermal_model::data.Ta_corr = eeprom_read_float((float*)EEPROM_TEMP_MODEL_Ta_corr);
temp_model::data.warn = eeprom_read_float((float*)EEPROM_TEMP_MODEL_W); thermal_model::data.warn = eeprom_read_float((float*)EEPROM_TEMP_MODEL_W);
temp_model::data.err = eeprom_read_float((float*)EEPROM_TEMP_MODEL_E); thermal_model::data.err = eeprom_read_float((float*)EEPROM_TEMP_MODEL_E);
if(!temp_model::calibrated()) { if(!thermal_model::calibrated()) {
SERIAL_ECHOLNPGM("TM: stored calibration invalid, resetting"); SERIAL_ECHOLNPGM("TM: stored calibration invalid, resetting");
temp_model_reset_settings(); thermal_model_reset_settings();
} }
temp_model::setup(); thermal_model::setup();
} }
void temp_model_save_settings() void thermal_model_save_settings()
{ {
eeprom_update_byte((uint8_t*)EEPROM_TEMP_MODEL_ENABLE, temp_model::enabled); eeprom_update_byte((uint8_t*)EEPROM_TEMP_MODEL_ENABLE, thermal_model::enabled);
eeprom_update_float((float*)EEPROM_TEMP_MODEL_P, temp_model::data.P); eeprom_update_float((float*)EEPROM_TEMP_MODEL_P, thermal_model::data.P);
eeprom_update_float((float*)EEPROM_TEMP_MODEL_U, temp_model::data.U); eeprom_update_float((float*)EEPROM_TEMP_MODEL_U, thermal_model::data.U);
eeprom_update_float((float*)EEPROM_TEMP_MODEL_V, temp_model::data.V); eeprom_update_float((float*)EEPROM_TEMP_MODEL_V, thermal_model::data.V);
eeprom_update_float((float*)EEPROM_TEMP_MODEL_C, temp_model::data.C); eeprom_update_float((float*)EEPROM_TEMP_MODEL_C, thermal_model::data.C);
eeprom_update_float((float*)EEPROM_TEMP_MODEL_D, temp_model::data.fS); eeprom_update_float((float*)EEPROM_TEMP_MODEL_D, thermal_model::data.fS);
eeprom_update_word((uint16_t*)EEPROM_TEMP_MODEL_L, temp_model::data.L); eeprom_update_word((uint16_t*)EEPROM_TEMP_MODEL_L, thermal_model::data.L);
for(uint8_t i = 0; i != TEMP_MODEL_R_SIZE; ++i) 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_R + i, thermal_model::data.R[i]);
eeprom_update_float((float*)EEPROM_TEMP_MODEL_Ta_corr, temp_model::data.Ta_corr); eeprom_update_float((float*)EEPROM_TEMP_MODEL_Ta_corr, thermal_model::data.Ta_corr);
eeprom_update_float((float*)EEPROM_TEMP_MODEL_W, temp_model::data.warn); eeprom_update_float((float*)EEPROM_TEMP_MODEL_W, thermal_model::data.warn);
eeprom_update_float((float*)EEPROM_TEMP_MODEL_E, temp_model::data.err); eeprom_update_float((float*)EEPROM_TEMP_MODEL_E, thermal_model::data.err);
} }
namespace temp_model_cal { namespace thermal_model_cal {
// set current fan speed for both front/backend // set current fan speed for both front/backend
static __attribute__((noinline)) void set_fan_speed(uint8_t fan_speed) static __attribute__((noinline)) void set_fan_speed(uint8_t fan_speed)
@ -2491,7 +2491,7 @@ static void cooldown(float temp)
set_fan_speed(255); set_fan_speed(255);
while(current_temperature[0] >= temp) { while(current_temperature[0] >= temp) {
if(temp_error_state.v) break; if(temp_error_state.v) break;
float ambient = current_temperature_ambient + temp_model::data.Ta_corr; float ambient = current_temperature_ambient + thermal_model::data.Ta_corr;
if(current_temperature[0] < (ambient + TEMP_HYSTERESIS)) { if(current_temperature[0] < (ambient + TEMP_HYSTERESIS)) {
// do not get stuck waiting very close to ambient temperature // do not get stuck waiting very close to ambient temperature
break; break;
@ -2539,12 +2539,12 @@ static uint16_t record(uint16_t samples = REC_BUFFER_SIZE) {
static float cost_fn(uint16_t samples, float* const var, float v, uint8_t fan_pwm, float ambient) static float cost_fn(uint16_t samples, float* const var, float v, uint8_t fan_pwm, float ambient)
{ {
*var = v; *var = v;
temp_model::data.reset(rec_buffer[0].pwm, fan_pwm, rec_buffer[0].temp, ambient); thermal_model::data.reset(rec_buffer[0].pwm, fan_pwm, rec_buffer[0].temp, ambient);
float err = 0; float err = 0;
uint16_t cnt = 0; uint16_t cnt = 0;
for(uint16_t i = 1; i < samples; ++i) { for(uint16_t i = 1; i < samples; ++i) {
temp_model::data.step(rec_buffer[i].pwm, fan_pwm, rec_buffer[i].temp, ambient); thermal_model::data.step(rec_buffer[i].pwm, fan_pwm, rec_buffer[i].temp, ambient);
float err_v = temp_model::data.dT_err_prev; float err_v = thermal_model::data.dT_err_prev;
if(!isnan(err_v)) { if(!isnan(err_v)) {
err += err_v * err_v; err += err_v * err_v;
++cnt; ++cnt;
@ -2569,8 +2569,8 @@ static float estimate(uint16_t samples,
{ {
// during estimation we alter the model values without an extra copy to conserve memory // during estimation we alter the model values without an extra copy to conserve memory
// so we cannot keep the main checker active until a value has been found // so we cannot keep the main checker active until a value has been found
bool was_enabled = temp_model::enabled; bool was_enabled = thermal_model::enabled;
temp_model_reset_enabled(false); thermal_model_reset_enabled(false);
float orig = *var; float orig = *var;
float e = NAN; float e = NAN;
@ -2595,14 +2595,14 @@ static float estimate(uint16_t samples,
} }
*var = x; *var = x;
temp_model_reset_enabled(was_enabled); thermal_model_reset_enabled(was_enabled);
return e; return e;
} }
} }
SERIAL_ECHOLNPGM("TM estimation did not converge"); SERIAL_ECHOLNPGM("TM estimation did not converge");
*var = orig; *var = orig;
temp_model_reset_enabled(was_enabled); thermal_model_reset_enabled(was_enabled);
return NAN; return NAN;
} }
@ -2633,10 +2633,10 @@ static bool autotune(int16_t cal_temp)
return true; return true;
// we need a high R value for the initial C guess // we need a high R value for the initial C guess
if(isnan(temp_model::data.R[0])) if(isnan(thermal_model::data.R[0]))
temp_model::data.R[0] = TEMP_MODEL_CAL_R_high; thermal_model::data.R[0] = TEMP_MODEL_CAL_R_high;
e = estimate(samples, &temp_model::data.C, e = estimate(samples, &thermal_model::data.C,
TEMP_MODEL_CAL_C_low, TEMP_MODEL_CAL_C_high, TEMP_MODEL_CAL_C_low, TEMP_MODEL_CAL_C_high,
TEMP_MODEL_CAL_C_thr, TEMP_MODEL_CAL_C_itr, TEMP_MODEL_CAL_C_thr, TEMP_MODEL_CAL_C_itr,
0, current_temperature_ambient); 0, current_temperature_ambient);
@ -2653,7 +2653,7 @@ static bool autotune(int16_t cal_temp)
if(temp_error_state.v || !samples) if(temp_error_state.v || !samples)
return true; return true;
e = estimate(samples, &temp_model::data.R[0], e = estimate(samples, &thermal_model::data.R[0],
TEMP_MODEL_CAL_R_low, TEMP_MODEL_CAL_R_high, TEMP_MODEL_CAL_R_low, TEMP_MODEL_CAL_R_high,
TEMP_MODEL_CAL_R_thr, TEMP_MODEL_CAL_R_itr, TEMP_MODEL_CAL_R_thr, TEMP_MODEL_CAL_R_itr,
0, current_temperature_ambient); 0, current_temperature_ambient);
@ -2671,7 +2671,7 @@ static bool autotune(int16_t cal_temp)
for(int8_t i = TEMP_MODEL_R_SIZE - 1; i > 0; i -= TEMP_MODEL_CAL_R_STEP) { for(int8_t i = TEMP_MODEL_R_SIZE - 1; i > 0; i -= TEMP_MODEL_CAL_R_STEP) {
// always disable the checker while estimating fan resistance as the difference // always disable the checker while estimating fan resistance as the difference
// (esp with 3rd-party blowers) can be massive // (esp with 3rd-party blowers) can be massive
temp_model::data.R[i] = NAN; thermal_model::data.R[i] = NAN;
uint8_t speed = 256 / TEMP_MODEL_R_SIZE * (i + 1) - 1; uint8_t speed = 256 / TEMP_MODEL_R_SIZE * (i + 1) - 1;
set_fan_speed(speed); set_fan_speed(speed);
@ -2685,8 +2685,8 @@ static bool autotune(int16_t cal_temp)
// a fixed fan pwm (the norminal value) is used here, as soft_pwm_fan will be modified // a fixed fan pwm (the norminal value) is used here, as soft_pwm_fan will be modified
// during fan measurements and we'd like to include that skew during normal operation. // during fan measurements and we'd like to include that skew during normal operation.
e = estimate(samples, &temp_model::data.R[i], e = estimate(samples, &thermal_model::data.R[i],
TEMP_MODEL_CAL_R_low, temp_model::data.R[0], TEMP_MODEL_CAL_R_thr, TEMP_MODEL_CAL_R_itr, TEMP_MODEL_CAL_R_low, thermal_model::data.R[0], TEMP_MODEL_CAL_R_thr, TEMP_MODEL_CAL_R_itr,
i, current_temperature_ambient); i, current_temperature_ambient);
if(isnan(e)) if(isnan(e))
return true; return true;
@ -2703,25 +2703,25 @@ static bool autotune(int16_t cal_temp)
int8_t prev = next - TEMP_MODEL_CAL_R_STEP; int8_t prev = next - TEMP_MODEL_CAL_R_STEP;
if(prev < 0) prev = 0; if(prev < 0) prev = 0;
float f = (float)(i - prev) / TEMP_MODEL_CAL_R_STEP; float f = (float)(i - prev) / TEMP_MODEL_CAL_R_STEP;
float d = (temp_model::data.R[next] - temp_model::data.R[prev]); float d = (thermal_model::data.R[next] - thermal_model::data.R[prev]);
temp_model::data.R[i] = temp_model::data.R[prev] + d * f; thermal_model::data.R[i] = thermal_model::data.R[prev] + d * f;
} }
return false; return false;
} }
} // namespace temp_model_cal } // namespace thermal_model_cal
static bool temp_model_autotune_err = true; static bool thermal_model_autotune_err = true;
void temp_model_autotune(int16_t temp, bool selftest) void thermal_model_autotune(int16_t temp, bool selftest)
{ {
float orig_C, orig_R[TEMP_MODEL_R_SIZE]; float orig_C, orig_R[TEMP_MODEL_R_SIZE];
bool orig_enabled; bool orig_enabled;
static_assert(sizeof(orig_R) == sizeof(temp_model::data.R)); static_assert(sizeof(orig_R) == sizeof(thermal_model::data.R));
// fail-safe error state // fail-safe error state
temp_model_autotune_err = true; thermal_model_autotune_err = true;
char tm_message[LCD_WIDTH+1]; char tm_message[LCD_WIDTH+1];
if(moves_planned() || printer_active()) { if(moves_planned() || printer_active()) {
@ -2736,56 +2736,56 @@ void temp_model_autotune(int16_t temp, bool selftest)
lcd_return_to_status(); lcd_return_to_status();
// save the original model data and set the model checking state during self-calibration // save the original model data and set the model checking state during self-calibration
orig_C = temp_model::data.C; orig_C = thermal_model::data.C;
memcpy(orig_R, temp_model::data.R, sizeof(temp_model::data.R)); memcpy(orig_R, thermal_model::data.R, sizeof(thermal_model::data.R));
orig_enabled = temp_model::enabled; orig_enabled = thermal_model::enabled;
temp_model_reset_enabled(selftest); thermal_model_reset_enabled(selftest);
// autotune // autotune
SERIAL_ECHOLNPGM("TM: calibration start"); SERIAL_ECHOLNPGM("TM: calibration start");
temp_model_autotune_err = temp_model_cal::autotune(temp > 0 ? temp : TEMP_MODEL_CAL_T_high); thermal_model_autotune_err = thermal_model_cal::autotune(temp > 0 ? temp : TEMP_MODEL_CAL_T_high);
// always reset temperature // always reset temperature
disable_heater(); disable_heater();
if(temp_model_autotune_err) { if(thermal_model_autotune_err) {
sprintf_P(tm_message, PSTR("TM: calibr. failed!")); sprintf_P(tm_message, PSTR("TM: calibr. failed!"));
lcd_setstatus_serial(tm_message); lcd_setstatus_serial(tm_message);
if(temp_error_state.v) if(temp_error_state.v)
temp_model_cal::set_fan_speed(255); thermal_model_cal::set_fan_speed(255);
// show calibrated values before overwriting them // show calibrated values before overwriting them
temp_model_report_settings(); thermal_model_report_settings();
// restore original state // restore original state
temp_model::data.C = orig_C; thermal_model::data.C = orig_C;
memcpy(temp_model::data.R, orig_R, sizeof(temp_model::data.R)); memcpy(thermal_model::data.R, orig_R, sizeof(thermal_model::data.R));
temp_model_set_enabled(orig_enabled); thermal_model_set_enabled(orig_enabled);
} else { } else {
calibration_status_set(CALIBRATION_STATUS_TEMP_MODEL); calibration_status_set(CALIBRATION_STATUS_TEMP_MODEL);
lcd_setstatuspgm(MSG_WELCOME); lcd_setstatuspgm(MSG_WELCOME);
temp_model_cal::set_fan_speed(0); thermal_model_cal::set_fan_speed(0);
temp_model_set_enabled(orig_enabled); thermal_model_set_enabled(orig_enabled);
temp_model_report_settings(); thermal_model_report_settings();
} }
lcd_consume_click(); lcd_consume_click();
menu_unset_block(MENU_BLOCK_TEMP_MODEL_AUTOTUNE); menu_unset_block(MENU_BLOCK_TEMP_MODEL_AUTOTUNE);
} }
bool temp_model_autotune_result() bool thermal_model_autotune_result()
{ {
return !temp_model_autotune_err; return !thermal_model_autotune_err;
} }
#ifdef TEMP_MODEL_DEBUG #ifdef TEMP_MODEL_DEBUG
void temp_model_log_enable(bool enable) void thermal_model_log_enable(bool enable)
{ {
if(enable) { if(enable) {
TempMgrGuard temp_mgr_guard; TempMgrGuard temp_mgr_guard;
temp_model::log_buf.entry.stamp = _millis(); thermal_model::log_buf.entry.stamp = _millis();
} }
temp_model::log_buf.enabled = enable; thermal_model::log_buf.enabled = enable;
} }
#endif #endif
#endif #endif

View File

@ -175,23 +175,23 @@ FORCE_INLINE void autotempShutdown(){
void PID_autotune(float temp, int extruder, int ncycles); void PID_autotune(float temp, int extruder, int ncycles);
#ifdef TEMP_MODEL #ifdef TEMP_MODEL
bool temp_model_enabled(); // return temperature model state bool thermal_model_enabled(); // return temperature model state
void temp_model_set_enabled(bool enabled); void thermal_model_set_enabled(bool enabled);
void temp_model_set_warn_beep(bool enabled); void thermal_model_set_warn_beep(bool enabled);
void temp_model_set_params(float P=NAN, float U=NAN, float V=NAN, float C=NAN, float D=NAN, void thermal_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); 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 thermal_model_set_resistance(uint8_t index, float R);
void temp_model_report_settings(); void thermal_model_report_settings();
void temp_model_reset_settings(); void thermal_model_reset_settings();
void temp_model_load_settings(); void thermal_model_load_settings();
void temp_model_save_settings(); void thermal_model_save_settings();
void temp_model_autotune(int16_t temp = 0, bool selftest = false); void thermal_model_autotune(int16_t temp = 0, bool selftest = false);
bool temp_model_autotune_result(); // return true if the last autotune was complete and successful bool thermal_model_autotune_result(); // return true if the last autotune was complete and successful
#ifdef TEMP_MODEL_DEBUG #ifdef TEMP_MODEL_DEBUG
void temp_model_log_enable(bool enable); void thermal_model_log_enable(bool enable);
#endif #endif
#endif #endif

View File

@ -908,13 +908,13 @@ void lcd_commands()
break; break;
case 3: case 3:
temp_model_set_warn_beep(false); thermal_model_set_warn_beep(false);
enquecommand_P(PSTR("M310 A F1")); enquecommand_P(PSTR("M310 A F1"));
lcd_commands_step = 2; lcd_commands_step = 2;
break; break;
case 2: case 2:
if (temp_model_autotune_result()) if (thermal_model_autotune_result())
enquecommand_P(MSG_M500); enquecommand_P(MSG_M500);
lcd_commands_step = 1; lcd_commands_step = 1;
break; break;
@ -922,8 +922,8 @@ void lcd_commands()
case 1: case 1:
lcd_commands_step = 0; lcd_commands_step = 0;
lcd_commands_type = LcdCommands::Idle; lcd_commands_type = LcdCommands::Idle;
temp_model_set_warn_beep(true); thermal_model_set_warn_beep(true);
bool res = temp_model_autotune_result(); bool res = thermal_model_autotune_result();
if (eeprom_read_byte((uint8_t*)EEPROM_WIZARD_ACTIVE)) { if (eeprom_read_byte((uint8_t*)EEPROM_WIZARD_ACTIVE)) {
// resume the wizard // resume the wizard
lcd_wizard(res ? WizState::Restore : WizState::Failed); lcd_wizard(res ? WizState::Restore : WizState::Failed);
@ -954,8 +954,8 @@ void lcd_commands()
enquecommand_P(PSTR("G1 X125 Z200 F1000")); enquecommand_P(PSTR("G1 X125 Z200 F1000"));
enquecommand_P(PSTR("M109 S280")); enquecommand_P(PSTR("M109 S280"));
#ifdef TEMP_MODEL #ifdef TEMP_MODEL
was_enabled = temp_model_enabled(); was_enabled = thermal_model_enabled();
temp_model_set_enabled(false); thermal_model_set_enabled(false);
#endif //TEMP_MODEL #endif //TEMP_MODEL
lcd_commands_step = 2; lcd_commands_step = 2;
break; break;
@ -970,7 +970,7 @@ void lcd_commands()
if (lcd_show_fullscreen_message_yes_no_and_wait_P(_T(MSG_NOZZLE_CNG_CHANGED), false) == LCD_LEFT_BUTTON_CHOICE) { if (lcd_show_fullscreen_message_yes_no_and_wait_P(_T(MSG_NOZZLE_CNG_CHANGED), false) == LCD_LEFT_BUTTON_CHOICE) {
setTargetHotend(0); setTargetHotend(0);
#ifdef TEMP_MODEL #ifdef TEMP_MODEL
temp_model_set_enabled(was_enabled); thermal_model_set_enabled(was_enabled);
#endif //TEMP_MODEL #endif //TEMP_MODEL
lcd_commands_step = 1; lcd_commands_step = 1;
} }
@ -4552,7 +4552,7 @@ static void lcd_calibration_menu()
#endif #endif
} }
#ifdef TEMP_MODEL #ifdef TEMP_MODEL
MENU_ITEM_SUBMENU_P(_n("Thermal Model cal."), lcd_temp_model_cal); MENU_ITEM_SUBMENU_P(_n("Thermal Model cal."), lcd_thermal_model_cal);
#endif //TEMP_MODEL #endif //TEMP_MODEL
MENU_END(); MENU_END();
@ -5592,7 +5592,7 @@ void lcd_print_stop()
} }
#ifdef TEMP_MODEL #ifdef TEMP_MODEL
void lcd_temp_model_cal() void lcd_thermal_model_cal()
{ {
lcd_commands_type = LcdCommands::TempModel; lcd_commands_type = LcdCommands::TempModel;
lcd_return_to_status(); lcd_return_to_status();
@ -6448,8 +6448,8 @@ static bool lcd_selfcheck_check_heater(bool _isbed)
target_temperature[0] = (_isbed) ? 0 : 200; target_temperature[0] = (_isbed) ? 0 : 200;
target_temperature_bed = (_isbed) ? 100 : 0; target_temperature_bed = (_isbed) ? 100 : 0;
#ifdef TEMP_MODEL #ifdef TEMP_MODEL
bool tm_was_enabled = temp_model_enabled(); bool tm_was_enabled = thermal_model_enabled();
temp_model_set_enabled(false); thermal_model_set_enabled(false);
#endif //TEMP_MODEL #endif //TEMP_MODEL
manage_heater(); manage_heater();
manage_inactivity(true); manage_inactivity(true);
@ -6500,7 +6500,7 @@ static bool lcd_selfcheck_check_heater(bool _isbed)
} }
#ifdef TEMP_MODEL #ifdef TEMP_MODEL
temp_model_set_enabled(tm_was_enabled); thermal_model_set_enabled(tm_was_enabled);
#endif //TEMP_MODEL #endif //TEMP_MODEL
manage_heater(); manage_heater();
manage_inactivity(true); manage_inactivity(true);

View File

@ -51,7 +51,7 @@ void lcd_resume_print();
void lcd_print_stop(); // interactive print stop void lcd_print_stop(); // interactive print stop
void print_stop(bool interactive=false); void print_stop(bool interactive=false);
#ifdef TEMP_MODEL #ifdef TEMP_MODEL
void lcd_temp_model_cal(); void lcd_thermal_model_cal();
#endif //TEMP_MODEL #endif //TEMP_MODEL
void lcd_load_filament_color_check(); void lcd_load_filament_color_check();

View File

@ -402,7 +402,7 @@
#define TEMP_MODEL_Ta_corr -7 // Default ambient temperature correction #define TEMP_MODEL_Ta_corr -7 // Default ambient temperature correction
#include "temp_model/e3d_v6.h" #include "thermal_model/e3d_v6.h"
#define TEMP_MODEL_DEFAULT E3D_V6 // Default model parameters #define TEMP_MODEL_DEFAULT E3D_V6 // Default model parameters

View File

@ -406,7 +406,7 @@
#define TEMP_MODEL_Ta_corr -7 // Default ambient temperature correction #define TEMP_MODEL_Ta_corr -7 // Default ambient temperature correction
#include "temp_model/e3d_v6.h" #include "thermal_model/e3d_v6.h"
#define TEMP_MODEL_DEFAULT E3D_V6 // Default model parameters #define TEMP_MODEL_DEFAULT E3D_V6 // Default model parameters