Faster QUAD_GANTRY_LEVEL Macro

Ever wished QGL took less time? The main problem is that the initial probing height needs to be very tall (10mm-20mm) so that the machine doesn’t crash. But after that first course adjustment the machine is usually close enough to level to allow probing from a much smaller height.

The QUAD_GANTRY_LEVEL command isn’t documented but there are options you can pass to it to override its behavior. This is the missing manual:

QUAD_GANTRY_LEVEL

QUAD_GANTRY_LEVEL [HORIZONTAL_MOVE_Z=<value>] [RETRY_TOLERANCE=<value>] RETRIES=<value>

  • HORIZONTAL_MOVE_Z - A floating point value in mm that overrides the horizontal_move_z option specified in the config file.
  • RETRY_TOLERANCE - A floating point value between 0 and 1 that overrides the retry_tolerance value in the config.
  • RETRIES - The maximum number of retries to perform, overrides the retries value in the config

And here is a pair of GCode Macros that switch from course adjustment at the default configured height to fine adjustment at a lower height:

[gcode_macro QUAD_GANTRY_LEVEL]
rename_existing: _QUAD_GANTRY_LEVEL
gcode:
    # If QGL is not applied, first run a course calibration
    {% if printer.quad_gantry_level.applied == False %}
        _QUAD_GANTRY_LEVEL RETRY_TOLERANCE=1.0
    {% endif %}
    # then perform fine QGL down to desired spec
    # this has to be a separate macro call so the results of the above call will be visible!
    _FINE_QUAD_GANTRY_LEVEL

[gcode_macro _FINE_QUAD_GANTRY_LEVEL]
gcode:
    {% if printer.quad_gantry_level.applied == True %}
        # go for full quality at reduced probing height
        _QUAD_GANTRY_LEVEL HORIZONTAL_MOVE_Z=1.0  # <- set your preferred probing height here!
    {% else %}
        # This should never happen, just perform the full calibration using the defaults
        {action_respond_info("Fine QGL called without calling course QGL first!")}
        _QUAD_GANTRY_LEVEL  # default behavior, no speedup
    {% endif %}

If QGL is already applied, it always runs at the lower height, skipping the course adjustment.

4 Likes

Cant believe this hasnt got more party time action - its fabulous - thankyou!

1 Like

Note: that this could be even more clever if the QGL module exposed the achieved accuracy on the last pass in its status model. E.g. if the accuracy was better than the desired accuracy after the course pass you could skip the fine pass. But this is often a speedup and doesn’t require any changes to klipper to work.

1 Like

Hi, is there also this option for Z_TILT_ADJUST ?

Looks like it will work. Z_TILT_ADJUST also reads a RETRY_TOLERANCE parameter that’s not documented.

Hi, so it could look like this?

 [z_tilt]
 ...  
 speed: 300  
 horizontal_move_z: 4
 retries: 6
 retry_tolerance: 0.010  

[gcode_macro Z_TILT_ADJUST]
rename_existing: _Z_TILT_ADJUST
gcode:
    # If Z_TILT is not applied, first run a course calibration
    {% if printer.z_tilt.applied == False %}
        _Z_TILT_ADJUST RETRY_TOLERANCE=1.0 HORIZONTAL_MOVE_Z=15 RETRIES=1
    {% endif %}
    # then perform fine Z_TILT down to desired spec
    # this has to be a separate macro call so the results of the above call will be visible!
    _FINE_Z_TILT_ADJUST
	

[gcode_macro _FINE_Z_TILT_ADJUST]
gcode:
    {% if printer.z_tilt.applied == True %}
        # go for full quality at reduced probing height
        _Z_TILT_ADJUST RETRY_TOLERANCE=0.010 HORIZONTAL_MOVE_Z=1 RETRIES=6 
    {% else %}
        # This should never happen, just perform the full calibration using the defaults
        {action_respond_info("Fine Z_TILT called without calling course Z_TILT first!")}
        _Z_TILT_ADJUST  # default behavior, no speedup
    {% endif %}
    
1 Like

That looks correct, just one thought:

You don’t want to set RETRIES=1. Its going to quit when it achieves the requested tolerance. And it will be slightly better because it makes a final adjustment after the last measurement.

Not sure if the macro will stop if the course phase fails?

This is brilliant! :raised_hands:

Thank you so much @garethky and @DrumClock

1 Like