# This is a configuration file for the Creatbot F430NX. [include mainsail.cfg] [virtual_sdcard] path: ~/printer_data/gcodes on_error_gcode: CANCEL_PRINT [save_variables] filename: ~/printer_data/config/config_variables.cfg [exclude_object] [gcode_arcs] resolution: 1.0 [force_move] enable_force_move: True [idle_timeout] gcode: {% if printer.webhooks.state|lower == 'ready' %} {% if printer.pause_resume.is_paused %} {% if printer["extruder"] is defined %} SET_HEATER_TEMPERATURE HEATER=extruder {% endif %} {% if printer["extruder1"] is defined %} SET_HEATER_TEMPERATURE HEATER=extruder1 {% endif %} {% else %} TURN_OFF_HEATERS {% endif %} {% endif %} timeout: 1800 # 0.5 hour timeout # F446 MotherBoard ID [mcu] canbus_uuid: 000000000010 canbus_interface: can0 [printer] kinematics: cartesian max_velocity: 300 max_accel: 3000 max_z_velocity: 10 max_z_accel: 100 square_corner_velocity: 5.0 [bed_mesh] speed: 100 horizontal_move_z: 7 mesh_min: 34.6,17.4 mesh_max: 420, 300 probe_count: 5,4 mesh_pps: 2,2 fade_end: 5 algorithm: bicubic bicubic_tension: 0.2 [stepper_x] step_pin: PD1 dir_pin: !PD0 enable_pin: !PA15 rotation_distance: 50.8 microsteps: 64 full_steps_per_rotation: 200 endstop_pin: ^PC10 position_min: -20 position_endstop: -20 position_max: 475 homing_speed: 100 homing_retract_dist: 10 step_pulse_duration:0.0000025 [tmc5160 stepper_x] cs_pin: PE2 spi_software_sclk_pin: PB3 spi_software_mosi_pin: PB5 spi_software_miso_pin: PB4 run_current: 1.5 interpolate: True sense_resistor: 0.075 stealthchop_threshold: 300 [dual_carriage] axis: x step_pin: PE11 dir_pin: !PE10 enable_pin: !PE9 rotation_distance: 50.8 microsteps: 64 full_steps_per_rotation: 200 endstop_pin: ^PE7 position_endstop: 475 position_min: 55 position_max: 475 homing_speed: 100 homing_retract_dist: 10 safe_distance: 75 [tmc5160 dual_carriage] cs_pin: PE8 spi_software_sclk_pin: PB3 spi_software_mosi_pin: PB5 spi_software_miso_pin: PB4 run_current: 1.5 interpolate: True sense_resistor: 0.075 stealthchop_threshold: 300 [stepper_y] step_pin: PD4 dir_pin: !PD3 enable_pin: !PD2 rotation_distance: 73.152 microsteps: 64 full_steps_per_rotation: 200 gear_ratio: 1:1 endstop_pin: ^PC11 position_min: 0 position_endstop: 0 position_max: 300 homing_speed: 60 homing_retract_dist: 10 step_pulse_duration:0.0000025 [stepper_z] step_pin: PD7 dir_pin: PD6 enable_pin: !PD5 rotation_distance: 5 gear_ratio: 2.5:1 microsteps: 16 full_steps_per_rotation: 200 endstop_pin: probe:z_virtual_endstop position_max: 300 position_min: -4 homing_speed: 10 second_homing_speed: 1 homing_retract_dist: 2.0 [tmc5160 stepper_z] cs_pin: PE4 spi_software_sclk_pin: PB3 spi_software_mosi_pin: PB5 spi_software_miso_pin: PB4 run_current: 0.8 interpolate: True sense_resistor: 0.075 stealthchop_threshold: 0 [heater_bed] heater_pin: PD12 sensor_type: Generic 3950 sensor_pin: PC0 max_power: 1.0 min_temp: 0 max_temp: 150 # control: pid # pid_kp: 40.673 # pid_ki: 0.837 # pid_kd: 494.176 [verify_heater heater_bed] max_error: 20 check_gain_time:90 hysteresis: 5 heating_gain: 2 [heater_generic chamber] heater_pin: PD15 max_power: 1.0 sensor_type: Generic 3950 sensor_pin: PC3 min_temp: 0 max_temp: 80 # control: pid # pid_kp: 30.68 # pid_ki: 0.21 # pid_kd: 0 [verify_heater chamber] max_error: 120 hysteresis: 100 check_gain_time: 3600 heating_gain: 0.01 [multi_pin fan] pins: L_tool:PA10, R_tool:PA10 [fan] pin: multi_pin:fan max_power: 1.0 shutdown_speed: 0.0 kick_start_time: 1.0 off_below: 0.15 [fan_generic Air_filter_fan] pin: PC8 max_power: 1.0 shutdown_speed: 0.0 kick_start_time: 1.0 [controller_fan _controller_fan] pin: PC6 max_power: 0.8 heater: stepper: stepper_x, stepper_z, dual_carriage idle_speed: 0.5 [delayed_gcode INIT_LIGHT] initial_duration:0.01 gcode: {% set svv = printer.save_variables.variables %} {% set luminance = svv.interior_lighting|default(0)|float %} SET_LED LED=Interior_lighting WHITE={luminance} TRANSMIT=1 SYNC=0 [led Interior_lighting] white_pin: PC7 cycle_time: 0.010 initial_WHITE: 0 [neopixel _Status_light] pin: PB8 chain_count: 1 color_order: GRB initial_RED: 0.3 initial_GREEN: 0.3 initial_BLUE: 0.3 [filament_switch_sensor extruder] pause_on_runout: False runout_gcode: _RUNOUT_HANDLE event_delay: 3.0 pause_delay: 0.5 switch_pin: ^PC14 [filament_switch_sensor extruder1] pause_on_runout: False runout_gcode: _RUNOUT_HANDLE event_delay: 3.0 pause_delay: 0.5 switch_pin: ^PC15 # F072 Left nozzle ID [mcu L_tool] canbus_uuid: 000000000001 canbus_interface: can0 [adxl345] spi_speed: 5000000 cs_pin: L_tool:PB12 spi_software_sclk_pin:L_tool:PB13 spi_software_mosi_pin:L_tool:PB15 spi_software_miso_pin:L_tool:PB14 axes_map: -x, -z, -y rate: 3200 [resonance_tester] accel_chip: adxl345 probe_points: 200, 150, 20 min_freq: 20 max_freq: 70 accel_per_hz: 200 hz_per_sec: 1 [heater_fan Sink_fan_0] pin:L_tool:PA9 max_power: 1.0 kick_start_time: 0.5 heater: extruder heater_temp: 100 fan_speed:1.0 [extruder] sensor_type: MAX31855 sensor_pin: L_tool:PA15 spi_software_sclk_pin:L_tool:PB3 spi_software_mosi_pin:L_tool:PB5 spi_software_miso_pin:L_tool:PB4 [verify_heater extruder] max_error: 5 check_gain_time:30 hysteresis: 25 heating_gain: 2 [extruder] step_pin: L_tool:PB1 dir_pin: !L_tool:PB2 enable_pin: !L_tool:PB0 microsteps: 16 full_steps_per_rotation: 200 rotation_distance:23.5619445 gear_ratio: 2.53:1 nozzle_diameter: 0.400 filament_diameter: 1.750 max_extrude_only_distance: 500.0 max_extrude_only_velocity: 60.0 max_extrude_only_accel: 1000.0 max_extrude_cross_section:5 heater_pin: L_tool:PA8 max_power: 1.0 min_temp: 0 max_temp: 450 min_extrude_temp: 150 pressure_advance: 0.032 pressure_advance_smooth_time:0.040 # control = pid # pid_kp = 39.960 # pid_ki = 2.537 # pid_kd = 157.344 [tmc2209 extruder] uart_pin:L_tool:PB7 interpolate: False run_current: 0.6 sense_resistor: 0.110 stealthchop_threshold: 0 [probe] pin: ^!L_tool:PA1 x_offset: 34.6 y_offset: 17.4 # z_offset: 0 speed: 10.0 samples: 3 samples_result: median sample_retract_dist: 2.0 samples_tolerance: 0.05 samples_tolerance_retries: 3 deactivate_on_each_sample: False activate_gcode: PROBE_SERVO_OPEN deactivate_gcode: PROBE_SERVO_CLOSE [servo probe_servo] pin:L_tool:PA5 maximum_servo_angle: 180 minimum_pulse_width: 0.000900 maximum_pulse_width: 0.002100 initial_angle: 165 steps_decomposed: 60 signal_duration: 0.1 # initial_pulse_width: [input_shaper] #shaper_freq_x: 0 #shaper_freq_y: 0 shaper_type: mzv #shaper_type_x: #shaper_type_y: damping_ratio_x: 0.1 damping_ratio_y: 0.1 # F072 Right nozzle ID [mcu R_tool] canbus_uuid: 000000000002 canbus_interface: can0 [heater_fan Sink_fan_1] pin:R_tool:PA9 max_power: 1.0 kick_start_time: 0.5 heater: extruder1 heater_temp: 100 fan_speed: 1 [extruder1] sensor_type: MAX31855 sensor_pin: R_tool:PA15 spi_software_sclk_pin:R_tool:PB3 spi_software_mosi_pin:R_tool:PB5 spi_software_miso_pin:R_tool:PB4 [verify_heater extruder1] max_error: 5 check_gain_time:30 hysteresis: 25 heating_gain: 2 [extruder1] step_pin: R_tool:PB1 dir_pin: R_tool:PB2 enable_pin: !R_tool:PB0 microsteps: 16 full_steps_per_rotation: 200 rotation_distance:23.5619445 gear_ratio: 2.53:1 nozzle_diameter: 0.400 filament_diameter: 1.750 max_extrude_only_distance: 500.0 max_extrude_only_velocity: 60.0 max_extrude_only_accel: 1000.0 max_extrude_cross_section:5 heater_pin: R_tool:PA8 max_power: 1.0 min_temp: 0 max_temp: 450 min_extrude_temp: 150 pressure_advance: 0.032 pressure_advance_smooth_time:0.040 # control = pid # pid_kp = 39.960 # pid_ki = 2.537 # pid_kd = 157.344 [tmc2209 extruder1] uart_pin:R_tool:PB7 interpolate: False run_current: 0.6 sense_resistor: 0.110 stealthchop_threshold: 0 [safe_z_home] home_xy_position:200,150 speed:150 z_hop:5 [gcode_macro ENABLE_MOTOR] gcode: SET_STEPPER_ENABLE STEPPER=stepper_x ENABLE=1 SET_STEPPER_ENABLE STEPPER=stepper_y ENABLE=1 SET_STEPPER_ENABLE STEPPER=stepper_z ENABLE=1 SET_KINEMATIC_POSITION X=200 Y=150 Z=0 [gcode_macro _RESTORE_DEFAULT_EXTRUDER] gcode: SET_GCODE_OFFSET Z=0 SET_GCODE_OFFSET Y=0 SET_GCODE_OFFSET X=0 SYNC_EXTRUDER_MOTION EXTRUDER=extruder1 MOTION_QUEUE=extruder1 ACTIVATE_EXTRUDER EXTRUDER=extruder SET_DUAL_CARRIAGE CARRIAGE=0 [gcode_macro _PARK_extruder] gcode: ACTIVATE_EXTRUDER EXTRUDER=extruder SET_DUAL_CARRIAGE CARRIAGE=0 SAVE_GCODE_STATE NAME=park_extruder G90 G1 X-20 F6000 RESTORE_GCODE_STATE NAME=park_extruder [gcode_macro T0] gcode: {% set filament_insert = printer["filament_switch_sensor extruder"].filament_detected|default(False) %} {% set printing = printer.print_stats.state == "printing" %} {% if filament_insert or printing == False %} {% if "x" not in printer.toolhead.homed_axes %} G28 X {% set x_home = true %} {% endif %} {% if printer.toolhead.extruder != 'extruder' or x_home %} _PARK_{printer.toolhead.extruder} ACTIVATE_EXTRUDER EXTRUDER=extruder SET_DUAL_CARRIAGE CARRIAGE=0 {% if "z" in printer.toolhead.homed_axes | lower %} SET_GCODE_OFFSET Z=0 MOVE=1 {% else %} SET_GCODE_OFFSET Z=0 {% endif %} SET_GCODE_OFFSET Y=0 SET_GCODE_OFFSET X=0 SAVE_GCODE_STATE NAME=park0 G90 G1 X0 F6000 RESTORE_GCODE_STATE NAME=park0 {% endif %} {% else %} PAUSE SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=change_runout VALUE='"T0"' RESPOND TYPE=error MSG='{"Noting! Left extruder filament has been run out."}' {% endif %} [gcode_macro _PARK_extruder1] variable_x_offset: 0 gcode: ACTIVATE_EXTRUDER EXTRUDER=extruder1 SET_DUAL_CARRIAGE CARRIAGE=1 SAVE_GCODE_STATE NAME=park_extruder1 G90 G1 X{475 - (x_offset if x_offset >= 0 else 0)} F6000 G91 G1 X{0 if x_offset >= 0 else -x_offset} F6000 RESTORE_GCODE_STATE NAME=park_extruder1 [gcode_macro T1] gcode: {% set svv = printer.save_variables.variables %} {% set x_offset = svv.nozzle_x_offset_val|default(0)|float %} {% set y_offset = svv.nozzle_y_offset_val|default(0)|float %} {% set z_offset = svv.nozzle_z_offset_val|default(0)|float %} {% set filament_insert = printer["filament_switch_sensor extruder1"].filament_detected|default(False) %} {% set printing = (printer.print_stats.state == "printing") %} {% if filament_insert or printing == False %} {% if "x" not in printer.toolhead.homed_axes %} G28 X {% set x_home = true %} {% endif %} {% if printer.toolhead.extruder != 'extruder1' or x_home %} _PARK_{printer.toolhead.extruder} ACTIVATE_EXTRUDER EXTRUDER=extruder1 SET_DUAL_CARRIAGE CARRIAGE=1 SAVE_GCODE_STATE NAME=park1 G90 G1 X{455-x_offset} F6000 SET_GCODE_VARIABLE MACRO=_PARK_extruder1 VARIABLE=x_offset VALUE="{x_offset}" RESTORE_GCODE_STATE NAME=park1 {% if "z" in printer.toolhead.homed_axes | lower %} SET_GCODE_OFFSET Z={z_offset} MOVE=1 {% else %} SET_GCODE_OFFSET Z={z_offset} {% endif %} SET_GCODE_OFFSET Y={y_offset} SET_GCODE_OFFSET X={x_offset} {% endif %} {% else %} PAUSE SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=change_runout VALUE='"T1"' RESPOND TYPE=error MSG='{"Noting! Right extruder filament has been run out."}' {% endif %} [gcode_macro ACTIVATE_COPY_MODE] gcode: _SET_DUAL_MODE MODE="copy" [gcode_macro ACTIVATE_MIRROR_MODE] gcode: _SET_DUAL_MODE MODE="mirror" [gcode_macro _ACTIVATE_PRIMARY_MODE] gcode: _SET_DUAL_MODE MODE="primary" [gcode_macro _SET_DUAL_MODE] variable_dual_mode: "primary" gcode: {% set mode = params.MODE|default("primary") %} {% if 'xyz' in printer.toolhead.homed_axes %} {% if mode == "copy" or mode == "mirror"%} G90 SET_DUAL_CARRIAGE CARRIAGE=0 MODE=PRIMARY G1 X0 F6000 ACTIVATE_EXTRUDER EXTRUDER=extruder SET_DUAL_CARRIAGE CARRIAGE=1 MODE=PRIMARY {% endif %} {% if mode == "copy" %} G1 X227.5 F6000 SET_DUAL_CARRIAGE CARRIAGE=1 MODE=COPY SYNC_EXTRUDER_MOTION EXTRUDER=extruder1 MOTION_QUEUE=extruder {% elif mode == "mirror" %} G1 X455 F6000 SET_DUAL_CARRIAGE CARRIAGE=1 MODE=MIRROR SYNC_EXTRUDER_MOTION EXTRUDER=extruder1 MOTION_QUEUE=extruder {% elif mode == "primary" %} SYNC_EXTRUDER_MOTION EXTRUDER=extruder1 MOTION_QUEUE=extruder1 ACTIVATE_EXTRUDER EXTRUDER=extruder SET_DUAL_CARRIAGE CARRIAGE=0 {% endif %} _RUNOUT_HANDLE {% endif %} SET_GCODE_VARIABLE MACRO=_SET_DUAL_MODE VARIABLE=dual_mode VALUE='"{mode}"' [gcode_macro PROBE_SERVO_OPEN] gcode: SET_SERVO SERVO=probe_servo angle=45 G4 P2000 [gcode_macro PROBE_SERVO_CLOSE] gcode: G4 P500 SET_SERVO SERVO=probe_servo angle=165 [gcode_macro _START_PRINT_BASE] description: Call when starting to print gcode: _CLEAR_LAST_FILE _RUNOUT_HANDLE [gcode_macro _CANCEL_PRINT_BASE] description: Call when cancelled to print gcode: _ACTIVATE_PRIMARY_MODE [gcode_macro START_PRINT] gcode: {% set BED_TEMP = params.BED|default(0)|float %} {% set EXTRUDER_TEMP = params.EXTRUDER|default(0)|float %} {% set EXTRUDER_TEMP1 = params.EXTRUDER1|default(0)|float %} {% set CHAMBER_TEMP = params.CHAMBER|default(0)|float %} {% if params.BED is defined %} M140 S{BED_TEMP} {% endif %} {% if params.EXTRUDER is defined %} M104 T0 S{EXTRUDER_TEMP} {% endif %} {% if params.EXTRUDER1 is defined %} M104 T1 S{EXTRUDER_TEMP1} {% endif %} {% if params.CHAMBER is defined %} M141 S{CHAMBER_TEMP} {% endif %} G28 _START_PRINT_BED_MESH {% if BED_TEMP != 0 %} M190 S{BED_TEMP} {% endif %} {% if EXTRUDER_TEMP != 0 %} M109 T0 S{EXTRUDER_TEMP} {% endif %} {% if EXTRUDER_TEMP1 != 0 %} M109 T1 S{EXTRUDER_TEMP1} {% endif %} {% if CHAMBER_TEMP != 0 %} M191 S{CHAMBER_TEMP} {% endif %} G92 E0 M117 Printing start... [gcode_macro PRINT_START] gcode: START_PRINT [gcode_macro END_PRINT] gcode: {% set svv = printer.save_variables.variables %} {% set y_offset = svv.nozzle_y_offset_val|default(0)|float %} M400 G92 E0 G1 E-10.0 F3600 G91 {% if printer["dual_carriage"] is defined %} {% set dual_mode = printer['gcode_macro _SET_DUAL_MODE'].dual_mode|default("primary") %} {% if dual_mode == "copy" or dual_mode == "mirror" %} G0 Z1.00 F6000 _ACTIVATE_PRIMARY_MODE G90 _PARK_extruder _PARK_extruder1 G91 {% endif %} {% else %} G0 Z1.00 X20.0 Y20.0 F6000 {% endif %} TURN_OFF_HEATERS M107 G1 Z2 F3000 G90 G0 Y{300-(y_offset if printer.toolhead.extruder == 'extruder1' else 0)} F3600 # BED_MESH_CLEAR [gcode_macro PRINT_END] gcode: END_PRINT [gcode_macro SET_LED] rename_existing: LED_SET gcode: {% set led_name = params.LED %} {% set red = params.RED|default(0)|float %} {% set green = params.GREEN|default(0)|float %} {% set blue = params.BLUE|default(0)|float %} {% set white = params.WHITE|default(0)|float %} {% set index = params.INDEX|default(0)|float %} {% set transmit = params.TRANSMIT|default(0)|int %} {% set sync = params.SYNC|default(0)|int %} {% if led_name == "Interior_lighting" %} {% if white != 0 %} {% set white = 1 %} {% endif %} SAVE_VARIABLE VARIABLE=interior_lighting VALUE={white} {% endif %} {% if index == 0 %} LED_SET LED={led_name} RED={red} GREEN={green} BLUE={blue} WHITE={white} TRANSMIT={transmit} SYNC={sync} {% else %} LED_SET LED={led_name} RED={red} GREEN={green} BLUE={blue} WHITE={white} INDEX={index} TRANSMIT={transmit} SYNC={sync} {% endif %} [led_effect runstate] leds: neopixel:_Status_light autostart: true frame_rate: 24 hot: extruder extruder1 heater_bed chamber layers: status 0 0 top (0.3, 0.3, 0.3),( 0, 0, 0.3),(0, 0.3, 0) [gcode_macro LOAD_FILAMENT] variable_load_distance: 90 variable_purge_distance: 20 gcode: {% set speed = params.SPEED|default(200) %} {% set max_velocity = printer.configfile.settings['extruder'].max_extrude_only_velocity * 20 %} SAVE_GCODE_STATE NAME=load_state G91 G92 E0 G1 E{load_distance} F{max_velocity} # fast-load G1 E{purge_distance} F{speed} # purge RESTORE_GCODE_STATE NAME=load_state [gcode_macro UNLOAD_FILAMENT] variable_unload_distance: 90 variable_purge_distance: 20 gcode: {% set speed = params.SPEED|default(200) %} {% set max_velocity = printer.configfile.settings['extruder'].max_extrude_only_velocity * 20 %} SAVE_GCODE_STATE NAME=unload_state G91 G92 E0 G1 E{purge_distance} F{speed} # purge G1 E-{unload_distance} F{max_velocity} # fast-unload RESTORE_GCODE_STATE NAME=unload_state [gcode_macro G28] rename_existing: C28 gcode: {% set homing_cmd = ''%} {% set save_dual_mode = printer['gcode_macro _SET_DUAL_MODE'].dual_mode|default("primary") %} {% set do_x = 'X' in params|string %} {% set do_y = 'Y' in params|string %} {% set do_z = 'Z' in params|string %} {% if save_dual_mode == "copy" or save_dual_mode == "mirror" %} _SET_DUAL_MODE MODE="primary" {% endif %} {% if do_x %} {% set homing_cmd = 'X ' %} {% endif %} {% if do_y %} SET_STEPPER_ENABLE STEPPER=stepper_y ENABLE=1 {% set homing_cmd = homing_cmd + 'Y ' %} {% endif %} {% if do_z %} {% if 'x' not in printer.toolhead.homed_axes|lower or 'y' not in printer.toolhead.homed_axes|lower %} {% set homing_cmd = 'X Y Z' %} {% else %} {% set homing_cmd = homing_cmd + 'Z' %} {% endif %} {% endif %} {% if not homing_cmd %} SET_STEPPER_ENABLE STEPPER=stepper_y ENABLE=1 C28 _RESTORE_DEFAULT_EXTRUDER {% else %} C28 {homing_cmd} {% if 'X' in homing_cmd %} _RESTORE_DEFAULT_EXTRUDER {% endif %} {% endif %} {% if save_dual_mode == "copy" or save_dual_mode == "mirror" %} _SET_DUAL_MODE MODE={save_dual_mode} {% endif %} [gcode_macro M109] rename_existing: C109 gcode: {% set hotend = printer.toolhead.extruder %} {% set s = params.S|default(0)|float %} {% set t = params.T|default(0)|int %} {% if params.S is defined %} {% if params.T is defined %} {% set hotend = "extruder" ~ (t if t != 0 else '') %} {% endif %} SET_HEATER_TEMPERATURE HEATER={hotend} TARGET={s} {% if s != 0 %} TEMPERATURE_WAIT SENSOR={hotend} MINIMUM={s-3} MAXIMUM={s+3} {% endif %} {% endif %} [gcode_macro M141] gcode: {% set s = params.S|default(0)|float %} {% if params.S is defined %} SET_HEATER_TEMPERATURE HEATER=chamber target={s|int} {% endif %} [gcode_macro M190] rename_existing: C190 gcode: {% set s = params.S|default(0)|float %} {% if params.S is defined %} SET_HEATER_TEMPERATURE HEATER="heater_bed" TARGET={s} {% if s != 0 %} TEMPERATURE_WAIT SENSOR="heater_bed" MINIMUM={s-3} MAXIMUM={s+3} {% endif %} {% endif %} [gcode_macro M191] gcode: {% set s = params.S|default(0)|float %} {% if params.S is defined %} M141 S{s} {% if s != 0 %} TEMPERATURE_WAIT SENSOR="heater_generic chamber" MINIMUM={s-3} MAXIMUM={s+3} {% endif %} {% endif %} [gcode_macro M84] rename_existing: C84 gcode: C84 SET_STEPPER_ENABLE STEPPER=stepper_z enable=1 _RESTORE_DEFAULT_EXTRUDER ######################################## # CANCEL_PRINT/PAUSE/RESUME/ ######################################## [gcode_macro _CLIENT_VARIABLE] variable_use_custom_pos : True variable_custom_park_x : 180.0 variable_custom_park_y : 250.0 variable_custom_park_dz : 20.0 variable_retract : 2.0 variable_cancel_retract : 10.0 variable_speed_retract : 60.0 variable_unretract : 20.0 variable_speed_unretract : 6.0 variable_speed_hop : 5.0 variable_speed_move : 100.0 variable_park_at_cancel : False variable_park_at_cancel_x : None variable_park_at_cancel_y : None variable_use_fw_retract : False variable_idle_timeout : 600 variable_runout_sensor : "" variable_filament_sensor : "filament_switch_sensor extruder" variable_filament_sensor1 : "filament_switch_sensor extruder1" variable_user_temp_macro : "_USER_TEMP_RESUME" variable_user_pause_macro : "_USER_PAUSE" variable_user_resume_macro: "" variable_user_cancel_macro: "_USER_CANCEL" gcode: # Nothing [gcode_macro _USER_PAUSE] gcode: {% set extruderTools = [('extruder', 'last_extruder_temp'), ('extruder1', 'last_extruder1_temp')] %} {% set act = printer.gcode_move.gcode_position %} SAVE_VARIABLE VARIABLE=power_resume_z VALUE={act.z} {% for extruder_name, name in extruderTools %} {% set temp = printer[extruder_name].target if extruder_name in printer else 0 %} {% set restore = False if printer[extruder_name] == '' else True if params.RESTORE|default(1)|int == 1 else False %} SET_GCODE_VARIABLE MACRO=RESUME VARIABLE={name} VALUE="{{'restore': restore, 'temp': temp}}" {% endfor %} {% if printer["dual_carriage"] is defined %} {% set current_idex_mode = printer["dual_carriage"].carriage_1|lower %} {% if current_idex_mode == 'copy' or current_idex_mode == 'mirror' %} SAVE_DUAL_CARRIAGE_STATE SYNC_EXTRUDER_MOTION EXTRUDER=extruder1 MOTION_QUEUE=extruder1 SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=resume_dual VALUE=True {% endif %} {% endif %} SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=resume_extruder VALUE="'{printer.toolhead.extruder}'" [gcode_macro _USER_TEMP_RESUME] gcode: {% set extruder_info = [ {'index': 0, 'name': 'last_extruder_temp'}, {'index': 1, 'name': 'last_extruder1_temp'}] %} {% set temperature = "last_extruder_temp" if printer.toolhead.extruder == "extruder" else "last_extruder1_temp" %} {% set value = printer["gcode_macro RESUME"][temperature].temp %} {% for info in extruder_info %} {% set variable = printer["gcode_macro RESUME"][info.name] %} {% if variable.restore %} M104 T{ info.index } S{ variable.temp } {% endif %} {% endfor %} {% for info in extruder_info %} {% set variable = printer["gcode_macro RESUME"][info.name] %} {% if variable.restore %} {% set tool = "extruder" if info.index == 0 else "extruder1" %} {% set needwait = True if printer[tool].temperature < variable.temp else False %} {% if needwait %} RESPOND TYPE=echo MSG='{"Restoring activated extruder temperature, this may take some time."}' M109 T{info.index} S{variable.temp} {% endif %} {% endif %} {% endfor %} [gcode_macro _RESUME_EXTRUDER] gcode: {% set client = printer['gcode_macro RESUME']|default({}) %} {% set autoshift_on = params.AUTOSHIFT|default(False)|lower %} {% set toolchange = client.change_runout|lower|default("") %} {% set extruder_filament = client.filament_state.extruder %} {% set extruder1_filament = client.filament_state.extruder1 %} {% set resume_extruder = client.resume_extruder|default("extruder") %} {% if autoshift_on == 'true' %} {% if extruder_filament and extruder1_filament %} {% if toolchange == "t0" %} {% set resume_extruder = "extruder" %} {% elif toolchange == "t1" %} {% set resume_extruder = "extruder1" %} {% endif %} {% else %} {% if extruder_filament %} {% set resume_extruder = "extruder" %} {% elif extruder1_filament %} {% set resume_extruder = "extruder1" %} {% endif %} {% endif %} {% endif %} {% if printer.toolhead.extruder != resume_extruder %} T{0 if resume_extruder|default("extruder") == "extruder" else 1 } {% endif %} _FILAMENT_UPDATE [gcode_macro _EXTRUDER_TEMPERATURE_HANDLE] gcode: {% set client = printer['gcode_macro RESUME']|default({}) %} {% set last_extruder_temp = client.last_extruder_temp %} {% set last_extruder1_temp = client.last_extruder1_temp %} {% set resume_extruder = client.resume_extruder|lower %} {% if resume_extruder != printer.toolhead.extruder %} SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=last_extruder_temp VALUE="{ last_extruder1_temp }" SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=last_extruder1_temp VALUE="{ last_extruder_temp }" {% endif %} [gcode_macro _USER_CANCEL] gcode: {% if 'z' in printer.toolhead.homed_axes %} G91 G1 Z30 F600 ; lift nozzle {% endif %} M84 [gcode_macro _CLIENT_EXTRUDE] description: Extrudes, if the extruder is hot enough gcode: ##### get user parameters or use default ##### {% set client = printer['gcode_macro _CLIENT_VARIABLE']|default({}) %} {% set use_fw_retract = (client.use_fw_retract|default(false)|lower == 'true') and (printer.firmware_retraction is defined) %} {% set length = params.LENGTH|default(client.unretract)|default(1.0)|float %} {% set speed = params.SPEED|default(client.speed_unretract)|default(35) %} {% set absolute_extrude = printer.gcode_move.absolute_extrude %} ##### end of definitions ##### {% if printer.toolhead.extruder != '' %} {% if printer[printer.toolhead.extruder].can_extrude %} {% if use_fw_retract %} {% if length < 0 %} G10 {% else %} G11 {% endif %} {% else %} M83 G1 E{length} F{(speed|float|abs) * 60} {% if absolute_extrude %} M82 {% endif %} {% endif %} {% endif %} {% endif %} [gcode_macro _REAPPLY_OFFSET] gcode: {% set re_extruder = printer['gcode_macro RESUME'].resume_extruder|default("extruder") %} {% set svv = printer.save_variables.variables %} {% set x_offset = svv.nozzle_x_offset_val|default(0)|float %} {% set y_offset = svv.nozzle_y_offset_val|default(0)|float %} {% set z_offset = svv.nozzle_z_offset_val|default(0)|float %} {% set is_extruder = printer.toolhead.extruder == "extruder" %} {% if printer.toolhead.extruder!= re_extruder %} SET_GCODE_OFFSET Z={0 if is_extruder else z_offset} MOVE=1 SET_GCODE_OFFSET Y={0 if is_extruder else y_offset} SET_GCODE_OFFSET X={0 if is_extruder else x_offset} {% endif %} [gcode_macro RESUME] description: Resume the actual running print rename_existing: RESUME_BASE variable_last_extruder_temp: {'restore': False, 'temp': 0} variable_last_extruder1_temp: {'restore': False, 'temp': 0} variable_restore_idle_timeout: 0 variable_idle_state: False variable_resume_dual: False variable_filament_state: "" variable_change_runout: "" variable_resume_extruder: "" gcode: ##### get user parameters or use default ##### {% set autoshift = printer.save_variables.variables.auto_change_nozzle|default(False) %} {% set client = printer['gcode_macro _CLIENT_VARIABLE']|default({}) %} {% set do_resume = False %} {% set runout = True %} ##### end of definitions ##### _FILAMENT_UPDATE {% if resume_dual %} RESTORE_DUAL_CARRIAGE_STATE ACTIVATE_EXTRUDER EXTRUDER=extruder SYNC_EXTRUDER_MOTION EXTRUDER=extruder1 MOTION_QUEUE=extruder SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=resume_dual VALUE=False {% else %} _RESUME_EXTRUDER AUTOSHIFT={autoshift} {% endif %} _EXTRUDER_TEMPERATURE_HANDLE {% set can_extrude = True if printer.toolhead.extruder == '' # no extruder defined in config else printer[printer.toolhead.extruder].can_extrude %} # status of active extruder #### Printer comming from timeout idle state #### {% if printer.idle_timeout.state|upper == "IDLE" or idle_state %} SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=idle_state VALUE=False {% endif %} {% if last_extruder_temp.restore or last_extruder1_temp.restore %} {client.user_temp_macro|default("")} {% set do_resume = True %} {% elif can_extrude %} {% set do_resume = True %} {% endif %} _ACT_RESUME DO_RESUME={do_resume} [gcode_macro _ACT_RESUME] gcode: ##### get user parameters or use default ##### {% set client = printer['gcode_macro _CLIENT_VARIABLE']|default({}) %} {% set velocity = printer.configfile.settings.pause_resume.recover_velocity %} {% set auto_extruder = params.AUTO|default(False) %} {% set sp_move = client.speed_move|default(velocity) %} {% set do_resume = true if params.DO_RESUME|default(False)|lower == 'true' else false %} {% set filament_state = printer['gcode_macro RESUME'].filament_state.runout|default(False) %} {% set restore_idle_timeout = printer['gcode_macro RESUME'].restore_idle_timeout|default(0) %} {% set prompt_txt = [] %} {% if filament_state %} {% if do_resume or auto_extruder %} {% if restore_idle_timeout > 0 %} SET_IDLE_TIMEOUT TIMEOUT={restore_idle_timeout} {% endif %} # restore idle_timeout time {client.user_resume_macro|default("")} _CLIENT_EXTRUDE RESUME_BASE VELOCITY={params.VELOCITY|default(sp_move)} _REAPPLY_OFFSET SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=change_runout VALUE="None" {% else %} {% set msg = "Left" if printer.toolhead.extruder == "extruder" else "Right" %} {% set _d = prompt_txt.append("%s extruder not hot enough, will reheat and continue." % msg) %} {% endif %} {% else %} {% set msg = "Left" if printer.toolhead.extruder == "extruder" else "Right" %} {% set _d = prompt_txt.append("%s extruder detects no filament, please load filament and continue." % msg) %} {% endif %} ##### Generate User Information box in case of abort ##### {% if not (filament_state and do_resume) %} RESPOND TYPE=command MSG="action:prompt_begin RESUME ABORTED !" {% for element in prompt_txt %} RESPOND TYPE=command MSG='{"action:prompt_text %s" % element}' {% endfor %} RESPOND TYPE=command MSG="action:prompt_footer_button Ok|RESPOND TYPE=command MSG=action:prompt_end|info" RESPOND TYPE=command MSG="action:prompt_show" {% endif %} ######################################## # filament_runout ######################################## [gcode_macro _FILAMENT_UPDATE] gcode: {% set client = printer['gcode_macro _CLIENT_VARIABLE']|default({}) %} {% set runout_resume = True if client.filament_sensor|default("") == "" # no runout else True if not printer[client.filament_sensor].enabled # sensor is disabled else printer[client.filament_sensor].filament_detected %} # sensor status {% set runout_resume1 = True if client.filament_sensor1|default("") == "" # no runout else True if not printer[client.filament_sensor1].enabled # sensor1 is disabled else printer[client.filament_sensor1].filament_detected %} # sensor1 status ##### filament check ##### {% if printer["dual_carriage"] is not defined %} {% set runout = runout_resume if printer.toolhead.extruder == "extruder" else runout_resume1 %} {% else %} {% set current_idex_mode = printer["dual_carriage"].carriage_1|lower %} {% if current_idex_mode == 'copy' or current_idex_mode == 'mirror' %} {% set runout = True if (runout_resume and runout_resume1) else false %} {% else %} {% set runout = runout_resume if printer.toolhead.extruder == "extruder" else runout_resume1 %} {% endif %} {% endif %} SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=filament_state VALUE="{{'runout': runout, 'extruder': runout_resume, 'extruder1': runout_resume1}}" [gcode_macro _RUNOUT_HANDLE] description: filament state update gcode: _FILAMENT_UPDATE {% if printer.print_stats.state == "printing" %} _RUNOUT_PAUSE {% endif %} [gcode_macro _RUNOUT_PAUSE] gcode: {% set svv = printer.save_variables.variables %} {% set autoshift_extruder = svv.auto_change_nozzle|default(False) %} {% set filament_state = printer['gcode_macro RESUME'].filament_state.runout|default(False) %} {% set extruder_runout = printer['gcode_macro RESUME'].filament_state.extruder|default(False) %} {% set target_extruder = "extruder1" if printer.toolhead.extruder == "extruder" else "extruder" %} {% set idex = False %} {% if printer["dual_carriage"] is defined %} {% set current_idex_mode = printer["dual_carriage"].carriage_1|lower %} {% if current_idex_mode == 'copy' or current_idex_mode == 'mirror' %} {% set idex = True %} {% endif %} {% endif %} {% if not filament_state %} PAUSE {% if autoshift_extruder and idex == False %} {% if printer["gcode_macro RESUME"].filament_state[target_extruder] %} RESUME {% else %} RESPOND TYPE=error MSG='{"Noting! All extruders filament has been run out."}' {% endif %} {% else %} {% set msg = "Right" if extruder_runout else "Left" %} RESPOND TYPE=error MSG='{"Noting! %s extruder filament has been run out." % msg}' {% endif %} {% endif %} ######################################## # power loss recovery ######################################## [delayed_gcode _CHECK_POWER_LOSS_RECOVERY] initial_duration: 1 gcode: {% set was_interrupted = printer.save_variables.variables.was_interrupted | default(False) | string %} {% set enable_recovery = printer.save_variables.variables.power_loss_recovery | default(Ture) | string %} {% if enable_recovery != "False" and was_interrupted == "True" %} RESPOND TYPE=command MSG="action:prompt_begin " RESPOND TYPE=command MSG="action:prompt_text The last print job was not completed continue printing?" RESPOND TYPE=command MSG="action:prompt_footer_button Continue|_RESUME_INTERRUPTED" RESPOND TYPE=command MSG="action:prompt_footer_button Cancel|_ABORT_INTERRUPTED|error" RESPOND TYPE=command MSG="action:prompt_show" {% endif %} [gcode_shell_command _CLEAR_PLR] command: sh /home/klipper/klipper/scripts/clear_plr.sh timeout: 5. verbose: False [gcode_macro _CLEAR_LAST_FILE] gcode: {% set filename = '' %} {% set filepath = '' %} RUN_SHELL_COMMAND CMD=_CLEAR_PLR SAVE_VARIABLE VARIABLE=last_file VALUE='"{ filename }"' SAVE_VARIABLE VARIABLE=filepath VALUE='"{ filepath }"' {% set zero_vars = ['power_resume_x', 'power_resume_y', 'power_resume_z'] %} {% for var in zero_vars %} SAVE_VARIABLE VARIABLE={var} VALUE=0 {% endfor %} SAVE_VARIABLE VARIABLE=was_interrupted VALUE=False [gcode_shell_command _POWER_LOSS_RECOVERY] command: /home/klipper/klipper/scripts/plr.sh timeout: 420. verbose: False [gcode_macro _RESUME_INTERRUPTED] gcode: {% set sv = printer.save_variables.variables %} {% set client = printer['gcode_macro _CLIENT_VARIABLE']|default({}) %} {% set park_dz = client.custom_park_dz|default(2.0)|abs %} RESPOND TYPE=command MSG="action:prompt_end" SET_GCODE_OFFSET Z=0 MOVE=0 {% set z_height = params.Z_HEIGHT|default(sv.power_resume_z)|float %} {% set is_paused = sv.power_loss_paused|default(False) %} {% set last_file = params.GCODE_FILE|default(sv.last_file)|string %} {% set hotend = sv.power_resume_extruder|default("extruder")%} {% set z_offset = sv.nozzle_z_offset_val|default(0)|float %} {% set z_offset_total = park_dz if is_paused else 0 %} {% if hotend == "extruder1" %} {% set z_offset_total = z_offset_total + z_offset %} {% endif %} SET_STEPPER_ENABLE STEPPER=stepper_z ENABLE=1 G4 P300 M118 Recovery in progress, please wait RUN_SHELL_COMMAND CMD=_POWER_LOSS_RECOVERY PARAMS="{z_height} \"{last_file}\" \"{z_offset_total}\"" SDCARD_PRINT_FILE FILENAME=.plr/"{last_file}" SAVE_VARIABLE VARIABLE=was_interrupted VALUE=False [gcode_macro _ABORT_INTERRUPTED] gcode: RESPOND TYPE=command MSG="action:prompt_end" _CLEAR_LAST_FILE ######################################## # Adaptive mesh ######################################## [gcode_macro Adaptive_Mesh] description: This macro contains all adjustable settings for KAMP variable_verbose_enable: True # Set to True to enable KAMP information output when running. This is useful for debugging. variable_mesh_margin: 5 # Expands the mesh size in millimeters if desired. Leave at 0 to disable. variable_fuzz_amount: 0 # Slightly randomizes mesh points to spread out wear from nozzle-based probes. Leave at 0 to disable. gcode: # Gcode section left intentionally blank. Do not disturb. # Noting [gcode_macro _START_PRINT_BED_MESH] gcode: {% set idex_mode = False %} {% set profiles = printer["bed_mesh"].profiles %} {% set svv = printer.save_variables.variables %} {% set adaptive_mesh = svv.adaptive_meshing|default(false)|lower %} {% if printer["dual_carriage"] is defined %} {% set current_idex_mode = printer['gcode_macro _SET_DUAL_MODE'].dual_mode|default("primary") %} {% if current_idex_mode == "copy" or current_idex_mode == "mirror" %} {% set idex_mode = True %} {% endif %} {% endif %} {% if adaptive_mesh|lower == 'true' %} {% if printer.exclude_object.objects != [] %} {% if idex_mode %} BED_MESH_CLEAR {% else %} BED_MESH_CALIBRATE PROFILE=adaptive {% endif %} {% else %} {% if idex_mode %} BED_MESH_CLEAR {% else %} {% if 'default' in profiles %} BED_MESH_PROFILE LOAD=default {% else %} BED_MESH_CALIBRATE PROFILE=default BED_MESH_PROFILE SAVE=default {% endif %} {% endif %} {% endif %} {% endif %} [gcode_macro BED_MESH_CALIBRATE] rename_existing: _BED_MESH_CALIBRATE gcode: {% set all_points = printer.exclude_object.objects | map(attribute='polygon') | sum(start=[]) %} # Gather all object points {% set bed_mesh_min = printer.configfile.settings.bed_mesh.mesh_min %} # Get bed mesh min from printer.cfg {% set bed_mesh_max = printer.configfile.settings.bed_mesh.mesh_max %} # Get bed mesh max from printer.cfg {% set probe_count = printer.configfile.settings.bed_mesh.probe_count %} # Get probe count from printer.cfg {% set kamp_settings = printer["gcode_macro Adaptive_Mesh"] %} # Pull variables from _KAMP_Settings {% set verbose_enable = kamp_settings.verbose_enable | abs %} # Pull verbose setting from _KAMP_Settings {% set mesh_margin = kamp_settings.mesh_margin | float %} # Pull mesh margin setting from _KAMP_Settings {% set fuzz_amount = kamp_settings.fuzz_amount | float %} # Pull fuzz amount setting from _KAMP_Settings {% set default_profile = params.PROFILE | default("default") %} # get default mesh profile {% set probe_count = probe_count if probe_count|length > 1 else probe_count * 2 %} # If probe count is only a single number, convert it to 2. E.g. probe_count:7 = 7,7 {% set max_probe_point_distance_x = ( bed_mesh_max[0] - bed_mesh_min[0] ) / (probe_count[0] - 1) %} # Determine max probe point distance {% set max_probe_point_distance_y = ( bed_mesh_max[1] - bed_mesh_min[1] ) / (probe_count[1] - 1) %} # Determine max probe point distance {% set x_min = all_points | map(attribute=0) | min | default(bed_mesh_min[0]) %} # Set x_min from smallest object x point {% set y_min = all_points | map(attribute=1) | min | default(bed_mesh_min[1]) %} # Set y_min from smallest object y point {% set x_max = all_points | map(attribute=0) | max | default(bed_mesh_max[0]) %} # Set x_max from largest object x point {% set y_max = all_points | map(attribute=1) | max | default(bed_mesh_max[1]) %} # Set y_max from largest object y point {% set fuzz_range = range((0) | int, (fuzz_amount * 100) | int + 1) %} # Set fuzz_range between 0 and fuzz_amount {% set adapted_x_min = x_min - mesh_margin - (fuzz_range | random / 100.0) %} # Adapt x_min to margin and fuzz constraints {% set adapted_y_min = y_min - mesh_margin - (fuzz_range | random / 100.0) %} # Adapt y_min to margin and fuzz constraints {% set adapted_x_max = x_max + mesh_margin + (fuzz_range | random / 100.0) %} # Adapt x_max to margin and fuzz constraints {% set adapted_y_max = y_max + mesh_margin + (fuzz_range | random / 100.0) %} # Adapt y_max to margin and fuzz constraints {% set adapted_x_min = [adapted_x_min , bed_mesh_min[0]] | max %} # Compare adjustments to defaults and choose max {% set adapted_y_min = [adapted_y_min , bed_mesh_min[1]] | max %} # Compare adjustments to defaults and choose max {% set adapted_x_max = [adapted_x_max , bed_mesh_max[0]] | min %} # Compare adjustments to defaults and choose min {% set adapted_y_max = [adapted_y_max , bed_mesh_max[1]] | min %} # Compare adjustments to defaults and choose min {% set points_x = (((adapted_x_max - adapted_x_min) / max_probe_point_distance_x) | round(method='ceil') | int) + 1 %} # Define probe_count's x point count and round up {% set points_y = (((adapted_y_max - adapted_y_min) / max_probe_point_distance_y) | round(method='ceil') | int) + 1 %} # Define probe_count's y point count and round up {% if (([points_x, points_y]|max) > 6) %} # {% set algorithm = "bicubic" %} # {% set min_points = 4 %} # {% else %} # Calculate if algorithm should be bicubic or lagrange {% set algorithm = "lagrange" %} # {% set min_points = 3 %} # {% endif %} # {% set points_x = [points_x , min_points]|max %} # Set probe_count's x points to fit the calculated algorithm {% set points_y = [points_y , min_points]|max %} # Set probe_count's y points to fit the calculated algorithm {% set points_x = [points_x , probe_count[0]]|min %} {% set points_y = [points_y , probe_count[1]]|min %} {% if verbose_enable == True %} # If verbose is enabled, print information about KAMP's calculations {% if printer.exclude_object.objects != [] %} { action_respond_info( "Algorithm: {}.".format( (algorithm), )) } { action_respond_info("Default probe count: {},{}.".format( (probe_count[0]), (probe_count[1]), )) } { action_respond_info("Adapted probe count: {},{}.".format( (points_x), (points_y), )) } {action_respond_info("Default mesh bounds: {}, {}.".format( (bed_mesh_min[0],bed_mesh_min[1]), (bed_mesh_max[0],bed_mesh_max[1]), )) } {% if mesh_margin > 0 %} {action_respond_info("Mesh margin is {}, mesh bounds extended by {}mm.".format( (mesh_margin), (mesh_margin), )) } {% else %} {action_respond_info("Mesh margin is 0, margin not increased.")} {% endif %} {% if fuzz_amount > 0 %} {action_respond_info("Mesh point fuzzing enabled, points fuzzed up to {}mm.".format( (fuzz_amount), )) } {% else %} {action_respond_info("Fuzz amount is 0, mesh points not fuzzed.")} {% endif %} { action_respond_info("Adapted mesh bounds: {}, {}.".format( (adapted_x_min, adapted_y_min), (adapted_x_max, adapted_y_max), )) } {action_respond_info("KAMP adjustments successful. Happy KAMPing!")} {% else %} {action_respond_info("No objects detected! Check your gcode and make sure that EXCLUDE_OBJECT_DEFINE is happening before BED_MESH_CALIBRATE is called. Defaulting to regular meshing.")} G4 P5000 # Wait 5 seconds to make error more visible {% endif %} {% endif %} _BED_MESH_CALIBRATE PROFILE={default_profile} mesh_min={adapted_x_min},{adapted_y_min} mesh_max={adapted_x_max},{adapted_y_max} ALGORITHM={algorithm} PROBE_COUNT={points_x},{points_y} # End of verbose BED_MESH_PROFILE LOAD={default_profile} ######################################## # Nozzle Calibrate ######################################## [gcode_shell_command fetch_assets] command: sh /home/klipper/klipper/scripts/fetch_assets.sh timeout: 5. verbose: False [gcode_macro _NOZZLE_Z_OFFSET_CALIBRATE] gcode: G28 G90 _PARK_extruder G0 Z5 SET_GCODE_OFFSET Z=0 MOVE=0 ACTIVATE_EXTRUDER EXTRUDER=extruder1 SET_DUAL_CARRIAGE CARRIAGE=1 G1 X200 F6000 [gcode_macro _NOZZLE_XY_OFFSET_CALIBRATE] gcode: RUN_SHELL_COMMAND CMD=fetch_assets PARAMS="\"Gcode\" \"F430NX\" \"NozzleAglin.zip\"" SDCARD_PRINT_FILE FILENAME=".PresetModel/NozzleAglin.gcode"