Skip to content

Instantly share code, notes, and snippets.

@clee
Last active May 27, 2024 19:52
Show Gist options
  • Save clee/9108f7717defce8b1222698f816def0a to your computer and use it in GitHub Desktop.
Save clee/9108f7717defce8b1222698f816def0a to your computer and use it in GitHub Desktop.
how to sensorless XY on Vorons

Setting Up and Calibrating Sensorless XY Homing

When using the TMC2130 / TMC2209 / TMC2660 / TMC5160 drivers, the StallGuard feature makes it possible to set up sensorless homing on the X and Y axes for CoreXY machines. The Klipper project has a page with documentation and recommendations on getting it working.

Following are some more detailed instructions and suggestions to supplement the Klipper documentation specifically for Vorons.

Hardware Setup

You need to configure your hardware properly to enable sensorless homing. This involves two main steps:

  1. If you currently have Hall Effect or microswitch XY endstops connected to your microcontroller (SKR, Spider, Octopus, E3 mini, SKR Pico, etc), then you must physically pull them out of the microcontroller. If you leave the physical endstops connected, sensorless homing will not work.
  2. Install jumpers on the relevant DIAG pins to enable sensorless homing on the X and Y stepper drivers.

Software Setup

Klipper

You'll need to modify the endstop_pin values for [stepper_x] and [stepper_y], by adding a pullup ^, moving the current value into the relevant TMC blocks, and updating the endstop_pins to use the virtual_endstop as described in the following sections.

Also, as the Klipper docs instruct, set the homing_retract_dist to 0, and make sure your X and Y homing_speed values are set to half of your rotation_distance (homing_speed should be 20 for Vorons with 20T pulleys on the A/B motors).

For TMC2209

The following pin examples are from a BTT E3 mini V2; make sure to adjust based on your own configuration.

Before:

[stepper_x]
#
endstop_pin: PC0

[tmc2209 stepper_x]
#

[stepper_y]
#
endstop_pin: PC1

[tmc2209 stepper_y]
#

After:

[stepper_x]
endstop_pin: tmc2209_stepper_x:virtual_endstop

[tmc2209 stepper_x]
#
diag_pin: ^PC0 # use the same pin that was previously the endstop_pin!
driver_SGTHRS: 255

[stepper_y]
#
endstop_pin: tmc2209_stepper_y:virtual_endstop

[tmc2209 stepper_y]
#
diag_pin: ^PC1     # use the same pin that was previously the endstop_pin!
driver_SGTHRS: 255 # 255 is most sensitive value, 0 is least sensitive

For TMC5160

The following pin examples are from a BTT Octopus Pro; make sure to adjust based on your own configuration.

Before:

[stepper_x]
#
endstop_pin: PG6

[tmc5160 stepper_x]
#

After:

[stepper_x]
#
endstop_pin: tmc5160_stepper_x:virtual_endstop

[tmc5160 stepper_x]
#
diag1_pin: ^!PG6 # use the same pin that was previously the endstop_pin! 
driver_SGT: -64  # -64 is most sensitive value, 63 is least sensitive

Finding the right StallGuard threshold

The calibration process is:

  • For TMC2209, start with SET_TMC_FIELD FIELD=SGTHRS STEPPER=stepper_x VALUE=255 in the console. For TMC2130/TMC2660/TMC5160, use SET_TMC_FIELD FIELD=SGT STEPPER=stepper_x VALUE=-64 instead. Start with the most sensitive value for the StallGuard threshold based on which kind of TMC driver you're using (255 for TMC2209, or -64 for TMC2130/TMC2660/TMC5160).

  • Try running G28 X0 to see if the toolhead moves along the X axis.

  • If your toolhead moves all the way to the end of the rail, IMMEDIATELY HIT THE EMERGENCY STOP BUTTON.

  • The Klipper documentation is good here, with one exception. This information is not correct:

    Then issue a G28 X0 command and verify the axis does not move at all.

    When running the G28 X0 or G28 Y0 command, the toolhead WILL move a millimeter or so before it triggers the virtual endstop. This is normal.

  • Assuming that the toolhead moved a millimeter or so and then stopped, change the VALUE to decrease the sensitivity by 5-10, try again, and keep going until you find the first value that successfully homes your printer.

  • Follow the Klipper instructions on fine-tuning the value once your toolhead is homing successfully on this axis. Make sure you run

    G91
    G1 X-10

    to back the toolhead off after hitting the end of the rail (assuming you're homing to the maximum X value) or else Y homing will not work properly.

  • Update the driver_SGTHRS or driver_SGT value with your new StallGuard threshold.

Do not forget, you need to repeat this same process for the Y axis.

Homing macros

The Klipper docs recommend setting up dedicated SENSORLESS_HOME_X/SENSORLESS_HOME_Y macros. We're renaming them to _HOME_X and _HOME_Y here (the leading underscores will hide them in Mainsail/Fluidd, and those specific names are special for Klicky). This setup that has been working well for several Voron owners; you will probably want to tweak the HOME_CURRENT values for your own setup.

[gcode_macro _HOME_X]
gcode:
    # Set current for sensorless homing
    {% set RUN_CURRENT_X = printer.configfile.settings['tmc2209 stepper_x'].run_current|float %}
    {% set RUN_CURRENT_Y = printer.configfile.settings['tmc2209 stepper_y'].run_current|float %}
    {% set HOME_CURRENT = 0.7 %}
    SET_TMC_CURRENT STEPPER=stepper_x CURRENT={HOME_CURRENT}
    SET_TMC_CURRENT STEPPER=stepper_y CURRENT={HOME_CURRENT}

    # Home
    G28 X0
    # Move away
    G91
    G1 X-10 F1200
    
    # wait just a second… (give StallGuard registers time to clear)
    G4 P1000
    # Set current for printing
    SET_TMC_CURRENT STEPPER=stepper_x CURRENT={RUN_CURRENT_X}
    SET_TMC_CURRENT STEPPER=stepper_y CURRENT={RUN_CURRENT_Y}

[gcode_macro _HOME_Y]
gcode:
    # Set current for sensorless homing
    {% set RUN_CURRENT_X = printer.configfile.settings['tmc2209 stepper_x'].run_current|float %}
    {% set RUN_CURRENT_Y = printer.configfile.settings['tmc2209 stepper_y'].run_current|float %}
    {% set HOME_CURRENT = 0.7 %}
    SET_TMC_CURRENT STEPPER=stepper_x CURRENT={HOME_CURRENT}
    SET_TMC_CURRENT STEPPER=stepper_y CURRENT={HOME_CURRENT}
    
    # Home
    G28 Y0
    # Move away
    G91
    G1 Y-10 F1200
    
    # wait just a second… (give StallGuard registers time to clear)
    G4 P1000
    # Set current for printing
    SET_TMC_CURRENT STEPPER=stepper_x CURRENT={RUN_CURRENT_X}
    SET_TMC_CURRENT STEPPER=stepper_y CURRENT={RUN_CURRENT_Y}

Final setup

If you have a [safe_z_home] section, you need to comment out the entire block (not just the [safe_z_home] line!). Or you could just delete the entire block, but if sensorless homing doesn't work reliably for you for some reason and you decide you want to go back to a physical endstop setup, you'll be glad you didn't delete it.

The last piece to bring everything together is the [homing_override] macro. If you use the Klicky probe, then you already have a [homing_override] section. Make sure you update to the latest klicky-macros.cfg, and then you can skip the rest of this guide; you're done now!

If you already have a [homing_override] and you're not using Klicky, replace calls to G28 X with _HOME_X and replace G28 Y with _HOME_Y.

For anybody who needs a [homing_override], the following example has proven extremely reliably on a V0.1.

[homing_override]
axes: xyz
gcode: 
  {% set home_all = 'X' not in params and 'Y' not in params and 'Z' not in params %}

  {% if home_all or 'X' in params %}
    _HOME_X
  {% endif %}
  
  {% if home_all or 'Y' in params %}
    _HOME_Y
  {% endif %}
  
  {% if home_all or 'Z' in params %}
    G28 Z0
    G1 Z10
  {% endif %}

Restart Klipper, and now the "Home X"/"Home Y"/"Home Z" buttons in Mainsail and Fluidd will work properly (and so will commands like "G28 X"), using your new sensorless homing setup.

@gcormier
Copy link

Ideally, hold_current is not set in a printers CFG. However, just in case, would it be possible to set that to 0 during the macro?

Be sure that a hold_current setting is not specified in the TMC driver section of the config. (If a hold_current is set then after contact is made, the motor stops while the carriage is pressed against the end of the rail, and reducing the current while in that position may cause the carriage to move - that results in poor performance and will confuse the tuning process.)
https://www.klipper3d.org/TMC_Drivers.html#sensorless-homing

@gcormier
Copy link

Missing G90 after the G91 pulloff's as well.

@danielsmoura
Copy link

I need "comment" [z_safe_home] Session, but in this sessiso have the parameter home_xy_position: , to locate Z-End stop, how i do now do make z-home ?

@EricZimmerman
Copy link

how i do now do make z-home ?

[homing_override]

would be where you would do all that work

@paulbarton556
Copy link

I've managed to get x and y to work sensorless but at a loss as to how to do Z homing. I see the comment [homing_override] but don't understand what to do. Any help welcome.

@EricZimmerman
Copy link

this is how klicky does it

[gcode_macro _Home_Z]
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" 
        G0 Z{safe_z} F{z_drop_feedrate}
    {% endif %}

    _exit_point function=Home_Z

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment