X2D Manual Aux fan control in cooling mode and disable autocooling for PETG+PLA

If you are printing PETG with a PLA interface, the default cooling will likely be too strong. It works well for PLA, but when switching from PETG to PLA, both AUX fans may ramp up to around 90%, which can cause the PETG to warp and detach from the PLA interface.
If you try to manually adjust the AUX fan speeds, they will reset on each layer and during every filament change.

To fix this, you can disable automatic cooling. Once it’s disabled, you’ll have full manual control over the fans (both AUX and exhaust), and your settings won’t be overwritten. This makes the X2D perform even better than before.
To do this, comment out the following G-code:
Under Machine Start, one line below:

;M142 P6 R30 S40 U0.3 V0.8 ; set PLA/TPU/PETG exhaust chamber autocooling

I’ll also include the full code for both layer change and filament change. I’m not adding anything new—just disabling autocooling during those steps.
Happy printing!

.
.
.

Layer change G-Code

;======== X2D layer_change gcode ==========
;===== 2025/04/08 =====

{if (layer_num + 1 == 1)}
{if (overall_chamber_temperature >= 40)}
;not reset filter fan in first layer
;not reset fan
{endif}
{endif}

{if (layer_num + 1 <= close_additional_fan_first_x_layers[current_extruder])}
{if (overall_chamber_temperature < 40)}
; M106 P2 S{first_x_layer_fan_speed[current_extruder]*255.0/100.0}
; M106 P10 S{first_x_layer_fan_speed[current_extruder]*255.0/100.0}
{endif}
;not reset fan
{elsif (layer_num + 1 < additional_fan_full_speed_layer[current_extruder] && additional_fan_full_speed_layer[current_extruder] > close_additional_fan_first_x_layers[current_extruder])}
{if (overall_chamber_temperature < 40)}
; M106 P2 S{(first_x_layer_fan_speed[current_extruder] + (additional_cooling_fan_speed[current_extruder] - first_x_layer_fan_speed[current_extruder]) * (layer_num + 1 - close_additional_fan_first_x_layers[current_extruder]) / (additional_fan_full_speed_layer[current_extruder] - close_additional_fan_first_x_layers[current_extruder])) * 255.0/100.0}
; M106 P10 S{(first_x_layer_fan_speed[current_extruder] + (additional_cooling_fan_speed[current_extruder] - first_x_layer_fan_speed[current_extruder]) * (layer_num + 1 - close_additional_fan_first_x_layers[current_extruder]) / (additional_fan_full_speed_layer[current_extruder] - close_additional_fan_first_x_layers[current_extruder])) * 255.0/100.0}
{endif}
;not reset fan
;{elsif (layer_num + 1 == max(close_additional_fan_first_x_layers[current_extruder] + 1, additional_fan_full_speed_layer[current_extruder]))}
;{if (overall_chamber_temperature < 40)}
;updata chamber autocooling in Xth layer
{if (min_vitrification_temperature <= 50)}
{if (nozzle_diameter == 0.2)}
; M142 P1 R30 S35 U{max_additional_fan/100.0} V1.0 O40; set PLA/TPU ND0.2 chamber autocooling
{else}
; M142 P1 R30 S40 U{max_additional_fan/100.0} V1.0 O45; set PLA/TPU ND0.4 chamber autocooling
{endif}
{else}
{if (nozzle_diameter == 0.2)}
; M142 P1 R35 S45 U{max_additional_fan/100.0} V0.5 O50; set PETG ND0.2 chamber autocooling
{else}
; M142 P1 R35 S50 U{max_additional_fan/100.0} V0.5 O55; set PETG ND0.4 chamber autocooling
{endif}
{endif}
{else}
;not reset filter fan in Xth layer
{endif}
;not reset fan
{endif}

; update layer progress
M73 L{layer_num+1}
M991 S0 P{layer_num} ;notify layer change

.
.
.
.
.
.

Change filament G-Code

======== X2D filament_change gcode ==========
;===== 2026/04/08 =====

M620 S[next_extruder]A B H[next_hotend]
;M204 S9000
{if toolchange_count > 1 && (z_hop_types[current_extruder] == 0 || z_hop_types[current_extruder] == 3)}
G17
G2 Z{z_after_toolchange + 0.4} I0.86 J0.86 P1 F10000 ; spiral lift a little from second lift
{endif}

;nozzle_change_gcode

G1 Z{max_layer_z + 3.0} F1200

M400
M106 P1 S0

{if toolchange_count == 2}
; get travel path for change filament
;M620.1 X[travel_point_1_x] Y[travel_point_1_y] F21000 P0
;M620.1 X[travel_point_2_x] Y[travel_point_2_y] F21000 P1
;M620.1 X[travel_point_3_x] Y[travel_point_3_y] F21000 P2
{endif}

{if ((filament_type[current_extruder] == “PLA”) || (filament_type[current_extruder] == “PLA-CF”) || (filament_type[current_extruder] == “PETG”)) && (nozzle_diameter[current_extruder] == 0.2)}
M620.10 A0 F74.8347 L[flush_length] H{nozzle_diameter[current_extruder]} T{flush_temperatures[current_extruder]} P[old_filament_temp] S1
{else}
M620.10 A0 F{flush_volumetric_speeds[current_extruder]/2.4053*60} L[flush_length] H{nozzle_diameter[current_extruder]} T{flush_temperatures[current_extruder]} P[old_filament_temp] S1
{endif}

{if ((filament_type[next_extruder] == “PLA”) || (filament_type[next_extruder] == “PLA-CF”) || (filament_type[next_extruder] == “PETG”)) && (nozzle_diameter[next_extruder] == 0.2)}
M620.10 A1 F74.8347 L[flush_length] H{nozzle_diameter[next_extruder]} T{flush_temperatures[next_extruder]} P[new_filament_temp] S1
{else}
M620.10 A1 F{flush_volumetric_speeds[next_extruder]/2.4053*60} L[flush_length] H{nozzle_diameter[next_extruder]} T{flush_temperatures[next_extruder]} P[new_filament_temp] S1
{endif}

M620.15 C{new_filament_temp - filament_cooling_before_tower[next_extruder]}

{if long_retraction_when_cut}
M620.11 P1 L0 I[current_extruder] B[current_hotend] E-{retraction_distance_when_cut} F{max((flush_volumetric_speeds[current_extruder]/2.4053*60), 200)}
{else}
M620.11 P0 L0 I[current_extruder] B[current_hotend] E0
{endif}

{if long_retraction_when_ec}
M620.11 K1 I[current_extruder] B[current_hotend] R{retraction_distance_when_ec} F{max((flush_volumetric_speeds[current_extruder]/2.4053*60), 200)}
{else}
M620.11 K0 I[current_extruder] B[current_hotend] R0
{endif}

M620.22 I[next_extruder] P1 ; enable remote extruder runout auto purge.

T[next_extruder] H[next_hotend]

;deretract
{if filament_type[next_extruder] == “TPU”}
{else}
{if filament_type[next_extruder] == “PA”}
;VG1 E1 F{max(new_filament_e_feedrate, 200)}
;VG1 E1 F{max(new_filament_e_feedrate/2, 100)}
{else}
;VG1 E4 F{max(new_filament_e_feedrate, 200)}
;VG1 E4 F{max(new_filament_e_feedrate/2, 100)}
{endif}
{endif}

; VFLUSH_START
{if flush_length>41.5}
;VG1 E41.5 F{min(old_filament_e_feedrate,new_filament_e_feedrate)}
;VG1 E{flush_length-41.5} F{new_filament_e_feedrate}
{else}
;VG1 E{flush_length} F{min(old_filament_e_feedrate,new_filament_e_feedrate)}
{endif}
SYNC T{ceil(flush_length / 125) * 5}
; VFLUSH_END

M1002 set_filament_type:{filament_type[next_extruder]}

M400
M83
{if next_extruder < 255}
M620.10 R{retract_length_toolchange[filament_map[next_extruder]-1]}
M628 S0
;VM109 S[new_filament_temp]
M629
M400

;prime_tower_interface
{if is_prime_tower_interface && filament_tower_interface_purge_volume !=0}
G150.1
M620.13 W0 L{filament_tower_interface_purge_volume} T{filament_tower_interface_print_temp} R0.0
{endif}
;prime_tower_interface

M983.3 F{filament_max_volumetric_speed[next_extruder]/2.4} A0.4 R{retract_length_toolchange[filament_map[next_extruder]-1]}

M400

G1 Z{max_layer_z + 3.0} F3000

{else}
G1 X[x_after_toolchange] Y[y_after_toolchange] Z[z_after_toolchange] F12000
{endif}

M621 S[next_extruder]A B

M622.1 S0 ;for prev version, default skip
M1002 judge_flag powerloss_resume_flag
M622 J1
M983.3 F{filament_max_volumetric_speed[next_extruder]/2.4} A0.4 R{retract_length_toolchange[filament_map[next_extruder]-1]}
M400
G1 Z{max_layer_z + 3.0} F3000
M1002 set_flag powerloss_resume_flag=0
M623

M620.6 I[next_extruder] H[next_hotend] W1 ;enable ams air printing detect

{if (filament_type[next_extruder] == “TPU”)}
M1015.3 S1 H[nozzle_diameter];enable tpu clog detect
{else}
M1015.3 S0;disable tpu clog detect
{endif}

{if (filament_type[next_extruder] == “PLA”) || (filament_type[next_extruder] == “PETG”)
|| (filament_type[next_extruder] == “PLA-CF”) || (filament_type[next_extruder] == “PETG-CF”)}
M1015.4 S1 K1 H[nozzle_diameter] ;enable E air printing detect
{else}
M1015.4 S0 K0 H[nozzle_diameter] ;disable E air printing detect
{endif}

{if layer_z <= (initial_layer_print_height + 0.001)}
M204 S[initial_layer_acceleration]
{else}
M204 S[travel_acceleration]
{endif}

G1 Y256 F18000

{if (overall_chamber_temperature < 40)}
{if (layer_num + 1 <= close_additional_fan_first_x_layers[next_extruder])}
; M106 P2 S{first_x_layer_fan_speed[next_extruder]*255.0/100.0 };set first x_layer fan
; M106 P10 S{first_x_layer_fan_speed[next_extruder]*255.0/100.0 };set first x_layer fan
;{elsif (layer_num + 1 < additional_fan_full_speed_layer[next_extruder] && additional_fan_full_speed_layer[next_extruder] > close_additional_fan_first_x_layers[next_extruder])}
; M106 P2 S{(first_x_layer_fan_speed[next_extruder] + (additional_cooling_fan_speed[next_extruder] - first_x_layer_fan_speed[next_extruder]) * (layer_num + 1 - close_additional_fan_first_x_layers[next_extruder]) / (additional_fan_full_speed_layer[next_extruder] - close_additional_fan_first_x_layers[next_extruder])) * 255.0/100.0}
; M106 P10 S{(first_x_layer_fan_speed[next_extruder] + (additional_cooling_fan_speed[next_extruder] - first_x_layer_fan_speed[next_extruder]) * (layer_num + 1 - close_additional_fan_first_x_layers[next_extruder]) / (additional_fan_full_speed_layer[next_extruder] - close_additional_fan_first_x_layers[next_extruder])) * 255.0/100.0}
{else}
{if (min_vitrification_temperature <= 50)}
{if (nozzle_diameter == 0.2)}
; M142 P1 R30 S35 U{max_additional_fan/100.0} V1.0 O40; set PLA/TPU ND0.2 chamber autocooling
{else}
; M142 P1 R30 S40 U{max_additional_fan/100.0} V1.0 O45; set PLA/TPU ND0.4 chamber autocooling
{endif}
{else}
{if (nozzle_diameter == 0.2)}
; M142 P1 R35 S45 U{max_additional_fan/100.0} V0.5 O50; set PETG ND0.2 chamber autocooling
{else}
; M142 P1 R35 S50 U{max_additional_fan/100.0} V0.5 O55; set PETG ND0.4 chamber autocooling
{endif}
{endif}
{endif}
{endif}
;not set fan changing filament

6 Likes

I’m looking in the machine start gcode and I can’t find the line you said to comment out. Do I have to add it?

EDIT: Nevermind, I scrolled right past it lol

1 Like

If you go back to printing just PLA do you need to uncomment these out again? or will it still cool like it needs to? I am having bad problems with PETG warping when using PLA support interface on the AUX nozzle

When you comment out those lines, create a separate user printer profile (e.g., X2D PETG/PLA) and use that profile only when slicing PETG prints. The default profile should remain unchanged, as it can’t really be modified.

What you’re doing is essentially creating a custom user profile tailored for that type of printing. Just make sure to select this profile when slicing PETG, because the slicer will revert to the default profile when you reopen the project.

1 Like

Thanks! That’s exactly what I ended up doing!

So I did everything and it’s still doing the auto chamber cooling for pla. Does this only work for PETG?

you probobly missed line or two in layer change or filament change. I’m printing right now dual color PLA and I have ful manual controll of all 3 fans. There is few lines that start with { they need to be commented out as well eg:

;{elsif (layer_num + 1 == max(close_additional_fan_first_x_layers[current_extruder] + 1, additional_fan_full_speed_layer[current_extruder]))}

I’ll double check. Would you possibly be able to slice a benchy and upload your machine profile as a 3mf here? Then I could just open the 3mf and click save lol

1 Like

X2D Manual Fans.3mf (27.8 KB)

2 Likes

You da man! Thanks!

25 character

1 Like

Looked through everything and I believe I found the problem. I had the semicolons right next to the fan gcode instead of at the start of the line. This was only in the layer change gcode and chang filament gcode. The machine start gcode was fine. Going to run a test to see what happens.

I did however find 2 lines in your gcode that are different from mine and the default machine profile gcode. Do you know what these are?

Looks like I missed another one. On the lower photo your gcode has the E12 D4. The default and my profile doesn’t have this either.

Welp, unfortunately the printer is still doing auto cooling. Chamber fan is running at 70% like I have it set but the aux fans should be at 10%. I’ll try your machine profile as soon as I figure out what those extra lines of gcode are

Nice workaround. But thats all it is, a workaround. And quite annoying to execute every time. Its like going back in time about 10 years lol

1 Like

You do need:

M400 P50 finishes all movements and waits 50 milliseconds to clear the buffer

M500 D1 - you are saving eg bed mesh leveling and other values like z-offset and other cal values to EEPROM so when you turn off the printer values are still there.

G1 Z0.5 raises nozzle 0.5mm at the end of load line and your case a bit higher to 1mm

I left 40% on both Aux and 70 on Exhaust so people don’t smoke the printer. Just change this after first layer to anything and it will keep those new values.

Okay, so I’m guessing those were all changes you made? Or are you running an older, or beta, version of Bambu studio? I’m confused why your gcode is different than even the default.

Ahhh, okay. So with your changes the aux fan controls in the filament profile still don’t do anything? I have to either change them in the gcode or wait till the print starts and do it on the screen? I was hoping to have full control via the filament profile.

Why not use the P2S’s “machine G-code/layer_change g-code” as a guide?

Printing PETG works well with the P2S.

And why is there a difference in the Bambu/Generic PETG print profiles/cooling/AUX speed between 0% and 40% when comparing the profiles between the P2S and X2D?

The “layer_change g-code” of the two printers is, of course, different.

X2D layer_change gcode:

;======== X2D layer_change gcode ==========
;===== 2025/04/08 =====

{if (layer_num + 1 == 1)}
{if (overall_chamber_temperature >= 40)}
    ;not reset filter fan in first layer
    ;not reset fan
{endif}
{endif}

{if (layer_num + 1 <= close_additional_fan_first_x_layers[current_extruder])}
{if (overall_chamber_temperature < 40)}
    M106 P2 S{first_x_layer_fan_speed[current_extruder]*255.0/100.0}
	M106 P10 S{first_x_layer_fan_speed[current_extruder]*255.0/100.0}
{endif}
;not reset fan
{elsif (layer_num + 1 < additional_fan_full_speed_layer[current_extruder] && additional_fan_full_speed_layer[current_extruder] > close_additional_fan_first_x_layers[current_extruder])}
{if (overall_chamber_temperature < 40)}
    M106 P2 S{(first_x_layer_fan_speed[current_extruder] + (additional_cooling_fan_speed[current_extruder] - first_x_layer_fan_speed[current_extruder]) * (layer_num + 1 - close_additional_fan_first_x_layers[current_extruder]) / (additional_fan_full_speed_layer[current_extruder] - close_additional_fan_first_x_layers[current_extruder])) * 255.0/100.0}
	M106 P10 S{(first_x_layer_fan_speed[current_extruder] + (additional_cooling_fan_speed[current_extruder] - first_x_layer_fan_speed[current_extruder]) * (layer_num + 1 - close_additional_fan_first_x_layers[current_extruder]) / (additional_fan_full_speed_layer[current_extruder] - close_additional_fan_first_x_layers[current_extruder])) * 255.0/100.0}
{endif}
;not reset fan
{elsif (layer_num + 1 == max(close_additional_fan_first_x_layers[current_extruder] + 1, additional_fan_full_speed_layer[current_extruder]))}
{if (overall_chamber_temperature < 40)}
    ;updata chamber autocooling in Xth layer
    {if (min_vitrification_temperature <= 50)}
        {if (nozzle_diameter == 0.2)}
            M142 P1 R30 S35 U{max_additional_fan/100.0} V1.0 O40; set PLA/TPU ND0.2 chamber autocooling
        {else}
            M142 P1 R30 S40 U{max_additional_fan/100.0} V1.0 O45; set PLA/TPU ND0.4 chamber autocooling
        {endif}
    {else}
        {if (nozzle_diameter == 0.2)}
            M142 P1 R35 S45 U{max_additional_fan/100.0} V0.5 O50; set PETG ND0.2 chamber autocooling
        {else}
            M142 P1 R35 S50 U{max_additional_fan/100.0} V0.5 O55; set PETG ND0.4 chamber autocooling
        {endif}
    {endif}
{else}
        ;not reset filter fan in Xth layer
{endif}
;not reset fan
{endif}


; update layer progress
M73 L{layer_num+1}
M991 S0 P{layer_num} ;notify layer change

P2S layer_change gcode:

;======== P2S layer_change gcode ==========
;===== 2026/04/08 ====

{if (layer_num + 1 == 1)}
{if (overall_chamber_temperature >= 40)}
    ;not reset filter fan in first layer
    ;not reset fan
{else}
{if (min_vitrification_temperature > 50)}
    ;not reset filter fan in first layer
    ;not reset fan
{endif}        
{endif}
{endif}

{if (layer_num + 1 <= close_additional_fan_first_x_layers[current_extruder])}
{if (overall_chamber_temperature < 40)}
    {if (min_vitrification_temperature <= 50)}
        M106 P2 S{first_x_layer_fan_speed[current_extruder]*255.0/100.0}
    {endif}
{endif}
    M622.1 S0
    M1002 judge_flag ventobox_replace_aux1_fan_flag
    M622 J0
    M106 P10 S{first_x_layer_fan_speed[current_extruder]*255.0/100.0}; set first x_layer left aux fan 
    M623
;not reset fan
{elsif (layer_num + 1 < additional_fan_full_speed_layer[current_extruder] && additional_fan_full_speed_layer[current_extruder] > close_additional_fan_first_x_layers[current_extruder])}
{if (overall_chamber_temperature < 40)}
    {if (min_vitrification_temperature <= 50)}
        M106 P2 S{(first_x_layer_fan_speed[current_extruder] + (additional_cooling_fan_speed[current_extruder] - first_x_layer_fan_speed[current_extruder]) * (layer_num + 1 - close_additional_fan_first_x_layers[current_extruder]) / (additional_fan_full_speed_layer[current_extruder] - close_additional_fan_first_x_layers[current_extruder])) * 255.0/100.0}
    {endif}
{endif}
    M622.1 S0
    M1002 judge_flag ventobox_replace_aux1_fan_flag
    M622 J0
    M106 P10 S{(first_x_layer_fan_speed[current_extruder] + (additional_cooling_fan_speed[current_extruder] - first_x_layer_fan_speed[current_extruder]) * (layer_num + 1 - close_additional_fan_first_x_layers[current_extruder]) / (additional_fan_full_speed_layer[current_extruder] - close_additional_fan_first_x_layers[current_extruder])) * 255.0/100.0}
    M623
;not reset fan
{elsif (layer_num + 1 == max(close_additional_fan_first_x_layers[current_extruder] + 1, additional_fan_full_speed_layer[current_extruder]))}
{if (overall_chamber_temperature < 40)}
    ;updata chamber autocooling in Xth layer
    {if (min_vitrification_temperature <= 50)}
        {if (nozzle_diameter == 0.2)}
            M142 P1 R30 S40 U{max_additional_fan/100.0} V1.0 O45; set PLA/TPU ND0.2 chamber autocooling
        {else}
            M142 P1 R30 S40 U{max_additional_fan/100.0} V1.0 O45; set PLA/TPU ND0.4 chamber autocooling
        {endif}
    {else}
            ;not reset filter fan in Xth layer
    {endif}
{else}
        ;not reset filter fan in Xth layer
{endif}
    M622.1 S0
    M1002 judge_flag ventobox_replace_aux1_fan_flag
    M622 J0
    M106 P10 S{additional_cooling_fan_speed[current_extruder]*255.0/100.0}; set left aux fan 
    M623
;not reset fan
{endif}

; update layer progress
M73 L{layer_num+1}
M991 S0 P{layer_num} ;notify layer change


Great work, the editing the start m142 gcode and commenting out the toolchange ones helped turn off the left aux fan and control the exhaust.

For those confused by the m142 parameters, I think the firmware is suppose to scale the fan speed between the U and V values as the temperature goes between S and R values.

My exhaust fan speed scales like mentioned above with the chamber temperature. However the right aux fan stays on so I may need to try another P value for the fan control gcode. @Sebo3D1 did you figure out the right aux fan?

Why Bambu used a decimal for U and V when gcode values are standard as 0-255 is a mystery (but probably for future lock in and general open source unfriendliness).

It is different code for different printers—don’t do that. X2D from 2025…something doesn’t add up.

yes you can experiment with P2,P3,P10 under machine code, set them to different values and you will see what controlls what fan.

Usage of R S and V O and decimal values allows on auto cooling based on temps, nothing nefarious, industry standard.

Yea, looks like right aux is fan index 10, from the start gcode looking at it again

M106 P2 S255 ; turn on auxiliary fan for cooling
M106 P10 S255 ; turn on auxiliary fan for cooling