Klipper: Check and set current tool on startup

Created on 14 Sep 2019  路  8Comments  路  Source: KevinOConnor/klipper

I have built a toolchanger that uses a lock/unlock gcode and some g0 commands to switch tools using activate/deactivate gcode. This works well so far. I am implementing some safety mechanisms so that if a tool is dropped / not picket up things don't go really bad.

One of the issues I have no idea how to resolve is how to set current tool without running the activate/deactivate gcode. One of the things I am doing right now is leaving T0 unused (no tools attached) and at the end of the print i am switching to it. This means that if i print then power off, there should be no tool picked up.

The isue is that if power is lost, on startup T0 is selected and I want to find a way to automatically park it if needed. That means I want to detect the current tool and set klipper current tool to Tx. I can detect a tool via a input_button using an ir sensor or a switch or optical sensor so i can have a on/off state for each park. Now, I can make a macro that runs only once ( example https://github.com/vladbabii/3dp_klipper_octoprint_x86/blob/master/macro_run_only_once.MD ) and set it to G28. This way the printer detects current tool on first home and then works normally.

What I don't know how to do is how to set current tool on the printer without running T0/T1/etc command.

Is there any way to resolve this with the current klipper implementation?

Attached the config file so the bot doesn't close the ticket automatically.
klipper.zip

All 8 comments

What your describing sounds like it would be best solved by implementing python code. I'm not sure macros or a config will get you what you want.

-Kevin

I think i can do it like this

  • delayed gcode with query button to check sensors on boot,
  • make a macro for each activate and de-activate and add that macro in [extruderX] for parking/picking up
  • on home do this
  • home x
  • home y
  • move to detect tool position
  • run delayed gcode macro delay for 20 seconds
  • pickup tool 1 ( z probe)
  • home z

in delayed gcode macro
A. if tool detected run safe_tool_drop gcode

in safe_tool_drop_gcode

  • use jinja templates to check all buttons for state of tool presence, first one that doesn't have it will have the toold placed there

The 20 second delay at (4) would be needed to allow enough time for the printer to park any tool it would have attached - so save_tool_drop gcode runs.

Would this work? If i do a pause gcode command for 20 seconds, can i run delayed gcode in it?

Thank you for your time

This is a problem I have been thinking about as well... I think the easiest would be to find a way to set which tool is actually physically attached right now by suppressing deselect/select scripts until Klipper's active tool matches the physical state. My untested idea so far was:

Create a macro SET_TOOL_SELECT_CLEAN

[gcode_macro set_tool_select_clean]
variable_clean: 0
gcode:
  # change our gcode macro variable
  SET_GCODE_VARIABLE MACRO=set_tool_select_clean VARIABLE=clean VALUE=1

Encapsulate the commands in select_gcode and deselect_gcode of all the extruders in a python conditional so that the scripts will only execute if the gcode macro variable clean is set to 1

[extruder]
...
select_gcode:
  {% if printer["gcode_macro set_tool_select_clean"].clean  %}
    ...all my tool select commands
  {% endif %}
deselect_gcode:
  {% if printer["gcode_macro set_tool_select_clean"].clean  %}
    ...all my tool deselect commands
  {% endif %}

Now you should be able to run a delayed_gcode on startup to check which tool holder is empty and issue a Tn to select it. Right after that run SET_TOOL_SELECT_CLEAN and you should be good to go... right?

As I said, I haven't tested this yet - what do you think?

@simonkuehling This is even better and should work. The variable should be set at the end of the first G28 so it only does this once. Nice!

And you can run another command to disable toolchanging so you can use the printer as a normal single-nozzle printer.

Thanks!

I use the macros below for park/pickup so i only need to modify one park macro and one pickup macro for all tools.

I also use output pins as on/off indicators so i can later attach leds to them and get an indication of what status the printer has. But the variable should also work.

If i use the macro variables then i could probably simplify the below scripts to read the default X/Y values from a single macro needs to be configured, and leave each activate/deactive gcode very simple in implementation.

## TOOL_PARK XINIT=67.5 YINIT=80 YCLOSE=35 YFINAL=22.1

[gcode_macro TOOL_PARK]
gcode:

  {% if printer.gcode.gcode_position.y < params.YINIT|float %}

  ; back away to not hit a tool if under Y80
  M118 ToolPark - Backing away from Y position then move to X
  G0 Y{ params.YINIT|float } F1500
  G0 X{ params.XINIT|float } F1500

  {% else %}

  ; move to x/y in front of tool
  M118 ToolPark - Moving closer to TOOL X/Y directly
  G0 Y{ params.YINIT|float } X{ params.XINIT|float } F1500

  {% endif %}

  ; move almost touching tool fast
  G0 Y{ params.YCLOSE|float } F1500

  ; move to mount tool slow
  G0 Y{ params.YFINAL|float } F500

  ; drop tool
  TOOLUNLOCK

  ; move away slow while on parking spot
  G0 Y{ params.YCLOSE|float } F500

  ; move away fast while out of parking
  G0 Y{ params.YINIT|float } F1500

```

TOOL_PICKUP XINIT=67.5 YINIT=80 YCLOSE=35 YFINAL=22.1

[gcode_macro TOOL_PICKUP]
gcode:

{% if printer.gcode.gcode_position.y < params.YINIT|float %}

; back away to not hit a tool if under Y80
M118 Toolmeet - Backing away from Y position then move to X
G0 Y{ params.YINIT|float } F1500
G0 X{ params.XINIT|float } F1500

{% else %}

; move to x/y in front of tool
M118 Toolmeet - Moving closer to TOOL X/Y directly
G0 Y{ params.YINIT|float } X{ params.XINIT|float } F1500

{% endif %}

; make sure we're unlocked
TOOLUNLOCK

; move almost touching tool fast
G0 Y{ params.YCLOSE|float } F1500

; move to mount tool slow
G0 Y{ params.YFINAL|float } F500

; grab tool
TOOLLOCK

; move away slow while on parking spot
G0 Y{ params.YCLOSE|float } F500

; move away fast while out of parking
G0 Y{ params.YINIT|float } F1500
````

@vladbabii - good point, that's even tidier in macros with parameters!

@simonkuehling I will move paramaters to a single [macro tool_settings] section so if you need to reconfigure a tool position you won't need to touch the extruder section.

I will close the ticket tomorrow if there's nothing new here.

Thank you everyone for your help!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ChiliApple picture ChiliApple  路  4Comments

CHILLYSMOKES picture CHILLYSMOKES  路  5Comments

sapell picture sapell  路  3Comments

smokez89 picture smokez89  路  4Comments

leungtech picture leungtech  路  4Comments