From ce87103da0ce063356d812c8d301bc578033712e Mon Sep 17 00:00:00 2001 From: Zach Schimke Date: Sat, 23 Jul 2022 01:28:37 -0700 Subject: [PATCH] Feat: Add klicky probe for bed leveling --- bed_mesh.cfg | 178 ++++++++++++ bed_screws.cfg | 9 +- printer.cfg | 10 + probe.cfg | 717 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 911 insertions(+), 3 deletions(-) create mode 100644 bed_mesh.cfg create mode 100644 probe.cfg diff --git a/bed_mesh.cfg b/bed_mesh.cfg new file mode 100644 index 0000000..53742fb --- /dev/null +++ b/bed_mesh.cfg @@ -0,0 +1,178 @@ +##################################################################### +# Bed Mesh Definition +##################################################################### +[bed_mesh] +speed: 100 +horizontal_move_z: 20 +mesh_min: 15,15 +mesh_max: 105,105 +algorithm: lagrange +## relative_reference_index should be the location where the +## For the center of the bed: [(7x7)-1] / 2 = position 24 +probe_count: 3,3 +relative_reference_index: 4 +#fade_start: 1 +#fade_end: 10 +#fade_target: 0 +move_check_distance: 3 +split_delta_z: 0.0125 +mesh_pps: 2,2 +#bicubic_tension: 0.2 + + +##################################################################### +# Macros +##################################################################### +[gcode_macro BED_MESH_CALIBRATE] +rename_existing: _BED_MESH_CALIBRATE +description: Perform Mesh Bed Leveling with klicky automount +variable_parameter_AREA_START : 0,0 +variable_parameter_AREA_END : 0,0 +; the clearance between print area and probe area +variable_mesh_area_offset : 5.0 +; number of sample per probe point +variable_probe_samples : 2 +; minimum probe count +variable_min_probe_count : 3 +; scale up the probe count, should be 1.0 ~ < variable_max_probe_count/variable_min_probe_count +variable_probe_count_scale_factor : 1.0 +gcode: + {% set V = printer["gcode_macro _User_Variables"].verbose %} + {% if V %} + { action_respond_info("Bed Mesh Calibrate") } + {% endif %} + + BED_MESH_CLEAR + SMARTHOME + + _CheckProbe action=query + G90 + Attach_Probe_Lock + + SMARTQGL + {% if params.AREA_START and params.AREA_END %} + {% set bedMeshConfig = printer["configfile"].config["bed_mesh"] %} + {% set safe_min_x = bedMeshConfig.mesh_min.split(",")[0]|float %} + {% set safe_min_y = bedMeshConfig.mesh_min.split(",")[1]|float %} + {% set safe_max_x = bedMeshConfig.mesh_max.split(",")[0]|float %} + {% set safe_max_y = bedMeshConfig.mesh_max.split(",")[1]|float %} + + {% set area_min_x = params.AREA_START.split(",")[0]|float %} + {% set area_min_y = params.AREA_START.split(",")[1]|float %} + {% set area_max_x = params.AREA_END.split(",")[0]|float %} + {% set area_max_y = params.AREA_END.split(",")[1]|float %} + + {% if bedMeshConfig.probe_count.split(",")|length == 2 %} + {% set meshPointX = bedMeshConfig.probe_count.split(",")[0]|int %} + {% set meshPointY = bedMeshConfig.probe_count.split(",")[1]|int %} + {% else %} + {% set meshPointX = bedMeshConfig.probe_count.split(",")[0]|int %} + {% set meshPointY = bedMeshConfig.probe_count.split(",")[0]|int %} + {% endif %} + + {% set meshMaxPointX = meshPointX %} + {% set meshMaxPointY = meshPointY %} + + + {% if (area_min_x < area_max_x) and (area_min_y < area_max_y) %} + {% if area_min_x - mesh_area_offset >= safe_min_x %} + {% set area_min_x = area_min_x - mesh_area_offset %} + {% else %} + {% set area_min_x = safe_min_x %} + {% endif %} + + {% if area_min_y - mesh_area_offset >= safe_min_y %} + {% set area_min_y = area_min_y - mesh_area_offset %} + {% else %} + {% set area_min_y = safe_min_y %} + {% endif %} + + {% if area_max_x + mesh_area_offset <= safe_max_x %} + {% set area_max_x = area_max_x + mesh_area_offset %} + {% else %} + {% set area_max_x = safe_max_x %} + {% endif %} + + {% if area_max_y + mesh_area_offset <= safe_max_y %} + {% set area_max_y = area_max_y + mesh_area_offset %} + {% else %} + {% set area_max_y = safe_max_y %} + {% endif %} + + {% set meshPointX = (meshPointX * (area_max_x - area_min_x) / (safe_max_x - safe_min_x) * probe_count_scale_factor)|round(0)|int %} + {% if meshPointX < min_probe_count %} + {% set meshPointX = min_probe_count %} + {% endif %} + {% if meshPointX > meshMaxPointX %} + {% set meshPointX = meshMaxPointX %} + {% endif %} + + {% set meshPointY = (meshPointY * (area_max_y -area_min_y ) / (safe_max_y - safe_min_y) * probe_count_scale_factor )|round(0)|int %} + {% if meshPointY < min_probe_count %} + {% set meshPointY = min_probe_count %} + {% endif %} + {% if meshPointY > meshMaxPointY %} + {% set meshPointY = meshMaxPointY %} + {% endif %} + + _BED_MESH_CALIBRATE mesh_min={area_min_x},{area_min_y} mesh_max={area_max_x},{area_max_y} probe_count={meshPointX},{meshPointY} samples={probe_samples|int} + {% else %} + _BED_MESH_CALIBRATE + {% endif %} + {% else %} + _BED_MESH_CALIBRATE + {% endif %} + Dock_Probe_Unlock + + +## use MESH_STORE -> generate MESH and save immediately +## use MESH_STORE SAVE=false -> generate MESH and save it later +[gcode_macro MESH_STORE] +variable_save_at_end: 'false' +gcode: + # set default parameter value + {% set save = params.SAVE|default('true') %} + BED_MESH_CALIBRATE + BED_MESH_PROFILE SAVE=Voron-Bed_Temp-{printer.heater_bed.target|int}C + BED_MESH_PROFILE REMOVE=default + # Move to Middle + G90 ; set absolute + G0 Z7.5 F900 ; lift nozzle + G0 X175 Y175 Z30 F7200 ; move to middle + {% if save|lower == 'true' %} + _PRINT_AR T="MESH: Save Config!" + SAVE_CONFIG + {% else %} + _PRINT_AR T="MESH: Save Config after print done" + SET_GCODE_VARIABLE MACRO=MESH_STORE VARIABLE=save_at_end VALUE='"true"' + {% endif %} + +## use MESH_LOAD -> load an existing MESH +## use MESH_LOAD AUTO=true -> load an existing MESH or generate a new one and prepare it to be saved after print end +[gcode_macro MESH_LOAD] +# set that to true to enable autogeneration of a missing mesh +gcode: + # set default parameter value + {% set auto = params.AUTO|default('false') %} + {% set bed_temp = printer.heater_bed.target|int %} + {% if printer.configfile.config["bed_mesh Voron-Bed_Temp-" + bed_temp|string + "C"] is defined %} + BED_MESH_CLEAR + BED_MESH_PROFILE LOAD=Voron-Bed_Temp-{printer.heater_bed.target|int}C + _PRINT_AR T="{"MESH: Voron-Bed_Temp-" + bed_temp|string + "C loaded"}" + {% else %} + {% if auto|lower == 'true' %} + _PRINT_AR T="{"MESH: Voron-Bed_Temp-" + bed_temp|string + "C needs to be generated"}" + MESH_STORE SAVE=false + {% else %} + _PRINT_AR T="{"MESH ERROR: Voron-Bed_Temp-" + bed_temp|string + "C not defined"}" + {% endif %} + {% endif %} + +## add this to your PRINT_END to save a mesh if needed 10 seconds after print ended +## UPDATE_DELAYED_GCODE ID=_MESH_SAVE DURATION=10 +[delayed_gcode _MESH_SAVE] +gcode: + {% if printer["gcode_macro MESH_STORE"].save_at_end == 'true' %} + _PRINT_AR T="MESH: Save Config!" + SAVE_CONFIG + {% endif %} diff --git a/bed_screws.cfg b/bed_screws.cfg index 134d4dc..cb63568 100644 --- a/bed_screws.cfg +++ b/bed_screws.cfg @@ -1,7 +1,10 @@ -[bed_screws] +[screws_tilt_adjust] screw1: 60,5 screw1_name: front screw -screw2: 5,115 +screw2: 0,115 screw2_name: back left -screw3: 115,115 +screw3: 100,115 screw3_name: back right +horizontal_move_z: 20 +speed: 100 +screw_thread: CW-M3 diff --git a/printer.cfg b/printer.cfg index 77dedf3..2b1b060 100644 --- a/printer.cfg +++ b/printer.cfg @@ -8,6 +8,11 @@ [include machine.cfg] [include pi.cfg] +##################################################################### +# Bed/Gantry Leveling Probe +##################################################################### +[include probe.cfg] + ##################################################################### # Macros ##################################################################### @@ -23,6 +28,11 @@ ##################################################################### [include homing.cfg] +##################################################################### +# Bed Mesh +##################################################################### +[include bed_mesh.cfg] + ##################################################################### # Calibration ##################################################################### diff --git a/probe.cfg b/probe.cfg new file mode 100644 index 0000000..02306eb --- /dev/null +++ b/probe.cfg @@ -0,0 +1,717 @@ +#################################################################### +# Probe +##################################################################### + +[probe] +## Klicky Probe +## This probe is not used for Z height, only bed leveling +pin: PWE_DCT +x_offset: 9.5 +y_offset: 0 +z_offset: 14.5 +speed: 4 +lift_speed: 15 +samples: 3 +samples_result: median +sample_retract_dist: 2 +samples_tolerance: 0.01 +samples_tolerance_retries: 10 +drop_first_result: true + + +##################################################################### +# Menu +##################################################################### + + +##################################################################### +# Macros +##################################################################### +# This macro was provided by discord user Garrettwp to whom i give my thanks for sharing it with me. +# I have tweaked it a lot. +# +# this macro is based on the great Annex magprobe dockable probe macros "#Originally developed by Mental, modified for better use on K-series printers by RyanG and Trails" +# that macro can be found here https://github.com/Annex-Engineering/Annex-Engineering_Other_Printer_Mods/blob/master/All_Printers/Microswitch_Probe/Klipper_Macros/dockable_probe_macros.cfg +# +# by standing on the shoulders of giants, lets see if we can see further +# Klicky-probe.cfg version 16-11-2021 01 +[gcode_macro _User_Variables] +variable_verbose: True # Enable verbose output +variable_debug: False # Enable Debug output +variable_travel_speed: 100 # how fast all other travel moves will be performed when running these macros +variable_move_accel: 1000 # how fast should the toolhead accelerate when moving +variable_dock_speed: 50 # how fast should the toolhead move when docking the probe for the final movement +variable_release_speed: 55 # how fast should the toolhead move to release the hold of the magnets after docking +variable_z_drop_speed: 20 # how fast the z will lower when moving to the z location to clear the probe +variable_safe_z: 20 # Minimum Z for attach/dock and homing functions +# if true it will move the bed away from the nozzle when Z is not homed +variable_enable_z_hop: True # set this to false for beds that fall significantly under gravity (almost to Z max) + +variable_max_bed_y: 120 # maximum Bed size avoids doing a probe_accuracy outside the bed +variable_max_bed_x: 120 # maximum Bed size avoids doing a probe_accuracy outside the bed + +# if a separate Z endstop switch is in +# use, specify the coordinates of the switch here (Voron). +# Set to 0 to have the probe move to center of bed +variable_z_endstop_x: 0 +variable_z_endstop_y: 0 + +#Check the printer specific documentation on klipper Dock/Undock configuration, these are dummy values +#dock location +variable_docklocation_x: 120 # X Dock position +variable_docklocation_y: 0 # Y Dock position +variable_docklocation_z: 10 # Z dock position, (-128 for a gantry mount) + +#The following variables are used if the dock is deployed and retracted via a servo motor +variable_enable_dock_servo: False # Set to true if your klicky dock is servo-controlled +variable_servo_name: 'NAME' # The name of the dock servo defined in printer.cfg under [servo] +variable_servo_deploy: 10 # This EXAMPLE is the value used to deploy the servo fully +variable_servo_retract: 11 # This EXAMPLE is the value used to retract the servo fully (initial_angle in [servo] config) +variable_servo_delay: 1000 # This is a delay to wait the servo to reach the requested position, be carefull with high values + +#Dock move, final toolhead movement to release the probe on the dock +#it's a relative move +Variable_dockmove_x: 0 +Variable_dockmove_y: 40 +Variable_dockmove_z: 0 + +#Attach move. final toolhead movement to attach the probe on the mount +#it's a relative move +Variable_attachmove_x: 30 # Toolhead movement necessary to clear the dock arms +Variable_attachmove_y: 0 +Variable_attachmove_z: 0 + +#Umbilical to help untangle the umbilical in difficult situations +variable_umbilical: False # should we untangle the umbilical +variable_umbilical_x: 15 # X umbilical position +variable_umbilical_y: 15 # Y umbilical position + +# location to park the toolhead +variable_park_toolhead: False # Enable toolhead parking +variable_parkposition_x: 125 +variable_parkposition_y: 125 +variable_parkposition_z: 30 + +variable_version: 1 # Helps users to update the necessary variables, do not update if the variables above are not updated + +#Below this remark, you normally do not need to configure +#Attach move2 +Variable_attachmove2_x: 0 # intermediate toolhead movement to attach +Variable_attachmove2_y: 0 # the probe on the dock +Variable_attachmove2_z: 0 # (can be negative) + +variable_home_backoff: 10 # how many mm to move away from the endstop after homing + +variable_override_homing: '' # configures what axis to home first + # '' = default klicky behavior (tries to avoid the hitting the dock + # 'X' = forces X to home first + # 'Y' = forces Y to home first + +# Do not modify below +gcode: + {% set Mx = printer['configfile'].config["stepper_x"]["position_max"]|float %} + {% set My = printer['configfile'].config["stepper_y"]["position_max"]|float %} + {% set Ox = printer['configfile'].config["probe"]["x_offset"]|float %} + {% set Oy = printer['configfile'].config["probe"]["y_offset"]|float %} + {% set Oz = printer['configfile'].config["probe"]["z_offset"]|float %} + + # If x, y coordinates are set for z endstop, assign them + {% if z_endstop_x != 0 or z_endstop_y != 0 %} + SET_GCODE_VARIABLE MACRO=_Probe_Variables VARIABLE=z_endstop_x VALUE={ z_endstop_x } + SET_GCODE_VARIABLE MACRO=_Probe_Variables VARIABLE=z_endstop_y VALUE={ z_endstop_y } + + # if no x, y coordinates for z endstop, assume probe is endstop and move toolhead to center of bed + {% else %} + SET_GCODE_VARIABLE MACRO=_Probe_Variables VARIABLE=z_endstop_x VALUE={ (Mx * 0.5) - Ox } + SET_GCODE_VARIABLE MACRO=_Probe_Variables VARIABLE=z_endstop_y VALUE={ (My * 0.5) - Oy } + {% endif %} + +[gcode_macro _Probe_Variables] +variable_probe_attached: False +variable_probe_state: False +variable_probe_lock: False +variable_z_endstop_x: 0 +variable_z_endstop_y: 0 +gcode: + + +#checks if the variable definitions are up to date +[gcode_macro _klicky_check_variables_version] +gcode: + {% set version = printer["gcode_macro _User_Variables"].version|default(0) %} + + {% if version != 1 %} + { action_raise_error("Please update your klicky variables, there are some functionality changes") } + {% endif %} + + +[gcode_macro _KlickyDebug] +gcode: + {% set message = params.MSG %} + {% set debug = printer["gcode_macro _User_Variables"].debug|default(False) %} + + {% if debug %} + { action_respond_info(message) } + {% endif %} + + +[gcode_macro _exit_point] +gcode: + {% set function = 'pre_' ~ params.FUNCTION %} + {% set move = params.MOVE|default(0) %}i + {% set speed = printer["gcode_macro _User_Variables"].travel_speed %} + + # mandatory to save the new safe position + M400 + RESTORE_GCODE_STATE NAME={function} MOVE={move} + SET_VELOCITY_LIMIT ACCEL={printer.configfile.settings.printer.max_accel} + SET_VELOCITY_LIMIT ACCEL_TO_DECEL={printer.configfile.settings.printer.max_accel_to_decel} + RESTORE_GCODE_STATE NAME={function} MOVE={move} MOVE_SPEED={speed} + +[gcode_macro _entry_point] +gcode: + {% set function = 'pre_' ~ params.FUNCTION %} + {% set move_accel = printer["gcode_macro _User_Variables"].move_accel|default(1000) %} + # mandatory to save the new safe position + M400 + SAVE_GCODE_STATE NAME={function} + # removes the Z offset for better bed based docking + SET_GCODE_OFFSET Z=0 + # all the macros initially assume absolute positioning + G90 + # set a safe(sane) Acceleration + SET_VELOCITY_LIMIT ACCEL={move_accel} + +[gcode_macro _Homing_Variables] +gcode: + {% set reset = params.RESET|default(0) %} + {% if reset %} + SET_GCODE_VARIABLE MACRO=_Probe_Variables VARIABLE=probe_lock VALUE={ False } + {% endif %} + +# Attach probe and lock it +[gcode_macro Attach_Probe_Lock] +description: Attaches Klicky Probe, can only be docked after unlocking +gcode: + Attach_Probe + _Probe_Lock + +# Dock probe and lock it +[gcode_macro Dock_Probe_Unlock] +description: Docks Klicky Probe even if it was locked +gcode: + _Probe_Unlock + Dock_Probe + +# Unlock Probe +[gcode_macro Probe_Unlock] +description: Unlocks Klicky Probe state +gcode: + _KlickyDebug msg="_Probe_Lock setting probe_lock variable to False" + SET_GCODE_VARIABLE MACRO=_Probe_Variables VARIABLE=probe_lock VALUE={ False } + +# Lock Probe +[gcode_macro Probe_Lock] +description: Locks Klicky Probe state +gcode: + _KlickyDebug msg="_Probe_Lock setting probe_lock variable to True" + SET_GCODE_VARIABLE MACRO=_Probe_Variables VARIABLE=probe_lock VALUE={ True } + + +# Klicky Dock Servo Deploy +[gcode_macro _DeployKlickyDock] +description: Deploys Klicky servo-controlled dock +gcode: + {% set enable_dock_servo = printer["gcode_macro _User_Variables"].enable_dock_servo|default(False) %} + {% set servo_delay = printer["gcode_macro _User_Variables"].servo_delay|default(1000) %} + {% set servo_name = printer["gcode_macro _User_Variables"].servo_name %} + {% set servo_deploy = printer["gcode_macro _User_Variables"].servo_deploy|default(360) %} + + #wait for all the moves to complete + M400 + {% if enable_dock_servo != False %} + _KlickyDebug msg="_DeployKlickyDock Klicky servo configuration enabled" + {% if servo_deploy == 360 %} + { action_raise_error("Klicky: servo active on klicky-variables, but no servo deploy angle specified") } + {% endif %} + _KlickyDebug msg="_DeployKlickyDock SET_SERVO SERVO={servo_name|string} ANGLE={servo_deploy|int}" + SET_SERVO SERVO={servo_name|string} ANGLE={servo_deploy|int} + M400 + G4 P{servo_delay|int} + _KlickyDebug msg="_DeployKlickyDock SET_SERVO SERVO={servo_name|string} WIDTH=0" + SET_SERVO SERVO={servo_name|string} WIDTH=0 + {% elif printer["gcode_macro _DeployDock"] is defined %} + _KlickyDebug msg="_DeployKlickyDock calling _DeployDock" + _DeployDock + {% endif %} + + +# Dock Servo Retract +[gcode_macro _RetractKlickyDock] +description: Retracts Klicky servo-controlled dock +gcode: + {% set enable_dock_servo = printer["gcode_macro _User_Variables"].enable_dock_servo|default(False) %} + {% set servo_delay = printer["gcode_macro _User_Variables"].servo_delay|default(1000) %} + {% set servo_name = printer["gcode_macro _User_Variables"].servo_name %} + {% set servo_retract = printer["gcode_macro _User_Variables"].servo_retract|default(360) %} + + #wait for all the moves to complete + M400 + {% if enable_dock_servo != False %} + _KlickyDebug msg="_RetractKlickyDock Klicky servo configuration enabled" + {% if servo_retract == 360 %} + { action_raise_error("Klicky: servo active on klicky-variables, but no servo retract angle specified") } + {% endif %} + _KlickyDebug msg="_RetractKlickyDock SET_SERVO SERVO={servo_name|string} ANGLE={servo_retract|int}" + SET_SERVO SERVO={servo_name|string} ANGLE={servo_retract|int} + M400 + G4 P{servo_delay|int} + _KlickyDebug msg="_RetractKlickyDock SET_SERVO SERVO={servo_name|string} WIDTH=0" + SET_SERVO SERVO={servo_name|string} WIDTH=0 + {% elif printer["gcode_macro _RetractDock"] is defined %} + _KlickyDebug msg="_RetractKlickyDock calling _RetractDock" + _RetractDock + {% endif %} + + +# Attach Probe Routine +[gcode_macro Attach_Probe] +description: Attaches Klicky Probe +gcode: + # See if the position should be restored after the attach + {% set goback = params.BACK|default(0) %} + # Get probe attach status + {% set probe_attached = printer["gcode_macro _Probe_Variables"].probe_attached %} + {% set probe_lock = printer["gcode_macro _Probe_Variables"].probe_lock %} + {% set verbose = printer["gcode_macro _User_Variables"].verbose %} + # Get Docking location + {% set dockmove_x = printer["gcode_macro _User_Variables"].dockmove_x|default(0) %} + {% set dockmove_y = printer["gcode_macro _User_Variables"].dockmove_y|default(0) %} + {% set dockmove_z = printer["gcode_macro _User_Variables"].dockmove_z|default(0) %} + {% set docklocation_x = printer["gcode_macro _User_Variables"].docklocation_x %} + {% set docklocation_y = printer["gcode_macro _User_Variables"].docklocation_y %} + {% set docklocation_z = printer["gcode_macro _User_Variables"].docklocation_z %} + {% set attachmove_x = printer["gcode_macro _User_Variables"].attachmove_x|default(0) %} + {% set attachmove_y = printer["gcode_macro _User_Variables"].attachmove_y|default(0) %} + {% set attachmove_z = printer["gcode_macro _User_Variables"].attachmove_z|default(0) %} + {% set attachmove2_x = printer["gcode_macro _User_Variables"].attachmove2_x|default(0) %} + {% set attachmove2_y = printer["gcode_macro _User_Variables"].attachmove2_y|default(0) %} + {% set attachmove2_z = printer["gcode_macro _User_Variables"].attachmove2_z|default(0) %} + # Safe Z for travel + {% set safe_z = printer["gcode_macro _User_Variables"].safe_z %} + {% set enable_z_hop = printer["gcode_macro _User_Variables"].enable_z_hop %} + # Set speed + {% set travel_feedrate = printer["gcode_macro _User_Variables"].travel_speed * 60 %} + {% set dock_feedrate = printer["gcode_macro _User_Variables"].dock_speed * 60 %} + {% set release_feedrate = printer["gcode_macro _User_Variables"].release_speed * 60 %} + {% set z_drop_feedrate = printer["gcode_macro _User_Variables"].z_drop_speed * 60 %} + + _entry_point function=Attach_Probe + + # If x and y are not homed + {% if not 'xy' in printer.toolhead.homed_axes %} + { action_raise_error("Must Home X and Y Axis First!") } + _KlickyDebug msg="Attach_Probe Axis homed" + + # If probe not attached and locked + {% elif not probe_attached and not probe_lock %} + _KlickyDebug msg="Attach_Probe going to attach probe" + {% if verbose %} + { action_respond_info("Attaching Probe") } + {% endif %} + _KLICKY_STATUS_BUSY + + {% if not 'z' in printer.toolhead.homed_axes %} + {% if verbose %} + { action_respond_info("Resetting Z position to zero") } + {% endif %} + _KlickyDebug msg="Attach_Probe Z not homed, setting position as X=Y=Z=0" + SET_KINEMATIC_POSITION Z=0 + {% if not enable_z_hop %} # Disables safe_z + _KlickyDebug msg="Attach_Probe z_hop disabled" + {% set safe_z = 0 %} + {% endif %} + {% endif %} + + # Prior to saving actual position, check if its necessary to move to a safe Z + # that has enought overhead for the attached probe + {% if printer.toolhead.position.z < safe_z %} + _KlickyDebug msg="Attach_Probe toolhead too low, raising it by {safe_z}mm" + {% if verbose %} + { action_respond_info("moving to a safe Z distance") } + {% endif %} + G0 Z{safe_z} F{z_drop_feedrate} + {% endif %} + + {% if not 'z' in printer.toolhead.homed_axes %} #duplicate?? + {% if verbose %} + { action_respond_info("Resetting Z position to zero, duplicate?") } + {% endif %} + _KlickyDebug msg="Attach_Probe Z not homed, setting position as X=Y=Z=0" + SET_KINEMATIC_POSITION Z=0 + {% endif %} + + {% if printer.toolhead.position.z < safe_z %} #duplicate?? + _KlickyDebug msg="Attach_Probe toolhead too low, raising it by {safe_z}mm, duplicate?" + G0 Z{safe_z} F{z_drop_feedrate} + {% endif %} + + _Umbilical_Path + + _entry_point function=Attach_Probe_intern + + # Probe entry location + _KlickyDebug msg="Attach_Probe moving near the dock with G0 X{docklocation_x|int - attachmove_x|int - attachmove2_x|int} Y{docklocation_y|int - attachmove_y|int - attachmove2_y} F{travel_feedrate}" + G0 X{docklocation_x|int - attachmove_x|int - attachmove2_x|int} Y{docklocation_y|int - attachmove_y|int - attachmove2_y} F{travel_feedrate} + {% if docklocation_z != -128 %} + _KlickyDebug msg="Attach_Probe moving near the dock with G0 Z{docklocation_z|int - attachmove_z|int - attachmove2_z|int} F{dock_feedrate}" + G0 Z{docklocation_z|int - attachmove_z|int - attachmove2_z|int} F{dock_feedrate} + _KlickyDebug msg="Attach_Probe moving near the dock with G0 Z{docklocation_z|int - attachmove_z|int} F{dock_feedrate}" + G0 Z{docklocation_z|int - attachmove_z|int} F{dock_feedrate} + {% endif %} + + # if necessary do some actions before moving the toolhead to dock + _DeployKlickyDock + + + # Drop Probe to Probe location + {% if docklocation_z != -128 %} + _KlickyDebug msg="Attach_Probe moving to the dock with G0 Z{docklocation_z} F{dock_feedrate}" + G0 Z{docklocation_z} F{dock_feedrate} + {% endif %} + _KlickyDebug msg="Attach_Probe moving to the dock with G0 X{docklocation_x|int - attachmove2_x|int} Y{docklocation_y|int - attachmove2_y} F{dock_feedrate}" + G0 X{docklocation_x|int - attachmove2_x|int} Y{docklocation_y|int - attachmove2_y} F{dock_feedrate} + _KlickyDebug msg="Attach_Probe moving to the dock with G0 X{docklocation_x} Y{docklocation_y} F{dock_feedrate}" + G0 X{docklocation_x} Y{docklocation_y} F{dock_feedrate} + + # Probe Attached + {% if docklocation_z != -128 %} + _KlickyDebug msg="Attach_Probe moving from the dock to G0 Z{docklocation_z|int - attachmove_z|int} F{z_drop_feedrate}" + G0 Z{docklocation_z|int - attachmove_z|int} F{z_drop_feedrate} + {% endif %} + _KlickyDebug msg="Attach_Probe moving from the dock to G0 X{docklocation_x|int - attachmove_x|int} Y{docklocation_y|int - attachmove_y|int} F{release_feedrate}" + G0 X{docklocation_x|int - attachmove_x|int} Y{docklocation_y|int - attachmove_y|int} F{release_feedrate} + + # if necessary do some actions after attaching the probe + _RetractKlickyDock + + # Go to Z safe distance + {% if printer.toolhead.position.z < safe_z %} + _KlickyDebug msg="Attach_Probe moving to a safe Z position: G0 Z{safe_z} F{z_drop_feedrate}" + G0 Z{safe_z} F{z_drop_feedrate} + {% endif %} + + _Park_Toolhead + + _CheckProbe action=attach + + _exit_point function=Attach_Probe_intern move={goback} + _KLICKY_STATUS_READY + + {% elif probe_lock %} + {% if verbose %} + { action_respond_info("Probe locked!") } + {% endif %} + + # Probe attached, do nothing + _KlickyDebug msg="Attach_Probe probe locked not attaching probe" + _CheckProbe action=query + + {% else %} + {% if verbose %} + { action_respond_info("Probe already attached!") } + {% endif %} + + # Probe attached, do nothing + _KlickyDebug msg="Attach_Probe probe already attached, doing nothing" + _CheckProbe action=query + + {% endif %} + + _exit_point function=Attach_Probe + + +# Dock Probe Routine +[gcode_macro Dock_Probe] +description: Docks Klicky Probe +gcode: + # See if the position should be restored after the dock + {% set goback = params.back|default(0) %} + # Get probe attach status + {% set probe_attached = printer["gcode_macro _Probe_Variables"].probe_attached %} + {% set probe_lock = printer["gcode_macro _Probe_Variables"].probe_lock %} + {% set verbose = printer["gcode_macro _User_Variables"].verbose %} + # Get Docking location + {% set dockmove_x = printer["gcode_macro _User_Variables"].dockmove_x|default(0) %} + {% set dockmove_y = printer["gcode_macro _User_Variables"].dockmove_y|default(0) %} + {% set dockmove_z = printer["gcode_macro _User_Variables"].dockmove_z|default(0) %} + {% set docklocation_x = printer["gcode_macro _User_Variables"].docklocation_x %} + {% set docklocation_y = printer["gcode_macro _User_Variables"].docklocation_y %} + {% set docklocation_z = printer["gcode_macro _User_Variables"].docklocation_z %} + {% set attachmove_x = printer["gcode_macro _User_Variables"].attachmove_x|default(0) %} + {% set attachmove_y = printer["gcode_macro _User_Variables"].attachmove_y|default(0) %} + {% set attachmove_z = printer["gcode_macro _User_Variables"].attachmove_z|default(0) %} + # Safe Z for travel + {% set safe_z = printer["gcode_macro _User_Variables"].safe_z|float %} + # Set feedrates + {% set travel_feedrate = printer["gcode_macro _User_Variables"].travel_speed * 60 %} + {% set dock_feedrate = printer["gcode_macro _User_Variables"].dock_speed * 60 %} + {% set release_feedrate = printer["gcode_macro _User_Variables"].release_speed * 60 %} + {% set z_drop_feedrate = printer["gcode_macro _User_Variables"].z_drop_speed * 60 %} + + # If axis aren't homed, fail + {% if not 'xyz' in printer.toolhead.homed_axes %} + { action_raise_error("Must Home X, Y and Z Axis First!") } + {% endif %} + _KlickyDebug msg="Dock_Probe Axis homed" + + _entry_point function=Dock_Probe + + # If probe not attached and not locked + {% if probe_attached and not probe_lock %} + _KlickyDebug msg="Dock_Probe going to dock probe" + {% if verbose %} + { action_respond_info("Docking Probe") } + {% endif %} + _KLICKY_STATUS_BUSY + + {% if printer.toolhead.position.z < safe_z %} + _KlickyDebug msg="Dock_Probe toolhead too low, raising it to {safe_z}mm" + G0 Z{safe_z} F{z_drop_feedrate} + {% endif %} + + _Umbilical_Path + + # Probe entry location + _KlickyDebug msg="Dock_Probe moving near the dock with G0 X{docklocation_x|int - attachmove_x|int} Y{docklocation_y|int - attachmove_y|int} F{travel_feedrate}" + G0 X{docklocation_x|int - attachmove_x|int} Y{docklocation_y|int - attachmove_y|int} F{travel_feedrate} + {% if docklocation_z != -128 %} + _KlickyDebug msg="Dock_Probe moving near the dock with G0 Z{docklocation_z|int - attachmove_z|int} F{dock_feedrate}" + G0 Z{docklocation_z|int - attachmove_z|int} F{dock_feedrate} + {% endif %} + + # if necessary do some actions before moving the toolhead to dock + _DeployKlickyDock + + # Drop Probe to Probe location + _KlickyDebug msg="Dock_Probe moving to the dock with G0 X{docklocation_x} Y{docklocation_y} F{dock_feedrate}" + G0 X{docklocation_x} Y{docklocation_y} F{dock_feedrate} + {% if docklocation_z != -128 %} + _KlickyDebug msg="Attach_Probe moving to the dock with G0 Z{docklocation_z} F{dock_feedrate}" + G0 Z{docklocation_z} F{dock_feedrate} + {% endif %} + + # Probe decoupling + {% if docklocation_z != -128 %} + _KlickyDebug msg="Dock_Probe moving from the dock to G0 Z{docklocation_z|int + dockmove_z|int} F{release_feedrate}" + G0 Z{docklocation_z|int + dockmove_z|int} F{release_feedrate} + {% endif %} + _KlickyDebug msg="Dock_Probe moving from the dock to G0 X{docklocation_x|int + dockmove_x|int} Y{docklocation_y|int + dockmove_y|int} F{release_feedrate}" + G0 X{docklocation_x|int + dockmove_x|int} Y{docklocation_y|int + dockmove_y|int} F{release_feedrate} + + # if necessary do some actions after attaching the probe + _RetractKlickyDock + + #Do an extra move away + _KlickyDebug msg="Dock_Probe moving away from the dock to G0 X{docklocation_x|int + dockmove_x|int - attachmove_x|int} Y{docklocation_y|int + dockmove_y|int - attachmove_y|int} F{release_feedrate}" + G0 X{docklocation_x|int + dockmove_x|int - attachmove_x|int} Y{docklocation_y|int + dockmove_y|int - attachmove_y|int} F{release_feedrate} + + # Go to Z safe distance + {% if printer.toolhead.position.z < safe_z %} + _KlickyDebug msg="Dock_Probe toolhead too low, raising it to {safe_z}mm" + G0 Z{safe_z} F{z_drop_feedrate} + {% endif %} + + _Park_Toolhead + + G4 P1000 + _CheckProbe action=dock + _KLICKY_STATUS_READY + + {% elif probe_lock %} + {% if verbose %} + { action_respond_info("Probe locked") } + {% endif %} + + # Probe docked, do nothing + _KlickyDebug msg="Dock_Probe probe locked not docking probe" + _CheckProbe action=query + + {% else %} + {% if verbose %} + { action_respond_info("Probe already docked") } + {% endif %} + + # Probe docked, do nothing + _KlickyDebug msg="Dock_Probe probe already docked, doing nothing" + _CheckProbe action=query + + {% endif %} + + _exit_point function=Dock_Probe move={goback} + +# Probe Calibrate +[gcode_macro PROBE_CALIBRATE] +rename_existing: _PROBE_CALIBRATE +description:Calibrate the probe's z_offset with klicky automount +gcode: + {% set safe_z = printer["gcode_macro _User_Variables"].safe_z|float %} + {% set z_drop_feedrate = printer["gcode_macro _User_Variables"].z_drop_speed * 60 %} + {% set max_x = printer["gcode_macro _User_Variables"].max_bed_x|float %} + {% set max_y = printer["gcode_macro _User_Variables"].max_bed_y|float %} + {% set probe_offset_x = printer['configfile'].config["probe"]["x_offset"]|float %} + {% set probe_offset_y = printer['configfile'].config["probe"]["y_offset"]|float %} + + {% if not 'xyz' in printer.toolhead.homed_axes %} + { action_raise_error("Must Home X, Y and Z Axis First!") } + {% endif %} + _KlickyDebug msg="probe_calibrate Axis homed" + _KlickyDebug msg="probe_calibrate Variables max_x={max_x},max_y={max_y},probe_offset_x={probe_offset_x},probe_offset_y={probe_offset_y}" + + # Protect against PROBE CALIBRATE performed from outside the bed + {% if printer['gcode_move'].position.y > (max_y - probe_offset_y) + or printer['gcode_move'].position.y < - probe_offset_y + or printer['gcode_move'].position.x > (max_x - probe_offset_x) + or printer['gcode_move'].position.x < - probe_offset_x %} + { action_raise_error("Must perform PROBE_CALIBRATE with the probe above the BED, check klicky_variables bed size!") } + {% endif%} + + _CheckProbe action=query + G90 + Attach_Probe back=1 + _KLICKY_STATUS_CALIBRATING_Z + + _KlickyDebug msg="probe_calibrate calling klipper probe_calibrate" + _PROBE_CALIBRATE {% for p in params + %}{'%s=%s ' % (p, params[p])}{% + endfor %} + + M118 moving the toolhead 20 mm from the bed + _KlickyDebug msg="probe_calibrate Moving Z up by 20mm" + TESTZ Z=20 + M118 remove manually the probe and continue calibration + _KLICKY_STATUS_READY + + +# Probe Accuracy +[gcode_macro PROBE_ACCURACY] +rename_existing: _PROBE_ACCURACY +description:Probe Z-height accuracy at current XY position with klicky automount +gcode: + {% set safe_z = printer["gcode_macro _User_Variables"].safe_z|float %} + {% set z_drop_feedrate = printer["gcode_macro _User_Variables"].z_drop_speed * 60 %} + {% set max_x = printer["gcode_macro _User_Variables"].max_bed_x|float %} + {% set max_y = printer["gcode_macro _User_Variables"].max_bed_y|float %} + {% set probe_offset_x = printer['configfile'].config["probe"]["x_offset"]|float %} + {% set probe_offset_y = printer['configfile'].config["probe"]["y_offset"]|float %} + + {% if not 'xyz' in printer.toolhead.homed_axes %} + { action_raise_error("Must Home X, Y and Z Axis First!") } + {% endif %} + _KlickyDebug msg="probe_accuracy Axis homed" + _KlickyDebug msg="probe_accuracy Variables max_x={max_x},max_y={max_y},probe_offset_x={probe_offset_x},probe_offset_y={probe_offset_y}" + + _entry_point function=PROBE_ACCURACY + + # Protect against PROBE_ACCURACY performed from outside the bed + {% if printer['gcode_move'].position.y > (max_y - probe_offset_y) + or printer['gcode_move'].position.y < - probe_offset_y + or printer['gcode_move'].position.x > (max_x - probe_offset_x) + or printer['gcode_move'].position.x < - probe_offset_x %} + { action_raise_error("Must perform PROBE_ACCURACY with the probe above the BED, check klicky_variables bed size!") } + {% endif%} + + _CheckProbe action=query + Attach_Probe back=1 + + _KlickyDebug msg="probe_accuracy calling klipper probe accuracy" + _PROBE_ACCURACY {% for p in params + %}{'%s=%s ' % (p, params[p])}{% + endfor %} + + Dock_Probe back=1 + + _exit_point function=PROBE_ACCURACY move=1 + + +# Umbilical path setup +[gcode_macro _Umbilical_Path] +gcode: + {% set umbilical = printer["gcode_macro _User_Variables"].umbilical %} + {% set umbilical_x = printer["gcode_macro _User_Variables"].umbilical_x %} + {% set umbilical_y = printer["gcode_macro _User_Variables"].umbilical_y %} + {% set safe_z = printer["gcode_macro _User_Variables"].safe_z|float %} + {% set travel_feedrate = printer["gcode_macro _User_Variables"].travel_speed * 60 %} + + {% if umbilical %} + # Used to give the umbilical a better path to follow and coil properly if dock is tight in space + _entry_point function=Umbilical_Path + + _KlickyDebug msg="_Umbilical_Path moving to G0 X{umbilical_x} Y{umbilical_y} Z{safe_z} F{travel_feedrate}" + G0 X{umbilical_x} Y{umbilical_y} Z{safe_z} F{travel_feedrate} + + _exit_point function=Umbilical_Path + {% endif %} + + +# check to see if probe is where it is supposed to be after +# attaching/docking maneuver and set homing error or shutdown +[gcode_macro _CheckProbe] +variable_probe_state: 0 +gcode: + Query_Probe + _SetProbeState action={ params.ACTION } + +# due to how templates are evaluated, we have query endstops in one +# macro and call another macro to make decisions based on the result +[gcode_macro _SetProbeState] +gcode: + {% set query_probe_triggered = printer.probe.last_query %} + {% set action = params.ACTION|default('') %} + + # If triggered (true), probe not attached + {% if query_probe_triggered %} + SET_GCODE_VARIABLE MACRO=_Probe_Variables VARIABLE=probe_attached VALUE={ False } + {% else %} + # If not triggered (false), probe attached + SET_GCODE_VARIABLE MACRO=_Probe_Variables VARIABLE=probe_attached VALUE={ True } + {% endif %} + + {% if action == 'query' %} + SET_GCODE_VARIABLE MACRO=_Probe_Variables VARIABLE=probe_state VALUE={ query_probe_triggered } + {% endif %} + + # If probe fails to attach/detach + + # If not docked + {% if not query_probe_triggered and action == 'dock' %} + { action_raise_error("Probe dock failed!") } + {% endif %} + + # If not attached + {% if query_probe_triggered and action == 'attach' %} + { action_raise_error("Probe attach failed!") } + {% endif %} + + +# Park Toolhead Routine +[gcode_macro _Park_Toolhead] +gcode: + {% set park_toolhead = printer["gcode_macro _User_Variables"].park_toolhead %} + {% set parkposition_x = printer["gcode_macro _User_Variables"].parkposition_x %} + {% set parkposition_y = printer["gcode_macro _User_Variables"].parkposition_y %} + {% set parkposition_z = printer["gcode_macro _User_Variables"].parkposition_z %} + {% set travel_feedrate = printer["gcode_macro _User_Variables"].travel_speed * 60 %} + {% set verbose = printer["gcode_macro _User_Variables"].verbose %} + + _entry_point function=Park_Toolhead + + {% if park_toolhead and 'xyz' in printer.toolhead.homed_axes %} + {% if verbose %} + { action_respond_info("Parking Toolhead") } + {% endif %} + _KlickyDebug msg="_Park_Toolhead moving to G0 X{parkposition_x} Y{parkposition_y} Z{parkposition_z} F{travel_feedrate}" + G0 X{parkposition_x} Y{parkposition_y} Z{parkposition_z} F{travel_feedrate} + {% endif %} + _exit_point function=Park_Toolhead +