jlas1 / Klicky-Probe

Microswitch probe with magnetic attachement, primarily aimed at CoreXY 3d printers
GNU General Public License v3.0
1.26k stars 280 forks source link

z-hob disabled, bed still crashes on low position when homing #122

Closed ulk4 closed 2 years ago

ulk4 commented 2 years ago

I installed klicky-probe on a Qidi i-mate. Dock is mounted on upper front profile. i-mate is a printer, where the bed falls down to bottom position (Z max), when motors are off. I am using klicky-probe as Z-Endstop When the printer is homing, it still tries to move the bed to a safe_z positon, but this is not possible, since the bed is already at lowest position. Z-hob is disabled. I am not good in reading macros, so i could not really find out, where it happens and what is the problem.

The relevant configs are klicky-variables.cfg

## only the modified lines 
variable_safe_z:                 7
variable_enable_z_hop:       False
variable_max_bed_y:            200
variable_max_bed_x:            270
variable_z_endstop_x:            0
variable_z_endstop_y:            0  
variable_docklocation_x:       266
variable_docklocation_y:        -7
Variable_dockmove_x:           -40
Variable_attachmove_x:           0
Variable_attachmove_y:         -30

printer.cfg

## only the changes made for klicky-probe

[include klicky-probe.cfg]

[stepper_z]
endstop_pin: probe:z_virtual_endstop
#position_endstop: 205.030          # removed for klicky-probe

[probe]
pin=^PE3
x_offset: 0
y_offset: -23
z_offset: 4.455
speed: 2.5
samples: 3
samples_result: median
sample_retract_dist: 2.0
samples_tolerance: 0.01
samples_tolerance_retries: 5

and the debug log from klipper terminal

20:48:21    probe: TRIGGERED
20:48:20    probe: TRIGGERED
20:48:18    Dock_Probe moving away from the dock to G0 X226 Y23 F4500
20:48:17    Dock_Probe moving from the dock to G0 X226 Y-7 F4500
20:48:17    Dock_Probe moving to the dock with G0 X266 Y-7 F3000
20:48:15    Dock_Probe moving near the dock with G0 X266 Y23 F12000
20:48:15    Dock_Probe going to dock probe
20:48:15    Dock_Probe Axis homed
20:48:15    Docking Probe
20:48:15    homing_override probe no longer required, docking probe
20:48:14    _Home_Z toolhead too low, raising it to 7.0mm
20:47:43    _Home_Z Homing Z G28 Z
20:47:43    _Home_Z moving to Z endstop position G0 X134.0 Y124.5 F12000
20:47:43    _Home_Z Axis homed
20:47:43    probe: open
20:47:42    Attach_Probe moving to a safe Z position: G0 Z7 F1200
20:47:41    Attach_Probe moving from the dock to G0 X266 Y23 F4500
20:47:41    Attach_Probe moving to the dock with G0 X266 Y-7 F3000
20:47:41    Attach_Probe moving to the dock with G0 X266 Y-7 F3000
20:47:39    Attach_Probe moving near the dock with G0 X266 Y23 F12000
20:47:38    Attach_Probe toolhead too low, raising it by 7mm, duplicate?
20:47:38    Attach_Probe toolhead too low, raising it by 7mm
20:47:37    Attach_Probe going to attach probe
20:47:37    moving to a safe Z distance
20:47:37    Attaching Probe
20:47:37    homing_override probe configured as a virtual Z endstop attaching probe
20:47:37    homing_override backing off Y endstop, G0 Y193.0 F12000
20:47:32    homing_override Homing Y G28 Y0
20:47:32    homing_override backing off X endstop, G0 X258.0 F12000
20:47:26    homing_override Homing X G28 X0
20:47:26    homing_override toolhead too low, raising it by 0mm
20:47:26    homing_override Z not homed, setting position as X=Y=Z=0
20:47:26    homing_override z_hop disabled
20:47:25    homing_override goint to home all axes
20:47:25    probe: TRIGGERED
20:47:25    Homing Z
20:47:25    Homing Y
20:47:25    Homing X
20:47:25    Z not homed, forcing full G28
20:47:25    G28

I think the bed move in positive Z direction is happening at 20:47:38, but it is scrolling quite fast.

Btw, when I apply the klicky-probe manually before homing, it is working without the collision move.

For the moment as a workaround, I lowered safe_z to only 7mm and placed some foam on the bottom of the printer, so the bed does not fall down all the way and the collision is a soft one. Any idea, why variable_enable_z_hop: False is not working as expected?

And last not least, Docking, attaching and bed mesh calibration are working fine :-)

jlas1 commented 2 years ago

I see the issue, it needs to be able to move to attach if the Z is too low. Try this macro: https://raw.githubusercontent.com/jlas1/Klicky-Probe/z_hop_tests/Klipper_macros/klicky-variables.cfg It should work as expected, it is on a new branch.

ulk4 commented 2 years ago

I used the macro https://raw.githubusercontent.com/jlas1/Klicky-Probe/z_hop_tests/Klipper_macros/klicky-macros.cfg from z-hob_tests branch. Now, when the printer is homing, before homing x any y, the bed is moved up by variable_safe_z. Later on, before attaching the probe, the bed is lowered again the same amount, which is now possible. I guess this is the expected behaviour. At least, it does not try to move the bed downwards anymore in the beginning, when it is already at bottom position. Looks good to me, I can take out the foam again :-). Thanks.

jlas1 commented 2 years ago

Can you enable the debug variable on klicky-variables.cfg and do a homing please? Would like to find out why is it moving like that.

ulk4 commented 2 years ago

Sure. Here is the debug log

07:42:53 probe: TRIGGERED 07:42:52 probe: TRIGGERED 07:42:50 Dock_Probe moving away from the dock to G0 X226 Y23 F4500 07:42:49 Dock_Probe moving from the dock to G0 X226 Y-7 F4500 07:42:49 Dock_Probe moving to the dock with G0 X266 Y-7 F3000 07:42:47 Dock_Probe moving near the dock with G0 X266 Y23 F12000 07:42:47 Dock_Probe going to dock probe 07:42:47 Dock_Probe Axis homed 07:42:47 Docking Probe 07:42:47 homing_override probe no longer required, docking probe 07:42:46 _Home_Z toolhead too low, raising it to 7.0mm 07:42:21 _Home_Z Homing Z G28 Z 07:42:21 _Home_Z moving to Z endstop position G0 X134.0 Y124.5 F12000 07:42:21 _Home_Z XY Axis homed 07:42:21 probe: open 07:42:21 Attach_Probe moving to a safe Z position: G0 Z7 F1200 from -0.029827 07:42:19 Attach_Probe moving from the dock to G0 X266 Y23 F4500 07:42:19 Attach_Probe moving to the dock with G0 X266 Y-7 F3000 07:42:19 Attach_Probe moving to the dock with G0 X266 Y-7 F3000 07:42:18 Attach_Probe moving near the dock with G0 X266 Y23 F12000 07:42:16 Attach_Probe toolhead too low, raising it by 7mm, duplicate? 07:42:16 Attach_Probe toolhead too low, raising it by 7mm 07:42:16 Attach_Probe going to attach probe 07:42:16 moving to a safe Z distance 07:42:16 Attaching Probe 07:42:16 homing_override probe configured as a virtual Z endstop attaching probe 07:42:10 homing_override Homing Y G28 Y0 07:42:03 homing_override Homing X G28 X0 07:42:03 homing_override toolhead too low, raising it by 0mm 07:42:03 homing_override Z not homed, setting position as X=Y=0 Z=7 07:42:03 homing_override z_hop disabled 07:42:03 homing_override goint to home all axes 07:42:03 probe: TRIGGERED 07:42:03 Homing Z 07:42:03 Homing Y 07:42:03 Homing X 07:42:03 Z not homed, forcing full G28 07:42:03 G28

I think it happens at 07:42:03 homing_override toolhead too low, raising it by 0mm, even when it says it's moving by 0mm. Bed is raised by safe_z. My guess is, kinematic position is set to Z=7 and then the bed is moved absolutely to safe_z, which is 0 at that time. This results in the first bed raise. BUT: it is only my guess, i'm not good in reading and understanding macros.

jlas1 commented 2 years ago

Can you try now with the main macros? https://raw.githubusercontent.com/jlas1/Klicky-Probe/main/Klipper_macros/klicky-macros.cfg

You are better at macros than you think, your guess is right.

ulk4 commented 2 years ago

Perfect ! No unnecessary moves any more. Here is the log with unhomed printer.

13:04:05    probe: TRIGGERED
13:04:04    probe: TRIGGERED
13:04:02    Dock_Probe moving away from the dock to G0 X226 Y23 F4500
13:04:00    Dock_Probe moving from the dock to G0 X226 Y-7 F4500
13:04:00    Dock_Probe moving to the dock with G0 X266 Y-7 F3000
13:03:59    Dock_Probe moving near the dock with G0 X266 Y23 F12000
13:03:59    Dock_Probe going to dock probe
13:03:59    Dock_Probe Axis homed
13:03:59    Docking Probe
13:03:59    homing_override probe no longer required, docking probe
13:03:58    _Home_Z toolhead too low, raising it to 7.0mm
13:03:33    _Home_Z Homing Z G28 Z
13:03:33    _Home_Z moving to Z endstop position G0 X134.0 Y124.5 F12000
13:03:33    _Home_Z XY Axis homed
13:03:33    probe: open
13:03:31    Attach_Probe moving from the dock to G0 X266 Y23 F4500
13:03:31    Attach_Probe moving to the dock with G0 X266 Y-7 F3000
13:03:31    Attach_Probe moving to the dock with G0 X266 Y-7 F3000
13:03:29    Attach_Probe moving near the dock with G0 X266 Y23 F12000
13:03:29    Attach_Probe going to attach probe
13:03:29    Attaching Probe
13:03:29    homing_override probe configured as a virtual Z endstop attaching probe
13:03:21    homing_override Homing Y G28 Y0
13:03:18    homing_override Homing X G28 X0
13:03:18    homing_override Z not homed, setting position as X=Y=0 Z=7
13:03:18    homing_override z_hop disabled
13:03:18    homing_override goint to home all axes
13:03:18    probe: TRIGGERED
13:03:18    Homing Z
13:03:18    Homing Y
13:03:18    Homing X
13:03:18    Z not homed, forcing full G28
13:03:18    G28

Thanks for your help. Btw, do you want to add the custom klicky-probe files for the Qidi i-mate to your github? Don't know, if it makes sense, since you need several modifications to the printer in advance. (klipper and a new printhead).

jlas1 commented 2 years ago

you can submit them to the usermods , it supports multiple printers. https://github.com/jlas1/Klicky-Probe/tree/main/Usermods. I'll just close this issue now ;-).

MrReflex89 commented 10 months ago

Hello everyone, I also have the same problem that if the bed is on the old limit switch and continues to move freely at the beginning, this leads to a collision. I have another problem when a print is finished that the printer switches to save z 10, which would cause a collision with the printed part. Of course I could set the safety height to 200, but when touching it at the start of the print program it would unnecessarily move up and down twice. does anyone have an idea what I can do? I have the latest macros and configs.

klicky-variables.cfg: [gcode_macro _User_Variables] variable_verbose: True # Enable verbose output variable_debug: False # Enable Debug output variable_travel_speed: 200 # 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: 75 # 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: 10 # Minimum Z for attach/dock and homing functions #orig: 25

if true it will move the bed away from the nozzle when Z is not homed

variable_enable_z_hop: False # set this to false for beds that fall significantly under gravity (almost to Z max) #orig: True

variable_max_bed_y: 200 # maximum Bed size avoids doing a probe_accuracy outside the bed variable_max_bed_x: 270 # 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 #orig: 1000 variable_z_endstop_y: 0 #orig: 1000

Check the printer specific documentation on klipper Dock/Undock configuration, these are dummy values

dock location

variable_docklocation_x: 268 # X Dock position variable_docklocation_y: 6 # Y Dock position variable_docklocation_z: -128 # Z dock position (-128 for a gantry/frame 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: 250 # 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: -40 Variable_dockmove_y: 0 Variable_dockmove_z: 0

Attach move. final toolhead movement to attach the probe on the mount

it's a relative move

Variable_attachmove_x: 0 Variable_attachmove_y: -30 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_x: 10 # how many mm to move away from the X endstop after homing X

                                  # this is useful for the voron v0 to enable the toolhead to move out of the way to allow an unstricted Y homing

variable_home_backoff_y: 10 # how many mm to move away from the Y endstop after homing Y

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

variable_dock_on_zhome: True # docks the probe on Z Homing if not necessary (avoids hitting the bed on some printers

variable_bypass_probe_docking: False

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 %}

printer.cfg:

[include mainsail.cfg] [include klicky-probe.cfg]

[stepper_z] step_pin: PA6 dir_pin: PF15 enable_pin: !PA5 microsteps: 16 rotation_distance: 7.9672

endstop_pin: !PC13 #----------->removed for klicky-probe

endstop_pin: probe:z_virtual_endstop

position_endstop: 207 #----------->removed for klicky-probe

position_max: 212
position_min: -0.6 homing_retract_dist: 5 homing_positive_dir: false #-------------->löschen wenn homing Z homing_speed: 90 second_homing_speed: 5

[probe] # Bei Homing Z alles ausblenden # pin: ^PE3 x_offset: 0 y_offset: -23 z_offset: 3.35 speed: 2.5 samples: 2 samples_result: median sample_retract_dist: 2.0 samples_tolerance: 0.01 samples_tolerance_retries: 5


mainsail.cfg:

[virtual_sdcard] path: ~/printer_data/gcodes on_error_gcode: CANCEL_PRINT

[pause_resume]

[display_status]

[respond]

[gcode_macro CANCEL_PRINT] description: Cancel the actual running print rename_existing: CANCEL_PRINT_BASE gcode:

get user parameters or use default

{% set client = printer['gcode_macro _CLIENT_VARIABLE']|default({}) %} {% set allow_park = client.park_at_cancel|default(false)|lower == 'true' %} {% set retract = client.cancel_retract|default(5.0)|abs %}

define park position

{% set park_x = "" if (client.park_at_cancel_x|default(none) is none) else "X=" ~ client.park_at_cancel_x %} {% set park_y = "" if (client.park_at_cancel_y|default(none) is none) else "Y=" ~ client.park_at_cancel_y %} {% set custom_park = park_x|length > 0 or park_y|length > 0 %}

end of definitions

restore idle_timeout time if needed

{% if printer['gcode_macro RESUME'].restore_idle_timeout > 0 %} SET_IDLE_TIMEOUT TIMEOUT={printer['gcode_macro RESUME'].restore_idle_timeout} {% endif %} {% if (custom_park or not printer.pause_resume.is_paused) and allow_park %} _TOOLHEAD_PARK_PAUSE_CANCEL {park_x} {park_y} {% endif %} _CLIENT_RETRACT LENGTH={retract} TURN_OFF_HEATERS M106 S0 {client.user_cancel_macro|default("")} SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=idle_state VALUE=False

clear pause_next_layer and pause_at_layer as preparation for next print

SET_PAUSE_NEXT_LAYER ENABLE=0 SET_PAUSE_AT_LAYER ENABLE=0 LAYER=0 CANCEL_PRINT_BASE

[gcode_macro PAUSE] description: Pause the actual running print rename_existing: PAUSE_BASE gcode:

get user parameters or use default

{% set client = printer['gcode_macro _CLIENT_VARIABLE']|default({}) %} {% set idle_timeout = client.idle_timeout|default(0) %} {% set temp = printer[printer.toolhead.extruder].target if printer.toolhead.extruder != '' else 0 %} {% set restore = False if printer.toolhead.extruder == '' else True if params.RESTORE|default(1)|int == 1 else False %}

end of definitions

SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=last_extruder_temp VALUE="{{'restore': restore, 'temp': temp}}"

set a new idle_timeout value

{% if idle_timeout > 0 %} SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=restore_idle_timeout VALUE={printer.configfile.settings.idle_timeout.timeout} SET_IDLE_TIMEOUT TIMEOUT={idle_timeout} {% endif %} PAUSE_BASE {client.user_pause_macro|default("")} _TOOLHEAD_PARK_PAUSE_CANCEL {rawparams}

[gcode_macro RESUME] description: Resume the actual running print rename_existing: RESUME_BASE variable_last_extruder_temp: {'restore': False, 'temp': 0} variable_restore_idle_timeout: 0 variable_idle_state: False gcode:

get user parameters or use default

{% set client = printer['gcode_macro _CLIENT_VARIABLE']|default({}) %} {% set velocity = printer.configfile.settings.pause_resume.recover_velocity %} {% set sp_move = client.speed_move|default(velocity) %} {% set runout_resume = True if client.runout_sensor|default("") == "" # no runout else True if not printer[client.runout_sensor].enabled # sensor is disabled else printer[client.runout_sensor].filament_detected %} # sensor status {% set can_extrude = True if printer.toolhead.extruder == '' # no extruder defined in config else printer[printer.toolhead.extruder].can_extrude %} # status of active extruder {% set do_resume = False %}

end of definitions

Printer comming from timeout idle state

{% if printer.idle_timeout.state|upper == "IDLE" or idle_state %} SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=idle_state VALUE=False {% if last_extruder_temp.restore %}

we need to use the unicode (\u00B0) for the ° as py2 env's would throw an error otherwise

  RESPOND TYPE=echo MSG='{"Restoring \"%s\" temperature to %3.1f\u00B0C, this may take some time" % (printer.toolhead.extruder, last_extruder_temp.temp) }'
  M109 S{last_extruder_temp.temp}
  {% set do_resume = True %}
{% elif can_extrude %}
  {% set do_resume = True %}
{% else %} 
  RESPOND TYPE=error MSG='{"Resume aborted !!! \"%s\" not hot enough, please heat up again and press RESUME" % printer.toolhead.extruder}'
{% endif %}

Printer comming out of regular PAUSE state

{% elif can_extrude %} {% set do_resume = True %} {% else %} RESPOND TYPE=error MSG='{"Resume aborted !!! \"%s\" not hot enough, please heat up again and press RESUME" % printer.toolhead.extruder}' {% endif %} {% if runout_resume %} {% if do_resume %} {% if restore_idle_timeout > 0 %} SET_IDLE_TIMEOUT TIMEOUT={restore_idle_timeout} {% endif %} # restore idle_timeout time {client.user_resume_macro|default("")} _CLIENT_EXTRUDE RESUME_BASE VELOCITY={params.VELOCITY|default(sp_move)} {% endif %} {% else %} RESPOND TYPE=error MSG='{"Resume aborted !!! \"%s\" detects no filament, please load filament and press RESUME" % (client.runout_sensor.split(" "))[1]}' {% endif %}

Usage: SET_PAUSE_NEXT_LAYER [ENABLE=[0|1]] [MACRO=]

[gcode_macro SET_PAUSE_NEXT_LAYER] description: Enable a pause if the next layer is reached gcode: {% set pause_next_layer = printer['gcode_macro SET_PRINT_STATS_INFO'].pause_next_layer %} {% set ENABLE = params.ENABLE|default(1)|int != 0 %} {% set MACRO = params.MACRO|default(pause_next_layer.call, True) %} SET_GCODE_VARIABLE MACRO=SET_PRINT_STATS_INFO VARIABLE=pause_next_layer VALUE="{{ 'enable': ENABLE, 'call': MACRO }}"

Usage: SET_PAUSE_AT_LAYER [ENABLE=[0|1]] [LAYER=] [MACRO=]

[gcode_macro SET_PAUSE_AT_LAYER] description: Enable/disable a pause if a given layer number is reached gcode: {% set pause_at_layer = printer['gcode_macro SET_PRINT_STATS_INFO'].pause_at_layer %} {% set ENABLE = params.ENABLE|int != 0 if params.ENABLE is defined else params.LAYER is defined %} {% set LAYER = params.LAYER|default(pause_at_layer.layer)|int %} {% set MACRO = params.MACRO|default(pause_at_layer.call, True) %} SET_GCODE_VARIABLE MACRO=SET_PRINT_STATS_INFO VARIABLE=pause_at_layer VALUE="{{ 'enable': ENABLE, 'layer': LAYER, 'call': MACRO }}"

Usage: SET_PRINT_STATS_INFO [TOTAL_LAYER=] [CURRENT_LAYER= ]

[gcode_macro SET_PRINT_STATS_INFO] rename_existing: SET_PRINT_STATS_INFO_BASE description: Overwrite, to get pause_next_layer and pause_at_layer feature variable_pause_next_layer: { 'enable': False, 'call': "PAUSE" } variable_pause_at_layer : { 'enable': False, 'layer': 0, 'call': "PAUSE" } gcode: {% if pause_next_layer.enable %} RESPOND TYPE=echo MSG='{"%s, forced by pause_next_layer" % pause_next_layer.call}' {pause_next_layer.call} ; execute the given gcode to pause, should be either M600 or PAUSE SET_PAUSE_NEXT_LAYER ENABLE=0 {% elif pause_at_layer.enable and params.CURRENT_LAYER is defined and params.CURRENT_LAYER|int == pause_at_layer.layer %} RESPOND TYPE=echo MSG='{"%s, forced by pause_at_layer [%d]" % (pause_at_layer.call, pause_at_layer.layer)}' {pause_at_layer.call} ; execute the given gcode to pause, should be either M600 or PAUSE SET_PAUSE_AT_LAYER ENABLE=0 {% endif %} SET_PRINT_STATS_INFO_BASE {rawparams}

internal use

[gcode_macro _TOOLHEAD_PARK_PAUSE_CANCEL] description: Helper: park toolhead used in PAUSE and CANCEL_PRINT gcode:

get user parameters or use default

{% set client = printer['gcode_macro _CLIENT_VARIABLE']|default({}) %} {% set velocity = printer.configfile.settings.pause_resume.recover_velocity %} {% set use_custom = client.use_custom_pos|default(false)|lower == 'true' %} {% set custom_park_x = client.custom_park_x|default(0.0) %} {% set custom_park_y = client.custom_park_y|default(0.0) %} {% set park_dz = client.custom_park_dz|default(2.0)|abs %} {% set sp_hop = client.speed_hop|default(15) 60 %} {% set sp_move = client.speed_move|default(velocity) 60 %}

get config and toolhead values

{% set origin = printer.gcode_move.homing_origin %} {% set act = printer.gcode_move.gcode_position %} {% set max = printer.toolhead.axis_maximum %} {% set cone = printer.toolhead.cone_start_z|default(max.z) %} ; height as long the toolhead can reach max and min of an delta {% set round_bed = True if printer.configfile.settings.printer.kinematics is in ['delta','polar','rotary_delta','winch'] else False %}

define park position

{% set z_min = params.Z_MIN|default(0)|float %} {% set z_park = [[(act.z + park_dz), z_min]|max, (max.z - origin.z)]|min %} {% set x_park = params.X if params.X is defined else custom_park_x if use_custom else 0.0 if round_bed else (max.x - 5.0) %} {% set y_park = params.Y if params.Y is defined else custom_park_y if use_custom else (max.y - 5.0) if round_bed and z_park < cone else 0.0 if round_bed else (max.y - 5.0) %}

end of definitions

_CLIENT_RETRACT {% if "xyz" in printer.toolhead.homed_axes %} G90 G1 Z{z_park} F{sp_hop} G1 X{x_park} Y{y_park} F{sp_move} {% if not printer.gcode_move.absolute_coordinates %} G91 {% endif %} {% else %} RESPOND TYPE=echo MSG='Printer not homed' {% endif %}

[gcode_macro _CLIENT_EXTRUDE] description: Extrudes, if the extruder is hot enough gcode:

get user parameters or use default

{% set client = printer['gcode_macro _CLIENT_VARIABLE']|default({}) %} {% set use_fw_retract = (client.use_fw_retract|default(false)|lower == 'true') and (printer.firmware_retraction is defined) %} {% set length = params.LENGTH|default(client.unretract)|default(1.0)|float %} {% set speed = params.SPEED|default(client.speed_unretract)|default(35) %} {% set absolute_extrude = printer.gcode_move.absolute_extrude %}

end of definitions

{% if printer.toolhead.extruder != '' %} {% if printer[printer.toolhead.extruder].can_extrude %} {% if use_fw_retract %} {% if length < 0 %} G10 {% else %} G11 {% endif %} {% else %} M83 G1 E{length} F{(speed|float|abs) * 60} {% if absolute_extrude %} M82 {% endif %} {% endif %} {% else %} RESPOND TYPE=echo MSG='{"\"%s\" not hot enough" % printer.toolhead.extruder}' {% endif %} {% endif %}

[gcode_macro _CLIENT_RETRACT] description: Retracts, if the extruder is hot enough gcode: {% set client = printer['gcode_macro _CLIENT_VARIABLE']|default({}) %} {% set length = params.LENGTH|default(client.retract)|default(1.0)|float %} {% set speed = params.SPEED|default(client.speed_retract)|default(35) %}

_CLIENT_EXTRUDE LENGTH=-{length|float|abs} SPEED={speed|float|abs}


klicky-macros.cfg:

[respond]

[gcode_macro _Probe_Variables] variable_probe_attached: False variable_probe_state: False variable_probe_lock: False variable_probe_z_homed: 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 _exitpoint] gcode: {% set function = 'pre' ~ params.FUNCTION %} {% set move = params.MOVE|default(0) %} {% set speed = printer["gcode_macro _User_Variables"].travel_speed %}

# mandatory to save the new safe position
M400
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 _entrypoint] 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 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 %}
{% set bypass_probe_docking = printer["gcode_macro _User_Variables"].bypass_probe_docking|default(False) %}

_entry_point function=Attach_Probe

{% if bypass_probe_docking == False %}

    # 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.gcode_move.gcode_position.z < safe_z %}
            _KlickyDebug msg="Attach_Probe toolhead too low, raising it to {safe_z}mm from {printer.gcode_move.gcode_position.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.gcode_move.gcode_position.z < safe_z %} #duplicate??
            _KlickyDebug msg="Attach_Probe toolhead too low, raising it to {safe_z}mm from {printer.gcode_move.gcode_position.z}mm"
            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.gcode_move.gcode_position.z < safe_z) or (docklocation_z != -128 and docklocation_z < safe_z ))%}
          _KlickyDebug msg="Attach_Probe moving to a safe Z position: G0 Z{safe_z} F{z_drop_feedrate} from {printer.gcode_move.gcode_position.z}"
          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
{% else %}
    _KlickyDebug msg="Attach_Probe probe docking bypassed, doing nothing"
{% endif %}

####################

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 %}
{% set bypass_probe_docking = printer["gcode_macro _User_Variables"].bypass_probe_docking|default(False) %}
{% if bypass_probe_docking == True %}
    _KlickyDebug msg="Attach_Probe probe docking bypassed, doing nothing"
{% endif %}

{% if bypass_probe_docking != True %}
    _entry_point function=Dock_Probe

    # If probe not attached and not locked
    {% if probe_attached and not probe_lock %}
      _KLICKY_STATUS_BUSY
      {% if printer.gcode_move.gcode_position.z < safe_z %}
          _KlickyDebug msg="Dock_Probe toolhead too low, raising it to {safe_z}mm from {printer.gcode_move.gcode_position.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.gcode_move.gcode_position.z < safe_z) %}
        _KlickyDebug msg="Dock_Probe moving to a safe Z position: G0 Z{safe_z} F{z_drop_feedrate} from {printer.gcode_move.gcode_position.z}"
        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}
{% else %}
    _KlickyDebug msg="Dock_Probe probe docking bypassed, doing nothing"
{% endif %}

#################

Probe Calibrate

[gcode_macro PROBE_CALIBRATE] rename_existing: _PROBE_CALIBRATE description:Calibrate the probes 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 %} {% set bypass_probe_docking = printer["gcode_macro _User_Variables"].bypass_probe_docking|default(False) %}

{% 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 %}

{% if bypass_probe_docking == False %}
    _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
{% else %}
    _KLICKY_STATUS_CALIBRATING_Z
    _KlickyDebug msg="probe_calibrate calling klipper probe_calibrate"
    _PROBE_CALIBRATE {% for p in params
            %}{'%s=%s ' % (p, params[p])}{%
           endfor %}
    _KLICKY_STATUS_READY
{% endif %}

################

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

#############################################

Enable to SET_KINEMATIC_POSITION for Z hop

[force_move] enable_force_move: True

#################

Homing Override

[homing_override] axes: xyz gcode:

collect user state variables

_User_Variables
{% set verbose = printer["gcode_macro _User_Variables"].verbose %}
{% set safe_z = printer["gcode_macro _User_Variables"].safe_z|float %}
# 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 kinematic_z = 0 %}
{% set dock_on_zhome = printer["gcode_macro _User_Variables"].dock_on_zhome|default(True) %}
{% 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 z_drop_feedrate = printer["gcode_macro _User_Variables"].z_drop_speed * 60 %}
{% set travel_feedrate = printer["gcode_macro _User_Variables"].travel_speed * 60 %}
{% set home_backoff_x = printer["gcode_macro _User_Variables"].home_backoff_x|default(0) %}
{% set home_backoff_y = printer["gcode_macro _User_Variables"].home_backoff_y|default(0) %}
{% set override_homing = printer["gcode_macro _User_Variables"].override_homing|default('') %}

#checks if the variable definitions are up to date
_klicky_check_variables_version

_CheckProbe action=query

# reset parameters
{% set home_x, home_y, home_z, leave_probe_attached = False, False, False, False %}

{% if 'PROBE_LOCK' in params%}
    {% if verbose %}
        { action_respond_info("PROBE_LOCK = True") }
    {% endif %}
    {% set leave_probe_attached = True %}
{% endif %}

# which axes have been requested for homing
{% if not 'X' in params
    and not 'Y' in params
    and not 'Z' in params %}

    {% set home_x, home_y, home_z = True, True, True %}
    _KlickyDebug msg="homing_override goint to home all axes"

{% else %}
    {% if 'X' in params %}
        {% set home_x = True %}
         _KlickyDebug msg="homing_override goint to home X"

    {% endif %}

    {% if 'Y' in params %}
        {% set home_y = True %}
        _KlickyDebug msg="homing_override goint to home Y"
    {% endif %}

    {% if 'Z' in params %}
        {% set home_z = True %}
        _KlickyDebug msg="homing_override goint to home Z"
    {% endif %}

    {% if 'X' in params
      and 'Y' in params
      and 'Z' in params %}
        # reset homing state variables
        # if homing all axes
        _Homing_Variables reset=1
        _KlickyDebug msg="homing_override goint to home all axes"
     {% endif %}

{% endif %}

_entry_point function=homing_override
_KLICKY_STATUS_HOMING

# if Z is not homed, do not move the bed if it goes down
{% if 'z' not in printer.toolhead.homed_axes %}
     {% if enable_z_hop == False %} # Disables safe_z
        _KlickyDebug msg="homing_override z_hop disabled"
        #preserve safe_z to use as the SET KINEMATIC Z position, so that the toolhead does not move to pick up the probe
        {% set kinematic_z = safe_z %}
        {% set safe_z = safe_z %}
    {% endif %}
{% endif %}

#On the first G28 after motors losing power, moves the Z to safe_z distance, if z_hop is enabled
{% if 'x' not in printer.toolhead.homed_axes and 'y' not in printer.toolhead.homed_axes and 'z' not in printer.toolhead.homed_axes%}
    {% if verbose %}
        { action_respond_info("No axis homed") }
    {% endif %}
    _KlickyDebug msg="homing_override no axis homed, setting position as X=Y=0 Z={kinematic_z}"
    SET_KINEMATIC_POSITION X=0 Y=0 Z={kinematic_z}
    M400
    _KlickyDebug msg="homing_override moving toolhead to {safe_z}mm from {printer.gcode_move.gcode_position.z}mm"
    {% if verbose %}
        { action_respond_info("moving to a safe Z distance") }
    {% endif %}
    G0 Z{safe_z} F{z_drop_feedrate}
{% if home_z != True %} 
      _KlickyDebug msg="homing_override clearing axis homed state if not already homing Z"
      M84
    {% endif %}
{% endif %}

{% if home_z %}
    {% if 'x' not in printer.toolhead.homed_axes and 'y' not in printer.toolhead.homed_axes%}
        {% if verbose %}
            { action_respond_info("X or Y not homed, forcing full G28") }
        {% endif %}
        {% set home_x, home_y, home_z = True, True, True %}
    {% endif %}
{% endif %}

# if the dock is oriented on the Y, first do Y endstop
{% if ((attachmove_y == 0 and override_homing == '' ) or (override_homing == 'Y'))%}
    # Home y
    {% if home_y %}
        {% if override_homing == 'Y' %}
          _KlickyDebug msg="homing_override Y homing first override, due to override_homing = Y"
        {% else %}
          _KlickyDebug msg="homing_override Y homing first override, due to attachmove_y = 0"
        {% endif %}
        {% if verbose %}
            { action_respond_info("Homing Y") }
        {% endif %}
        {% if 'z' in printer.toolhead.homed_axes %}
            _KlickyDebug msg="homing_override moving toolhead to {safe_z}mm from {printer.gcode_move.gcode_position.z}mm in Y homing seq"
            {% if verbose %}
                { action_respond_info("moving to a safe Z distance") }
            {% endif %}
            G0 Z{safe_z} F{z_drop_feedrate}
        {% endif %}
        {% if printer["gcode_macro _HOME_Y"] is defined %}
            _KlickyDebug msg="homing_override calling _HOME_Y external script to handle the Y homing"
            _HOME_Y
        {% else %}
            _KlickyDebug msg="homing_override Homing Y G28 Y0"
            G28 Y0
            # does it need to back away from the home position
            {% if home_backoff_y != 0 %}
                {% if (printer.configfile.settings.stepper_y.position_endstop > (printer.configfile.settings.stepper_y.position_min|default(0) + printer.configfile.settings.stepper_y.position_max)/2) %}
                    _KlickyDebug msg="homing_override backing off Y endstop, G0 Y{printer.configfile.settings.stepper_y.position_endstop-home_backoff_y|int} F{travel_feedrate}"
                    G0 Y{printer.configfile.settings.stepper_y.position_endstop - home_backoff_y|int} F{travel_feedrate}
                {% else %}
                    _KlickyDebug msg="homing_override backing off Y endstop, G0 Y{printer.configfile.settings.stepper_y.position_endstop + home_backoff_y|int} F{travel_feedrate}"
                    G0 Y{printer.configfile.settings.stepper_y.position_endstop + home_backoff_y|int} F{travel_feedrate}
                {%endif %}
            {%endif %}
        {% endif %}
    {% endif %}
    {% set home_y = False %}
{% endif %}

# Home x
{% if home_x %}
    {% if verbose %}
        { action_respond_info("Homing X") }
    {% endif %}
    {% if 'z' in printer.toolhead.homed_axes %}
        _KlickyDebug msg="homing_override moving toolhead to {safe_z}mm from {printer.gcode_move.gcode_position.z}mm in X homing seq"
        {% if verbose %}
            { action_respond_info("moving to a safe Z distance") }
        {% endif %}
        G0 Z{safe_z} F{z_drop_feedrate}
    {% endif %}
    {% if printer["gcode_macro _HOME_X"] is defined %}
        _KlickyDebug msg="homing_override calling _HOME_X external script to handle the X homing"
        _HOME_X
    {% else %}
        _KlickyDebug msg="homing_override Homing X, G28 X0"
        G28 X0
        # does it need to back away from the home position
        {% if home_backoff_x != 0 %}
            {% if (printer.configfile.settings.stepper_x.position_endstop > (printer.configfile.settings.stepper_x.position_min|default(0) + printer.configfile.settings.stepper_x.position_max)/2) %}
                _KlickyDebug msg="homing_override backing off X endstop, G0 X{printer.configfile.settings.stepper_x.position_endstop - home_backoff_x|int} F{travel_feedrate}"
                G0 X{printer.configfile.settings.stepper_x.position_endstop - home_backoff_x|int} F{travel_feedrate}
            {% else %}
                _KlickyDebug msg="homing_override backing off X endstop, G0 X{printer.configfile.settings.stepper_x.position_endstop + home_backoff_x|int} F{travel_feedrate}"
                G0 X{printer.configfile.settings.stepper_x.position_endstop + home_backoff_x|int} F{travel_feedrate}
            {%endif %}
        {%endif %}
    {% endif %}
{% endif %}

# Home y
{% if home_y %}
    {% if verbose %}
        { action_respond_info("Homing Y") }
    {% endif %}
    {% if 'z' in printer.toolhead.homed_axes %}
        _KlickyDebug msg="homing_override moving toolhead to {safe_z}mm from {printer.gcode_move.gcode_position.z}mm in Y homing seq"
        {% if verbose %}
            { action_respond_info("moving to a safe Z distance") }
        {% endif %}
        G0 Z{safe_z} F{z_drop_feedrate}
    {% endif %}
    {% if printer["gcode_macro _HOME_Y"] is defined %}
        _KlickyDebug msg="homing_override calling _HOME_Y external script to handle the Y homing"
        _HOME_Y
    {% else %}
      _KlickyDebug msg="homing_override Homing Y, G28 Y0"
        G28 Y0
        {% if home_backoff_y != 0 %}
            {% if (printer.configfile.settings.stepper_y.position_endstop > (printer.configfile.settings.stepper_y.position_min|default(0) + printer.configfile.settings.stepper_y.position_max)/2) %}
                _KlickyDebug msg="homing_override backing off Y endstop, G0 Y{printer.configfile.settings.stepper_y.position_endstop - home_backoff_y|int} F{travel_feedrate}"
                G0 Y{printer.configfile.settings.stepper_y.position_endstop - home_backoff_y|int} F{travel_feedrate}
            {% else %}
                _KlickyDebug msg="homing_override backing off Y endstop, G0 Y{printer.configfile.settings.stepper_y.position_endstop + home_backoff_y|int} F{travel_feedrate}"
                G0 Y{printer.configfile.settings.stepper_y.position_endstop + home_backoff_y|int} F{travel_feedrate}
            {%endif %}
        {%endif %}
    {% endif %}
{% endif %}
# Home z
{% if home_z %}
    {% if verbose %}
        { action_respond_info("Homing Z") }
    {% endif %}
    {% if 'z' in printer.toolhead.homed_axes %}
        _KlickyDebug msg="homing_override moving toolhead to {safe_z}mm from {printer.gcode_move.gcode_position.z}mm in Y homing seq"
        {% if verbose %}
            { action_respond_info("moving to a safe Z distance") }
        {% endif %}
        G0 Z{safe_z} F{z_drop_feedrate}
    {% endif %}

    # if probe is configured as endstop, attach it, else check if the probe needs to be docked if attached
    {% if 'z_virtual_endstop' in printer['configfile'].config["stepper_z"]["endstop_pin"] %}
        _KlickyDebug msg="homing_override probe configured as a virtual Z endstop attaching probe"
        Attach_Probe
        # if PROBE_LOCK parameter is given, Attach Probe and lock until it´s unlocked
        {% if leave_probe_attached %}
            _Probe_Lock
        {% endif %}
    {% elif dock_on_zhome == True %}
        Dock_Probe
    {% endif %}

    _Home_Z_

    # if probe is configured as endstop, dock it
    {% if 'z_virtual_endstop' in printer['configfile'].config["stepper_z"]["endstop_pin"] %}
        _KlickyDebug msg="homing_override probe no longer required, docking probe"
        Dock_Probe
    {% elif dock_on_zhome == False %}
        Dock_Probe
    {% endif %}
{% endif %}
_CheckProbe action=query

# park the toolhead
_Park_Toolhead

_exit_point function=homing_override
_KLICKY_STATUS_READY

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 %}

Home Z Routine

[gcode_macro _HomeZ] gcode: {% set z_endstop_x = printer["gcode_macro _Probe_Variables"].z_endstop_x %} {% set z_endstop_y = printer["gcode_macro _Probe_Variables"].z_endstop_y %} {% set safe_z = printer["gcode_macro _User_Variables"].safe_z|float %} {% set travel_feedrate = printer["gcode_macro _User_Variables"].travel_speed 60 %} {% set z_drop_feedrate = printer["gcode_macro _User_Variables"].z_drop_speed 60 %} {% set verbose = printer["gcode_macro _User_Variables"].verbose %}

_entry_point function=Home_Z

# if x and y are not homed yet, raise error
{% if not 'xy' in printer.toolhead.homed_axes %}
    { action_raise_error("Must Home X and Y Axis First!") }
{% else %}
    _KlickyDebug msg="_Home_Z_ XY Axis homed"
    {% if not 'z' in printer.toolhead.homed_axes %}
        {% if verbose %}
            { action_respond_info("Resetting Z position to zero") }
        {% endif %}
         _KlickyDebug msg="_Home_Z_ Z not homed, setting position as X=Y=Z=0"
        SET_KINEMATIC_POSITION Z=0
    {% endif %}

    # Move tool to safe homing position and home Z axis
    # location of z endstop
    _KlickyDebug msg="_Home_Z_ moving to Z endstop position G0 X{z_endstop_x} Y{z_endstop_y} F{travel_feedrate}"
    G0 X{z_endstop_x} Y{z_endstop_y} F{travel_feedrate}
    _KlickyDebug msg="_Home_Z_ Homing Z G28 Z"
    G28 Z0
    _KlickyDebug msg="_Home_Z_ toolhead too low, raising it to {safe_z}mm from {printer.gcode_move.gcode_position.z}mm"
    G0 Z{safe_z} F{z_drop_feedrate}
{% endif %}

_exit_point function=Home_Z

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 %}
    {% if parkposition_z == -128 %}
        _KlickyDebug msg="_Park_Toolhead moving to G0 X{parkposition_x} Y{parkposition_y} F{travel_feedrate}"
        G0 X{parkposition_x} Y{parkposition_y} F{travel_feedrate}

    {% else %}

        _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 %}

{% endif %}
_exit_point function=Park_Toolhead

#################

Status LEDs

This enables stealthburner-led status macros to be used in klicky macros if they exist.

https://github.com/VoronDesign/Voron-Afterburner/blob/sb-beta/Klipper_Macros/stealthburner_leds.cfg

[gcode_macro _klicky_status_ready] gcode: {% if printer['gcode_macro status_ready'] is defined %} _KlickyDebug msg="_klicky_status_ready activating the LED STATUS_READY" STATUS_READY {% endif %}

[gcode_macro _klicky_status_busy] gcode: {% if printer['gcode_macro status_busy'] is defined %} _KlickyDebug msg="_klicky_status_busy activating the LED STATUS_BUSY" STATUS_BUSY {% endif %}

[gcode_macro _klicky_status_leveling] gcode: {% if printer['gcode_macro status_leveling'] is defined %} _KlickyDebug msg="_klicky_status_leveling activating the LED STATUS_LEVELING" STATUS_LEVELING {% endif %}

[gcode_macro _klicky_status_homing] gcode: {% if printer['gcode_macro status_homing'] is defined %} _KlickyDebug msg="_klicky_status_homing activating the LED STATUS_HOMING" STATUS_HOMING {% endif %}

[gcode_macro _klicky_status_cleaning] gcode: {% if printer['gcode_macro status_cleaning'] is defined %} _KlickyDebug msg="_klicky_status_cleaning activating the LED STATUS_CLEANING" STATUS_CLEANING {% endif %}

[gcode_macro _klicky_status_meshing] gcode: {% if printer['gcode_macro status_meshing'] is defined %} _KlickyDebug msg="_klicky_status_meshing activating the LED STATUS_MESHING" STATUS_MESHING {% endif %}

[gcode_macro _klicky_status_calibrating_z] gcode: {% if printer['gcode_macro status_calibrating_z'] is defined %} _KlickyDebug msg="_klicky_status_calibrating_z activating the LED STATUS_CALIBRATING_Z" STATUS_CALIBRATING_Z {% endif %}