What's new
VORON Design

Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members!

Solved Home Z to high Z-endstops, then reset position Z0 to exact bed location just before print using a probe

Indeed

Active member
Hi
I have a 2.4 with four Z endstops at the high end, and a Tap.
I'd like to use the Tap to find and set the actual Z0 position just before a print.
Homing is done Z first, the gantry moves to the top, then X and Y are homed and it works just fine.
It's done by using some macros and a [homing_override] in the config files.

What I can't figure out is how to configure klipper to, just before a print, find the bed and have the result replace the already homed Z position with a new, accurate, probed Z position.

One solution is to correct the Z position found by the endstops by doing a bed mesh calibration before each print, but I want to avoid that.
Also, by doing mesh calibrations that way the mesh corrections are relative to the not so accurate (and also off by 0.5mm, see DETAILS below) Z position obtained from the Z endstops, instead of being relative to a properly probed bed, at the true Z0 position. It's untidy, if nothing else... :)

Any ideas?


--------------------------------------
DETAILS

Why I like to home to the top instead of the bed:
* Home at any time without scraping anything off the bed, or the bed itself.
* Home and quickly get out of a bad situation. Like after an emergency stop or a crash, software or hardware.
* Home after each print and move the toolhead away from the bed.

Other methods exist, but it's very convenient to just hit home.

I'd like to make it work similar to my delta printer. It has a Duet controller running reprap.
Homing lifts the carriages to the "high" endstops which is normal for any delta.
The endstop positions don't have to be that accurate since the true bed position at true Z0 is probed and adjusted just before each print using a Smart Effector, a "Tap" for delta printers.

On the delta (and the Voron) I have configured the value of "position_endstop" (or M665 Hxxx on the delta) to be a half a millimeter lower than it actually is.
On the Voron "position_endstop" is set to 357 instead of 357.5 where it actually is, this makes the homed Z0 position to be half a millimeter above the bed.
So even if I were to do something stupid like a "G1 Z0" move in absolute mode, I probably won't hit the bed.
At least not until after the bed is probed, which is done only just before a print.

On the Voron with the high Z endstops I can do the PROBE*, BED_MESH* and QUAD_GANTRY_LEVEL stuff as usual.
But I can't figure out how to reset the Z position just before a print, unless I load a bed mesh.
To get accurate values with the correct Z offset a BED_MESH_CALIBRATE must be done before each print and I'd like to avoid that, including adaptive bed meshing.

I'd be very happy if I could:
1. Home Z to the high position and set that position to a value a just a little bit lower than it actually is. (this I already do)
2. Before each print probe Z0 and have the already homed Z position reset to the true bed position.
3. Then load a saved bed mesh, now relative to the true Z0, independent from nozzle length and from the need to have perfectly calibrated Z endstops.
 
Last edited:
I finally got it going after much trial and error.
Perhaps a bit clumsy but it seems to work just fine.

It wasn't enough to SET_GCODE_OFFSET Z, because BED_MESH_CALIBRATE did not listen to the new shiny offset value.
In the end I had to enable FORCE_MOVE and use SET_KINEMATIC_POSITION. Ugh...

Most of the commands were added to the G32 macro, see below.
But I had to put some commands in a separate macro to get a usable result from status value 'printer.probe.last_z_result'.
No idea why.

This is what I had to do to get everything to work correctly with BED_MESH_CALIBRATE, QUAD_GANTRY_LEVEL and whatnot.
  1. Home, with G28. Must be done before each PROBE or the probed correction value will keep adding to the set Z position.
  2. Then PROBE
  3. Now move away from the bed to a known Z location
  4. SET_KINEMATIC_POSITION Z to (the known location) - (the probe result) + (the calibrated z_offset found in printer.cfg)
G32 will be called from the [gcode_macro PRINT_START] section, before any BED_MESH_PROFILE LOAD command.
G32 must also be called before any BED_MESH_CALIBRATE and BED_MESH_PROFILE commands, not just before BED_MESH_PROFILE_LOAD.
This to ensure that they start with the probed Z0 bed position and not with the less accurate position obtained from the high Z endstop.

From my config file:
Code:
[force_move]
enable_force_move: true  #*** enable FORCE_MOVE and SET_KINEMATIC_POSITION


[gcode_macro G32]
gcode:
  SAVE_GCODE_STATE NAME=STATE_G32
  G28                  #*** Home all
  G90                  #*** Absolute positioning
  G1 X175 Y175 F3000   #*** X and Y, go to bed center
  G1 Z10 F1200         #*** Move to a safe Z position not too close to the bed
  PROBE                #*** Find the bed
  G1 Z10 F1200         #*** Move away to a known Z position
  _adjust_z_location   #*** Had to move the rest of the commands to a separate macro, or status
                       #*** printer.probe.last_z_result would read '0' every time. No idea why.

  QUAD_GANTRY_LEVEL    #*** Level the gantry. Maybe not crucial now that we have Z endstops, but still.
  G90                  #*** Absolute positioning, just in case...
  G1 Z10 F1200         #*** Lift z a bit
  G1 X175 Y175 F3600   #*** Move to bed center
  RESTORE_GCODE_STATE NAME=STATE_G32


[gcode_macro _adjust_z_location]
gcode:
  #*** Set current location to (the known location - the probe result + the calibrated z_offset found in printer.cfg)
  {% set probed_z = 10 - printer.probe.last_z_result|float + printer.configfile.settings['probe'].z_offset|float %}
  SET_KINEMATIC_POSITION Z={probed_z}
 
Last edited:
I'll chime in and say that homing at an extreme away from your critical measurement (IE nozzle to bed height) is a bad idea. But it sounds like you are actually homing with Tap, which makes the stops at the top of your frame more accurately described as endstops, and not homing stops. If I were you, I would think about things like that. Stop trying to have things "home" at the top, and have those endstops be for emergency recovery. (And I DO like the idea that you can recover that way!)
 
I'll chime in and say that homing at an extreme away from your critical measurement (IE nozzle to bed height) is a bad idea. But it sounds like you are actually homing with Tap, which makes the stops at the top of your frame more accurately described as endstops, and not homing stops. If I were you, I would think about things like that. Stop trying to have things "home" at the top, and have those endstops be for emergency recovery. (And I DO like the idea that you can recover that way!)

The Z endstops are indeed used for homing Z.
So when I hit the home button the gantry moves away from the bed and any trouble that may exist down there.

It doesn't matter at all if the endstops are far away from the bed.
They can be off by several millimeters, and they can move up and down from heat expansion and such, without any impact on the Z position accuracy when printing.

Because the Z position found with the endstops are not used at all when printing.
They are only used for homing, not for finding out where the bed is.

When it's time to run G32 and then print, the bed is found with the Tap and Klipper is forced to accept the new Z0 location.
Same accuracy as when Tap is actually used as the Z endstop.

It's as if the Tap is a new Z "endstop" that suddenly overrides the previous high endstops. But only until the next G28 (home), Klipper then goes to the actual endstops again, the endstops at the top of the printer. :)

See [gcode_macro G32] and [gcode_macro _adjust_z_location] above.

I have actually set the high endstop position slightly off on purpose, so the bed can't be reached unless I go to negative Z values.
At least not not until G32 is called, and that only happens when a print starts.

I also have to call G32 before probe offset calibration and bed mesh calibration, but that's not very often.
 
Last edited:
Homing is done Z first, the gantry moves to the top, then X and Y are homed and it works just fine.
It's done by using some macros and a [homing_override] in the config files.
Thanks for sharing the macro and detailed description of your setup, I'm looking to do something similar with a custom (non-voron) machine that has dual z-axis (and endstops) with Tap.
Could you share your `[homing_override]`? I think it would help a lot, thanks.
 
Top