Bed Probe Offset- How does it really work? What I've learned

Basic Information:

Printer Model: Ender3v2
MCU / Printerboard: Creality 4.2.2

I’ve not included the klippy.log because I think the issue is pretty self evident. I’m happy to add it if desired.

Describe your issue:

Question: Why doesn’t Klipper utilize the x_offset and y_offset in the [bltouch] or [probe] section during z homing, bed probing, screw tilt calculate and other?

Are my assumptions in all the things I’ve learned correct?

Below I’ve captured:

  • My expectation on how it should work
  • Detailed question asked slightly better?
  • Everything I’ve learned so far about the probe and probe offset

My Expectation
When I tell the printer to probe, the print head should move based on the probe/bltouch/smart effector x_offset and y_offset, and test the specific z-offset of the build plate.

Detailed Question
How does klipper use the probe data within automated calibration functions? Specifically the [bed_mesh] function and SCREWS_TILT_CALCULATE. If these are based off of the probe location and offset, does that mean it modifies the mesh calculation to include the probe offset? Why not just use the probe offset to directly probe the locations defined (ex. in SCREWS_TILT_CALCULATE)?

What I’ve Learned
This section includes:

  • How to setup CR Touch / BL Touch
    • Set z home probe location
    • Calibrate z offset
    • Probe screw tilt
    • Probe bed mesh

How to setup CR Touch / BL Touch
Set z home probe location
I already had the CR Touch installed (I’m assuming this works the same with the BL Touch). Modify your [stepper_z] section to change the endstop_pin to “probe:z_virtual_endstop” and comment out the “position_endstop.” Add a [safe_z_home] and [bltouch] section to your printer.cfg. Mine are below.

endstop_pin: probe:z_virtual_endstop
#position_endstop: 0.0

#home_xy_position: 117.5,117.5   # Coordinates for center of print bed
home_xy_position: 163.5,123.5    # Modified center to include probe offset
z_hop: 10                     # Move up 10mm 
z_hop_speed: 5

sensor_pin: ^PB1
control_pin: PB0
x_offset: -46
y_offset: -6
z_offset: 2     #  this will become commented out once you do the probe calibrate

The [safe_z_home] tells Klipper to test the Z offset at the middle of my build plate. I had to specifically offset the normal center (235/2=117) and add the x and y offsets. This appears to be the right way to make this work.

Issue 1: This is not the way I expected this to work and it took forever to find this in a random post, not in the documentation. My experience with Marlin and other, have the print head move so that the probe is over the same spot as the nozzle. While this appears to be the appropriate way to make this work, I’m still not sure if its actually correct.

(only 2 links allowed) www (dot) klipper3d (dot) org/Probe_Calibrate.html#calibrating-probe-z-offset
Calibrate Z offset
This was also not horribly clear. I know that my z offset is about 1.5 mm, so I set the z offset as 2 above. I think it also works with 0. I homed all 3 axes. When I run PROBE_CALIBRATE, Klipper specifically moves the print head to the x and y offset values, probes the print surface and then goes to about +5mm above probe height. I then used the TESTZ z=-5 and then TESTZ z=-.5 until it captures the paper. If you go below the height value on screen, you get an error and the PROBE_CALIBRATE function exits and requires a new 3 axis home.

Issue 2: Given I am manually moving the print head with the TESTZ command, I was surprised (A) that I could not go to a negative z value and (B) that when the printer get mad, I had to completely restart and the error was not clear. This is an opportunity to enhance the docs and/or the errors.
This took me a while to find as it was at the bottom of a section (also linked level guide within this section). I would recommend making this its own major section and very easy to find. Again, this appears to require the screw locations to be relative to the z probe (similar to the z probe location, different than the “PROBE_CALIBRATE” command). Mine is below

# add the x and y probe offset 46 and 6
# per my testing, My Ender3v2 X axis can go to 250.  I had to change my stepper_x position_max value.
screw1: 79.5,39.5
screw1_name: front left screw
screw2: 248,39.5
screw2_name: front right screw
screw3: 248,208
screw3_name: rear right screw
screw4: 79.5,208
screw4_name: rear left screw
horizontal_move_z: 10
speed: 50
screw_thread: CW-M4

Issue 3: When telling me to turn the knob clockwise or counter clockwize tell me its while looking down from above my printer please.
Issue 1 part b: This is again not the way I expected this to work. The first time I did this, my probe was off the base and I almost crashed the head into the base. Why does this not internally use the offset to probe the specific location?

(I’m only allowed 2 links) www (dot) klipper3d (dot) org/Bed_Mesh.html

Finally, Automated Bed Mesh calibration. This is relative to the z-probe, not the nozzle. Values below are automatically calculated to include the x and y offset values. Mine is below:

# add the x and y probe offset 46 and 6
# note, in testing the Ender3v2, my X axis goes to 250 safely
speed: 120
horizontal_move_z: 5
mesh_min: 15, 15
# 250-46=200, 235-6=229... I shrank this because I was hitting the y endstop when moving at speed
mesh_max: 200, 220   
probe_count: 5,5
algorithm: bicubic
#fade_start: 1
#fade_end: 10
#fade_target: 0

Issue 1 part c: This is exactly the way I expected it to work, and I got it wrong because of the changing values. It just seems like there are so many places that the offsets could be standardized and calculated automatically, versus calculated by the human (me) who definitely gets things wrong, especially with the swapping.

Can anyone tell me? Did I get the above correct? Are my assumptions correct?

I just got time to run the bed leveling and my assumption there is wrong. The location is that of the probe, so when I tell it above (modified) to start at 15,15… that is the probe at 15,15, not the nozzle at 15,15. Initial post updated to be correct.

Also please note, I had to edit my printer.cfg file to make my X axis longer.

I specifically tested my X and Y axis on my Ender3v2. My X axis could safely travel to 250 and my Y axis maxed out at 235 (no change). If you test or want to test, change the below “position_max” value in the “stepper_x” section in your printer config.

position_max: 250

I partially agree with your “rant”: When starting with Klipper, I found this to be quite confusing as well. I would have expected to enter the nozzle coordinates everywhere and the math is done internally. Meanwhile, I guess, I’m just used to the way it is.

My workflow:

  1. Place the probe’s tip over the location I want to have, e.g. as close to bed’s 0/0 or max/max as possible
  2. Get the nozzle coordinates
  3. Correct it with the probe’s offsets
  4. Put it in the cfg

Quote from: Bed leveling - Klipper documentation

During calibration it may be necessary to set the printer’s Z position_min to a negative number (eg, position_min = -2). The printer enforces boundary checks even during calibration routines. Setting a negative number allows the printer to move below the nominal position of the bed, which may help when trying to determine the actual bed position.

SCREWS_TILT_CALCULATE indeed requires the nozzle coordinates at the location where the probe’s tip is ideally above the screw’s center.
Correction is given when looking down on the bed.

Ideally your max and / or min positions are set to values that can be physically reached. Often the values in the provided cfgs are conservative, which surely makes sense for beginners.

1 Like

I remember reading somewhere that the reason it was done this way is for when you are using an IDEX printer or it a printer with a tool head changer, in either case the offset values will be different for each toolhead, and so it was decided that the best practise would be to standardise on probe position rather than nozzle position, and then use SET_GCODE_OFFSET at run-time to adjust the nozzle position depending on which toolhead is in use


I hope my original post was not to rant-y. I greatly appreciate the word done and want to figure out how to help reduce the learning curve for new folks, and for when I forget and need to do this again. I can definitely see and appreciate the huge amount of work that has gone into this.