Files
klipper-macros/macros/print/print_start_end.cfg
T
mangavalkandClaude Opus 5.5 fbdb2d5e1d Show errors and warnings on the display (_ERROR, _WARN)
action_raise_error aborts while the macro renders, so an M117 in the same
macro never ran and errors such as the RESUME lane check only reached the
console. messages.cfg adds _ERROR (M117, then raise in a separate macro)
and _WARN (RESPOND TYPE=error + M117); all errors and warnings use them.
PAUSE shows AFC's error as the pause reason; RESUME, CANCEL_PRINT and
PRINT_WARMUP clear the display.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 17:41:41 +02:00

311 lines
12 KiB
INI

# Print start and end: PRINT_WARMUP, PRINT_START, PRINT_END
# Idle time (in seconds) to wait before running the above G-Code
# commands. The default is 600 seconds.
#####################################################################
# Macros
#####################################################################
# [gcode_macro PRINT_START]
# gcode:
# PRINT_WARMUP BED={params.BED} EXTRUDER={params.EXTRUDER} CHAMBER={params.CHAMBER|default("0")} TOOL={params.TOOL|default("0")}
# PRINT_START_2 EXTRUDER={params.EXTRUDER}
[gcode_macro PRINT_WARMUP]
description: Perform initial homing and heating tasks
gcode:
{% set target_bed = params.BED|int %}
{% set target_extruder = params.EXTRUDER|int %}
{% set target_chamber = params.CHAMBER|default("0")|int %}
# {% set x_wait = printer.toolhead.axis_maximum.x|float / 2 %}
# {% set y_wait = printer.toolhead.axis_maximum.y|float / 2 %}
{% set initial_tool = params.TOOL|default("0")|int %}
{% set chamber_temp = printer["temperature_sensor chamber"].temperature|float %}
RESET_FAILURE
CLEAR_PAUSE
# Clear what an earlier print or error left on the display
M117
_motion_detected
#SET_PIN PIN=caselight VALUE=1.00
UPDATE_DELAYED_GCODE ID=_delayed_motors_off DURATION=0
BED_MESH_CLEAR
SET_GCODE_OFFSET Z=0
CLEAR_PAUSE
SKEW_PROFILE LOAD=Califlower
{% set current_temp = printer.extruder.temperature %}
{% if current_temp > 150 %}
RESPOND MSG="nozzle to hot, lowering to 150"
M104 S150 ; set nozzle temp to 150
M109 S150 ; wait until nozzle reaches 150 ; wait until nozzle reaches 0
{% endif %}
_status_homing
RESPOND MSG="homing"
HOME
RESPOND MSG="homing finished"
# G0 Z2 ; position beacon at 2mm for heat soak
{% if target_bed < 60 %}
RESPOND MSG="Using PID for <60°C bed"
SET_HEATER_TEMPERATURE HEATER=heater_bed TARGET={target_bed} PID_KP=33.606 PID_KI=0.694 PID_KD=407.058
{% else %}
RESPOND MSG="Using PID for ≥60°C bed"
SET_HEATER_TEMPERATURE HEATER=heater_bed TARGET={target_bed} pid_Kp=46.843 pid_Ki=2.002 pid_Kd=274.034
{% endif %}
G1 X175 Y175 Z2 F1200
_status_heating
RESPOND MSG="heating"
{% if target_bed > 0 %}
M140 S{target_bed} ; start bed heater
M104 S150 ; set nozzle temp to 150
M109 S150 ; wait until nozzle reaches 150 ; wait until nozzle reaches 0
M190 S{target_bed} ; wait on bed temperature
{% endif %}
HOME
QUAD_GANTRY_LEVEL
BLOBIFIER_CLEAN ; call another macro to wipe nozzle if available
G1 X175 Y175 Z5 F1200
_HEAT_FOR_LOADED_LANE TOOL={initial_tool} ; unload needs the loaded filament's temperature
T{initial_tool} #PURGE_LENGTH=100 #Load Initial Tool
M104 S{target_extruder} ; set extruder to print temp
M109 S{target_extruder} ; wait for extruder temp
_NOZZLE_RETRACT LENGTH=2 ; no oozing while waiting; PRINT_START pushes it back
M104 S150 ; set nozzle temp to 150
M109 S150 ; wait until nozzle reaches 150 ; wait until nozzle reaches 0
BLOBIFIER_CLEAN ; call another macro to wipe nozzle if available
G1 X175 Y175 Z5 F1200
{% if target_chamber > 30 %}
RESPOND MSG="waiting for chamber temperature"
M141 S{target_chamber}
# M191 S{target_chamber} ; Waits until the chamber temperature reaches 60°C
# TEMPERATURE_WAIT SENSOR="temperature_sensor chamber" MINIMUM={target_chamber}
M106 S255
# HEAT_SOAK HEATER='heater_bed' TARGET={BED_TEMP} SOAKER='temperature_sensor iHeater_S' SOAK_TEMP={target_chamber} TIMEOUT=60 CANCEL='_NOTHING'
HEAT_SOAK HEATER='heater_bed' TARGET={target_bed} SOAKER='temperature_sensor chamber' SOAK_TEMP={target_chamber} TIMEOUT=60 CANCEL='_NOTHING'
# (CANCEL='_NOTHING') and having unreachable SOAK_TEMP makes it run till the TIMEOUT and continue without canceling the print.
{% else %}
RESPOND MSG="waiting for bed core temperature"
HEAT_SOAK HEATER='heater_bed' TARGET={target_bed} SOAKER='temperature_sensor bed_core' SOAK_TEMP={target_bed - 5} TIMEOUT=30 CANCEL='_NOTHING'
# (CANCEL='_NOTHING') and having unreachable SOAK_TEMP makes it run till the TIMEOUT and continue without canceling the print.
{% endif %}
# AFC heats for a tool change from the print file's per-tool temperatures.
# When the loaded lane's tool number is not in that list (for example lane5 =
# T4 loaded, single-colour print with only T0), AFC does not heat at all and
# the unload fails below min_extrude_temp. Heat for the loaded filament first.
[gcode_macro _HEAT_FOR_LOADED_LANE]
description: Heat to the loaded lane's filament temperature before changing to another tool
gcode:
{% set tool = 'T' ~ params.TOOL|default(0)|int %}
{% set cur = printer.AFC.current_load %}
{% if cur and ('AFC_stepper ' ~ cur) in printer %}
{% set lane = printer['AFC_stepper ' ~ cur] %}
{% if lane.map != tool %}
{% set min_temp = printer.configfile.settings.extruder.min_extrude_temp|int + 20 %}
{% set temp = [lane.extruder_temp|default(0, true)|int, min_temp]|max %}
RESPOND MSG="Heating to {temp}C to unload {cur} ({lane.material}) before {tool}"
M109 S{temp}
{% endif %}
{% endif %}
[gcode_macro _NOTHING]
gcode:
RESUME_BASE
[gcode_macro PRINT_START]
gcode:
RESPOND MSG="print start macro continued"
_motion_detected
{% set target_extruder = params.EXTRUDER|int %}
M106 S0
M104 S150 ; set nozzle temp to 150
M109 S150 ; wait until nozzle reaches 150 ; wait until nozzle reaches 0
HOME
BLOBIFIER_CLEAN ; call another macro to wipe nozzle if available
_status_calibrating_z
G28 Z METHOD=CONTACT CALIBRATE=1 ; calibrate z offset and beacon model hot
_status_leveling
RESPOND MSG="quad ganrty level"
QUAD_GANTRY_LEVEL
_status_meshing
RESPOND MSG="meshing"
BED_MESH_CALIBRATE RUNS=2 ; bed mesh in scan mode
BLOBIFIER_CLEAN ; call another macro to wipe nozzle if available
M104 S150 ; set nozzle temp to 150
M109 S150 ; wait until nozzle reaches 150 ; wait until nozzle reaches 0
_status_calibrating_z
G28 Z METHOD=CONTACT CALIBRATE=1 ; calibrate z offset and beacon model hot
_status_heating
M104 S{target_extruder} ; set extruder to print temp
M109 S{target_extruder} ; wait for extruder temp
BLOBIFIER_PARK ; over the bucket, then undo the retracts
_NOZZLE_UNRETRACT ; of PRINT_WARMUP and the previous PRINT_END
# ; needs fine tuning, long meltzones require more
# SET_GCODE_OFFSET Z_ADJUST={OFFSET} ; apply optional material squish via slicer
#SET_GCODE_OFFSET Z=-0.06 ; squish
# SET_GCODE_OFFSET Z=0.02 ; squish # worked before but a bit to high now
# SET_GCODE_OFFSET Z=-0.05 ; squish
SET_GCODE_OFFSET Z=-0.00 ; squish
RESPOND MSG="starting"
;PRIME_NOZZLE ; call another macro to purge or prime nozzle
# WIPE_NOZZLE ; call another macro to wipe nozzle if available
# Line_Purge
# AFC_POOP PURGE_LENGTH=100
# AFC_KICK
BLOBIFIER_CLEAN
PA_CALIBRATE_ALL_LANES LANES="lane1,lane2,lane3,lane4,lane5"
M104 S{target_extruder} ; set extruder to print temp
M109 S{target_extruder} ; wait for extruder temp
BLOBIFIER_CLEAN
; start printing
G90 ; absolute positioning
G1 Z20 F30000 ; move nozzle away from bed
G1 X175 Y175 F30000 ; move nozzle away from bed
G28 XYZ
#G11 ; unretract
_AFC_STORE_HOME_REFERENCE
# bdwidth is not used while printing: its motion reading stays at 0 and its
# per-reading width compensation made the flow jump between 77 and 119%.
# To use it again: SET_BDWIDTH NAME=fila_width_0 COMMAND=ENABLE_WIDTH
_status_printing
[gcode_macro PRINT_END]
# Use PRINT_END for the slicer ending script - please customise for your slicer of choice
gcode:
# safe anti-stringing move coords
{% set th = printer.toolhead %}
{% set x_safe = th.position.x + 20 * (1 if th.axis_maximum.x - th.position.x > 20 else -1) %}
{% set y_safe = th.position.y + 20 * (1 if th.axis_maximum.y - th.position.y > 20 else -1) %}
{% set z_safe = [th.position.z + 2, th.axis_maximum.z]|min %}
SAVE_GCODE_STATE NAME=STATE_PRINT_END
_motion_detected
M400 ; wait for buffer to clear
G92 E0 ; zero the extruder
_NOZZLE_RETRACT ; so the nozzle does not leak while cooling down
TURN_OFF_HEATERS
iHEATER_OFF ; Turns off the chamber heater
G90 ; absolute positioning
G0 X{x_safe} Y{y_safe} Z{z_safe} F20000 ; move nozzle to remove stringing
G0 X{th.axis_maximum.x//2} Y{th.axis_maximum.y - 5} F3600 ; park nozzle at rear
M107 ; turn off fan
#SET_PIN PIN=caselight VALUE=0.03
_status_part_ready
UPDATE_DELAYED_GCODE ID=_delayed_motors_off DURATION=3600
RESTORE_GCODE_STATE NAME=STATE_PRINT_END
# After the restore: RESTORE_GCODE_STATE also restores the flow (M221)
_PRINT_CLEANUP
# End-of-print cleanup shared by PRINT_END and CANCEL_PRINT
[gcode_macro _PRINT_CLEANUP]
description: Heaters (incl. chamber heater) and part fan off, flow back to 100%, bdwidth off, mesh and skew cleared
gcode:
TURN_OFF_HEATERS
iHEATER_OFF ; stops the chamber heater control loop too
M107
{% if 'bdwidth fila_width_0' in printer %}
SET_BDWIDTH NAME=fila_width_0 COMMAND=DISABLE ; also sets M221 S100
{% endif %}
M221 S100
BED_MESH_CLEAR
SET_SKEW CLEAR=1
{% if 'gcode_macro _PURGE_CHECK_CFG' in printer %}
SET_GCODE_VARIABLE MACRO=_PURGE_CHECK_CFG VARIABLE=ignore_missing_sensor VALUE=False
{% endif %}
# Retract/unretract that is remembered across prints and restarts.
# Klipper's G10 only retracts once until a G11, and nothing sends G11 here,
# so G10 in PRINT_WARMUP used up the retract and PRINT_END's G10 did nothing.
# _NOZZLE_RETRACT adds to the saved variable nozzle_retract, _NOZZLE_UNRETRACT
# extrudes that amount again (over the bucket, in PRINT_START) and clears it.
[gcode_macro _NOZZLE_RETRACT]
description: Retract LENGTH mm (default variable_length) and remember it for _NOZZLE_UNRETRACT; EXTRA=mm already retracted elsewhere, only remembered
variable_length: 5.0 # end-of-print retract; more stops leaking, too much can jam (PLA/heat creep)
variable_max_total: 15.0 # never remember more than this in total
gcode:
{% set length = params.LENGTH|default(length)|float %}
{% set extra = params.EXTRA|default(0)|float %}
{% set done = printer.save_variables.variables.nozzle_retract|default(0)|float %}
{% set length = [length, max_total - done - extra]|min %}
{% if length > 0 and printer.extruder.can_extrude %}
SAVE_GCODE_STATE NAME=_nozzle_retract
M83
G1 E-{length} F1800
RESTORE_GCODE_STATE NAME=_nozzle_retract
{% else %}
{% set length = 0 %}
{% endif %}
{% if length + extra > 0 %}
SAVE_VARIABLE VARIABLE=nozzle_retract VALUE={[done + extra + length, max_total]|min}
{% endif %}
[gcode_macro _NOZZLE_UNRETRACT]
description: Extrude what _NOZZLE_RETRACT retracted (call over the bucket, nozzle hot)
gcode:
{% set done = printer.save_variables.variables.nozzle_retract|default(0)|float %}
{% if done > 0 %}
{% if printer.extruder.can_extrude %}
SAVE_GCODE_STATE NAME=_nozzle_unretract
M83
G1 E{done} F300
RESTORE_GCODE_STATE NAME=_nozzle_unretract
SAVE_VARIABLE VARIABLE=nozzle_retract VALUE=0
{% else %}
_WARN MSG="_NOZZLE_UNRETRACT: extruder too cold, {done} mm still retracted"
{% endif %}
{% endif %}
[delayed_gcode _delayed_motors_off]
gcode:
M84