New Option: Model Predictive Temperature Control (Experimental)

Hi all,

Support for a new option to replace PID heating for the hotend has just been merged. This seems to have a lot better control over the hotend heater, and at least in my testing, seems to have a better profile for heating.

You can find the new setting in the Firmware Builder as per the below screenshot.

The documentation is still being processed - but in simple terms, the new command M306 is now added.

The basic options are:

 A<watts/kelvin>           Ambient heat transfer coefficient (no fan).
 C<joules/kelvin>          Block heat capacity.
 E<extruder>               Extruder number to set. (Default: E0)
 F<watts/kelvin>           Ambient heat transfer coefficient (fan on full).
 P<watts>                  Heater power.
 R<kelvin/second/kelvin>   Sensor responsiveness (= transfer coefficient / heat capcity).
 T                         Autotune the active extruder.

Once you flash your printer with a MPC enabled firmware, set your heater power as per the rating - most printers have either 30W or 40W heaters (mine is 70W), so you’d run:

M306 P30 ; 30W heater
M306 P40 ; 40W heater
M306 P70 ; 70W heater

Once that’s done, run the autotune:

M306 T

At this point, the rest of the setup is automatic.

When it finishes, save your settings via M500.

On my personal printer, the heatup profile when from this with an overshoot of 10-15c when using PID:

To this when autotuned using MPC:

I look forward to seeing peoples feedback on this brand new feature.

1 Like

I am extremely happy with temperature control! However, it has taken control of part cooling fan. It is constantly changing speeds. I just ran a temp tower with bridging allowed and it failed the bridging terribly. The fan is still oscillating and bridging needs max cooling to cool filament when crossing the bridge. How can I get control of cooling fan from this feature?

MPCTEMP doesn’t control the fans. I’d suggest checking your slicer settings.

this is great. For some strange reason I was NOT able to tune PID at all, no matter how many iterations I tried. It’d always end up with a huge delta. (I’d set it to 215 and it’d jump from 213 to 218, some times 220! then back to 212, etc)
Tried MPC out of curiosity, and now is rock solid (± 1°C). No hardware changes at all. This is on Marlin 2.1.1. The hotend is a Volcano with a 70W cartridge. The rest is a simple Tevo Tornado without any mods in the extruder area.

Disclaimer: I still need to test it properly. This is just after one hour of playing with MPC. But I’m pretty happy with it so far. Even if it’s not perfect in the long run, it’s much better than my previous PID calibration.

1 Like

My fan issue was an intermittent wire connection to fan. When the fan kicked on the wire disconnected. The fan stopped spinning and power reconnected to fan- thus fan ramping up and down. I thought software, but wiring issue. I have used MPC for many hours and very solid temps!! It puts PID to shame. I love it!

1 Like

I don’t have octoprint but enabled it instead of the pid with bang bang. With stock settings in Marlin at 50mm/s and I am getting better quality than I did with the other way around. And seeing rock solid temps on the hotend unlike the stock settings used in YouTube videos for setup. Have some things to iron out with my SKR 2 rev B. In the firmware and make a new case for it. Once I have my manta M8P I will play around with the settings

Is anyone having issues with getting MPC Autotune to work on an Ender3Pro v4.2.7 w/bltouch and stock hotend?
Everytime I try to autotune it stops at first attempt ramping to 200C

Send: M306 T
Recv: MPC Autotune start for E0
Recv: M106 P0 S0
Recv: M106 P0 S255
Recv: Cooling to ambient
Recv: M106 P0 S0
Recv: Heating to over 200C
Recv: MPC Autotune interrupted!
Recv: M106 P0 S0
Recv: ok P15 B3

I can’t figure any reason for it to not work. I’m using a custom build made with the firmware builder (tried today’s build to be sure it wasn’t a bug already patched) and although it does seem to print okay and the ramp up is nice and free of ringing I can’t get the autotune working.
When first trying it out I didn’t set my heater power and just tried to autotune. Today I read I was supposed to set that heater power (M306 P40) but it didn’t help with the autotune.

Am I stuck tuning it manually?

That’s interesting - I’ve never seen that before…

Do you see the temperature rise when heating is in progress?

That’s just the thing - it fails with “MPC Autotune interrupted” as soon as it reaches the “Heating to over 200c” stage (no changes in hotend temp observed). Odd that it fails to heat up when I was able to manually tune it thereafter following the Marlin documentation and the performance seems to be as expected.

Let try this… Reset your printer to factory defaults (M502), then store those settings to the EEPROM (M500), power cycle the printer, and then try M306 T again.

The default / stock hotend power I believe is 40W, so that setting shouldn’t need to be changed.

I’m just wondering if something weird is going on in the saved EEPROM settings…

After M502 + M500 + power cycle the M306 T command did the same as before, not even engaging the hotend for a moment before “interruption” (see log excerpt below)

Recv: Cooling to ambient
Recv: T:24.59 /0.00 B:27.32 /0.00 @:0 B@:0
Recv: T:24.55 /0.00 B:27.37 /0.00 @:0 B@:0
Recv: T:24.58 /0.00 B:27.37 /0.00 @:0 B@:0
Recv: T:24.59 /0.00 B:27.34 /0.00 @:0 B@:0
Recv: T:24.58 /0.00 B:27.34 /0.00 @:0 B@:0
Recv: T:24.55 /0.00 B:27.30 /0.00 @:0 B@:0
Recv: T:24.63 /0.00 B:27.35 /0.00 @:0 B@:0
Recv: T:24.61 /0.00 B:27.34 /0.00 @:0 B@:0
Recv: T:24.56 /0.00 B:27.34 /0.00 @:0 B@:0
Recv: T:24.61 /0.00 B:27.32 /0.00 @:0 B@:0
Recv: T:24.63 /0.00 B:27.28 /0.00 @:0 B@:0
Recv: M106 P0 S0
Recv: Heating to over 200C
Recv: MPC Autotune interrupted!
Recv: M106 P0 S0
Recv: T:24.63 /0.00 B:27.28 /0.00 @:0 B@:0
Recv: ok P15 B3
Send: M113 S2
Recv: ok P15 B3
Recv: T:24.61 /0.00 B:27.27 /0.00 @:0 B@:0

Isn’t the autotune script supposed to be running M104 S200 / M109 S200 at the point it errors?

Certainly there should be some heating going on… If you just set a heat for the hotend normally, does it heat up ok?

If so, I’d jump over and lodge an issue here including all your logs:

Yes, the hotend operates as expected outside of the MPC autotune. Prints normal and can be manually set with no issue.

I’ll head over to the Issues page you linked. Thanks, @CRCinAU

Well, if you read the Marlin page about Model Predictive Control you have the Manual Tuning section that says " If M306 T doesn’t work –e.g., with positive temperature coefficient (PTC) hotends– MPC can be configured manually."

I was also excited to try this new feature when I got the same MPC Autotune interrupted! message.
The manual procedure seems too complicated. I’ll buy a Trianglelab NTC 100K B3950 thermistor for my Ender 3.

I’ve been informed that there’s a fix for this pending under this PR:

If you keep an eye on that PR, once its merged, an hour or so later, the builder will grab the fixed version and you can try building a custom firmware again.

If you use the nightlies, the next build will have those fixes.

I’m having trouble with this using the nightly builds from the Firmware builder. I selected the options for MPTC and to add the MPTC menu option for tuning.

On my Ender 3 Pro with v4.2.7, Sprite Pro and a BLTouch, I get no activity in response to a M306 T - it just returns the current values. There’s also no menu option for tuning on the LCD screen.

Do you have a build ID for this so I can check the logs?

Sure, it’s cb1479ce for the latest attempt, and I think 3417a0b4 for a previous attempt before I built a version with hot end PID.

I do have bed PID and the bed PID tuning menu turned on, which I guess might be set up to conflict.

Looking in the config/examples/Creality/Ender-3 Pro/CrealityV427/Configuration.h, around line 707, the MPC_AUTOTUNE, MPC_EDIT_MENU, and and MPC_AUTOTUNE_MENU options are commented out by default. I assume the Firmware builder profile is supposed to turn these on?

(ps. it’d be great if the firmware builder tool allowed you to download the configuration.h and configuration_adv.h as well as the binary)

1 Like

I’ve extracted the saved Config from my firmware with M503 C.

Prettified version is below. I don’t see the MPTC tuning or menu options in this config.

    "__INITIAL_HASH": "46983608e6a3ceff48aa",
    "Configuration.h": {
        "TEMP_SENSOR_PROBE": "0",
        "PREHEAT_1_LABEL": "\"PLA\"",
        "EXTRUDE_MAXLENGTH": "200",
        "MPC_STEADYSTATE": "0.5f",
        "TEMP_WINDOW": "1",
        "EEPROM_SETTINGS": "",
        "MPC_MAX": "255",
        "PREHEAT_1_TEMP_HOTEND": "195",
        "LCD_INFO_SCREEN_STYLE": "0",
        "CONFIGURATION_H_VERSION": "02010300",
        "SOFT_PWM_SCALE": "0",
        "DEFAULT_bedKi": ".023",
        "PREHEAT_1_TEMP_CHAMBER": "35",
        "DUMMY_THERMISTOR_998_VALUE": "25",
        "FAN_SOFT_PWM": "",
        "Z_MAX_POS": "250",
        "G26_XY_FEEDRATE_TRAVEL": "100",
        "NOZZLE_TO_PROBE_OFFSET": "{ -45, -7, 0 }",
        "RET6_12864_LCD": "",
        "X_MIN_POS": "0",
        "PREHEAT_2_TEMP_CHAMBER": "35",
        "COOLER_OVERSHOOT": "2",
        "XY_PROBE_FEEDRATE": "(200*60)",
        "SERVO_DELAY": "{ 50 }",
        "INVERT_E0_DIR": "false",
        "AUTO_BED_LEVELING_UBL": "",
        "TEMP_SENSOR_0": "1",
        "TEMP_SENSOR_BOARD": "0",
        "TEMP_SENSOR_BED": "1",
        "JUNCTION_DEVIATION_MM": "0.08",
        "TEMP_BED_WINDOW": "1",
        "LCD_PROBE_Z_RANGE": "4",
        "BLTOUCH": "",
        "STRING_CONFIG_H_AUTHOR": "\"\"",
        "E_ENABLE_ON": "0",
        "MPC_TUNING_POS": "{ X_CENTER, Y_CENTER, 1.0f }",
        "BANG_MAX": "255",
        "MESH_TEST_NOZZLE_SIZE": "0.6",
        "HEATER_0_MINTEMP": "5",
        "LCD_LANGUAGE": "en",
        "MESH_TEST_BED_TEMP": "62",
        "X_BED_SIZE": "220",
        "Z_PROBE_OFFSET_RANGE_MAX": "20",
        "SDSUPPORT": "",
        "PRINTCOUNTER": "",
        "Z_PROBE_OFFSET_RANGE_MIN": "-20",
        "INVERT_Y_DIR": "false",
        "PIDTEMPBED": "",
        "TEMP_BED_HYSTERESIS": "3",
        "Y_MAX_POS": "Y_BED_SIZE",
        "G26_RETRACT_MULTIPLIER": "1.0",
        "PROBING_MARGIN": "10",
        "MPC_SENSOR_RESPONSIVENESS": "{ 0.22f }",
        "PID_FUNCTIONAL_RANGE": "10",
        "FILAMENT_HEAT_CAPACITY_PERMM": "{ 5.6e-3f }",
        "EXTRUDERS": "1",
        "Z_ENABLE_ON": "0",
        "USE_PROBE_FOR_Z_HOMING": "",
        "MESH_TEST_HOTEND_TEMP": "210",
        "CR10_STOCKDISPLAY": "",
        "INVERT_X_DIR": "false",
        "HOTEND_OVERSHOOT": "15",
        "G26_MESH_VALIDATION": "",
        "LEVELED_SEGMENT_LENGTH": "5.0",
        "WEBSITE_URL": "\"\"",
        "G26_XY_FEEDRATE": "20",
        "Z_HOME_DIR": "-1",
        "CUSTOM_MACHINE_NAME": "\"Ender-3\"",
        "DEFAULT_bedKp": "10.00",
        "MPC_HEATER_POWER": "{ 40.0f }",
        "DEFAULT_MAX_FEEDRATE": "{ 500, 500, 5, 25 }",
        "TEMP_SENSOR_COOLER": "0",
        "UBL_MESH_EDIT_MOVES_Z": "",
        "Z_PROBE_FEEDRATE_FAST": "(10*60)",
        "BUSY_WHILE_HEATING": "",
        "SERIAL_PORT": "1",
        "TEMP_BED_RESIDENCY_TIME": "10",
        "MPC_BLOCK_HEAT_CAPACITY": "{ 16.7f }",
        "PID_K1": "0.95",
        "PID_EDIT_MENU": "",
        "MPC_SMOOTHING_FACTOR": "0.5f",
        "Y_HOME_DIR": "-1",
        "MPC_AMBIENT_XFER_COEFF_FAN255": "{ 0.097f }",
        "SPEAKER": "",
        "DUMMY_THERMISTOR_999_VALUE": "100",
        "TEMP_HYSTERESIS": "3",
        "DEFAULT_AXIS_STEPS_PER_UNIT": "{ 80, 80, 400, 93 }",
        "MAX_CHAMBER_POWER": "255",
        "MPC_TUNING_END_Z": "10.0f",
        "Z_MIN_POS": "0",
        "TEMP_SENSOR_1": "0",
        "TEMP_SENSOR_2": "0",
        "TEMP_SENSOR_3": "0",
        "TEMP_SENSOR_4": "0",
        "TEMP_SENSOR_5": "0",
        "TEMP_SENSOR_6": "0",
        "TEMP_SENSOR_7": "0",
        "X_MAX_POS": "X_BED_SIZE",
        "ENDSTOPPULLUPS": "",
        "PREHEAT_2_LABEL": "\"ABS\"",
        "TEMP_SENSOR_CHAMBER": "0",
        "MESH_EDIT_Z_STEP": "0.025",
        "HOMING_FEEDRATE_MM_M": "{ (20*60), (20*60), (4*60) }",
        "Z_SAFE_HOMING": "",
        "MPC_INCLUDE_FAN": "",
        "EEPROM_BOOT_SILENT": "",
        "Y_ENABLE_ON": "0",
        "Z_PROBE_LOW_POINT": "-5",
        "X_HOME_DIR": "-1",
        "MPC_AMBIENT_XFER_COEFF": "{ 0.068f }",
        "MPC_MIN_AMBIENT_CHANGE": "1.0f",
        "Y_MIN_POS": "0",
        "DEFAULT_MAX_ACCELERATION": "{ 500, 500, 100, 5000 }",
        "PID_MAX": "255",
        "PREHEAT_2_TEMP_BED": "70",
        "HEATER_0_MAXTEMP": "300",
        "ENABLE_LEVELING_AFTER_G28": "",
        "PREHEAT_1_FAN_SPEED": "255",
        "GRID_MAX_POINTS_X_UBL": "5",
        "PREHEAT_2_FAN_SPEED": "255",
        "MESH_TEST_LAYER_HEIGHT": "0.3",
        "BAUDRATE": "115200",
        "BED_MINTEMP": "5",
        "EEPROM_CHITCHAT": "",
        "DEFAULT_bedKd": "305.4",
        "EXTRUDE_MINTEMP": "170",
        "DEFAULT_EJERK": "5.0",
        "TEMP_RESIDENCY_TIME": "10",
        "DEFAULT_ACCELERATION": "500",
        "UBL_SAVE_ACTIVE_ON_M500": "",
        "MAX_BED_POWER": "255",
        "BAUDRATE_2": "250000",
        "BAUDRATE_3": "250000",
        "CONFIG_EXAMPLES_DIR": "\"Creality/Ender-3/CrealityV427\"",
        "DETAILED_BUILD_VERSION": "\"bugfix-2.1.x-mfs\"",
        "TEMP_SENSOR_SOC": "0",
        "PREHEAT_1_TEMP_BED": "60",
        "MANUAL_PROBE_START_Z": "0.2",
        "MESH_INSET": "1",
        "Y_BED_SIZE": "220",
        "PID_AUTOTUNE_MENU": "",
        "BED_OVERSHOOT": "10",
        "PREHEAT_2_TEMP_HOTEND": "240",
        "MPCTEMP": "",
        "X_ENABLE_ON": "0",
        "BED_MAXTEMP": "125",
        "INVERT_Z_DIR": "true",
    "Configuration_adv.h": {
        "FANMUX2_PIN": "-1",
        "FWRETRACT": "",
        "CHAMBER_AUTO_FAN_SPEED": "255",
        "MICROSTEP_MODES": "{ 16, 16, 16, 16, 16, 16 }",
        "RETRACT_FEEDRATE": "80",
        "COOLER_AUTO_FAN_SPEED": "255",
        "TEMP_SENSOR_AD8495_GAIN": "1.0",
        "TX_BUFFER_SIZE": "0",
        "PROBE_OFFSET_WIZARD": "",
        "FANMUX1_PIN": "-1",
        "SOUND_ON_DEFAULT": "",
        "EXTRUDER_AUTO_FAN_SPEED": "255",
        "MAX_ARC_SEGMENT_MM": "1.0",
        "CHAMBER_CHECK_INTERVAL": "5000",
        "HOTEND_IDLE_TIMEOUT_SEC": "(5*60)",
        "HOMING_BUMP_MM": "{ 5, 5, 2 }",
        "FANMUX0_PIN": "-1",
        "SHAPING_MENU": "",
        "SHAPING_ZETA_X": "0.15f",
        "SHAPING_ZETA_Y": "0.15f",
        "FINE_MANUAL_MOVE": "0.025",
        "HOMING_BUMP_DIVISOR": "{ 4, 4, 4 }",
        "INPUT_SHAPING_X": "",
        "HOTEND_IDLE_MIN_TRIGGER": "180",
        "FAN_KICKSTART_TIME": "100",
        "SD_PROCEDURE_DEPTH": "1",
        "MENU_HOLLOW_FRAME": "",
        "INPUT_SHAPING_Y": "",
        "RETRACT_LENGTH_SWAP": "13",
        "MINIMUM_PLANNER_SPEED": "0.05",
        "BABYSTEPPING": "",
        "LIN_ADVANCE": "",
        "N_ARC_CORRECTION": "25",
        "REPORT_FAN_CHANGE": "",
        "STATUS_CHAMBER_ANIM": "",
        "SHAPING_FREQ_X": "40",
        "SHAPING_FREQ_Y": "40",
        "MAX_AUTORETRACT": "99",
        "COOLER_AUTO_FAN_PIN": "-1",
        "SHOW_BOOTSCREEN": "",
        "SLOWDOWN_DIVISOR": "2",
        "SHOW_ELAPSED_TIME": "",
        "MANUAL_FEEDRATE": "{ 50*60, 50*60, 4*60, 2*60 }",
        "HOST_PROMPT_SUPPORT": "",
        "PROBE_OFFSET_WIZARD_START_Z": "-4.0",
        "BLOCK_BUFFER_SIZE": "16",
        "CHAMBER_AUTO_FAN_PIN": "-1",
        "MULTISTEPPING_LIMIT": "16",
        "MIN_ARC_SEGMENT_MM": "0.1",
        "TEMP_SENSOR_AD8495_OFFSET": "0.0",
        "DISABLE_IDLE_X": "",
        "DISABLE_IDLE_Z": "",
        "ENCODER_10X_STEPS_PER_SEC": "30",
        "BLTOUCH_HS_MODE": "true",
        "RETRACT_ZRAISE": "0.3",
        "FASTER_GCODE_PARSER": "",
        "XYZ_HOLLOW_FRAME": "",
        "STATUS_BED_ANIM": "",
        "DEFAULT_MINSEGMENTTIME": "20000",
        "ADVANCE_K": "0.22",
        "BUFSIZE": "4",
        "SLOWDOWN": "",
        "HOTEND_IDLE_BED_TARGET": "0",
        "ARC_SUPPORT": "",
        "USE_WATCHDOG": "",
        "DISABLE_IDLE_E": "",
        "DISABLE_IDLE_Y": "",
        "LCD_INFO_MENU": "",
        "TEMP_SENSOR_AD595_OFFSET": "0.0",
        "STEP_STATE_E": "HIGH",
        "STEP_STATE_X": "HIGH",
        "BOOTSCREEN_TIMEOUT": "3000",
        "MAX_CMD_SIZE": "96",
        "ADVANCED_OK": "",
        "MIN_STEPS_PER_SEGMENT": "6",
        "SD_MENU_CONFIRM_START": "",
        "CONFIGURATION_ADV_H_VERSION": "02010300",
        "BLTOUCH_DELAY": "500",
        "MIN_CIRCLE_SEGMENTS": "72",
        "WATCH_BED_TEMP_PERIOD": "60",
        "STATUS_HOTEND_ANIM": "",
        "EVENT_GCODE_SD_ABORT": "\"G28XY\"",
        "AXIS_RELATIVE_MODES": "{ false, false, false, false }",
        "HOTEND_IDLE_TIMEOUT": "",
        "WATCH_TEMP_PERIOD": "40",
        "ENCODER_100X_STEPS_PER_SEC": "80",
        "CONFIG_EXAMPLES_DIR": "\"Creality/Ender-3/CrealityV427\"",
        "STEP_STATE_Y": "HIGH",
        "STEP_STATE_Z": "HIGH",
        "QUICK_HOME": "",
        "WATCH_TEMP_INCREASE": "2",
        "RETRACT_LENGTH": "3",
        "TEMP_SENSOR_AD595_GAIN": "1.0",
        "E0_AUTO_FAN_PIN": "-1"
    "VERSION": {
        "DETAILED_BUILD_VERSION": "\"bugfix-2.1.x-mfs\"",
        "STRING_DISTRIBUTION_DATE": "\"2023-05-22\"",
        "GIT_REF": "9ceecefae2"