MCPcopy Create free account
hub / github.com/MarlinFirmware/Marlin / MPC_autotune

Method MPC_autotune

Marlin/src/module/temperature.cpp:1325–1452  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1323 }
1324
1325 void Temperature::MPC_autotune(const uint8_t e, MPCTuningType tuning_type=AUTO) {
1326 SERIAL_ECHOLNPGM(STR_MPC_AUTOTUNE_START, e);
1327
1328 MPC_autotuner tuner(e);
1329
1330 MPCHeaterInfo &hotend = temp_hotend[e];
1331 MPC_t &mpc = hotend.mpc;
1332
1333 // Move to center of bed, just above bed height and cool with max fan
1334 gcode.home_all_axes(true);
1335 disable_all_heaters();
1336 #if HAS_FAN
1337 zero_fan_speeds();
1338 set_fan_speed(TERN(SINGLEFAN, 0, e), 255);
1339 planner.sync_fan_speeds(fan_speed);
1340 #endif
1341 do_blocking_move_to(xyz_pos_t(MPC_TUNING_POS));
1342
1343 // Determine ambient temperature.
1344 SERIAL_ECHOLNPGM(STR_MPC_COOLING_TO_AMBIENT);
1345 TERN_(EXTENSIBLE_UI, ExtUI::onMPCTuning(ExtUI::mpcresult_t::MPC_STARTED));
1346 TERN(DWIN_LCD_PROUI, LCD_ALERTMESSAGE(MSG_MPC_COOLING_TO_AMBIENT), LCD_MESSAGE(MSG_COOLING));
1347
1348 if (tuner.measure_ambient_temp() != MPC_autotuner::MeasurementState::SUCCESS) return;
1349 hotend.modeled_ambient_temp = tuner.get_ambient_temp();
1350
1351 #if HAS_FAN
1352 set_fan_speed(TERN(SINGLEFAN, 0, e), 0);
1353 planner.sync_fan_speeds(fan_speed);
1354 #endif
1355
1356 // Heat to 200 degrees
1357 SERIAL_ECHOLNPGM(STR_MPC_HEATING_PAST_200);
1358 LCD_ALERTMESSAGE(MSG_MPC_HEATING_PAST_200);
1359
1360 if (tuner.measure_heatup() != MPC_autotuner::MeasurementState::SUCCESS) return;
1361
1362 // Calculate physical constants from three equally-spaced samples
1363 const float t1 = tuner.get_sample_1_temp(),
1364 t2 = tuner.get_sample_2_temp(),
1365 t3 = tuner.get_sample_3_temp();
1366 float asymp_temp = (t2 * t2 - t1 * t3) / (2 * t2 - t1 - t3),
1367 block_responsiveness = -log((t2 - asymp_temp) / (t1 - asymp_temp)) / tuner.get_sample_interval();
1368
1369 #if ENABLED(MPC_AUTOTUNE_DEBUG)
1370 SERIAL_ECHOLNPGM("asymp_temp ", asymp_temp);
1371 SERIAL_ECHOLNPGM("block_responsiveness ", p_float_t(block_responsiveness, 4));
1372 #endif
1373
1374 // Make initial guess at transfer coefficients
1375 mpc.ambient_xfer_coeff_fan0 = mpc.heater_power * (MPC_MAX) / 255 / (asymp_temp - tuner.get_ambient_temp());
1376 TERN_(MPC_INCLUDE_FAN, mpc.fan255_adjustment = 0.0f);
1377
1378 if (tuning_type == AUTO || tuning_type == FORCE_ASYMPTOTIC) {
1379 // Analytic tuning
1380 mpc.block_heat_capacity = mpc.ambient_xfer_coeff_fan0 / block_responsiveness;
1381 mpc.sensor_responsiveness = block_responsiveness / (1.0f - (tuner.get_ambient_temp() - asymp_temp) * exp(-block_responsiveness * tuner.get_sample_1_time()) / (t1 - asymp_temp));
1382 }

Callers 3

M306Method · 0.80
drawHotendMPCMenuFunction · 0.80
menuItemHandlerMethod · 0.80

Calls 15

do_blocking_move_toFunction · 0.85
home_all_axesMethod · 0.80
sync_fan_speedsMethod · 0.80
measure_ambient_tempMethod · 0.80
get_ambient_tempMethod · 0.80
measure_heatupMethod · 0.80
get_sample_1_tempMethod · 0.80
get_sample_2_tempMethod · 0.80
get_sample_3_tempMethod · 0.80
get_sample_intervalMethod · 0.80
get_sample_1_timeMethod · 0.80
get_rate_fastestMethod · 0.80

Tested by

no test coverage detected