mirror of
https://github.com/MarlinFirmware/Marlin.git
synced 2025-06-26 09:25:18 -06:00
✨ 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_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?
|
||||
|
||||
|
|
|
@ -64,9 +64,13 @@ void GcodeSuite::M306() {
|
|||
case 2: tuning_type = Temperature::MPCTuningType::FORCE_ASYMPTOTIC; break;
|
||||
default: tuning_type = Temperature::MPCTuningType::AUTO; break;
|
||||
}
|
||||
LCD_MESSAGE(MSG_MPC_AUTOTUNE);
|
||||
thermalManager.MPC_autotune(e, tuning_type);
|
||||
ui.reset_status();
|
||||
if (TERN0(MPC_PTC, tuning_type == Temperature::MPCTuningType::FORCE_ASYMPTOTIC))
|
||||
SERIAL_ECHOLNPGM("Aymptotic tuning not avaiable for PTC hotends");
|
||||
else {
|
||||
LCD_MESSAGE(MSG_MPC_AUTOTUNE);
|
||||
thermalManager.MPC_autotune(e, tuning_type);
|
||||
ui.reset_status();
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
@ -74,6 +78,10 @@ void GcodeSuite::M306() {
|
|||
if (parser.seen("ACFPRH")) {
|
||||
MPC_t &mpc = thermalManager.temp_hotend[e].mpc;
|
||||
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('R')) mpc.sensor_responsiveness = 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() {
|
||||
report_echo_start(forReplay);
|
||||
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),
|
||||
#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),
|
||||
" 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_EDIT_MENU
|
||||
#undef MPC_AUTOTUNE_MENU
|
||||
#undef MPC_PTC
|
||||
#endif
|
||||
|
||||
#if ENABLED(MPC_INCLUDE_FAN)
|
||||
|
|
|
@ -3710,6 +3710,10 @@ void MarlinSettings::reset() {
|
|||
#if ENABLED(MPCTEMP)
|
||||
|
||||
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_sensor_responsiveness[] = MPC_SENSOR_RESPONSIVENESS;
|
||||
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;
|
||||
|
||||
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_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.");
|
||||
|
@ -3730,6 +3738,10 @@ void MarlinSettings::reset() {
|
|||
HOTEND_LOOP() {
|
||||
MPC_t &mpc = thermalManager.temp_hotend[e].mpc;
|
||||
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.sensor_responsiveness = _mpc_sensor_responsiveness[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
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
/* <-- 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 int32_t e_position; // For E tracking
|
||||
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 sensor_responsiveness; // M306 R
|
||||
float ambient_xfer_coeff_fan0; // M306 A
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue