Z Tilt Check Without Klipper Auto Adjusting?

I am wondering if there is a way to check Z Tilt without Klipper auto adjusting the lead screws? Say I do a Z tilt adjust, and it is nice and level, then I just want to check if it is still where I left it or if it has changed since I last checked, how would I go about doing that?.

If I could have a Z Tilt check macro just like the Z Tilt adjust macro, that would be even better.

Without additional hardware: No.

The moment the Z-motors are powered off, they lose their position and the tilt adjust is down the drain.


I did it a different way:

I have a dual Z-axes printer with another Z-endstop installed. Z-homing just go to the endstops and the both axes are levelled.

I have been wanting to do that so it can home after power loss with toolhead in safe place, but not sure how to with my setup. Currently, I have BTT SKR 1.4 Turbo, I have BLTouch for Z endstop, Dual Z axis with Z1 assigned to E1 driver, and sensorless homing for X and Y using TMC2209’s… Do I just reassign one of the X or Y end stop pins for a secondary Z homing sequence? Maybe you can give me a config example so I can take a look how you did it?

I also have a BTT Octopus V1.1, but I wont be upgrading to that till I get some TMC5160T’s. I am basically using the SKR 1.4 Turbo for my learning process so I dont mess up my better board.

https://www.klipper3d.org/G-Codes.html#get_position

and in more detail

https://www.klipper3d.org/Code_Overview.html#coordinate-systems

But that’s only valid after you’ve homed.

I have been wanting to do that so it can home after power loss with toolhead in safe place,

https://www.klipper3d.org/Config_Reference.html#safe_z_home

If you mean make sure that the gantry isn’t skewed so that the back of it doesn’t hit the bottom when you rehome… I have the same issue and have been thinking about implementing something for it to configure psuedo endstops on the back of my Voron 2.4 gantry.

I’m got a 350mm setup and the back of the gantry sags a lot when the power is off.
I’ve thought about adding some endstops as a psuedo button and see if I can code it where if while homing it hits one of those on the back of the gantry it moves the back up the gantry up by a set amount and tries homing again.

Then again, I’m also thought about using some servos and making a “kickstand” when I power off.

1 Like

Sometimes I want to check current z tilt position because I walked away since last calibration/home/ztilt, and I’m not sure if the motors may or may not have powered down causing alignment change, so it would be nice to do a quick check to verify current position rather than go through a full on Z-Tilt calibration back and forth over and over till it levels.

In addition to that, I would love to have 2 homing options on my CoreXY. 1. Home on clean build plate using bltouch in center of bed, and 2. an option to home/z tilt align using an endstop switch per motor without the bltouch needing to home in center of bed before any calibration process. If there was a way to add a mechanical endstop switch per z motor, or use sensorless homing per motor in addition to bed probe, that would very be helpful.

That’s impossible because once the motors power down Klipper has no idea where they’re at. You have to rehome unless you implement a linear position sensor or something similar.

If there was a way to add a mechanical endstop switch per z motor

Multi Stepper Config

 #endstop_pin:
#   If an endstop_pin is defined for the additional stepper then the
#   stepper will home until the endstop is triggered. Otherwise, the
#   stepper will home until the endstop on the primary stepper for the
#   axis is triggered.

Right, but that’s exactly my point of wanting this option. Say motors power down, I home the printer, then a simple check on each z tilt point could verify bed tilt instead of running a calibration where it adjusts them during that process… Just like it homes and finds home position for Z, it would be nice to find position on each side of the bed without it adjusting.

I use this in my printer.cfg and the paper method to verify if the bed is level. You can adjust in toolhead settings just like tilt adjust.

[bed_screws]
screw1: 45, 62 # Using front left as baseline
screw1_name: front left screw
screw2: 45, 200
screw2_name: rear left screw
screw3: 200, 200
screw3_name: rear right screw
screw4: 200, 62
screw4_name: front right screw
screw5: 115, 115
screw5_name: Center

Besides the multi stepper option above, Check against WHAT? It needs a reference.

I really don’t understand your question, and maybe you aren’t understanding mine either.

I want a check z tilt position instead of calibration is because calibration takes time and does 3-6 attempts till it finds a level point or fails. Even right after I do a Z tilt calibration successfully, If I run it again, it will do 4+ checks till it either fails or successfully levels the tilt again, so that is why I want it to do a check position of bed tilt instead of calibration.

Here is a successful Z tilt calibration

Here is a z tilt calibration right after the first calibration finished:

As you can see, it had to do 4 attempts to level the tilt again, even though it was already calibrated seconds before the 2nd calibration.

The difference between those two sets measurements is between .0018 and .0005mm
Or 1 to .5 microns.

So literally roughly somewhere in the size range of a small bacteria or the width of the mitochondria in your cells.

In other words, ridiculously tiny.


Your tolerance of .00001 is way too small and unrealistic.

.00001mm is 10 nanometers, we’re talking atomic scale at that level.
That’s higher resolution than used for interferometry in the highest resolution science experiments in the world.

(Unless you’re LIGO but lets not go there, cause they have a 4Km long beam setup. They can measure changes 10,000 times smaller than an atomic nucleus. That’s not ridiculously small, that’s unfathomably absurdly, mind blowingly, “I can’t even begin to imagine trying to imagine it” kind of small.) [1]

That’s smaller than wavelengths of light. That’s somewhere in the high end of UV/Soft X-Ray range.

So ridiculously tiny doesn’t even begin to touch how ridiculously tiny that is.

Put another way, Assuming your bed is aluminum.
Using the co-efficient of thermal expansion for aluminum.

For every degree Celsius change, your bed would expand/contract 6600 nanometers

So a realistic temperature fluctuation in a temperature controlled environment (like a house) is .1C fluctuation of the period of seconds (it’s most definitely far more in a 3d printer). A .1 C fluctuation is 660 nm, or 66 times your tolerance…

You’ll ALWAYS have adjustments with that level of tolerance.


Sorry for the info dump, I always find it intersting to calculate things to scale that’s intuitive. Because those numbers are so small it’s beyond the capability of the human mind to grasp unless you put it into something in more common terms. Which is always fun to do for me.

It was set to .001 before, and it failed just about every time I tried to do the z tilt adjust. This is why I started messing with the higher resolution that I currently have it set to.

For whatever reason, the z-tilt values would increase higher and higher each side till it said the value increased and it aborted. Once I put it to a higher resolution value, it did that far less often which is why I kept it at this value. I had the same issues with be leveling too, so I had to increase the values there as well till I got the perfect first layer.

If your values keep getting higher and higher, then i would suggest checking your “z_positions” parameters, the chances are these are wrong and causing the adjustment calculation to output the wrong corrections.

z_positions:
A list of X, Y coordinates (one per line; subsequent lines
indented) describing the location of each bed “pivot point”. The
“pivot point” is the point where the bed attaches to the given Z
stepper. It is described using nozzle coordinates (the X, Y position
of the nozzle if it could move directly above the point). The
first entry corresponds to stepper_z, the second to stepper_z1,
the third to stepper_z2, etc. This parameter must be provided.

Can you post your klippy log? Would help to see if there is something easily diagnosable that might be causing it.

My probe values increase each probe just like this guy: Probe accuracy: always higher z? · Issue #2509 · Klipper3d/klipper · GitHub

I tried adjusting the z tilt position, motor current, microsteps, interpolate true/false, and many other things, but the only way I got the printer to give me a proper bed leveling mesh, and not have increasing probe values was to increase the tolerance on the bltouch and z tilt to 0.00001.

klippy(4).zip (962.2 KB)

Here are some probe accuracy tests with different tolerance values to show how it increases with each probe:

Tolerance set to .0025 on bltouch and z tilt:
14:41:58 // probe accuracy results: maximum 1.462500, minimum 1.427500, range 0.035000, average 1.448687, median 1.450000, standard deviation 0.010922
14:41:58 // probe at 249.987,200.000 is z=1.460000
14:41:54 // probe at 249.987,200.000 is z=1.461250
14:41:50 // probe at 249.987,200.000 is z=1.457500
14:41:46 // probe at 249.987,200.000 is z=1.460000
14:41:42 // probe at 249.987,200.000 is z=1.462500
14:41:38 // probe at 249.987,200.000 is z=1.455000
14:41:34 // probe at 249.987,200.000 is z=1.458750
14:41:30 // probe at 249.987,200.000 is z=1.458750
14:41:26 // probe at 249.987,200.000 is z=1.455000
14:41:22 // probe at 249.987,200.000 is z=1.451250
14:41:18 // probe at 249.987,200.000 is z=1.447500
14:41:14 // probe at 249.987,200.000 is z=1.448750
14:41:10 // probe at 249.987,200.000 is z=1.446250
14:41:06 // probe at 249.987,200.000 is z=1.448750
14:41:03 // probe at 249.987,200.000 is z=1.437500
14:40:59 // probe at 249.987,200.000 is z=1.436250
14:40:55 // probe at 249.987,200.000 is z=1.436250
14:40:51 // probe at 249.987,200.000 is z=1.432500
14:40:47 // probe at 249.987,200.000 is z=1.432500
14:40:43 // probe at 249.987,200.000 is z=1.427500
14:40:31 // PROBE_ACCURACY at X:249.988 Y:200.000 Z:11.400 (samples=20 retract=2.000 speed=1.0 lift_speed=15.0)
14:40:31 $ PROBE_ACCURACY samples=20

Tolerance set to .0001 on bltouch and z tilt:
14:32:34 // probe accuracy results: maximum 1.420000, minimum 1.407500, range 0.012500, average 1.412750, median 1.412500, standard deviation 0.003000
14:32:34 // probe at 249.987,199.987 is z=1.420000
14:32:30 // probe at 249.987,199.987 is z=1.417500
14:32:26 // probe at 249.987,199.987 is z=1.415000
14:32:22 // probe at 249.987,199.987 is z=1.415000
14:32:18 // probe at 249.987,199.987 is z=1.415000
14:32:14 // probe at 249.987,199.987 is z=1.412500
14:32:10 // probe at 249.987,199.987 is z=1.415000
14:32:06 // probe at 249.987,199.987 is z=1.412500
14:32:02 // probe at 249.987,199.987 is z=1.415000
14:31:59 // probe at 249.987,199.987 is z=1.412500
14:31:55 // probe at 249.987,199.987 is z=1.412500
14:31:51 // probe at 249.987,199.987 is z=1.412500
14:31:47 // probe at 249.987,199.987 is z=1.411250
14:31:43 // probe at 249.987,199.987 is z=1.410000
14:31:39 // probe at 249.987,199.987 is z=1.412500
14:31:35 // probe at 249.987,199.987 is z=1.411250
14:31:31 // probe at 249.987,199.987 is z=1.410000
14:31:27 // probe at 249.987,199.987 is z=1.408750
14:31:23 // probe at 249.987,199.987 is z=1.408750
14:31:19 // probe at 249.987,199.987 is z=1.407500
14:31:07 // PROBE_ACCURACY at X:249.988 Y:199.988 Z:11.400 (samples=20 retract=2.000 speed=1.0 lift_speed=15.0)
14:31:07 $ PROBE_ACCURACY samples=20

Tolerance set to .00001 on bltouch and z tilt:
14:38:16 // probe accuracy results: maximum 1.398750, minimum 1.377500, range 0.021250, average 1.382875, median 1.381250, standard deviation 0.005334
14:38:16 // probe at 250.000,200.000 is z=1.380000
14:38:12 // probe at 250.000,200.000 is z=1.378750
14:38:08 // probe at 250.000,200.000 is z=1.377500
14:38:04 // probe at 250.000,200.000 is z=1.378750
14:38:00 // probe at 250.000,200.000 is z=1.378750
14:37:56 // probe at 250.000,200.000 is z=1.382500
14:37:52 // probe at 250.000,200.000 is z=1.380000
14:37:48 // probe at 250.000,200.000 is z=1.380000
14:37:44 // probe at 250.000,200.000 is z=1.381250
14:37:40 // probe at 250.000,200.000 is z=1.382500
14:37:36 // probe at 250.000,200.000 is z=1.378750
14:37:32 // probe at 250.000,200.000 is z=1.382500
14:37:28 // probe at 250.000,200.000 is z=1.380000
14:37:25 // probe at 250.000,200.000 is z=1.383750
14:37:21 // probe at 250.000,200.000 is z=1.381250
14:37:17 // probe at 250.000,200.000 is z=1.383750
14:37:13 // probe at 250.000,200.000 is z=1.386250
14:37:09 // probe at 250.000,200.000 is z=1.387500
14:37:05 // probe at 250.000,200.000 is z=1.395000
14:37:01 // probe at 250.000,200.000 is z=1.398750
14:36:49 // PROBE_ACCURACY at X:250.000 Y:200.000 Z:11.400 (samples=20 retract=2.000 speed=1.0 lift_speed=15.0)
14:36:49 $ PROBE_ACCURACY samples=20

Please see my reply to mjfsch.

I dont want to have my tolerance that high, but it is the only thing I found that gave me a good bed mesh and first layer.

What kind of printer do you have? I see it’s a core XY and your Z has adjustment screws.

I ask because your [z_tilt] is setup like this…

[z_tilt]
z_positions = 542, 200
	-43, 200

Those are way outside where your max/min X are (at least the 542 is with a max of 400). How big is your actual bed and gantry? They don’t quite make sense for a Corexy printer I don’t think? Trying to wrap my head around it.

The larger the bed and gantry in a core-xy the more issues with twisting and sag you’re going to have.

Also, I don’t see any setup for Quad_Gantry_Level? How are you sure that your gantry is level when you’re computing the Z tilt?

Edit for future readers: I realize I’m dumb, QGL isn’t used for lead screw z drives.

Printer was a Tronxy X5SA-400 but it has been modified.

I have 2 lead screws with 2 z motors/drivers. Bed is 420mm/420mm (Elegoo Neptune 4 Max Bed/build plate) and the lead screws are roughly 75mm away from the edge of the bed.

I have tried many different z_positions, but none made a difference.

Technically, the correct values are these:
z_positions: 497, 200
-86, 200
points: 420, 200
79, 200
but it made no difference… If anything, it made it worse. I tried same values as the probe points420 and 79 for X position, I tried values where I measured from the bltouch to lead screw, I tried measurements from nozzle to lead screw (should be correct measurement) but it only got worse and worse.

Wait… I’m kind of confused by your pictures? How many Z axis drives do you have?

If you are asking how many motors/drivers/lead screws, there are 2.

[stepper_z]
step_pin: P0.22
dir_pin: !P2.11
enable_pin: !P0.21
microsteps: 32
rotation_distance: 8
endstop_pin: probe:z_virtual_endstop
position_max: 400
position_min: -2
step_pulse_duration: 0.000001

[tmc2209 stepper_z]
uart_pin: P1.8
run_current: 1.400
hold_current: 0.950
#sense_resistor: 0.700
stealthchop_threshold: 999999
interpolate: True

[stepper_z1]
step_pin: P1.15
dir_pin: !P1.14
enable_pin: !P1.16
microsteps: 32
rotation_distance: 8
step_pulse_duration: 0.000001

[tmc2209 stepper_z1]
uart_pin: P1.1
run_current: 1.400
hold_current: 0.950
#sense_resistor: 0.700
stealthchop_threshold: 999999
interpolate: True

[z_tilt]
z_positions: 497, 200
-86, 200
points: 420, 200
79, 200
speed: 550
horizontal_move_z: 5
retries: 20
retry_tolerance: .00001 #was working with .00001