Bed mesh upside down?

Hello all
When I issue the command BED_MESH_OUTPUT I get (as expected) the list of probed z values then the list of interpolated poins.
Is it then correct to have a specular view of interpolated points vs. probed? This could be explaining my issues with poor bed mapping.

// Bed Mesh state has been saved to profile [default]
// for the current session.  The SAVE_CONFIG command will
// update the printer config file and restart the printer.
// Mesh Leveling Probed Z positions:
// 1.002778 0.920556 0.895833 0.796667 0.641667 0.613333
// 0.925556 1.022500 0.979444 0.916944 0.866944 0.719167
// 0.879722 1.000556 1.068889 1.005000 0.996389 0.851111
// 0.805556 0.935000 1.013611 0.999444 1.011667 0.931389
Mesh X,Y: 6,4
Search Height: 34
Mesh Offsets: X=0.0000, Y=0.0000
Mesh Average: 0.91
Mesh Range: min=0.6133 max=1.0689
Interpolation Algorithm: bicubic
Measured points:
0.805556  0.935000  1.013611  0.999444  1.011667  0.931389
0.879722  1.000556  1.068889  1.005000  0.996389  0.851111
0.925556  1.022500  0.979444  0.916944  0.866944  0.719167
1.002778  0.920556  0.895833  0.796667  0.641667  0.613333

It is a large custom corexy machine (600x400mm) therefore bed mapping is absolutely needed…and to date not working well.

Excerpt from .cfg:

[probe]
pin: !IN6
x_offset: -12.5
y_offset: -19.5
speed: 2
lift_speed: 15
z_offset: 30.88

[bed_mesh]
algorithm: bicubic
bicubic_tension: 0.2
speed: 400
horizontal_move_z: 34.0
mesh_min: 28, 50
mesh_max: 628, 440
probe_count: 6,4
move_check_distance: 5
split_delta_z: .025
mesh_pps: 0, 0

[printer]
kinematics: corexy
max_velocity: 700
max_accel: 15000
max_z_velocity: 20
max_z_accel: 100
square_corner_velocity: 10


Thanks to everybody for any feedback!

1 Like

Ok, was thinking it was a quick thing (hoping I was wondering about something usual).
Surprisingly enough, the values shown into the log are quite different from console output.
At this point I pass the hand to more skilled people to tell me what is going on.
Brgds
klippy_log.zip (15.5 KB)

The SAVE_CONFIG log entry shows the points as they are stored internally. The first probed point is at (min_x, min_y).

The BED_MESH_OUTPUT command was implemented to be compatible with Marlin / Prusa Firmware at the time, therefore the y-axis is inverted. The first point printed is at (min_x, max_y). The output appears to be a “birds eye” view of the surface, where the origin is at the lower left corner.

Today we have front ends like Mainsail and Fluidd that provide mesh visualization, thus BED_MESH_OUTPUT is rarely used.

1 Like

Argh.
Was hoping to hear I made some weird configuration mistake, since I am wrestling with Klipper bed meshing but got nowhere near to a workable solution.

Tried
-mapping and using without saving (yes, using BED_MESH_PROFILE LOAD=whonows)
-saving with and without name (default or whonows).
-using “whonows” or whonows
-checking mechanical probe repeatability (range 0.003889,standard deviation 0.000905)
-can’t using axis twist check,since I use a dockable probe
-ramping up sampling resolution (one point every 2mm)
-double checking probe offset and sign (both negative, since it is front-left of extuder)
-checking axis squareness (very good - skew test comes out perfect).

…but result is always the same: squashed on front left corner, in the air mid front side.

Build is very tough, everything is milled/turned from solid metal (no extruded alu profiles).
Using industrial linear guides (no cheap no-names).

Can’t understand why on same machine(s) Marlin success rate is way better on this matter.

Really hope to hear something good soon - at current rate I will be bald soon.

Thanks.

The only place in the config that I I see BED_MESH_CALIBRATE is in G29:

**
[gcode_macro G29]
gcode = 
	BED_MESH_CLEAR
	T0
	G28
	T0
	SET_VELOCITY_LIMIT ACCEL=3000
	G1 X2 Y62 F16000
	G1 Z0.1 F3000
	G4 P500
	G1 Z60 F3000
	BED_MESH_CALIBRATE PROFILE="default"
	M400
	BED_MESH_OUTPUT
	BED_MESH_PROFILE LOAD="default"
	PLATTER_CALIBRATION OPMODE=2
	G92 Z30.7
	G1 Z90
	G1 X2 Y62 F16000
	G1 Z0.1 F500
	G1 X5 Y80
	G1 Z70
	SET_VELOCITY_LIMIT ACCEL=24000**

You can just call BED_MESH_CALIBRATE, it writes to the default profile by… default. It also becomes active after the command so you don’t need to call BED_MESH_PROFILE LOAD...

I don’t know what PLATTER_CALIBRATION is and I cant find a source for it. Its some extra that’s not part of core klipper. Can we have a link please?

Starting Klippy...
Args: ['/opt/klipper/NPU/klippy/klippy.py', '/var/lib/Repetier-Server/database/klipper/NPU.cfg', '-l', '/tmp/klippy_NPU.log', '-I', '/var/lib/klipper/sockets/NPU', '-a', '/var/lib/klipper/sockets/NPU.api']
Git version: 'v0.12.0-490-g5493bdfb4-dirty'
Untracked files: klippy/extras/led_effect.py, klippy/extras/platter_calibration.py
Modified files: klippy/extras/__init__.py, klippy/extras/ad5206.py, klippy/extras/adc_scaled.py, klippy/extras/adc_temperature.py, klippy/extras/ads1220.py, klippy/extras/ads1x1x.py, klippy/extras/adxl345.py, klippy/extras/aht10.py, klippy/extras/angle.py, klippy/extras/axis_twist_compensation.py, (+118 files)
Branch: master
Remote: origin
Tracked URL: https://github.com/Klipper3d/klipper.git

+118 modfified files in addition to the listed ones. Would be interesting to know what happened to this installation anyway.

3 Likes

Hello Sineos
It is a klipper installation running on Repetier server.
All the installation process is handled from the user interface - surely I didn’t alter/touch 118 files!
I began installing version 11, then 12, then latest/greatest (Python3) on Github - always using Repetier Server graphical user interface.

About platter calibration, is a short .py to probe around some reference points to help me understand what is going on. Disabling it it doesnt change things.

from . import probe
import math

class platter_calibration:
    def __init__(self, config):
        self.printer = config.get_printer()
        x_pos_center, y_pos_center = config.getfloatlist("center_xy", count=2)
        x_pos_endstop, y_pos_endstop = config.getfloatlist("reference_xy", count=2)
        self.center_x_pos, self.center_y_pos = x_pos_center, y_pos_center
        self.endstop_x_pos, self.endstop_y_pos = x_pos_endstop, y_pos_endstop
        zconfig = config.getsection('stepper_z')
        self.max_z = zconfig.getfloat('position_max', note_valid=False)
        self.endstop_pin = zconfig.get('endstop_pin')
        self.speed = config.getfloat('speed', 50.0, above=0.)
        self.opmode = config.getfloat('opmode', 1)
        self.gcode = self.printer.lookup_object('gcode')
        self.gcode_move = self.printer.lookup_object('gcode_move')
        self.gcode.register_command("PLATTER_CALIBRATION", self.cmd_PLATTER_CALIBRATION, desc=self.cmd_PLATTER_CALIBRATION_help)

        # check if a probe is installed
        if config.has_section("probe"):
            probe = config.getsection('probe')
            self.x_offset = probe.getfloat('x_offset', note_valid=False)
            self.y_offset = probe.getfloat('y_offset', note_valid=False)

    def cmd_PLATTER_CALIBRATION(self, gcmd):
        paramopmode = gcmd.get_float('OPMODE', default=0)
        if  paramopmode != 0 :
            num_opmode = paramopmode
        else:
            num_opmode = self.opmode

        # check if all axes are homed
        toolhead = self.printer.lookup_object('toolhead')
        curtime = self.printer.get_reactor().monotonic()
        kin_status = toolhead.get_kinematics().get_status(curtime)
        probe_obj = self.printer.lookup_object('probe', None)

        if ('x' not in kin_status['homed_axes'] or
            'y' not in kin_status['homed_axes'] or
            'z' not in kin_status['homed_axes']):
            raise gcmd.error("You must home X, Y and Z axes first")

        gcmd_offset = self.gcode.create_gcode_command("SET_GCODE_OFFSET",
                                                      "SET_GCODE_OFFSET",
                                                      {'Z': 0})
        self.gcode_move.cmd_SET_GCODE_OFFSET(gcmd_offset)
        if num_opmode == 1:
            gcmd.respond_info("PLATTER: Probing reference ...")
            toolhead.manual_move([self.endstop_x_pos , self.endstop_y_pos ], self.speed)
            probe_session = probe_obj.start_probe_session(gcmd)
            probe_session.run_probe(gcmd)
            zendstop = probe_session.pull_probed_results()[0]
            probe_session.end_probe_session()

        if num_opmode == 2:
            gcmd.respond_info("PLATTER: Probing bed ...")
            toolhead.manual_move([self.center_x_pos , self.center_y_pos ], self.speed)
            probe_session = probe_obj.start_probe_session(gcmd)
            probe_session.run_probe(gcmd)
            zbed = probe_session.pull_probed_results()[0]
            probe_session.end_probe_session()

        if num_opmode == 3:
            gcmd.respond_info("PLATTER: tool setter" )
            probe_session = probe_obj.start_probe_session(gcmd)
            probe_session.run_probe(gcmd)
            ztset = probe_session.pull_probed_results()[0]
            probe_session.end_probe_session()


    cmd_PLATTER_CALIBRATION_help = "Set Z offset for current plate"


def load_config(config):
    return platter_calibration(config)

My guess for that…

This is, I think, common for probes that are located somewhere along the Y axis in relation to the nozzle. The X rail will always have some twist in it. Usually the toolhead droops in the middle of the axis. If the probe is behind the nozzle, like a Voron, this causes the probe to read high at that location. If you solve your Z offset so small prints work fine in the middle of the bed, you’ll find that the edge of the bed is squashed.

The best solution for this is to move the probe to a location that’s left or right of the nozzle. This is the reason why Prusa put its “pinda” probes off to the side, exactly in line with the nozzle. It nulls the axis twist (well it follows the axis twist).

I tried something similar on my Voron 2.4 by adapting the Stealthburner’s ADXL mounting spot to make a “foot” that holds a dockable Euclid probe. The switch button on the probe is in line with the nozzle in Y. This was a big improvement in global z accuracy. (not perfect but a lot better)

1 Like

Ok, making a bracket to host probe on same X of nozzles.
Will update as I install bracket and try new mapping!

Mounted a new bracket to bring probe aligned on X (therefore ruling out any issue of Y beam warping).
Sadly, problems are unchanged: same problems are into same locations.
Probe precision is still high (marginally improved, but we are splitting hair here, at micron scale), repeatibility is OK .
It seems to me that there is something else (bed mesh offsets?) that is wrong with my setup.
Tried heat soaking, slower probing (than 2mm/sec), shorter z probe (1mm deeper than nozzle) ,denser meshes (1cm), no interpolation…still no cigar.
I am starting to think that the bicubic surface model has some issues with my geometric proportions (600x400mm plate).

1 Like

Did you set the probe offset to compensate for the probes new position?

Yes, of course.
Then mapped bed at working temperature settled for 30 mins

1 Like

looking at the config, you have a coreXY with two Z motors for lifting the bed correct?

what for probe are you using, mechanical or induction.
if induction, are you using strong magnets in your build?

is it all the sides? front, back, right and left that are lower or only front and back. or only the front?
Are the X and Y not swaped? pressing jog left, it goes to the left and vica versa. ( i dont think this is a problem but better to check) .
i see in the config that endstop x and andstop Y are 0 that means that the 0 position is where your machine homes X and Y. this isnt normaly a problem but looking at values like bedmesh you dont know were each position is in the XY plane. X0 Y0 might be seen as front on the machine but for you it might be at the back. (depending on where the homing sensors are) the normal X0 Y0 should be at Front left from a birds eye perspective

do you adjust the Z motors/bed automaticaly or by hand? i believe bedmesh requires a somewhat initial leveling (QGL for voron2.4 or screw tilt adjust for 2 z motors). to get good reliable results (between -0.5 and 0.5 max deviation).

a other possibility can also be that you are losing Z steps along the way making one end higher and one end lower.

Hello Jules
First of all, thank you for your help.
Issues are quite repeatable: left part is squashed, middle/right too high,right a bit squashed.
Variance is 0.8mm (+/- 0.4) - can’t do any better when heating the plate (that is better/flat at room temp).
I am using mechanical probe, magnets are outside mapping/printing area anyway.

probe accuracy results:
maximum 32.121944,
minimum 32.118056,
range 0.003889,
average 32.119250,
median 32.119167,
standard deviation 0.000905

Right-left-front-back are OK. If I print anything with letters on it, it prints properly and without unexpected orientation.
XY zero position are front left.
No hand adjustment, as from my config above, I have two Z endstops, one per motor.

Multiple mappings return precisely repeatable readings (ok, up to first/second decimal…)

No step loss - using closed loop motors. And Probe accuracy is quite repeatable.

Argh.

Can we get some pictures, maybe it would give us some clues? Toolhead, axes etc?

(kicking myself)
Found the solution: I was probing the bed at working temperature.
BUT forgot that test print was performed also with HEATED CHAMBER.
Turning on the chamber during probing fixed it all.
Sorry to have bothered you all…

4 Likes

Yeah, if you don’t probe under the exact conditions where you print, you don’t know what the bed looks like.

You might also like this thread: Interruptible heat soak

1 Like

interesting read…thank you!

By the way, I am staring at 600x400mm single layers prints whose variance is better than 0.01 - geek paradise :slight_smile:

2 Likes