✨ MPC_PTC (#27911)
This commit is contained in:
parent
9ad9323aac
commit
89416a583c
6 changed files with 47 additions and 12 deletions
|
|
@ -735,7 +735,12 @@
|
||||||
//#define MPC_AUTOTUNE_MENU // Add MPC auto-tuning to the "Advanced Settings" menu. (~350 bytes of flash)
|
//#define MPC_AUTOTUNE_MENU // Add MPC auto-tuning to the "Advanced Settings" menu. (~350 bytes of flash)
|
||||||
|
|
||||||
#define MPC_MAX 255 // (0..255) Current to nozzle while MPC is active.
|
#define MPC_MAX 255 // (0..255) Current to nozzle while MPC is active.
|
||||||
#define MPC_HEATER_POWER { 40.0f } // (W) Heat cartridge powers.
|
#define MPC_HEATER_POWER { 40.0f } // (W) Nominal heat cartridge powers.
|
||||||
|
//#define MPC_PTC // Hotend power changes with temperature (e.g., PTC heat cartridges).
|
||||||
|
#if ENABLED(MPC_PTC)
|
||||||
|
#define MPC_HEATER_ALPHA { 0.0028f } // Temperature coefficient of resistance of the heat cartridges.
|
||||||
|
#define MPC_HEATER_REFTEMP { 20 } // (°C) Reference temperature for MPC_HEATER_POWER and MPC_HEATER_ALPHA.
|
||||||
|
#endif
|
||||||
|
|
||||||
#define MPC_INCLUDE_FAN // Model the fan speed?
|
#define MPC_INCLUDE_FAN // Model the fan speed?
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -64,9 +64,13 @@ void GcodeSuite::M306() {
|
||||||
case 2: tuning_type = Temperature::MPCTuningType::FORCE_ASYMPTOTIC; break;
|
case 2: tuning_type = Temperature::MPCTuningType::FORCE_ASYMPTOTIC; break;
|
||||||
default: tuning_type = Temperature::MPCTuningType::AUTO; break;
|
default: tuning_type = Temperature::MPCTuningType::AUTO; break;
|
||||||
}
|
}
|
||||||
LCD_MESSAGE(MSG_MPC_AUTOTUNE);
|
if (TERN0(MPC_PTC, tuning_type == Temperature::MPCTuningType::FORCE_ASYMPTOTIC))
|
||||||
thermalManager.MPC_autotune(e, tuning_type);
|
SERIAL_ECHOLNPGM("Aymptotic tuning not avaiable for PTC hotends");
|
||||||
ui.reset_status();
|
else {
|
||||||
|
LCD_MESSAGE(MSG_MPC_AUTOTUNE);
|
||||||
|
thermalManager.MPC_autotune(e, tuning_type);
|
||||||
|
ui.reset_status();
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -74,6 +78,10 @@ void GcodeSuite::M306() {
|
||||||
if (parser.seen("ACFPRH")) {
|
if (parser.seen("ACFPRH")) {
|
||||||
MPC_t &mpc = thermalManager.temp_hotend[e].mpc;
|
MPC_t &mpc = thermalManager.temp_hotend[e].mpc;
|
||||||
if (parser.seenval('P')) mpc.heater_power = parser.value_float();
|
if (parser.seenval('P')) mpc.heater_power = parser.value_float();
|
||||||
|
#if ENABLED(MPC_PTC)
|
||||||
|
if (parser.seenval('L')) mpc.heater_alpha = parser.value_float();
|
||||||
|
if (parser.seenval('Q')) mpc.heater_reftemp = parser.value_float();
|
||||||
|
#endif
|
||||||
if (parser.seenval('C')) mpc.block_heat_capacity = parser.value_float();
|
if (parser.seenval('C')) mpc.block_heat_capacity = parser.value_float();
|
||||||
if (parser.seenval('R')) mpc.sensor_responsiveness = parser.value_float();
|
if (parser.seenval('R')) mpc.sensor_responsiveness = parser.value_float();
|
||||||
if (parser.seenval('A')) mpc.ambient_xfer_coeff_fan0 = parser.value_float();
|
if (parser.seenval('A')) mpc.ambient_xfer_coeff_fan0 = parser.value_float();
|
||||||
|
|
@ -94,16 +102,20 @@ void GcodeSuite::M306_report(const bool forReplay/*=true*/) {
|
||||||
HOTEND_LOOP() {
|
HOTEND_LOOP() {
|
||||||
report_echo_start(forReplay);
|
report_echo_start(forReplay);
|
||||||
MPC_t &mpc = thermalManager.temp_hotend[e].mpc;
|
MPC_t &mpc = thermalManager.temp_hotend[e].mpc;
|
||||||
SERIAL_ECHOPGM(" M306 E", e,
|
SERIAL_ECHOLNPGM(" M306 E", e,
|
||||||
" P", p_float_t(mpc.heater_power, 2),
|
" P", p_float_t(mpc.heater_power, 2),
|
||||||
|
#if ENABLED(MPC_PTC)
|
||||||
|
" L", p_float_t(mpc.heater_alpha, 4),
|
||||||
|
" Q", p_float_t(mpc.heater_reftemp, 2),
|
||||||
|
#endif
|
||||||
" C", p_float_t(mpc.block_heat_capacity, 2),
|
" C", p_float_t(mpc.block_heat_capacity, 2),
|
||||||
" R", p_float_t(mpc.sensor_responsiveness, 4),
|
" R", p_float_t(mpc.sensor_responsiveness, 4),
|
||||||
" A", p_float_t(mpc.ambient_xfer_coeff_fan0, 4)
|
" A", p_float_t(mpc.ambient_xfer_coeff_fan0, 4),
|
||||||
|
#if ENABLED(MPC_INCLUDE_FAN)
|
||||||
|
" F", p_float_t(mpc.fanCoefficient(), 4),
|
||||||
|
#endif
|
||||||
|
" H", p_float_t(mpc.filament_heat_capacity_permm, 4)
|
||||||
);
|
);
|
||||||
#if ENABLED(MPC_INCLUDE_FAN)
|
|
||||||
SERIAL_ECHOPGM(" F", p_float_t(mpc.fanCoefficient(), 4));
|
|
||||||
#endif
|
|
||||||
SERIAL_ECHOLNPGM(" H", p_float_t(mpc.filament_heat_capacity_permm, 4));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1026,6 +1026,7 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i
|
||||||
#undef MPC_AUTOTUNE
|
#undef MPC_AUTOTUNE
|
||||||
#undef MPC_EDIT_MENU
|
#undef MPC_EDIT_MENU
|
||||||
#undef MPC_AUTOTUNE_MENU
|
#undef MPC_AUTOTUNE_MENU
|
||||||
|
#undef MPC_PTC
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ENABLED(MPC_INCLUDE_FAN)
|
#if ENABLED(MPC_INCLUDE_FAN)
|
||||||
|
|
|
||||||
|
|
@ -3710,6 +3710,10 @@ void MarlinSettings::reset() {
|
||||||
#if ENABLED(MPCTEMP)
|
#if ENABLED(MPCTEMP)
|
||||||
|
|
||||||
constexpr float _mpc_heater_power[] = MPC_HEATER_POWER;
|
constexpr float _mpc_heater_power[] = MPC_HEATER_POWER;
|
||||||
|
#if ENABLED(MPC_PTC)
|
||||||
|
constexpr float _mpc_heater_alpha[] = MPC_HEATER_ALPHA;
|
||||||
|
constexpr float _mpc_heater_reftemp[] = MPC_HEATER_REFTEMP;
|
||||||
|
#endif
|
||||||
constexpr float _mpc_block_heat_capacity[] = MPC_BLOCK_HEAT_CAPACITY;
|
constexpr float _mpc_block_heat_capacity[] = MPC_BLOCK_HEAT_CAPACITY;
|
||||||
constexpr float _mpc_sensor_responsiveness[] = MPC_SENSOR_RESPONSIVENESS;
|
constexpr float _mpc_sensor_responsiveness[] = MPC_SENSOR_RESPONSIVENESS;
|
||||||
constexpr float _mpc_ambient_xfer_coeff[] = MPC_AMBIENT_XFER_COEFF;
|
constexpr float _mpc_ambient_xfer_coeff[] = MPC_AMBIENT_XFER_COEFF;
|
||||||
|
|
@ -3719,6 +3723,10 @@ void MarlinSettings::reset() {
|
||||||
constexpr float _filament_heat_capacity_permm[] = FILAMENT_HEAT_CAPACITY_PERMM;
|
constexpr float _filament_heat_capacity_permm[] = FILAMENT_HEAT_CAPACITY_PERMM;
|
||||||
|
|
||||||
static_assert(COUNT(_mpc_heater_power) == HOTENDS, "MPC_HEATER_POWER must have HOTENDS items.");
|
static_assert(COUNT(_mpc_heater_power) == HOTENDS, "MPC_HEATER_POWER must have HOTENDS items.");
|
||||||
|
#if ENABLED(MPC_PTC)
|
||||||
|
static_assert(COUNT(_mpc_heater_alpha) == HOTENDS, "MPC_HEATER_ALPHA must have HOTENDS items.");
|
||||||
|
static_assert(COUNT(_mpc_heater_reftemp) == HOTENDS, "MPC_HEATER_REFTEMP must have HOTENDS items.");
|
||||||
|
#endif
|
||||||
static_assert(COUNT(_mpc_block_heat_capacity) == HOTENDS, "MPC_BLOCK_HEAT_CAPACITY must have HOTENDS items.");
|
static_assert(COUNT(_mpc_block_heat_capacity) == HOTENDS, "MPC_BLOCK_HEAT_CAPACITY must have HOTENDS items.");
|
||||||
static_assert(COUNT(_mpc_sensor_responsiveness) == HOTENDS, "MPC_SENSOR_RESPONSIVENESS must have HOTENDS items.");
|
static_assert(COUNT(_mpc_sensor_responsiveness) == HOTENDS, "MPC_SENSOR_RESPONSIVENESS must have HOTENDS items.");
|
||||||
static_assert(COUNT(_mpc_ambient_xfer_coeff) == HOTENDS, "MPC_AMBIENT_XFER_COEFF must have HOTENDS items.");
|
static_assert(COUNT(_mpc_ambient_xfer_coeff) == HOTENDS, "MPC_AMBIENT_XFER_COEFF must have HOTENDS items.");
|
||||||
|
|
@ -3730,6 +3738,10 @@ void MarlinSettings::reset() {
|
||||||
HOTEND_LOOP() {
|
HOTEND_LOOP() {
|
||||||
MPC_t &mpc = thermalManager.temp_hotend[e].mpc;
|
MPC_t &mpc = thermalManager.temp_hotend[e].mpc;
|
||||||
mpc.heater_power = _mpc_heater_power[e];
|
mpc.heater_power = _mpc_heater_power[e];
|
||||||
|
#if ENABLED(MPC_PTC)
|
||||||
|
mpc.heater_alpha = _mpc_heater_alpha[e];
|
||||||
|
mpc.heater_reftemp = _mpc_heater_reftemp[e];
|
||||||
|
#endif
|
||||||
mpc.block_heat_capacity = _mpc_block_heat_capacity[e];
|
mpc.block_heat_capacity = _mpc_block_heat_capacity[e];
|
||||||
mpc.sensor_responsiveness = _mpc_sensor_responsiveness[e];
|
mpc.sensor_responsiveness = _mpc_sensor_responsiveness[e];
|
||||||
mpc.ambient_xfer_coeff_fan0 = _mpc_ambient_xfer_coeff[e];
|
mpc.ambient_xfer_coeff_fan0 = _mpc_ambient_xfer_coeff[e];
|
||||||
|
|
|
||||||
|
|
@ -1864,7 +1864,8 @@ void Temperature::mintemp_error(const heater_id_t heater_id OPTARG(ERR_INCLUDE_T
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the modeled temperatures
|
// Update the modeled temperatures
|
||||||
float blocktempdelta = hotend.soft_pwm_amount * mpc.heater_power * (MPC_dT / 127) / mpc.block_heat_capacity;
|
const float _heater_power = DIV_TERN(MPC_PTC, mpc.heater_power, 1.0f + mpc.heater_alpha * (hotend.modeled_block_temp - mpc.heater_reftemp));
|
||||||
|
float blocktempdelta = hotend.soft_pwm_amount * _heater_power * (MPC_dT / 127) / mpc.block_heat_capacity;
|
||||||
blocktempdelta += (hotend.modeled_ambient_temp - hotend.modeled_block_temp) * ambient_xfer_coeff * MPC_dT / mpc.block_heat_capacity;
|
blocktempdelta += (hotend.modeled_ambient_temp - hotend.modeled_block_temp) * ambient_xfer_coeff * MPC_dT / mpc.block_heat_capacity;
|
||||||
hotend.modeled_block_temp += blocktempdelta;
|
hotend.modeled_block_temp += blocktempdelta;
|
||||||
|
|
||||||
|
|
@ -1888,7 +1889,7 @@ void Temperature::mintemp_error(const heater_id_t heater_id OPTARG(ERR_INCLUDE_T
|
||||||
power -= (hotend.modeled_ambient_temp - hotend.modeled_block_temp) * ambient_xfer_coeff;
|
power -= (hotend.modeled_ambient_temp - hotend.modeled_block_temp) * ambient_xfer_coeff;
|
||||||
}
|
}
|
||||||
|
|
||||||
float pid_output = power * 254.0f / mpc.heater_power + 1.0f; // Ensure correct quantization into a range of 0 to 127
|
float pid_output = power * 254.0f / _heater_power + 1.0f; // Ensure correct quantization into a range of 0 to 127
|
||||||
LIMIT(pid_output, 0, MPC_MAX);
|
LIMIT(pid_output, 0, MPC_MAX);
|
||||||
|
|
||||||
/* <-- add a slash to enable
|
/* <-- add a slash to enable
|
||||||
|
|
|
||||||
|
|
@ -386,6 +386,10 @@ typedef struct { float p, i, d, c, f; } raw_pidcf_t;
|
||||||
static bool e_paused; // Pause E filament permm tracking
|
static bool e_paused; // Pause E filament permm tracking
|
||||||
static int32_t e_position; // For E tracking
|
static int32_t e_position; // For E tracking
|
||||||
float heater_power; // M306 P
|
float heater_power; // M306 P
|
||||||
|
#if ENABLED(MPC_PTC)
|
||||||
|
float heater_alpha; // M306 L
|
||||||
|
float heater_reftemp; // M306 Q
|
||||||
|
#endif
|
||||||
float block_heat_capacity; // M306 C
|
float block_heat_capacity; // M306 C
|
||||||
float sensor_responsiveness; // M306 R
|
float sensor_responsiveness; // M306 R
|
||||||
float ambient_xfer_coeff_fan0; // M306 A
|
float ambient_xfer_coeff_fan0; // M306 A
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue