Files
klipper-macros/macros/print/print_start_end.cfg
T
mangavalkandClaude Opus 5.5 e5be65834e LEDs: nozzle light follows the motion sensor, new logo status macro
The motion timeout switched the nozzle LEDs off during prints, motion
switched them off when idle or paused, the timeout counted from the first
movement, and every _status_* macro stopped the nozzle light.

- _LIGHTS sets case light and nozzle LEDs from presence, print state and
  CASELIGHT MODE=AUTO|ON|OFF; the timeout (60 s) starts at the sensor
  release
- _STATUS STATE=... replaces the _status_* macros; logo effects only
  cover the logo LEDs and use REPLACE=1
- heater gauge while heating, print progress, paused, error flash from
  _ERROR, part ready once the bed is cool, dim night mode when idle and
  nobody near, cleaning during BLOBIFIER_CLEAN
- removed unused effects and macros, 12 fps for the toolhead effects

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

315 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
_LIGHTS_ON
#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 STATE=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 STATE=heating_bed
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 %}
_STATUS STATE=homing
HOME
_STATUS STATE=leveling
QUAD_GANTRY_LEVEL
BLOBIFIER_CLEAN ; call another macro to wipe nozzle if available
G1 X175 Y175 Z5 F1200
_STATUS STATE=heating_extruder
_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
_STATUS STATE=heating_bed
{% 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"
_LIGHTS_ON
{% 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 STATE=calibrating_z
G28 Z METHOD=CONTACT CALIBRATE=1 ; calibrate z offset and beacon model hot
_STATUS STATE=leveling
RESPOND MSG="quad ganrty level"
QUAD_GANTRY_LEVEL
_STATUS STATE=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 STATE=calibrating_z
G28 Z METHOD=CONTACT CALIBRATE=1 ; calibrate z offset and beacon model hot
_STATUS STATE=heating_extruder
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 STATE=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
_LIGHTS_ON
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 STATE=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