This commit is contained in:
2025-03-16 03:22:40 +03:00
commit f6d104b882
38 changed files with 3767 additions and 0 deletions

View File

@@ -0,0 +1,164 @@
[gcode_macro BED_MESH_CALIBRATE]
variable_buffer: 20
rename_existing: _BED_MESH_CALIBRATE
; Do not change any of the existing values below.
variable_last_area_start_x: -1 ; Do not change
variable_last_area_start_y: -1 ; Do not change
variable_last_area_end_x: -1 ; Do not change
variable_last_area_end_y: -1 ; Do not change
variable_probing:False
gcode:
STATUS_MESHING
SET_GCODE_VARIABLE MACRO=_KNOMI_STATUS VARIABLE=probing VALUE=True
{% if params.FORCE_NEW_MESH != null %}
{ action_respond_info("Force New Mesh: %s" % (params.FORCE_NEW_MESH)) }
{% endif %}
{% if printer["bed_mesh"].profile_name == '' %}
{ action_respond_info("No existing bed mesh found.") }
{% set last_area_end_x=-1 %}
{% endif %}
{% if printer.toolhead.homed_axes != "xyz" %}
G28
{% endif %}
{% set klicky_available = printer['gcode_macro _Probe_Variables'] != null %}
{% set euclid_available = printer['gcode_macro EuclidProbe'] != null %}; Requires v5 macros https://github.com/nionio6915/Euclid_Probe/blob/main/Firmware_Examples/Klipper/00-euclid_exampleV5.cfg
{% if params.PRINT_MIN %}
{ action_respond_info("print_min: %s" % params.PRINT_MIN) }
{ action_respond_info("print_max: %s" % params.PRINT_MAX) }
{% set blTouchConfig = printer['configfile'].config["bltouch"] %}
{% if blTouchConfig %}
{% set OffsetX = blTouchConfig.x_offset|default(0)|float %}
{% set OffsetY = blTouchConfig.y_offset|default(0)|float %}
{% endif %}
{% set probeConfig = printer['configfile'].config["probe"] %}
{% if probeConfig %}
{% set OffsetX = probeConfig.x_offset|default(0)|float %}
{% set OffsetY = probeConfig.y_offset|default(0)|float %}
{% endif %}
{% set print_min_x = params.PRINT_MIN.split(",")[0]|float %}
{% set print_min_y = params.PRINT_MIN.split(",")[1]|float %}
{% set print_max_x = params.PRINT_MAX.split(",")[0]|float %}
{% set print_max_y = params.PRINT_MAX.split(",")[1]|float %}
{% if last_area_start_x > 0 %}
{ action_respond_info("last_bed_mesh: %s,%s %s,%s" % (last_area_start_x, last_area_start_y, last_area_end_x, last_area_end_y)) }
{% endif %}
{% if (params.FORCE_NEW_MESH != null) or (print_min_x < last_area_start_x) or (print_max_x > last_area_end_x) or (print_min_y < last_area_start_y) or (print_max_y > last_area_end_y) %}
{% if klicky_available %}
_CheckProbe action=query
Attach_Probe
{% elif euclid_available %}
DEPLOY_PROBE
{% endif %}
{% if (print_min_x < print_max_x) and (print_min_y < print_max_y) %}
# Get bed_mesh config (probe count, mesh_min and mesh_max for x and y
{% set bedMeshConfig = printer['configfile'].config["bed_mesh"] %}
{% set minimum_probe_count = 3 %}
{% if bedMeshConfig.algorithm == "bicubic" %}
{% set minimum_probe_count = 5 %}
{% endif %}
{% set probe_count = bedMeshConfig.probe_count.split(",") %}
{% set probe_count_x = probe_count[0]|int %}
{% if probe_count.__len__() > 1 %}
{% set probe_count_y = probe_count[1]|int %}
{% else %}
{% set probe_count_y = probe_count_x|int %}
{% endif %}
{% set relative_reference_index = bedMeshConfig.relative_reference_index %}
{% set mesh_min_x = bedMeshConfig.mesh_min.split(",")[0]|float %}
{% set mesh_min_y = bedMeshConfig.mesh_min.split(",")[1]|float %}
{% set mesh_max_x = bedMeshConfig.mesh_max.split(",")[0]|float %}
{% set mesh_max_y = bedMeshConfig.mesh_max.split(",")[1]|float %}
# If print area X is smaller than 50% of the bed size, change to to 3 probe counts for X instead of the default
{% if print_max_x - print_min_x < (mesh_max_x - mesh_min_x) * 0.50 %}
{% set probe_count_x = minimum_probe_count %}
{% endif %}
# If print area Y is smaller than 50% of the bed size, change to to 3 probe counts for Y instead of the default
{% if print_max_y - print_min_y < (mesh_max_y - mesh_min_y) * 0.50 %}
{% set probe_count_y = minimum_probe_count %}
{% endif %}
{% if print_min_x - buffer >= mesh_min_x %}
{% set mesh_min_x = print_min_x - buffer %}
{% endif %}
{% if print_min_y - buffer >= mesh_min_y %}
{% set mesh_min_y = print_min_y - buffer %}
{% endif %}
{% if print_max_x + buffer <= mesh_max_x %}
{% set mesh_max_x = print_max_x + buffer %}
{% endif %}
{% if print_max_y + buffer <= mesh_max_y %}
{% set mesh_max_y = print_max_y + buffer %}
{% endif %}
{ action_respond_info("mesh_min: %s,%s" % (mesh_min_x, mesh_min_y)) }
{ action_respond_info("mesh_max: %s,%s" % (mesh_max_x, mesh_max_y)) }
{ action_respond_info("probe_count: %s,%s" % (probe_count_x,probe_count_y)) }
; Set variables so they're available outside of macro
SET_GCODE_VARIABLE MACRO=BED_MESH_CALIBRATE VARIABLE=last_area_start_x VALUE={print_min_x}
SET_GCODE_VARIABLE MACRO=BED_MESH_CALIBRATE VARIABLE=last_area_start_y VALUE={print_min_y}
SET_GCODE_VARIABLE MACRO=BED_MESH_CALIBRATE VARIABLE=last_area_end_x VALUE={print_max_x}
SET_GCODE_VARIABLE MACRO=BED_MESH_CALIBRATE VARIABLE=last_area_end_y VALUE={print_max_y}
{% if printer["gcode_macro status_meshing"] != null %}
status_meshing
{% endif %}
{% if relative_reference_index == 0 or relative_reference_index == null %}
_BED_MESH_CALIBRATE mesh_min={mesh_min_x},{mesh_min_y} mesh_max={mesh_max_x},{mesh_max_y} probe_count={probe_count_x},{probe_count_y}
{% else %}
{% set relative_reference_index = ((probe_count_x * probe_count_y - 1) / 2)|int %}
{ action_respond_info("relative_reference_index: %s" % relative_reference_index) }
_BED_MESH_CALIBRATE mesh_min={mesh_min_x},{mesh_min_y} mesh_max={mesh_max_x},{mesh_max_y} probe_count={probe_count_x},{probe_count_y} relative_reference_index={relative_reference_index}
{% endif %}
{% else %}
{% if printer["gcode_macro status_meshing"] != null %}
status_meshing
{% endif %}
_BED_MESH_CALIBRATE
{% endif %}
{% if klicky_available %}
Dock_Probe
{% elif euclid_available %}
STOW_PROBE
{% endif %}
{% else %}
{ action_respond_info("No need to recreate Bed Mesh since it's same as current mesh or smaller") }
{% endif %}
{% else %}
{% if klicky_available %}
_CheckProbe action=query
Attach_Probe
{% elif euclid_available %}
STOW_PROBE
{% endif %}
{% if printer["gcode_macro status_meshing"] != null %}
STATUS_MESHING
{% endif %}
_BED_MESH_CALIBRATE
{% if klicky_available %}
Dock_Probe
{% endif %}
{% if euclid_available %}
STOW_PROBE
{% endif %}
{% endif %}
{% if printer["gcode_macro status_ready"] != null %}
STATUS_READY
{% endif %}
SET_GCODE_VARIABLE MACRO=_KNOMI_STATUS VARIABLE=probing VALUE=False

262
macros/calibrate_flow.cfg Normal file
View File

@@ -0,0 +1,262 @@
#########################################
###### FLOW MULTIPLIER CALIBRATION ######
#########################################
# Written by Frix_x#0161 #
# @version: 1.5
# CHANGELOG:
# v1.5: moved the install notes into a proper markdown file in: doc > features > flow_calibration.md
# v1.4: fix issue when extrude_factor is != 1
# v1.3: fix the logging
# v1.2: fix for those using absolute extrusion that leads to an error
# v1.1: added part cooling fan control and some speed optimizations
# v1.0: first flow calibration macro
# -------------------------------------------------------------------------------------------------------------------------
# If you want to use it into your own config, please install it as a standalone macro as described in the
# installation section of this file: doc > features > flow_calibration.md
# -------------------------------------------------------------------------------------------------------------------------
### What is it ? ###
# The main reason for this set of macros is to get a filament and slicer agnostic way to calibrate the flow extrusion multiplier.
# The goal is to make it easy to set, share and use it.
# This macro is parametric and most of the values can be adjusted with their respective input parameters.
# It can be called without any parameters - in which case the default values would be used - or with any combination of parameters as desired.
# Feel free to ping me on Discord (Frix_x#0161) if you need help or have any comments to improve it :)
# https://github.com/yomgui1/klipper-voron-config/blob/main/doc/features/flow_calibration.md?ysclid=lzuo22xrfl138875688
# ===========================================================================================================
# DO NOT MODIFY THOSE VARIABLES (they are used internaly by the flow calibration macro)
[gcode_macro _FLOW_CALIB_VARIABLES]
variable_last_shell_thickness: 0.0
variable_last_evalue: 0.0
gcode:
[gcode_macro FLOW_MULTIPLIER_CALIBRATION]
description: Print a small tower to calibrate the extrusion flow multiplier by measuring the shell
gcode:
#
# PARAMETERS
#
{% set do_raft = params.DO_RAFT|default(1)|int %} # whether to print a raft or not
{% set do_retract = params.DO_RECTRACT|default(0)|int %} # whether to enable retract/unrectract on travel moves
{% set print_size = params.PRINT_SIZE|default(40)|int %} # size of the printed object on the build plate
{% set print_height = params.HEIGHT|default(15)|int %} # height of the printed object
{% set corner_radius = params.CORNER_RADIUS|default(8)|int %} # radius of the corners to smooth the shell and toolpath
{% set number_of_perimeters = params.PERIMETERS|default(2)|int %} # number of perimeters to print the shell
{% set fan_speed = params.FAN_SPEED|default(20)|int %} # part cooling fan speed in percent (0-100)
{% set e_multiplier = params.EXTRUSION_MULTIPLIER|default(1.00)|float %} # extrusion multiplier for the shell
{% set filament_diameter = params.FILAMENT_DIAMETER|default(1.75)|float %} # filament diameter
{% set extrusion_width = params.EXTRUSION_WIDTH|default(0.4)|float %} # extrusion width goal for one line
{% set layer_height = params.LAYER_HEIGHT|default(0.2)|float %} # layer height for the print
{% set retract_length = params.RETRACT_LENGTH|default(0.5)|float %} # how much to retract when traveling between print moves
{% set initial_purge = params.PURGE_MM|default(1)|int %} # mm of filament to purge before printing. set to 0 to disable
{% set z_hop_height = 2 * layer_height %}
{% set feedrate_print = params.CONTROL_SPEED|default(100)|int * 60 %} # print feedrate
{% set feedrate_travel = params.TRAVEL_SPEED|default(200)|int * 60 %} # travel feedrate between print moves
{% set feedrate_raft = params.RAFT_SPEED|default(60)|int * 60 %} # print feedrate for printing raft
{% set feedrate_z = params.Z_LIFT_SPEED|default(20)|int * 60 %} # z axis travel feedrate
{% set feedrate_retract = params.RETRACT_SPEED|default(50)|int * 60 %} # retract and deretract feedrate
#
# COMPUTED VALUES
#
{% set e_per_mm = ((extrusion_width - layer_height) * layer_height + 3.14159 * (layer_height / 2)**2) / (3.14159 * (filament_diameter / 2)**2) %} # computed E factor (similar to Slic3r/PrusaSlicer/SuperSlicer)
{% set spacing = extrusion_width - layer_height * (1 - 3.14159 / 4) %} # line spacing during the print
{% set shell_thickness = extrusion_width + (number_of_perimeters|float - 1) * spacing %} # theoric shell thickness
{% set max_x = printer.toolhead.axis_maximum.x|float %}
{% set max_y = printer.toolhead.axis_maximum.y|float %}
{% set x_start = max_x / 2 - print_size / 2 %}
{% set y_start = max_y / 2 - print_size / 2 %}
{% set x_end = x_start + print_size %}
{% set y_end = y_start + print_size %}
{% set num_raft_lines = ([print_size, max_x]|min / spacing)|round(0, 'floor')|int %}
{% set raft_size = num_raft_lines * spacing %}
#
# STARTING...
#
{action_respond_info("")}
{action_respond_info("Starting extrusion flow calibration print")}
{action_respond_info("This operation can not be interrupted by normal means. Hit the \"emergency stop\" button to stop it if needed")}
{action_respond_info("")}
{action_respond_info("Exrusion multiplier used: %.4f" % e_multiplier)}
{action_respond_info("Number of perimeters to print: %d" % number_of_perimeters)}
{action_respond_info("THEORIC SHELL THICKNESS: %.4f" % shell_thickness)}
{action_respond_info("")}
{action_respond_info("Measure the shell thickness using a caliper or micrometer. Then call the computation macro with the measured value:")}
{action_respond_info("COMPUTE_FLOW_MULTIPLIER MEASURED_THICKNESS=xxx.xxx")}
{action_respond_info("")}
SAVE_GCODE_STATE NAME=STATE_FLOW_MULTIPLIER_CALIBRATION
#
# set variables for later computation
#
SET_GCODE_VARIABLE MACRO=_FLOW_CALIB_VARIABLES VARIABLE=last_shell_thickness VALUE={shell_thickness}
SET_GCODE_VARIABLE MACRO=_FLOW_CALIB_VARIABLES VARIABLE=last_evalue VALUE={e_multiplier}
#
# purging before raft
#
G90
M83
G92 E0.0
G0 X{x_start} Y{y_start - 5} Z{layer_height} F{feedrate_travel} # move at the start position to do a purge line
G91 # use relative coordinates for the prime line
G1 E{initial_purge} F{5 * 60}
G1 X{raft_size} E{raft_size * e_per_mm * 1.5} F{feedrate_raft / 2} # print prime line
G1 Y-{extrusion_width} E{extrusion_width * e_per_mm} F{feedrate_raft / 2} # move to next line
G1 X-{raft_size} E{raft_size * e_per_mm} F{feedrate_raft / 2} # print second prime line
G1 E-{retract_length} F{feedrate_retract} # retract
G0 Z{z_hop_height} F{feedrate_z} # z-hop
G90 # back to absolute coordinates
G0 X{x_start} Y{y_start} F{feedrate_travel} # move to start position
G1 Z{layer_height} F{feedrate_z} # move to print height
G1 E{retract_length} F{feedrate_retract} # unretract
# set extrude_factor
M221 S{e_multiplier * 100}
#
# print the raft
#
{% if do_raft == 1 %}
G91 # use relative coordinates for the raft
{% for curr_raft_line in range(1, num_raft_lines + 2) %}
# print a raft line with alternating direction
G1 Y{loop.cycle(1.0, -1.0) * raft_size} E{raft_size * e_per_mm} F{feedrate_raft}
# spacing move
{% if not loop.last %}
G1 X{spacing} E{spacing * e_per_mm} F{feedrate_raft}
{% endif %}
{% endfor %}
G1 E-{retract_length} F{feedrate_retract} # retract
G0 Z{z_hop_height} F{feedrate_z} # z-hop
G90 # back to absolute coordinates
{% endif %}
#
# print the shell
#
G90
M106 S{fan_speed * 255 / 100}
# for each layer
{% for curr_layer in range(1, (print_height / layer_height)|round|int) %}
G0 X{x_start + corner_radius} Y{y_start} F{feedrate_travel} # move to XY start position
G1 Z{(curr_layer * layer_height) + (layer_height if do_raft == 1 else 0)} F{feedrate_z} # move to Z start position
# print one layer of the shell (in a for loop to do all the perimeters of one layer)
{% for perim_num in range(number_of_perimeters) %}
# compute values for the current perimeter (offset and radius)
{% set perim_offset = perim_num * spacing %}
{% set perim_radius = corner_radius - (perim_num * spacing) %}
# start position of the current perimeter
G1 X{x_start + corner_radius} Y{y_start + perim_offset} F{feedrate_travel}
{% if do_retract == 1 %}
G1 E{retract_length} F{feedrate_retract} # unretract
{% endif %}
# print the perimeter using the offset and radius computed
G1 X{x_end - corner_radius} Y{y_start + perim_offset} E{(print_size - (2 * corner_radius)) * e_per_mm} F{feedrate_print}
G3 X{x_end - perim_offset} Y{y_start + corner_radius} J{perim_radius} E{(3.14159 / 2) * perim_radius * e_per_mm} F{feedrate_print}
G1 X{x_end - perim_offset} Y{y_end - corner_radius} E{(print_size - (2 * corner_radius)) * e_per_mm} F{feedrate_print}
G3 X{x_end - corner_radius} Y{y_end - perim_offset} I-{perim_radius} E{(3.14159 / 2) * perim_radius * e_per_mm} F{feedrate_print}
G1 X{x_start + corner_radius} Y{y_end - perim_offset} E{(print_size - (2 * corner_radius)) * e_per_mm} F{feedrate_print}
G3 X{x_start + perim_offset} Y{y_end - corner_radius} J-{perim_radius} E{(3.14159 / 2) * perim_radius * e_per_mm} F{feedrate_print}
G1 X{x_start + perim_offset} Y{y_start + corner_radius} E{(print_size - (2 * corner_radius)) * e_per_mm} F{feedrate_print}
G3 X{x_start + corner_radius} Y{y_start + perim_offset} I{perim_radius} E{(3.14159 / 2) * perim_radius * e_per_mm} F{feedrate_print}
{% if do_retract == 1 %}
G1 E-{retract_length} F{feedrate_retract} # retract
{% endif %}
{% endfor %}
{% if do_retract == 1 %}
G91
G0 Z{z_hop_height} F{feedrate_z}
G90
{% endif %}
{% endfor %}
#
# retract and move away
#
G1 E-{retract_length} F{feedrate_retract}
G91
G0 Z20 F{feedrate_travel}
RESTORE_GCODE_STATE NAME=STATE_FLOW_MULTIPLIER_CALIBRATION
[gcode_macro COMPUTE_FLOW_MULTIPLIER]
description: Compute a new flow multiplier by using the measured shell thickness on the calibration print
gcode:
{% set evalue = params.OLD_EXTRUSION_MULTIPLIER|default(0.0)|float %} # extrusion multiplier used for the calibration print
{% set theorical_thickness = params.THEORICAL_THICKNESS|default(0.0)|float %} # theorical shell thickness
{% set measured_thickness = params.MEASURED_THICKNESS|default(0.0)|float %} # measured shell thickness on the calibration print
# if there is no OLD_EXTRUSION_MULTIPLIER passed as param, get the one from the last print calib run
{% if evalue == 0.0 %}
{% set last_evalue = printer["gcode_macro _FLOW_CALIB_VARIABLES"].last_evalue %}
# then, if there is also no evalue saved from the last run, alert user
{% if last_evalue == 0.0 %}
{action_respond_info("It seems that no calibration print was run prior to this (or a restart of Klipper occured).")}
{action_respond_info("You can still manually use it by calling again this macro like that:")}
{action_respond_info("COMPUTE_FLOW_MULTIPLIER OLD_EXTRUSION_MULTIPLIER=xxx.xxx THEORICAL_THICKNESS=xxx.xxx MEASURED_THICKNESS=xxx.xxx")}
{action_raise_error("not enough data to perform the computation of the new flow !")}
{% else %}
{% set final_evalue = last_evalue %}
{action_respond_info("Using OLD_EXTRUSION_MULTIPLIER: %.3f" % final_evalue)}
{% endif %}
{% else %}
{% set final_evalue = evalue %}
{action_respond_info("Using OLD_EXTRUSION_MULTIPLIER: %.3f" % final_evalue)}
{% endif %}
# similarly, if there is no THEORICAL_THICKNESS passed as param, get the one from the last print calib run
{% if theorical_thickness == 0.0 %}
{% set last_shell_thickness = printer["gcode_macro _FLOW_CALIB_VARIABLES"].last_shell_thickness %}
# then, if there is also no evalue saved from the last run, alert user
{% if last_shell_thickness == 0.0 %}
{action_respond_info("It seems that no calibration print was run prior to this (or a restart of Klipper occured).")}
{action_respond_info("You can still manually use it by calling again this macro like that:")}
{action_respond_info("COMPUTE_FLOW_MULTIPLIER OLD_EXTRUSION_MULTIPLIER=xxx.xxx THEORICAL_THICKNESS=xxx.xxx MEASURED_THICKNESS=xxx.xxx")}
{action_raise_error("not enough data to perform the computation of the new flow !")}
{% else %}
{% set final_theorical_thickness = last_shell_thickness %}
{action_respond_info("Using THEORICAL_THICKNESS: %.3f" % final_theorical_thickness)}
{% endif %}
{% else %}
{% set final_theorical_thickness = theorical_thickness %}
{action_respond_info("Using THEORICAL_THICKNESS: %.3f" % final_theorical_thickness)}
{% endif %}
# use the measured thickness from the user to compute a new flow value
{% if measured_thickness == 0.0 %}
{action_respond_info("You must use a caliper or micrometer to measure the calibration print shell thickness and call this macro with the measured value !!!")}
{action_respond_info("COMPUTE_FLOW_MULTIPLIER MEASURED_THICKNESS=xxx.xxx")}
{action_raise_error("not enough data to perform the computation of the new flow !")}
{% else %}
{% set new_evalue = final_theorical_thickness * final_evalue / measured_thickness %}
{action_respond_info("NEW COMPUTED FLOW VALUE: %.3f" % new_evalue)}
{action_respond_info("Use this new value as extrusion multiplier in your slicer of choice")}
{action_respond_info("")}
{% endif %}

174
macros/homing.cfg Normal file
View File

@@ -0,0 +1,174 @@
[gcode_macro MOVE_UP]
variable_set_kinematic_z: 20
variable_up_z: 10
gcode:
SAVE_GCODE_STATE NAME=my_move_up_state
{% if not 'z' in printer.toolhead.homed_axes %}
SET_KINEMATIC_POSITION Z={set_kinematic_z}
{% endif %}
G91
G0 Z{up_z} F1200
RESTORE_GCODE_STATE NAME=my_move_up_state
[gcode_macro _HOME_X]
variable_homing_current: 0.49
variable_start_retract: 15
gcode:
# Always use consistent run_current on A/B steppers during sensorless homing
{% set RUN_CURRENT_X = printer.configfile.settings['tmc2240 stepper_x'].run_current|float %}
{% set RUN_CURRENT_Y = printer.configfile.settings['tmc2240 stepper_y'].run_current|float %}
SET_TMC_CURRENT STEPPER=stepper_x CURRENT={homing_current}
SET_TMC_CURRENT STEPPER=stepper_y CURRENT={homing_current}
M117 Homing X...
SET_KINEMATIC_POSITION X={start_retract}
G91
G1 X-{start_retract} F1200
M400
G28 X
G91
G1 X-40 F1200
#G4 P500
M117
SET_TMC_CURRENT STEPPER=stepper_x CURRENT={RUN_CURRENT_X}
SET_TMC_CURRENT STEPPER=stepper_y CURRENT={RUN_CURRENT_Y}
[gcode_macro _HOME_Y]
variable_homing_current: 0.49
variable_start_retract: 15
gcode:
# Set current for sensorless homing
{% set RUN_CURRENT_X = printer.configfile.settings['tmc2240 stepper_x'].run_current|float %}
{% set RUN_CURRENT_Y = printer.configfile.settings['tmc2240 stepper_y'].run_current|float %}
SET_TMC_CURRENT STEPPER=stepper_x CURRENT={homing_current}
SET_TMC_CURRENT STEPPER=stepper_y CURRENT={homing_current}
#SET_TMC_FIELD FIELD=SGT STEPPER=stepper_x VALUE=1
#G4 P1000
M117 Homing Y...
SET_KINEMATIC_POSITION Y={start_retract}
G91
G1 Y-{start_retract} F1200
M400
G28 Y
G91
G1 Y-10 F1200
#G4 P500
M117
# Set current during print
SET_TMC_CURRENT STEPPER=stepper_x CURRENT={RUN_CURRENT_X}
SET_TMC_CURRENT STEPPER=stepper_y CURRENT={RUN_CURRENT_Y}
[homing_override]
axes: xyz
gcode:
{% set home_all = 'X' not in params and 'Y' not in params and 'Z' not in params %}
{% set move_x = params.X|default(printer.toolhead.axis_maximum.y/2)|int %}
{% set move_y = params.Y|default(printer.toolhead.axis_maximum.y/2)|int %}
{% if params.Z == '' %}
{% set move_z = 10 %}
{% else %}
{% set move_z = params.Z|default(10)|int %}
{% endif %}
SET_GCODE_VARIABLE MACRO=_KNOMI_STATUS VARIABLE=homing VALUE=True
STATUS_HOMING
{% if home_all or 'X' or 'Y' in params %}
INIT_TMC STEPPER=stepper_y
INIT_TMC STEPPER=stepper_x
{% endif %}
{% if home_all or 'Z' in params %}
BED_MESH_CLEAR
MOVE_UP
{% endif %}
{% if home_all or 'X' in params %}
_HOME_X
{% endif %}
{% if home_all or 'Y' in params %}
_HOME_Y
{% endif %}
G90
{% if home_all or 'Z' in params %}
G1 X{printer.toolhead.axis_maximum.x/2} Y{printer.toolhead.axis_maximum.y/2} F12000 #probe point
G28 Z
G1 Z{move_z} F1200
{% endif %}
#{ action_respond_info("Move X,Y => {},{}".format(params.X,params.Y)) }
{% if params.X %}
G1 X{move_x} F12000
{% endif %}
{% if params.Y %}
G1 Y{move_y} F12000
{% endif %}
STATUS_OFF
SET_GCODE_VARIABLE MACRO=_KNOMI_STATUS VARIABLE=homing VALUE=False
[gcode_macro CG28]
gcode:
{% if "xyz" not in printer.toolhead.homed_axes %}
G28
{% endif %}
[gcode_macro PARKFRONT]
gcode:
CG28 ; home if not already homed
SAVE_GCODE_STATE NAME=PARKFRONT
G90 ; absolute positioning
G0 X{printer.toolhead.axis_maximum.x/2} Y{printer.toolhead.axis_minimum.y+5} Z{printer.toolhead.axis_maximum.z/2} F6000
RESTORE_GCODE_STATE NAME=PARKFRONT
[gcode_macro PARKFRONTLOW]
gcode:
CG28 ; home if not already homed
SAVE_GCODE_STATE NAME=PARKFRONT
G90 ; absolute positioning
G0 X{printer.toolhead.axis_maximum.x/2} Y{printer.toolhead.axis_minimum.y+5} Z20 F6000
RESTORE_GCODE_STATE NAME=PARKFRONT
[gcode_macro PARKREAR]
gcode:
CG28 ; home if not already homed
SAVE_GCODE_STATE NAME=PARKREAR
G90 ; absolute positioning
G0 X{printer.toolhead.axis_minimum.x+10} Y{printer.toolhead.axis_maximum.y-10} Z{printer.toolhead.axis_maximum.z-50} F6000
RESTORE_GCODE_STATE NAME=PARKREAR
[gcode_macro PARKCENTER]
gcode:
CG28 ; home if not already homed
SAVE_GCODE_STATE NAME=PARKCENTER
G90 ; absolute positioning
G0 X{printer.toolhead.axis_maximum.x/2} Y{printer.toolhead.axis_maximum.y/2} Z{printer.toolhead.axis_maximum.z/2} F6000
RESTORE_GCODE_STATE NAME=PARKCENTER
[gcode_macro PARKBED]
gcode:
CG28 ; home if not already homed
SAVE_GCODE_STATE NAME=PARKBED
G90 ; absolute positioning
G0 X{printer.toolhead.axis_maximum.x/2} Y{printer.toolhead.axis_maximum.y/2} Z15 F6000
RESTORE_GCODE_STATE NAME=PARKBED

174
macros/homing.cfg.old Normal file
View File

@@ -0,0 +1,174 @@
[gcode_macro MOVE_UP]
variable_set_kinematic_z: 20
variable_up_z: 10
gcode:
SAVE_GCODE_STATE NAME=my_move_up_state
{% if not 'z' in printer.toolhead.homed_axes %}
SET_KINEMATIC_POSITION Z={set_kinematic_z}
{% endif %}
G91
G0 Z{up_z} F1200
RESTORE_GCODE_STATE NAME=my_move_up_state
[gcode_macro _HOME_X]
variable_homing_current: 0.65
variable_start_retract: 15
gcode:
# Always use consistent run_current on A/B steppers during sensorless homing
{% set RUN_CURRENT_X = printer.configfile.settings['tmc2240 stepper_x'].run_current|float %}
{% set RUN_CURRENT_Y = printer.configfile.settings['tmc2240 stepper_y'].run_current|float %}
SET_TMC_CURRENT STEPPER=stepper_x CURRENT={homing_current}
SET_TMC_CURRENT STEPPER=stepper_y CURRENT={homing_current}
M117 Homing X...
SET_KINEMATIC_POSITION X={start_retract}
G91
G1 X-{start_retract} F1200
M400
G28 X
G91
G1 X-60 F1200
#G4 P500
M117
SET_TMC_CURRENT STEPPER=stepper_x CURRENT={RUN_CURRENT_X}
SET_TMC_CURRENT STEPPER=stepper_y CURRENT={RUN_CURRENT_Y}
[gcode_macro _HOME_Y]
variable_homing_current: 0.65
variable_start_retract: 15
gcode:
# Set current for sensorless homing
{% set RUN_CURRENT_X = printer.configfile.settings['tmc2240 stepper_x'].run_current|float %}
{% set RUN_CURRENT_Y = printer.configfile.settings['tmc2240 stepper_y'].run_current|float %}
SET_TMC_CURRENT STEPPER=stepper_x CURRENT={homing_current}
SET_TMC_CURRENT STEPPER=stepper_y CURRENT={homing_current}
#SET_TMC_FIELD FIELD=SGT STEPPER=stepper_x VALUE=1
#G4 P1000
M117 Homing Y...
SET_KINEMATIC_POSITION Y={start_retract}
G91
G1 Y-{start_retract} F1200
M400
G28 Y
G91
G1 Y-10 F1200
#G4 P500
M117
# Set current during print
SET_TMC_CURRENT STEPPER=stepper_x CURRENT={RUN_CURRENT_X}
SET_TMC_CURRENT STEPPER=stepper_y CURRENT={RUN_CURRENT_Y}
[homing_override]
axes: xyz
gcode:
{% set home_all = 'X' not in params and 'Y' not in params and 'Z' not in params %}
{% set move_x = params.X|default(printer.toolhead.axis_maximum.y/2)|int %}
{% set move_y = params.Y|default(printer.toolhead.axis_maximum.y/2)|int %}
{% if params.Z == '' %}
{% set move_z = 10 %}
{% else %}
{% set move_z = params.Z|default(10)|int %}
{% endif %}
SET_GCODE_VARIABLE MACRO=_KNOMI_STATUS VARIABLE=homing VALUE=True
STATUS_HOMING
{% if home_all or 'X' or 'Y' in params %}
INIT_TMC STEPPER=stepper_y
INIT_TMC STEPPER=stepper_x
{% endif %}
{% if home_all or 'Z' in params %}
BED_MESH_CLEAR
MOVE_UP
{% endif %}
{% if home_all or 'X' in params %}
_HOME_X
{% endif %}
{% if home_all or 'Y' in params %}
_HOME_Y
{% endif %}
G90
{% if home_all or 'Z' in params %}
G1 X{printer.toolhead.axis_maximum.x/2} Y{printer.toolhead.axis_maximum.y/2} F12000 #probe point
G28 Z
G1 Z{move_z} F1200
{% endif %}
#{ action_respond_info("Move X,Y => {},{}".format(params.X,params.Y)) }
{% if params.X %}
G1 X{move_x} F12000
{% endif %}
{% if params.Y %}
G1 Y{move_y} F12000
{% endif %}
STATUS_OFF
SET_GCODE_VARIABLE MACRO=_KNOMI_STATUS VARIABLE=homing VALUE=False
[gcode_macro CG28]
gcode:
{% if "xyz" not in printer.toolhead.homed_axes %}
G28
{% endif %}
[gcode_macro PARKFRONT]
gcode:
CG28 ; home if not already homed
SAVE_GCODE_STATE NAME=PARKFRONT
G90 ; absolute positioning
G0 X{printer.toolhead.axis_maximum.x/2} Y{printer.toolhead.axis_minimum.y+5} Z{printer.toolhead.axis_maximum.z/2} F6000
RESTORE_GCODE_STATE NAME=PARKFRONT
[gcode_macro PARKFRONTLOW]
gcode:
CG28 ; home if not already homed
SAVE_GCODE_STATE NAME=PARKFRONT
G90 ; absolute positioning
G0 X{printer.toolhead.axis_maximum.x/2} Y{printer.toolhead.axis_minimum.y+5} Z20 F6000
RESTORE_GCODE_STATE NAME=PARKFRONT
[gcode_macro PARKREAR]
gcode:
CG28 ; home if not already homed
SAVE_GCODE_STATE NAME=PARKREAR
G90 ; absolute positioning
G0 X{printer.toolhead.axis_minimum.x+10} Y{printer.toolhead.axis_maximum.y-10} Z{printer.toolhead.axis_maximum.z-50} F6000
RESTORE_GCODE_STATE NAME=PARKREAR
[gcode_macro PARKCENTER]
gcode:
CG28 ; home if not already homed
SAVE_GCODE_STATE NAME=PARKCENTER
G90 ; absolute positioning
G0 X{printer.toolhead.axis_maximum.x/2} Y{printer.toolhead.axis_maximum.y/2} Z{printer.toolhead.axis_maximum.z/2} F6000
RESTORE_GCODE_STATE NAME=PARKCENTER
[gcode_macro PARKBED]
gcode:
CG28 ; home if not already homed
SAVE_GCODE_STATE NAME=PARKBED
G90 ; absolute positioning
G0 X{printer.toolhead.axis_maximum.x/2} Y{printer.toolhead.axis_maximum.y/2} Z15 F6000
RESTORE_GCODE_STATE NAME=PARKBED

552
macros/main.cfg Normal file
View File

@@ -0,0 +1,552 @@
[include stealthburner_leds.cfg]
[gcode_macro _KNOMI_STATUS]
variable_homing: False
variable_probing: False
variable_qgling: False
variable_heating_nozzle: False
variable_heating_bed: False
gcode:
[include homing.cfg]
#[include private.cfg]
#[include nozzle_scrub.cfg]
[include ../KAMP_Settings.cfg]
#[include ../KAMP/KAMP_Settings.cfg]
[include tools.cfg]
[delayed_gcode init_printer]
initial_duration: 1
gcode:
STATUS_READY
SET_FAN_SPEED FAN=SoC SPEED=0.3
#SET_FILAMENT_SENSOR SENSOR=SFS_T0 ENABLE=0
[delayed_gcode _INIT_TIMELAPSE_CHECK_TIME]
initial_duration: 1
gcode: SET_GCODE_VARIABLE MACRO=TIMELAPSE_TAKE_FRAME VARIABLE=check_time VALUE=0.5
[gcode_button ps_lose]
pin: PC2
press_gcode:
{ action_respond_info("Power lose!") }
SHUTDOWN
[gcode_macro SHUTDOWN]
gcode:
SET_PIN PIN=ps_on VALUE=0
{action_respond_info('action:poweroff')}
{action_call_remote_method("shutdown_machine")}
[gcode_macro _CHAMBER_LED_OFF]
gcode:
SET_LED LED="chamber_leds" RED=0 GREEN=0 BLUE=0 SYNC=0 TRANSMIT=1
[gcode_macro _CHAMBER_LED_ON]
gcode:
SET_LED LED="chamber_leds" RED=1 GREEN=1 BLUE=1 SYNC=0 TRANSMIT=1
[gcode_macro _LED_SWITCH]
gcode:
{% set color_data = printer["neopixel chamber_leds"].color_data %}
{% if color_data[0][0] or color_data[0][1] or color_data[0][2] %}
SET_LED LED="chamber_leds" RED=0 GREEN=0 BLUE=0 SYNC=0 TRANSMIT=1
{% else %}
SET_LED LED="chamber_leds" RED=1 GREEN=1 BLUE=1 SYNC=0 TRANSMIT=1
{% endif %}
[gcode_button ps_double_click]
pin: !PG13
press_gcode:
{ action_respond_info("Double click!") }
_LED_SWITCH
[gcode_button ps_triple_click]
pin: !PG12
press_gcode:
{ action_respond_info("Triple click!") }
{ action_emergency_stop() }
[gcode_macro START_BED_MESH_CALIBRATE]
#rename_existing: _BED_MESH_CALIBRATE
gcode:
STATUS_MESHING
SET_GCODE_VARIABLE MACRO=_KNOMI_STATUS VARIABLE=probing VALUE=True
BED_MESH_CALIBRATE
SET_GCODE_VARIABLE MACRO=_KNOMI_STATUS VARIABLE=probing VALUE=False
STATUS_READY
[gcode_macro QUAD_GANTRY_LEVEL]
rename_existing: QUAD_GANTRY_LEVEL_BASE
gcode:
SET_GCODE_VARIABLE MACRO=_KNOMI_STATUS VARIABLE=qgling VALUE=True
STATUS_LEVELING
QUAD_GANTRY_LEVEL_BASE
STATUS_READY
SET_GCODE_VARIABLE MACRO=_KNOMI_STATUS VARIABLE=qgling VALUE=False
[gcode_macro G32]
gcode:
M117 Homing
BED_MESH_CLEAR
G28
QUAD_GANTRY_LEVEL
STATUS_CALIBRATING_Z
#G0 X350 Y350 Z30 F3600
G28 Z
G0 Z10 F3600
STATUS_READY
M117
[gcode_macro SFS_ENABLE]
description: Enable smart filament sensor
gcode:
M117 ENABLING the Smart Filament Sensor
G92 E0
#SET_FILAMENT_SENSOR SENSOR=SFS_T0 ENABLE=1
[gcode_macro SFS_DISABLE]
description: Disable smart filament sensor
gcode:
M117 DISABLING the Smart Filament Sensor
G92 E0
#SET_FILAMENT_SENSOR SENSOR=SFS_T0 ENABLE=0
[gcode_macro PRINT_START]
gcode:
_CHAMBER_LED_ON
#PRINT_MIN={first_layer_print_min[0]},{first_layer_print_min[1]} PRINT_MAX={first_layer_print_max[0]},{first_layer_print_max[1]}
{% set BED_TEMP = params.BED|default(60)|float %}
{% set EXTRUDER_TEMP = params.EXTRUDER|default(210)|float %}
{% set CHAMBER = params.CHAMBER|default(35)|float %}
{% if params.BED_TYPE %}
INIT_BED_TYPE BED_TYPE="{params.BED_TYPE}"
{% endif %}
SAVE_GCODE_STATE NAME=start
M117 Starting...
M140 S{BED_TEMP}
M141 S{CHAMBER}
M109 S150
M190 S{BED_TEMP}
BED_MESH_CLEAR
G90 # Use absolute coordinates
#SET_GCODE_OFFSET Z=0.0
G32
#{% if not 'xyz' in printer.toolhead.homed_axes %}
#G32 ; home all axes
#{% elif not printer.quad_gantry_level.applied %}
#QUAD_GANTRY_LEVEL
#{% else %}
#G28 Z10
#{% endif %}
START_BED_MESH_CALIBRATE #PRINT_MIN={params.PRINT_MIN} PRINT_MAX={params.PRINT_MAX} FORCE_NEW_MESH=True
#M191 S{CHAMBER}
Smart_Park
M117 Heating...
#M190 S{BED_TEMP}
M109 S{EXTRUDER_TEMP} ; M109 heat and wait for it to reach temp
SFS_ENABLE
M117
STATUS_CLEANING
VORON_PURGE
STATUS_PRINTING
RESTORE_GCODE_STATE NAME=start
SKEW_PROFILE LOAD=default
#SET_SKEW XY=140.56,141.21,99.82
[gcode_macro PRINT_END]
# Use PRINT_END for the slicer ending script - please customise for your slicer of choice
variable_retract_amount: 16 #
variable_park_speed: 6000 #3600
variable_park_xy: [350,350]
variable_up_z: 4 #12
gcode:
{% set max_velocity = printer.configfile.settings['extruder'].max_extrude_only_velocity * 60 %}
STATUS_BUSY
SET_SKEW CLEAR=1
M400 ; wait for buffer to clear
G92 E0 ; zero the extruder
G1 E-{retract_amount} F3600 ; retract filament {max_velocity}
G91 ; relative positioning
G0 Z1.00 X20.0 Y20.0 F20000 ; move nozzle to remove stringing
TURN_OFF_HEATERS
M107 ; turn off fan
G1 Z{up_z} F3000 ; move nozzle up 2mm
G90 ; absolute positioning
G0 X{park_xy[0]} Y{park_xy[1]} F{park_speed} ; park nozzle at rear
#BED_MESH_CLEAR
SFS_DISABLE
#M141 S35
SET_STEPPER_ENABLE STEPPER=extruder ENABLE=0 #disable stepper
STATUS_OFF
SET_VELOCITY_DEFAULT
INIT_BED_TYPE BED_TYPE="None"
M400
TIMELAPSE_TAKE_FRAME
[gcode_macro SET_VELOCITY_DEFAULT]
gcode:
SET_VELOCITY_LIMIT ACCEL={printer.configfile.settings.printer.max_accel}
SET_VELOCITY_LIMIT ACCEL_TO_DECEL={printer.configfile.settings.printer.max_accel / 2}
SET_VELOCITY_LIMIT SQUARE_CORNER_VELOCITY={printer.configfile.settings.printer.square_corner_velocity}
[gcode_macro M141]
gcode:
{% set s = params.S|default(0)|float %}
SET_TEMPERATURE_FAN_TARGET temperature_fan=chamber target={s}
[gcode_macro M191]
gcode:
{% set s = params.S|default(0)|float %}
M141 S{s}
TEMPERATURE_WAIT SENSOR="temperature_fan chamber" MINIMUM={s}
[gcode_macro M600]
gcode:
#LCDRGB R=0 G=1 B=0 ; Turn LCD green
PAUSE ; Pause
[gcode_macro PAUSE]
rename_existing: BASE_PAUSE
gcode:
# Parameters
{% set z = params.Z|default(10)|int %} ; z hop amount
{% if printer['pause_resume'].is_paused|int == 0 %}
SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=zhop VALUE={z} ; set z hop variable for reference in resume macro
SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=etemp VALUE={printer['extruder'].target} ; set hotend temp variable for reference in resume macro
SFS_DISABLE ; disable filament sensor
SAVE_GCODE_STATE NAME=PAUSE ; save current print position for resume
BASE_PAUSE ; pause print
{% if (printer.gcode_move.position.z + z) < printer.toolhead.axis_maximum.z %} ; check that zhop doesn't exceed z max
G91 ; relative positioning
G1 Z{z} F900 ; raise Z up by z hop amount
{% else %}
{ action_respond_info("Pause zhop exceeds maximum Z height.") } ; if z max is exceeded, show message and set zhop value for resume to 0
SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=zhop VALUE=0
{% endif %}
G90 ; absolute positioning
G1 X{printer.toolhead.axis_maximum.x/2} Y{printer.toolhead.axis_minimum.y+5} F6000 ; park toolhead at front center
SAVE_GCODE_STATE NAME=PAUSEPARK ; save parked position in case toolhead is moved during the pause (otherwise the return zhop can error)
M104 S0 ; turn off hotend
SET_IDLE_TIMEOUT TIMEOUT=43200 ; set timeout to 12 hours
{% endif %}
[gcode_macro RESUME]
rename_existing: BASE_RESUME
variable_zhop: 0
variable_etemp: 0
gcode:
# Parameters
{% set e = params.E|default(2.5)|int %}
{% if printer['pause_resume'].is_paused|int == 1 %}
SFS_ENABLE ; enable filament sensor
#RESETRGB ; reset LCD color
SET_IDLE_TIMEOUT TIMEOUT={printer.configfile.settings.idle_timeout.timeout} ; set timeout back to configured value
{% if etemp > 0 %}
M109 S{etemp|int} ; wait for hotend to heat back up
{% endif %}
RESTORE_GCODE_STATE NAME=PAUSEPARK MOVE=1 MOVE_SPEED=100 ; go back to parked position in case toolhead was moved during pause (otherwise the return zhop can error)
G91 ; relative positioning
M83 ; relative extruder positioning
{% if printer[printer.toolhead.extruder].temperature >= printer.configfile.settings.extruder.min_extrude_temp %}
G1 Z{zhop * -1} E{e} F900 ; prime nozzle by E, lower Z back down
{% else %}
G1 Z{zhop * -1} F900 ; lower Z back down without priming (just in case we are testing the macro with cold hotend)
{% endif %}
RESTORE_GCODE_STATE NAME=PAUSE MOVE=1 MOVE_SPEED=60 ; restore position
BASE_RESUME ; resume print
{% endif %}
[gcode_macro CANCEL_PRINT]
description: Cancel the actual running print
rename_existing: CANCEL_PRINT_BASE
gcode:
SET_IDLE_TIMEOUT TIMEOUT={printer.configfile.settings.idle_timeout.timeout} ;
CLEAR_PAUSE
SDCARD_RESET_FILE
PRINT_END
CANCEL_PRINT_BASE
[gcode_macro DUMP_PARAMETERS]
gcode:
{% for name1 in printer %}
{% for name2 in printer[name1] %}
{ action_respond_info("printer['%s'].%s = %s" % (name1, name2, printer[name1][name2])) }
{% else %}
{ action_respond_info("printer['%s'] = %s" % (name1, printer[name1])) }
{% endfor %}
{% endfor %}
[gcode_macro M109]
rename_existing: M99109
gcode:
SET_GCODE_VARIABLE MACRO=_KNOMI_STATUS VARIABLE=heating_nozzle VALUE=True
STATUS_HEATING
{% set s = params.S|float %}
{% if s != 0 %}
M104 {% for p in params %}{'%s%s' % (p, params[p])}{% endfor %} ; Set hotend temp
TEMPERATURE_WAIT SENSOR=extruder MINIMUM={s} MAXIMUM={s+1} ; Wait for hotend temp (within 1 degree)
{% endif %}
SET_GCODE_VARIABLE MACRO=_KNOMI_STATUS VARIABLE=heating_nozzle VALUE=False
STATUS_OFF
[gcode_macro M190]
rename_existing: M99190
gcode:
SET_GCODE_VARIABLE MACRO=_KNOMI_STATUS VARIABLE=heating_bed VALUE=True
STATUS_HEATING
{% set s = params.S|float %}
{% if s != 0 %}
M140 {% for p in params %}{'%s%s' % (p, params[p])}{% endfor %} ; Set bed temp
TEMPERATURE_WAIT SENSOR=heater_bed MINIMUM={s} MAXIMUM={s+1} ; Wait for bed temp (within 1 degree)
{% endif %}
SET_GCODE_VARIABLE MACRO=_KNOMI_STATUS VARIABLE=heating_bed VALUE=False
STATUS_OFF
[gcode_macro DISABLE_XY]
gcode:
SET_STEPPER_ENABLE STEPPER=stepper_x ENABLE=0
SET_STEPPER_ENABLE STEPPER=stepper_y ENABLE=0
[gcode_macro INIT_BED_TYPE]
variable_bed_z_offset: 0
variable_bed_types: { 'Textured PEI Plate': 0.00, 'None': 0 }
gcode:
{% set bed_type = params.BED_TYPE|default("None") %}
{% set new_bed_z_offset = bed_types[bed_type] %}
{% if bed_z_offset != 0 %}
SET_GCODE_OFFSET Z_ADJUST={0-bed_z_offset|float}
SET_GCODE_VARIABLE MACRO=INIT_BED_TYPE VARIABLE=bed_z_offset VALUE=0
{% endif %}
{ action_respond_info("Selected bed type: {}".format(bed_type)) }
{ action_respond_info("Used bed z offset: {}".format(bed_z_offset)) }
{% if new_bed_z_offset %}
{ action_respond_info("Use bed type {} with z offset {}".format(bed_type, new_bed_z_offset)) }
SET_GCODE_VARIABLE MACRO=INIT_BED_TYPE VARIABLE=bed_z_offset VALUE={new_bed_z_offset}
SET_GCODE_OFFSET Z_ADJUST={new_bed_z_offset}
{% endif %}
[gcode_macro LOAD_FILAMENT]
variable_load_distance: 72
variable_purge_distance: 0
gcode:
{% set speed = params.SPEED|default(300) %}
{% set max_velocity = printer.configfile.settings['extruder'].max_extrude_only_velocity * 60 %}
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: 76
variable_purge_distance: 0
gcode:
{% set speed = params.SPEED|default(300) %}
{% set max_velocity = printer.configfile.settings['extruder'].max_extrude_only_velocity * 60 %}
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 test_speed_fast]
gcode:
G28 X0 Y0
GET_POSITION
G1 X0 Y0 F27000
G1 X350 Y350 F27000
G1 X0 Y0 F27000
G1 X350 Y350 F27000
G1 X0 Y350 F36000
G1 X350 Y0 F27000
G1 X0 Y350 F27000
G1 X350 Y0 F27000
G1 X0 Y350 F27000
G1 X0 Y0 F36000
G1 X350 Y0 F36000
G1 X350 Y350 F36000
G1 X0 Y350 F36000
G1 X0 Y0 F36000
#DISABLE_XY
G28 X0 Y0
GET_POSITION
[gcode_macro TEST_SPEED]
# Home, get position, throw around toolhead, home again.
# If MCU stepper positions (first line in GET_POSITION) are greater than a full step different (your number of microsteps), then skipping occured.
# We only measure to a full step to accomodate for endstop variance.
# Example: TEST_SPEED SPEED=300 ACCEL=5000 ITERATIONS=10
# https://github.com/AndrewEllis93/Print-Tuning-Guide/blob/main/articles/determining_max_speeds_accels.md
description: Test for max speed and acceleration parameters for the printer. Procedure: Home -> ReadPositionFromMCU -> MovesToolhead@Vel&Accel -> Home -> ReadPositionfromMCU
gcode:
# Speed
{% set speed = params.SPEED|default(printer.configfile.settings.printer.max_velocity)|int %}
# Iterations
{% set iterations = params.ITERATIONS|default(5)|int %}
# Acceleration
{% set accel = params.ACCEL|default(printer.configfile.settings.printer.max_accel)|int %}
# Minimum Cruise Ratio
{% set min_cruise_ratio = params.MIN_CRUISE_RATIO|default(0.5)|float %}
# Bounding inset for large pattern (helps prevent slamming the toolhead into the sides after small skips, and helps to account for machines with imperfectly set dimensions)
{% set bound = params.BOUND|default(20)|int %}
# Size for small pattern box
{% set smallpatternsize = SMALLPATTERNSIZE|default(20)|int %}
# Large pattern
# Max positions, inset by BOUND
{% set x_min = printer.toolhead.axis_minimum.x + bound %}
{% set x_max = printer.toolhead.axis_maximum.x - bound %}
{% set y_min = printer.toolhead.axis_minimum.y + bound %}
{% set y_max = printer.toolhead.axis_maximum.y - bound %}
# Small pattern at center
# Find X/Y center point
{% set x_center = (printer.toolhead.axis_minimum.x|float + printer.toolhead.axis_maximum.x|float ) / 2 %}
{% set y_center = (printer.toolhead.axis_minimum.y|float + printer.toolhead.axis_maximum.y|float ) / 2 %}
# Set small pattern box around center point
{% set x_center_min = x_center - (smallpatternsize/2) %}
{% set x_center_max = x_center + (smallpatternsize/2) %}
{% set y_center_min = y_center - (smallpatternsize/2) %}
{% set y_center_max = y_center + (smallpatternsize/2) %}
# Save current gcode state (absolute/relative, etc)
SAVE_GCODE_STATE NAME=TEST_SPEED
# Output parameters to g-code terminal
{ action_respond_info("TEST_SPEED: starting %d iterations at speed %d, accel %d" % (iterations, speed, accel)) }
# Home and get position for comparison later:
M400 # Finish moves - https://github.com/AndrewEllis93/Print-Tuning-Guide/issues/66
G28
# QGL if not already QGLd (only if QGL section exists in config)
{% if printer.configfile.settings.quad_gantry_level %}
{% if printer.quad_gantry_level.applied == False %}
QUAD_GANTRY_LEVEL
G28 Z
{% endif %}
{% endif %}
# Move 50mm away from max position and home again (to help with hall effect endstop accuracy - https://github.com/AndrewEllis93/Print-Tuning-Guide/issues/24)
G90
G1 X{printer.toolhead.axis_maximum.x-50} Y{printer.toolhead.axis_maximum.y-50} F{30*60}
M400 # Finish moves - https://github.com/AndrewEllis93/Print-Tuning-Guide/issues/66
G28 X Y
G0 X{printer.toolhead.axis_maximum.x-1} Y{printer.toolhead.axis_maximum.y-1} F{30*60}
G4 P1000
GET_POSITION
# Go to starting position
G0 X{x_min} Y{y_min} Z{bound + 10} F{speed*60}
# Set new limits
{% if printer.configfile.settings.printer.minimum_cruise_ratio is defined %}
SET_VELOCITY_LIMIT VELOCITY={speed} ACCEL={accel} MINIMUM_CRUISE_RATIO={min_cruise_ratio}
{% else %}
SET_VELOCITY_LIMIT VELOCITY={speed} ACCEL={accel} ACCEL_TO_DECEL={accel / 2}
{% endif %}
{% for i in range(iterations) %}
# Large pattern diagonals
G0 X{x_min} Y{y_min} F{speed*60}
G0 X{x_max} Y{y_max} F{speed*60}
G0 X{x_min} Y{y_min} F{speed*60}
G0 X{x_max} Y{y_min} F{speed*60}
G0 X{x_min} Y{y_max} F{speed*60}
G0 X{x_max} Y{y_min} F{speed*60}
# Large pattern box
G0 X{x_min} Y{y_min} F{speed*60}
G0 X{x_min} Y{y_max} F{speed*60}
G0 X{x_max} Y{y_max} F{speed*60}
G0 X{x_max} Y{y_min} F{speed*60}
# Small pattern diagonals
G0 X{x_center_min} Y{y_center_min} F{speed*60}
G0 X{x_center_max} Y{y_center_max} F{speed*60}
G0 X{x_center_min} Y{y_center_min} F{speed*60}
G0 X{x_center_max} Y{y_center_min} F{speed*60}
G0 X{x_center_min} Y{y_center_max} F{speed*60}
G0 X{x_center_max} Y{y_center_min} F{speed*60}
# Small pattern box
G0 X{x_center_min} Y{y_center_min} F{speed*60}
G0 X{x_center_min} Y{y_center_max} F{speed*60}
G0 X{x_center_max} Y{y_center_max} F{speed*60}
G0 X{x_center_max} Y{y_center_min} F{speed*60}
{% endfor %}
# Restore max speed/accel/accel_to_decel to their configured values
{% if printer.configfile.settings.printer.minimum_cruise_ratio is defined %}
SET_VELOCITY_LIMIT VELOCITY={printer.configfile.settings.printer.max_velocity} ACCEL={printer.configfile.settings.printer.max_accel} MINIMUM_CRUISE_RATIO={printer.configfile.settings.printer.minimum_cruise_ratio}
{% else %}
SET_VELOCITY_LIMIT VELOCITY={printer.configfile.settings.printer.max_velocity} ACCEL={printer.configfile.settings.printer.max_accel} ACCEL_TO_DECEL={printer.configfile.settings.printer.max_accel_to_decel}
{% endif %}
# Re-home and get position again for comparison:
M400 # Finish moves - https://github.com/AndrewEllis93/Print-Tuning-Guide/issues/66
G28 # This is a full G28 to fix an issue with CoreXZ - https://github.com/AndrewEllis93/Print-Tuning-Guide/issues/12
# Go to XY home positions (in case your homing override leaves it elsewhere)
G90
G0 X{printer.toolhead.axis_maximum.x-1} Y{printer.toolhead.axis_maximum.y-1} F{30*60}
G4 P1000
GET_POSITION
# Restore previous gcode state (absolute/relative, etc)
RESTORE_GCODE_STATE NAME=TEST_SPEED
[gcode_macro test]
gcode:
{% set iterations = params.ITERATIONS|default(5)|int %}
;G32
SAVE_GCODE_STATE NAME=TEST
G1 Z10
;SET_VELOCITY_LIMIT ACCEL=8000
SET_VELOCITY_LIMIT ACCEL=10000 SQUARE_CORNER_VELOCITY=12
{% for i in range(iterations) %}
G1 F18000
G1 X300 Y300
G1 X150 Y50
{% endfor %}
SET_VELOCITY_DEFAULT
RESTORE_GCODE_STATE NAME=TEST
[gcode_macro _bot_data]
variable_lapse_video_size: 0
variable_lapse_filename: 'None'
variable_lapse_path: 'None'
gcode:
M118 Setting bot lapse variables

158
macros/nozzle_scrub.cfg Normal file
View File

@@ -0,0 +1,158 @@
[gcode_macro clean_nozzle]
variable_location_bucket_rear: True
variable_enable_purge: True
# These parameters define your filament purging. The retract variable is used to retract right after purging to prevent unnecessary
# oozing. Some filament are particularly oozy and may continue to ooze out of the nozzle for a second or two after retracting. The
# ooze dwell variable makes allowance for this. Update as necessary. If you decided to not enable purge, you can ignore this section.
variable_purge_len: 20 ; Amount of filament, in mm, to purge.
variable_purge_spd: 150 ; Speed, in mm/min, of the purge.
variable_purge_temp_min: 200 ; Minimum nozzle temperature to permit a purge. Otherwise, purge will not occur.
variable_purge_ret: 2 ; Retract length, in mm, after purging to prevent slight oozing. Adjust as necessary.
variable_ooze_dwell: 4 ; Dwell/wait time, in seconds, after purging and retracting.
# Adjust this so that your nozzle scrubs within the brush. Currently defaulted to be a lot higher for safety. Be careful not to go too low!
variable_brush_top: 0
# These parameters define your scrubbing, travel speeds, safe z clearance and how many times you want to wipe. Update as necessary. Wipe
# direction is randomized based off whether the left or right bucket is randomly selected in the purge & scrubbing routine.
variable_clearance_z: 5 ; When traveling, but not cleaning, the clearance along the z-axis between nozzle and brush.
variable_wipe_qty: 3 ; Number of complete (A complete wipe: left, right, left OR right, left, right) wipes.
variable_prep_spd_xy: 3000 ; Travel (not cleaning) speed along x and y-axis in mm/min.
variable_prep_spd_z: 1500 ; Travel (not cleaning) speed along z axis in mm/min.
variable_wipe_spd_xy: 5000 ; Nozzle wipe speed in mm/min.
# These parameters define the size of the brush. Update as necessary. A visual reference is provided below. Note that orientation of
# parameters remain the same whether bucket is at rear or front.
#
# ← brush_width →
# _________________ ↑
# | | ↑ If you chose location_bucket_rear = True, Y position is acquired
# brush_start (x) | | brush_depth from your stepper_y position_max. Adjust your brush physically in
# |_________________| ↓ Y so that the nozzle scrubs within the brush.
# (y) ↓
# brush_front
# __________________________________________________________
# PRINTER FRONT
#
#
variable_brush_start: 75
# This value is defaulted from brush location in CAD (rear left). Change if your brush width is different.
variable_brush_width: 52
## These are only used if location_bucket_rear is False. You specify a custom location in y axis for your brush - see diagram above. ##
variable_brush_front: 0
variable_brush_depth: 2
# These parameters define the size of your purge bucket. Update as necessary. If you decided to not enable purge, you can ignore
# this section. A visual reference is provided below. Note that orientation of parameters remain the same whether bucket is at rear
# or front.
#
# bucket_gap
# ← ---- →
# __________________________________________
# | | | |
# | | | |
# bucket_start (x) | |______| |
# | | | |
# | | | |
# |_________________|. . . |_________________|
# ← ------------- → ← ------------- →
# bucket_left_width bucket_right_width
# _______________________________________________________________________________________
# PRINTER FRONT
#
## For V2.4 350mm build, uncomment below
variable_bucket_left_width: 92
# These values are defaulted from bucket geometry in CAD (rear left location). Change only if you're using a custom bucket.
variable_bucket_right_width: 40
variable_bucket_gap: 22
# For V1.8, you may need to measure where your bucket start is and input into bucket_start. Otherwise, a value of 0 is for a default
# installation of purge bucket at rear left.
variable_bucket_start: 0
variable_bucket_pos: 1
gcode:
STATUS_CLEANING
# First, check if the axes are homed.
{% if "xyz" in printer.toolhead.homed_axes %}
## Save the gcode state in this macro instance.
SAVE_GCODE_STATE NAME=clean_nozzle
## Set to absolute positioning.
G90
## Grab max position of Y-axis from config to use in setting a fixed y position for location_bucket_rear = True.
{% set Ry = printer.configfile.config["stepper_y"]["position_max"]|float %}
## Check if user enabled purge option or not.
{% if enable_purge %}
### Randomly select left or right bin for purge. 0 = left, 1 = right
SET_GCODE_VARIABLE MACRO=clean_nozzle VARIABLE=bucket_pos VALUE={(range(2) | random)}
### Raise Z for travel.
G1 Z{brush_top + clearance_z} F{prep_spd_z}
### Check if user chose to use rear location.
{% if location_bucket_rear %}
G1 Y{Ry} F{prep_spd_xy}
{% else %}
G1 Y{brush_front + (brush_depth / 2)} F{prep_spd_xy}
{% endif %}
### Position for purge. Randomly selects middle of left or right bucket. It references from the middle of the left bucket.
G1 X{bucket_start + (bucket_left_width / (2 - bucket_pos)) + (bucket_pos * bucket_gap) + (bucket_pos * (bucket_right_width / 2))}
### Perform purge if the temp is up to min temp. If not, it will skip and continue executing rest of macro. Small retract after
### purging to minimize any persistent oozing at 5x purge_spd. G4 dwell is in milliseconds, hence * 1000 in formula.
{% if printer.extruder.temperature >= purge_temp_min %}
M83 ; relative mode
G1 E{purge_len} F{purge_spd}
G1 E-{purge_ret} F{purge_spd * 5}
G4 P{ooze_dwell * 1000}
G92 E0 ; reset extruder
{% endif %}
{% endif %}
## Position for wipe. Either left or right of brush based off bucket_pos to avoid unnecessary travel.
G1 Z{brush_top + clearance_z} F{prep_spd_z}
G1 X{brush_start + (brush_width * bucket_pos)} F{prep_spd_xy}
## Check if user chose to use rear location.
{% if location_bucket_rear %}
G1 Y{Ry}
{% else %}
G1 Y{brush_front + (brush_depth / 2)}
{% endif %}
## Move nozzle down into brush.
G1 Z{brush_top} F{prep_spd_z}
## Perform wipe. Wipe direction based off bucket_pos for cool random scrubby routine.
{% for wipes in range(1, (wipe_qty + 1)) %}
G1 X{brush_start + (brush_width * (1 - bucket_pos))} F{wipe_spd_xy}
G1 X{brush_start + (brush_width * bucket_pos)} F{wipe_spd_xy}
{% endfor %}
## Clear from area.
M117 Cleaned!
G1 Z{brush_top + clearance_z} F{prep_spd_z}
G1 X{bucket_start + (bucket_left_width / 4)} F{prep_spd_xy} #bugfix for right side mounted buckets
## Restore the gcode state to how it was before the macro.
RESTORE_GCODE_STATE NAME=clean_nozzle
{% else %}
## raise error will stop any macros that clean_nozzle is referenced in from proceeding for safety.
{ action_raise_error("Please home your axes!") }
M117 Please home first!
{% endif %}
STATUS_READY

View File

@@ -0,0 +1,254 @@
# Macros for setting the status leds on the Voron StealthBurner toolhead (or for any neopixel-type leds).
#
# You will need to configure a neopixel (or other addressable led, such as dotstar). See
# https://www.klipper3d.org/Config_Reference.html#neopixel for configuration details.
#####################################
# INSTRUCTIONS #
#####################################
# How to use all this stuff:
#
# 1. Copy this .cfg file into your Klipper config directory and then add [include stealthburner_leds.cfg]
# to the top of your printer.cfg in order to register the LEDs and macros with Klipper.
# 2. Define your LEDs by editing [neopixel sb_leds] below and entering the data pin from your control board
# as well as the color order.
#
# Note: RGB and RGBW are different and must be defined explicitly. RGB and RGBW are also not able to
# be mix-and-matched in the same chain. A separate data line would be needed for proper functioning.
#
# RGBW LEDs will have a visible yellow-ish phosphor section to the chip. If your LEDs do not have
# this yellow portion, you have RGB LEDs.
#
# 3. Save your config and restart Klipper.
#
# Note: We set RED and BLUE to 1.0 to make it easier for users and supporters to detect
# misconfigurations or miswiring. The default color format is for Neopixels with a dedicated
# white LED. On startup, all three SB LEDs should light up.
#
# If you get random colors across your LEDs, change the color_order to GRB and restart. Then
# omit the W for each suggested color_order in the next paragraph.
#
# If you get MAGENTA, your color order is correct. If you get CYAN, you need to use RGBW. If
# you get YELLOW, you need to use BRGW (note that BRG is only supported in the latest Klipper
# version).
#
# 4. Once you have confirmed that the LEDs are set up correctly, you must now decide where you want
# these macros called up...which means adding them to your existing gcode macros. NOTHING will happen
# unless you add the STATUS_????? macros to your existing gcode macros.
#
# Example: add STATUS_LEVELING to the beginning of your QGL gcode macro, and then add STATUS_READY
# to the end of it to set the logo LED and nozzle LEDs back to the `ready` state.
#
# Example: add STATUS_CLEANING to the beginning of your nozzle-cleaning macro, and then STATUS_READY
# to the end of it to return the LEDs back to `ready` state.
#
# 5. Feel free to change colors of each macro, create new ones if you have a need to. The macros provided below
# are just an example of what is possible. If you want to try some more complex animations, you will most
# likely have to use WLED with Moonraker and a small micro-controller
#
#####################################
# END INSTRUCTRUCTIONS #
#####################################
[neopixel sb_leds]
#pin: EBBCan:gpio16 #sht:RGBLED
#pin: EXP1_6
# The pin connected to the neopixel. This parameter must be provided.
chain_count: 3
# The number of Neopixel chips that are "daisy chained" to the
# provided pin. The default is 1 (which indicates only a single
# Neopixel is connected to the pin).
color_order: GRBW
# Set the pixel order required by the LED hardware. Options are GRB,
# RGB, GRBW, or RGBW. The default is GRB.
initial_RED: 1.0
initial_GREEN: 0.0
initial_BLUE: 1.0
initial_WHITE: 0.0
# Sets the initial LED color of the Neopixel. Each value should be
# between 0.0 and 1.0. The WHITE option is only available on RGBW
# LEDs. The default for each color is 0.#
# Most configuration for the macros can be done by modifying the variables in the _sb_vars macro
# at the start of this file.
##########
# MACROS #
##########
# The following status macros are available (these go inside of your macros):
#
# STATUS_READY
# STATUS_OFF
# STATUS_BUSY
# STATUS_HEATING
# STATUS_LEVELING
# STATUS_HOMING
# STATUS_CLEANING
# STATUS_MESHING
# STATUS_CALIBRATING_Z
#
# With additional macros for basic control:
#
# SET_NOZZLE_LEDS_ON
# SET_LOGO_LEDS_OFF
# SET_NOZZLE_LEDS_OFF
#
# Contributed by Voron discord users wile.e, Tetsunosuke, and etherwalker
[gcode_macro _sb_vars]
# User settings for the StealthBurner status leds. You can change the status colors and led
# configurations for the logo and nozzle here.
variable_colors: {
'logo': { # Colors for logo states
'busy': {'r': 0.4, 'g': 0.0, 'b': 0.0, 'w': 0.0},
'cleaning': {'r': 0.0, 'g': 0.02, 'b': 0.5, 'w': 0.0},
'calibrating_z': {'r': 0.8, 'g': 0., 'b': 0.35, 'w': 0.0},
'heating': {'r': 0.3, 'g': 0.18, 'b': 0.0, 'w': 0.0},
'homing': {'r': 0.0, 'g': 0.6, 'b': 0.2, 'w': 0.0},
'leveling': {'r': 0.5, 'g': 0.1, 'b': 0.4, 'w': 0.0},
'meshing': {'r': 0.2, 'g': 1.0, 'b': 0.0, 'w': 0.0},
'off': {'r': 0.0, 'g': 0.0, 'b': 0.0, 'w': 0.0},
'printing': {'r': 1.0, 'g': 0.0, 'b': 0.0, 'w': 0.0},
'standby': {'r': 0.01, 'g': 0.01, 'b': 0.01, 'w': 0.1},
},
'nozzle': { # Colors for nozzle states
'heating': {'r': 0.8, 'g': 0.35, 'b': 0.0, 'w':0.0},
'off': {'r': 0.0, 'g': 0.0, 'b': 0.0, 'w': 0.0},
'on': {'r': 0.8, 'g': 0.8, 'b': 0.8, 'w':1.0},
'standby': {'r': 0.6, 'g': 0.0, 'b': 0.0, 'w':0.0},
},
'thermal': {
'hot': {'r': 1.0, 'g': 0.0, 'b': 0.0, 'w': 0.0},
'cold': {'r': 0.3, 'g': 0.0, 'b': 0.3, 'w': 0.0}
}
}
variable_logo_led_name: "sb_leds"
# The name of the addressable LED chain that contains the logo LED(s)
variable_logo_idx: "1"
# A comma-separated list of indexes LEDs in the logo
variable_nozzle_led_name: "sb_leds"
# The name of the addressable LED chain that contains the nozzle LED(s). This will
# typically be the same LED chain as the logo.
variable_nozzle_idx: "2,3"
# A comma-separated list of indexes of LEDs in the nozzle
gcode:
# This section is required. Do Not Delete.
[gcode_macro _set_sb_leds]
gcode:
{% 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 led = params.LED|string %}
{% set idx = (params.IDX|string).split(',') %}
{% set transmit_last = params.TRANSMIT|default(1) %}
{% for led_index in idx %}
{% set transmit=transmit_last if loop.last else 0 %}
set_led led={led} red={red} green={green} blue={blue} white={white} index={led_index} transmit={transmit}
{% endfor %}
[gcode_macro _set_sb_leds_by_name]
gcode:
{% set leds_name = params.LEDS %}
{% set color_name = params.COLOR %}
{% set color = printer["gcode_macro _sb_vars"].colors[leds_name][color_name] %}
{% set led = printer["gcode_macro _sb_vars"][leds_name + "_led_name"] %}
{% set idx = printer["gcode_macro _sb_vars"][leds_name + "_idx"] %}
{% set transmit = params.TRANSMIT|default(1) %}
_set_sb_leds led={led} red={color.r} green={color.g} blue={color.b} white={color.w} idx="{idx}" transmit={transmit}
[gcode_macro _set_logo_leds]
gcode:
{% 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 led = printer["gcode_macro _sb_vars"].logo_led_name %}
{% set idx = printer["gcode_macro _sb_vars"].logo_idx %}
{% set transmit=params.TRANSMIT|default(1) %}
_set_sb_leds led={led} red={red} green={green} blue={blue} white={white} idx="{idx}" transmit={transmit}
[gcode_macro _set_nozzle_leds]
gcode:
{% 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 led = printer["gcode_macro _sb_vars"].nozzle_led_name %}
{% set idx = printer["gcode_macro _sb_vars"].nozzle_idx %}
{% set transmit=params.TRANSMIT|default(1) %}
_set_sb_leds led={led} red={red} green={green} blue={blue} white={white} idx="{idx}" transmit={transmit}
[gcode_macro set_logo_leds_off]
gcode:
{% set transmit=params.TRANSMIT|default(1) %}
_set_logo_leds red=0 blue=0 green=0 white=0 transmit={transmit}
[gcode_macro set_nozzle_leds_on]
gcode:
{% set transmit=params.TRANSMIT|default(1) %}
_set_sb_leds_by_name leds="nozzle" color="on" transmit={transmit}
[gcode_macro set_nozzle_leds_off]
gcode:
{% set transmit=params.TRANSMIT|default(1) %}
_set_sb_leds_by_name leds="nozzle" color="off" transmit={transmit}
[gcode_macro status_off]
gcode:
set_logo_leds_off transmit=0
set_nozzle_leds_off
[gcode_macro status_ready]
gcode:
_set_sb_leds_by_name leds="logo" color="standby" transmit=0
_set_sb_leds_by_name leds="nozzle" color="standby" transmit=1
[gcode_macro status_busy]
gcode:
_set_sb_leds_by_name leds="logo" color="busy" transmit=0
set_nozzle_leds_on
[gcode_macro status_heating]
gcode:
_set_sb_leds_by_name leds="logo" color="heating" transmit=0
_set_sb_leds_by_name leds="nozzle" color="heating" transmit=1
[gcode_macro status_leveling]
gcode:
_set_sb_leds_by_name leds="logo" color="leveling" transmit=0
set_nozzle_leds_on
[gcode_macro status_homing]
gcode:
_set_sb_leds_by_name leds="logo" color="homing" transmit=0
set_nozzle_leds_on
[gcode_macro status_cleaning]
gcode:
_set_sb_leds_by_name leds="logo" color="cleaning" transmit=0
set_nozzle_leds_on
[gcode_macro status_meshing]
gcode:
_set_sb_leds_by_name leds="logo" color="meshing" transmit=0
set_nozzle_leds_on
[gcode_macro status_calibrating_z]
gcode:
_set_sb_leds_by_name leds="logo" color="calibrating_z" transmit=0
set_nozzle_leds_on
[gcode_macro status_printing]
gcode:
_set_sb_leds_by_name leds="logo" color="printing" transmit=0
set_nozzle_leds_on

91
macros/tools.cfg Normal file
View File

@@ -0,0 +1,91 @@
#Аргументы
#NAME (строка) — отфильтруйте результаты по названию (отображайте только переменные с названиями, содержащими эту строку)
#VALUE (строка) — отфильтруйте результаты по значению (отображайте только значения, содержащие это значение)
#SHOW_CFG (целое число, 0-1) — установите значение 1, чтобы включить в вывод всю конфигурацию. По умолчанию 0 (конфигурация отфильтровывается)
#Примеры
#DUMP_VARIABLES: Возвращает все переменные (за исключением printer['configfile'].config и printer['configfile'].settings, так как они содержат всю конфигурацию).
#DUMP_VARIABLES NAME=stepper: Возвращает все переменные, в имени которых есть строка stepper.
#DUMP_VARIABLES VALUE=extruder : Возвращает все переменные, в значении которых есть строка extruder.
#DUMP_VARIABLES NAME=stepper VALUE=extruder : Возвращает все переменные, в названии которых есть строка stepper и в значении которых есть строка extruder.
#DUMP_VARIABLES SHOW_CFG=1 : Возвращает все переменные, включая конфигурацию.
[gcode_macro DUMP_VARIABLES]
gcode:
{% set filter_name = params.NAME|default('')|string|lower %}
{% set filter_value = params.VALUE|default('')|string|lower %}
{% set show_cfg = params.SHOW_CFG|default(0)|int %}
{% set out = [] %}
{% for key1 in printer %}
{% for key2 in printer[key1] %}
{% if (show_cfg or not (key1|lower == 'configfile' and key2|lower in ['config', 'settings'])) and (filter_name in key1|lower or filter_name in key2|lower) and filter_value in printer[key1][key2]|string|lower %}
{% set dummy = out.append("printer['%s'].%s = %s" % (key1, key2, printer[key1][key2])) %}
{% endif %}
{% else %}
{% if filter_name in key1|lower and filter_value in printer[key1]|string|lower %}
{% set dummy = out.append("printer['%s'] = %s" % (key1, printer[key1])) %}
{% endif %}
{% endfor %}
{% endfor %}
{action_respond_info(out|join("\n"))}
#Аргументы
#NAME (строка) (обязательно) — укажите имя переменной, которую вы хотите получить.
#Примеры
#GET_VARIABLE NAME=toolhead: Возвращает значение и тип переменной printer.toolhead.
#GET_VARIABLE NAME=bed_mesh.profiles.default.points.1.0: Возвращает значение и тип переменной printer.bed_mesh.profiles.default.points[1][0].
[gcode_macro GET_VARIABLE]
gcode:
{% set names = (params.NAME).split('.')|list %}
{% set join = (params.JOIN)|default(1)|int %}
{% set _dummy0 = namespace( break = 0 ) %}
{% set _dummy1 = namespace( out = printer[names|first] ) %}
{% for name in names if _dummy0.break == 0 %}
{% if loop.index > 1 %}
{% if name in _dummy1.out %}
{% set _dummy1.out = _dummy1.out[name] %}
{% elif name[0] in '0123456789' and _dummy1.out is iterable and _dummy1.out is not string and _dummy1.out is not mapping and _dummy1.out|length > name[0]|int %}
{% set _dummy1.out = _dummy1.out[name|int] %}
{% else %}
{% set _dummy0.break = loop.index0 %}
{% endif %}
{% endif %}
{% endfor %}
{% if _dummy1.out is boolean %}
{ action_respond_info('Type: boolean') }
{% elif _dummy1.out is float %}
{ action_respond_info('Type: float') }
{% elif _dummy1.out is integer %}
{ action_respond_info('Type: integer') }
{% elif _dummy1.out is mapping %}
{ action_respond_info('Type: mapping') }
{% elif _dummy1.out is string %}
{ action_respond_info('Type: string') }
{% elif _dummy1.out is iterable %}
{ action_respond_info('Type: iterable') }
{% elif _dummy1.out is none %}
{ action_respond_info('Type: none') }
{% elif _dummy1.out is undefined %}
{ action_respond_info('Type: undefined') }
{% elif _dummy1.out is callable %}
{ action_respond_info('Type: callable') }
{% else %}
{ action_respond_info('Type: unknown') }
{% endif %}
{% if join and _dummy1.out is iterable and _dummy1.out is not string and _dummy1.out is not mapping %}
{ action_respond_info('%s' % _dummy1.out|join("\n")) }
{% else %}
{ action_respond_info('%s' % _dummy1.out) }
{% endif %}
{% if _dummy0.break != 0 %}
{ action_respond_info('"printer.%s" does not contain "%s"!' % (names[0:_dummy0.break]|join('.'), names[_dummy0.break])) }
{% endif %}