Skip to content

Instantly share code, notes, and snippets.

@ChipCE
Last active October 14, 2024 16:52
Show Gist options
  • Save ChipCE/95fdbd3c2f3a064397f9610f915f7d02 to your computer and use it in GitHub Desktop.
Save ChipCE/95fdbd3c2f3a064397f9610f915f7d02 to your computer and use it in GitHub Desktop.
Klipper bed mesh on print area only macro install guide

READ THIS FIRST

Adaptive bed mesh is merged into klipper master branch. You can use this feature without this custom macro. Official klipper adaptive bed mesh

Klipper mesh on print area only install guide

What this macro do

  • This macro will dynamically changing the bed mesh area based on the size of the parts will be printed. The fw will only probe on the area that the part will be printed (plus mesh_area_offset value)

Setup guide

  • (1) Add the following macro to your printer config, this will replace the default BED_MESH_CALIBRATE command.
[gcode_macro BED_MESH_CALIBRATE]
rename_existing: BED_MESH_CALIBRATE_BASE
; gcode parameters
variable_parameter_AREA_START : 0,0
variable_parameter_AREA_END : 0,0
; the clearance between print area and probe area 
variable_mesh_area_offset : 5.0
; number of sample per probe point
variable_probe_samples : 2
; minimum probe count
variable_min_probe_count : 4
; scale up the probe count, should be 1.0 ~ < variable_max_probe_count/variable_min_probe_count
variable_probe_count_scale_factor : 1.0
; enable preference index
variable_enable_reference_index : False
gcode:
    {% if params.AREA_START and params.AREA_END %}
        {% set bedMeshConfig = printer["configfile"].config["bed_mesh"] %}
        {% set safe_min_x = bedMeshConfig.mesh_min.split(",")[0]|float %}
        {% set safe_min_y = bedMeshConfig.mesh_min.split(",")[1]|float %}
        {% set safe_max_x = bedMeshConfig.mesh_max.split(",")[0]|float %}
        {% set safe_max_y = bedMeshConfig.mesh_max.split(",")[1]|float %}

        {% set area_min_x = params.AREA_START.split(",")[0]|float %}
	{% set area_min_y = params.AREA_START.split(",")[1]|float %}
	{% set area_max_x = params.AREA_END.split(",")[0]|float %}
	{% set area_max_y = params.AREA_END.split(",")[1]|float %}

	{% if bedMeshConfig.probe_count.split(",")|length == 2 %}
            {% set meshPointX = bedMeshConfig.probe_count.split(",")[0]|int %}
            {% set meshPointY = bedMeshConfig.probe_count.split(",")[1]|int %}
        {% else %}
            {% set meshPointX = bedMeshConfig.probe_count.split(",")[0]|int %}
            {% set meshPointY = bedMeshConfig.probe_count.split(",")[0]|int %}
        {% endif %}

	{% set meshMaxPointX = meshPointX %}
	{% set meshMaxPointY = meshPointY %}


        {% if (area_min_x < area_max_x) and (area_min_y < area_max_y) %}
            {% if area_min_x - mesh_area_offset >=  safe_min_x %}
                {% set area_min_x = area_min_x - mesh_area_offset %}
            {% else %}
                {% set area_min_x = safe_min_x %}
            {% endif %}

            {% if area_min_y - mesh_area_offset >=  safe_min_y %}
                {% set area_min_y = area_min_y - mesh_area_offset %}
            {% else %}
                {% set area_min_y = safe_min_y %}
            {% endif %}

            {% if area_max_x + mesh_area_offset <=  safe_max_x %}
                {% set area_max_x = area_max_x + mesh_area_offset %}
            {% else %}
                {% set area_max_x = safe_max_x %}
            {% endif %}

            {% if area_max_y + mesh_area_offset <=  safe_max_y %}
                {% set area_max_y = area_max_y + mesh_area_offset %}
            {% else %}
                {% set area_max_y = safe_max_y %}
            {% endif %}

            {% set meshPointX = (meshPointX * (area_max_x - area_min_x) / (safe_max_x - safe_min_x) * probe_count_scale_factor)|round(0)|int %}
            {% if meshPointX < min_probe_count %}
                {% set meshPointX = min_probe_count %}
            {% endif %}
	    {% if meshPointX > meshMaxPointX %}
                {% set meshPointX = meshMaxPointX %}
            {% endif %}

            {% set meshPointY = (meshPointY * (area_max_y -area_min_y ) / (safe_max_y - safe_min_y) * probe_count_scale_factor )|round(0)|int %}
            {% if meshPointY < min_probe_count %}
                {% set meshPointY = min_probe_count %}
            {% endif %}
	    {% if meshPointY > meshMaxPointY %}
                {% set meshPointY = meshMaxPointY %}
            {% endif %}

            {% set algorithm = "bicubic" %}
	    {% if "algorithm" in bedMeshConfig %}
	        {% set algorithm = bedMeshConfig.algorithm %}
            {% endif %}
            {% if meshPointX >=7 or meshPointY >=7 %}
                {% set algorithm = "bicubic" %}
            {% endif %}

            {% if enable_reference_index %}
                {% set referenceIndex = (meshPointX * meshPointY / 2 - 1 )|round(0)|int %}
                BED_MESH_CALIBRATE_BASE mesh_min={area_min_x},{area_min_y} mesh_max={area_max_x},{area_max_y} probe_count={meshPointX},{meshPointY} samples={probe_samples|int} algorithm={algorithm} relative_reference_index={referenceIndex}
            {% else %}
                BED_MESH_CALIBRATE_BASE mesh_min={area_min_x},{area_min_y} mesh_max={area_max_x},{area_max_y} probe_count={meshPointX},{meshPointY} samples={probe_samples|int} algorithm={algorithm}
            {% endif %}
        {% else %}
            BED_MESH_CALIBRATE_BASE
        {% endif %}
    {% else %}
        BED_MESH_CALIBRATE_BASE
    {% endif %}
  • (2) Go to slicer setting and replace the old bed mesh gcode the following command.

Prusa Slicer
BED_MESH_CALIBRATE AREA_START={first_layer_print_min[0]},{first_layer_print_min[1]} AREA_END={first_layer_print_max[0]},{first_layer_print_max[1]}

Ideal maker
BED_MESH_CALIBRATE AREA_START={print_pos_min_x},{print_pos_min_y} AREA_END={print_pos_max_x},{print_pos_max_y}

Cura slicer
BED_MESH_CALIBRATE AREA_START=%MINX%,%MINY% AREA_END=%MAXX%,%MAXY%

*(Cura slicer plugin) To make the macro to work in Cura slicer, you need to install the post process plugin click here to download (based on frankbags's script)
- In cura menu Help -> Show configuration folder.
- Copy the python script from the above link in to scripts folder.
- Restart Cura
- In cura menu Extensions -> Post processing -> Modify G-Code and select Klipper print area mesh

For user using single command START_PRINT

  • (*) If you use single command start gcode like START_PRINT BED_TEMP={material_bed_temperature_layer_0} EXTRUDER_TEMP={material_print_temperature_layer_0} .You might need to add parameter parsing to BED_MESH_CALIBRATE inside START_PRINT. This is an example, also check my macro sample
[gcode_macro START_PRINT]
variable_parameter_EXTRUDER_TEMP: 190
variable_parameter_BED_TEMP: 60
; gcode parameters for area bed mesh
variable_parameter_AREA_START : 0,0
variable_parameter_AREA_END : 0,0
gcode:
    # preheat, homing, etc
    BED_MESH_CALIBRATE AREA_START={params.AREA_START|default("0,0")} AREA_END={params.AREA_END|default("0,0")}
    # the rest of your start macro here

And you will need to change Slicer start gcode to this

  • Cura: START_PRINT EXTRUDER_TEMP={material_print_temperature_layer_0} BED_TEMP={material_bed_temperature_layer_0} AREA_START=%MINX%,%MINY% AREA_END=%MAXX%,%MAXY%
  • Prusa slicer: START_PRINT EXTRUDER_TEMP=[first_layer_temperature] BED_TEMP=[first_layer_bed_temperature] AREA_START={first_layer_print_min[0]},{first_layer_print_min[1]} AREA_END={first_layer_print_max[0]},{first_layer_print_max[1]}

change logs

  • 2022/07/21
    • Added force lagrange algorithm for mesh with lower than 3 points
    • Added enable_reference_index config flag

The code does not work?

  • I will try to help if possible, you will have to post ALL of your configs, your slicer start gcode and your sliced gcode.
  • If I'm cannot or too slow to respose, our discord members might help you. Check our discord here
@frankbags
Copy link

are you including the macros.cfg twice by chance?
and are you renaming the original macro like this or simply rename the actual macro?

[gcode_macro BED_MESH_CALIBRATE] rename_existing: BED_MESH_CALIBRATE_BASE

@Nathan22211
Copy link

ok so I just copy pasted that macro into my config on my 350 siboor trident. It seems this macro doesn't work with Klicky. it didn't go and pick up my probe. I might modify the macro to fix that.

@Shaneweston
Copy link

I know I have done something stupid, but my brain has decided to take a holiday without me so i can't work out where I am wrong.

Two issues. The auto bed mesh seems to do the whole bed not just the print area. Also it leaves blobs of filament that slowly reduce in size as it probes the bed.


CURA START CODE
G21 ;metric values
G90 ;absolute positioning
M82 ;set extruder to absolute mode
M107 ;start with the fan off
G28 X0 Y0 ;move X/Y to min endstops
M300 S1318 P266
G28 Z0 ;move Z to min endstops
G0 Z0.2
G92 E0 ;zero the extruded length
G1 X40 E25 F400 ; Extrude 25mm of filament in a 4cm line. Reduce speed (F) if you have a nozzle smaller than 0.4mm!
G92 E0 ;zero the extruded length again
G1 E-1 F500 ; Retract a little
G1 X80 F4000 ; Quickly wipe away from the filament line
BED_MESH_CALIBRATE AREA_START=%MINX%,%MINY% AREA_END=%MAXX%,%MAXY%
M117 ; Printing…
G5


POST PLUGIN SCRIPT
C:\Users\shane\AppData\Roaming\cura\5.4\plugins\PostProcessingPlugin\Scripts\MeshPrintSize.py
import re #To perform the search and replace.

from ..Script import Script

class MeshPrintSize(Script):

def getSettingDataString(self):
    return """{
        "name": "Mesh Print Size",
        "key": "MeshPrintSize",
        "metadata": {},
        "version": 2,
        "settings":{}
    }"""

def execute(self, data):
        minMaxXY = {'MAXY':0,'MAXX':0, 'MINY':0,'MINX':0}
        lineData = ''

        for layer_number, layer in enumerate(data):
            for k,v in minMaxXY.items():
                result = re.search(str(k)+":(\d*\.?\d*)",layer)
                if result is not None:
                    minMaxXY[k] = result.group(1)

            if re.search('START_PRINT.*', layer) is not None:
                lineData = layer
                for k, v in minMaxXY.items():
                    pattern = re.compile('START_PRINT ')
                    replace = 'START_PRINT {variable}={value} '.format(variable = k, value = v)
                    lineData = re.sub(pattern, replace, lineData)

                data[layer_number] = lineData

        return data

******************************************************************8
BED_MESH_CALIBRATE.CFG
[gcode_macro BED_MESH_CALIBRATE]
rename_existing: BED_MESH_CALIBRATE_BASE
; gcode parameters
variable_parameter_AREA_START : 0,0
variable_parameter_AREA_END : 0,0
; the clearance between print area and probe area
variable_mesh_area_offset : 5.0
; number of sample per probe point
variable_probe_samples : 2
; minimum probe count
variable_min_probe_count : 8
; scale up the probe count, should be 1.0 ~ < variable_max_probe_count/variable_min_probe_count
variable_probe_count_scale_factor : 1.0
; enable preference index
variable_enable_reference_index : False
gcode:
{% if params.AREA_START and params.AREA_END %}
{% set bedMeshConfig = printer["configfile"].config["bed_mesh"] %}
{% set safe_min_x = bedMeshConfig.mesh_min.split(",")[0]|float %}
{% set safe_min_y = bedMeshConfig.mesh_min.split(",")[1]|float %}
{% set safe_max_x = bedMeshConfig.mesh_max.split(",")[0]|float %}
{% set safe_max_y = bedMeshConfig.mesh_max.split(",")[1]|float %}

    {% set area_min_x = params.AREA_START.split(",")[0]|float %}
{% set area_min_y = params.AREA_START.split(",")[1]|float %}
{% set area_max_x = params.AREA_END.split(",")[0]|float %}
{% set area_max_y = params.AREA_END.split(",")[1]|float %}

{% if bedMeshConfig.probe_count.split(",")|length == 2 %}
        {% set meshPointX = bedMeshConfig.probe_count.split(",")[0]|int %}
        {% set meshPointY = bedMeshConfig.probe_count.split(",")[1]|int %}
    {% else %}
        {% set meshPointX = bedMeshConfig.probe_count.split(",")[0]|int %}
        {% set meshPointY = bedMeshConfig.probe_count.split(",")[0]|int %}
    {% endif %}

{% set meshMaxPointX = meshPointX %}
{% set meshMaxPointY = meshPointY %}


    {% if (area_min_x < area_max_x) and (area_min_y < area_max_y) %}
        {% if area_min_x - mesh_area_offset >=  safe_min_x %}
            {% set area_min_x = area_min_x - mesh_area_offset %}
        {% else %}
            {% set area_min_x = safe_min_x %}
        {% endif %}

        {% if area_min_y - mesh_area_offset >=  safe_min_y %}
            {% set area_min_y = area_min_y - mesh_area_offset %}
        {% else %}
            {% set area_min_y = safe_min_y %}
        {% endif %}

        {% if area_max_x + mesh_area_offset <=  safe_max_x %}
            {% set area_max_x = area_max_x + mesh_area_offset %}
        {% else %}
            {% set area_max_x = safe_max_x %}
        {% endif %}

        {% if area_max_y + mesh_area_offset <=  safe_max_y %}
            {% set area_max_y = area_max_y + mesh_area_offset %}
        {% else %}
            {% set area_max_y = safe_max_y %}
        {% endif %}

        {% set meshPointX = (meshPointX * (area_max_x - area_min_x) / (safe_max_x - safe_min_x) * probe_count_scale_factor)|round(0)|int %}
        {% if meshPointX < min_probe_count %}
            {% set meshPointX = min_probe_count %}
        {% endif %}
    {% if meshPointX > meshMaxPointX %}
            {% set meshPointX = meshMaxPointX %}
        {% endif %}

        {% set meshPointY = (meshPointY * (area_max_y -area_min_y ) / (safe_max_y - safe_min_y) * probe_count_scale_factor )|round(0)|int %}
        {% if meshPointY < min_probe_count %}
            {% set meshPointY = min_probe_count %}
        {% endif %}
    {% if meshPointY > meshMaxPointY %}
            {% set meshPointY = meshMaxPointY %}
        {% endif %}

        {% set algorithm = "bicubic" %}
    {% if "algorithm" in bedMeshConfig %}
        {% set algorithm = bedMeshConfig.algorithm %}
        {% endif %}
        {% if meshPointX >=7 or meshPointY >=7 %}
            {% set algorithm = "bicubic" %}
        {% endif %}

        {% if enable_reference_index %}
            {% set referenceIndex = (meshPointX * meshPointY / 2 - 1 )|round(0)|int %}
            BED_MESH_CALIBRATE_BASE mesh_min={area_min_x},{area_min_y} mesh_max={area_max_x},{area_max_y} probe_count={meshPointX},{meshPointY} samples={probe_samples|int} algorithm={algorithm} relative_reference_index={referenceIndex}
        {% else %}
            BED_MESH_CALIBRATE_BASE mesh_min={area_min_x},{area_min_y} mesh_max={area_max_x},{area_max_y} probe_count={meshPointX},{meshPointY} samples={probe_samples|int} algorithm={algorithm}
        {% endif %}
    {% else %}
        BED_MESH_CALIBRATE_BASE
    {% endif %}
{% else %}
    BED_MESH_CALIBRATE_BASE
{% endif %}

PRINTER.CFG
###Anycubic Vyper Klipper Config###

[include mainsail.cfg]
[include BED_MESH_CALIBRATE.cfg]

[stepper_x]
step_pin: PC2
dir_pin: PB9
enable_pin: !PC3
microsteps: 16
rotation_distance: 40
endstop_pin: !PA7
position_min: -3
position_endstop: -3
position_max: 245
homing_speed: 30.0

[stepper_y]
step_pin: PB8
dir_pin: PB7
enable_pin: !PC13
microsteps: 16
rotation_distance: 32
endstop_pin: !PC5
position_min: -17
position_endstop: -17
position_max: 245
homing_speed: 30.0

[stepper_z]
step_pin: PB6
dir_pin: !PB5
enable_pin: !PC14
microsteps: 16
rotation_distance: 8
endstop_pin: PB2
#position_endstop: 0.0
position_max: 260
position_min: -5
homing_speed: 5.0

[stepper_z1]
step_pin: PC0
dir_pin: !PC1
enable_pin: !PC15
microsteps: 16
rotation_distance: 8
#endstop_pin: PC6

[extruder]
step_pin: PB4
dir_pin: !PB3
enable_pin: !PA15
microsteps: 16
rotation_distance: 22.185
gear_ratio: 50:17
full_steps_per_rotation: 200
nozzle_diameter: 0.400
filament_diameter: 1.750
max_extrude_cross_section: 5.0
heater_pin: PA1
sensor_type: ATC Semitec 104GT-2
sensor_pin: PC4
#control: pid
#pid_kp = 28.937
#pid_ki = 1.295
#pid_kd = 161.688
min_temp: 0
max_temp: 260
pressure_advance = 0.34

[heater_fan extruder_fan]
pin: PB1

[heater_bed]
heater_pin: PA4
sensor_type: EPCOS 100K B57560G104F
sensor_pin: PB0
#control: pid
#pid_kp = 67.648
#pid_ki = 1.044
#pid_kd = 1095.893
min_temp: 0
max_temp: 110

[fan]
pin: PA0

[probe]
pin: !PB12
#z_offset: 0
activate_gcode:
probe_reset

[output_pin LED]
pin: mcu:PA13
pwm: False
value: 0

[output_pin probe_reset_pin]
pin: PB13

[filament_switch_sensor runout]
pause_on_runout: True
switch_pin: PA5

[mcu]
serial: /dev/ttyUSB0
restart_method: command

[temperature_sensor Raspberry Pi]
sensor_type: temperature_host
min_temp: 0
max_temp: 100

[safe_z_home]
home_xy_position: -3,-17
z_hop: 10

[input_shaper]

#shaper_freq_x: 62.2

#shaper_type_x: ei

#shaper_freq_y: 36.8

#shaper_type_y: mzv

[printer]
kinematics: cartesian
max_velocity: 300
max_accel: 4000
max_accel_to_decel: 3000
max_z_velocity: 5
max_z_accel: 100

[bed_mesh]
mesh_min: 15,15
mesh_max: 230, 230
probe_count: 6,6
mesh_pps: 2,3
algorithm: bicubic
speed: 5400
horizontal_move_z: 5

[gcode_macro probe_reset]
gcode:
SET_PIN PIN=probe_reset_pin VALUE=0
G4 P300
SET_PIN PIN=probe_reset_pin VALUE=1
G4 P100

[display_status]

[pause_resume]

[gcode_macro PAUSE]
description: Pause the actual running print
rename_existing: PAUSE_BASE
gcode:
##### set defaults #####
{% set x = params.X|default(230) %} #edit to your park position
{% set y = params.Y|default(230) %} #edit to your park position
{% set z = params.Z|default(10)|float %} #edit to your park position
{% set e = params.E|default(1) %} #edit to your retract length
##### calculate save lift position #####
{% set max_z = printer.toolhead.axis_maximum.z|float %}
{% set act_z = printer.toolhead.position.z|float %}
{% set lift_z = z|abs %}
{% if act_z < (max_z - lift_z) %}
{% set z_safe = lift_z %}
{% else %}
{% set z_safe = max_z - act_z %}
{% endif %}
##### end of definitions #####
PAUSE_BASE
G91
{% if printer.extruder.can_extrude|lower == 'true' %}
G1 E-{e} F2100
{% else %}
{action_respond_info("Extruder not hot enough")}
{% endif %}
{% if "xyz" in printer.toolhead.homed_axes %}
G1 Z{z_safe}
G90
G1 X{x} Y{y} F6000
{% else %}
{action_respond_info("Printer not homed")}
{% endif %}

[gcode_macro RESUME]
description: Resume the actual running print
rename_existing: RESUME_BASE
gcode:
##### set defaults #####
{% set e = params.E|default(1) %} #edit to your retract length
#### get VELOCITY parameter if specified ####
{% if 'VELOCITY' in params|upper %}
{% set get_params = ('VELOCITY=' + params.VELOCITY) %}
{%else %}
{% set get_params = "" %}
{% endif %}
##### end of definitions #####
G91
{% if printer.extruder.can_extrude|lower == 'true' %}
G1 E{e} F2100
{% else %}
{action_respond_info("Extruder not hot enough")}
{% endif %}
RESUME_BASE {get_params}

[gcode_macro CANCEL_PRINT]
description: Cancel the actual running print
rename_existing: CANCEL_PRINT_BASE
gcode:
TURN_OFF_HEATERS
CANCEL_PRINT_BASE

## <---------------------- SAVE_CONFIG ---------------------->
#
# DO NOT EDIT THIS BLOCK OR BELOW. The contents are auto-generated.
##
#
# [input_shaper]
## shaper_type_x = ei
#
# shaper_freq_x = 61.0
## shaper_type_y = mzv
#
# shaper_freq_y = 58.0
##
#
# [bed_mesh default]
## version = 1
#
# points =
## -0.235000, -0.242500, -0.200000, -0.037500, 0.005000, -0.080000, 0.000000, 0.080000, 0.210000, 0.280000, 0.175000, 0.172500, 0.172500, 0.332500, 0.327500
#
# -0.232500, -0.227500, -0.190000, -0.067500, 0.087500, -0.330000, 0.027500, 0.085000, 0.235000, 0.357500, 0.245000, 0.225000, 0.260000, 0.330000, 0.122500
## -0.145000, -0.275000, -0.185000, -0.037500, -0.125000, 0.032500, -0.052500, 0.005000, 0.240000, 0.340000, 0.327500, 0.255000, 0.242500, 0.362500, 0.370000
#
# -0.155000, -0.247500, -0.200000, -0.015000, 0.122500, 0.090000, 0.005000, 0.077500, 0.215000, 0.147500, 0.287500, 0.197500, 0.240000, 0.295000, 0.327500
## -0.202500, -0.275000, -0.147500, -0.035000, 0.045000, 0.045000, -0.047500, 0.042500, 0.267500, 0.367500, 0.222500, 0.022500, 0.275000, 0.260000, 0.322500
#
# -0.065000, -0.352500, -0.230000, -0.077500, 0.005000, 0.090000, 0.037500, 0.047500, 0.160000, 0.370000, 0.325000, 0.200000, 0.297500, 0.370000, 0.370000
## -0.240000, -0.220000, -0.160000, -0.025000, 0.122500, 0.045000, 0.082500, -0.090000, 0.250000, 0.322500, 0.317500, 0.240000, 0.280000, 0.340000, 0.402500
#
# -0.052500, -0.200000, -0.130000, 0.005000, 0.005000, -0.485000, -0.040000, -0.050000, 0.247500, 0.362500, 0.182500, 0.242500, 0.297500, 0.400000, 0.432500
## -0.035000, -0.325000, -0.152500, -0.037500, 0.120000, -0.015000, 0.032500, 0.087500, 0.125000, 0.210000, 0.280000, 0.120000, 0.082500, 0.330000, 0.295000
#
# -0.065000, -0.315000, -0.155000, -0.055000, -0.202500, -0.035000, 0.090000, 0.125000, 0.260000, 0.245000, 0.160000, 0.167500, 0.240000, 0.012500, 0.327500
## -0.112500, -0.122500, -0.120000, 0.012500, 0.120000, 0.172500, 0.137500, 0.135000, 0.282500, 0.287500, 0.242500, 0.247500, 0.295000, 0.405000, 0.345000
#
# -0.112500, -0.307500, -0.127500, -0.035000, 0.127500, 0.187500, 0.115000, 0.080000, 0.160000, 0.407500, 0.342500, 0.250000, 0.317500, 0.120000, 0.395000
## -0.147500, -0.152500, -0.107500, -0.037500, 0.120000, 0.052500, 0.125000, 0.207500, 0.335000, 0.325000, 0.372500, 0.112500, 0.295000, 0.365000, 0.357500
#
# -0.112500, -0.357500, -0.077500, 0.005000, -0.045000, 0.147500, 0.127500, 0.037500, 0.330000, 0.450000, 0.267500, 0.227500, 0.302500, 0.365000, 0.407500
## -0.142500, -0.150000, -0.147500, 0.005000, 0.165000, 0.167500, 0.160000, 0.195000, 0.367500, -0.245000, 0.140000, 0.330000, 0.182500, 0.355000, 0.407500
#
# x_count = 15
## y_count = 15
#
# mesh_x_pps = 2
## mesh_y_pps = 2
#
# algo = bicubic
## tension = 0.2
#
# min_x = 15.0
## max_x = 229.9
#
# min_y = 15.0
## max_y = 229.9
#
#
## [probe]
#
# z_offset = -0.170
##
#
# [stepper_z]
## position_endstop = 2.760
#
#
## [extruder]
#
# control = pid
## pid_kp = 32.303
#
# pid_ki = 1.976
## pid_kd = 132.037
#
#
## [heater_bed]
#
# control = pid
## pid_kp = 68.901
#
# pid_ki = 1.215
## pid_kd = 976.672
#
#
## [bed_mesh 15x15]
#
# version = 1
## points =
#
# -0.777500, -0.850000, -0.895000, -0.792500, -0.632500, -0.932500, -0.637500, -0.665000, -0.592500, -0.460000, -0.537500, -0.682500, -0.715000, -0.640000, -1.017500
## -1.085000, -1.102500, -0.887500, -0.755000, -0.582500, -0.615000, -0.662500, -0.777500, -0.562500, -0.485000, -0.512500, -0.717500, -0.755000, -0.647500, -0.665000
#
# -0.795000, -0.805000, -0.827500, -0.730000, -0.632500, -0.565000, -0.645000, -0.687500, -0.650000, -0.477500, -0.517500, -0.632500, -0.672500, -0.572500, -0.982500
## -0.890000, -0.807500, -0.935000, -0.687500, -0.677500, -0.522500, -0.762500, -0.677500, -0.677500, -0.422500, -0.487500, -0.682500, -0.715000, -0.627500, -0.902500
#
# -0.802500, -0.722500, -0.825000, -0.735000, -0.555000, -0.545000, -1.007500, -0.645000, -0.557500, -0.430000, -0.485000, -0.625000, -0.650000, -0.542500, -0.950000
## -0.647500, -0.647500, -0.732500, -0.665000, -0.490000, -0.467500, -0.542500, -0.605000, -0.545000, -0.392500, -0.602500, -0.652500, -0.710000, -0.632500, -0.905000
#
# -0.685000, -0.835000, -0.747500, -0.750000, -0.547500, -0.472500, -0.592500, -0.617500, -0.437500, -0.352500, -0.427500, -0.595000, -0.662500, -0.515000, -0.867500
## -0.642500, -0.655000, -0.765000, -0.655000, -0.447500, -0.520000, -0.547500, -0.637500, -0.480000, -0.362500, -0.422500, -0.625000, -0.642500, -0.550000, -0.725000
#
# -0.565000, -0.680000, -0.912500, -0.667500, -0.472500, -0.477500, -0.552500, -0.552500, -0.440000, -0.287500, -0.362500, -0.500000, -0.550000, -0.437500, -0.850000
## -0.487500, -0.625000, -0.680000, -0.575000, -0.417500, -0.390000, -0.690000, -0.527500, -0.392500, -0.285000, -0.382500, -0.510000, -0.580000, -0.475000, -0.505000
#
# -0.512500, -0.595000, -0.642500, -0.565000, -0.400000, -0.357500, -0.435000, -0.490000, -0.340000, -0.250000, -0.360000, -0.635000, -0.540000, -0.550000, -0.782500
## -0.477500, -0.517500, -0.777500, -0.542500, -0.330000, -0.295000, -0.410000, -0.432500, -0.320000, -0.265000, -0.320000, -0.490000, -0.630000, -0.420000, -0.757500
#
# -0.762500, -0.962500, -0.797500, -0.680000, -0.377500, -0.305000, -0.595000, -0.470000, -0.280000, -0.192500, -0.197500, -0.545000, -0.517500, -0.517500, -0.675000
## -1.185000, -0.660000, -0.600000, -0.435000, -0.280000, -0.320000, -0.345000, -0.525000, -0.227500, -0.157500, -0.227500, -0.435000, -0.562500, -0.667500, -0.805000
#
# -0.605000, -0.525000, -0.607500, -0.475000, -0.320000, -0.252500, -0.357500, -0.427500, -0.230000, -0.112500, -0.215000, -0.440000, -0.600000, -0.405000, -0.510000
## x_count = 15
#
# y_count = 15
## mesh_x_pps = 2
#
# mesh_y_pps = 2
## algo = bicubic
#
# tension = 0.2
## min_x = 15.0
#
# max_x = 229.9
## min_y = 15.0
#
# max_y = 229.9
##
#
# [bed_mesh 15 hot]
## version = 1
#
# points =
## -0.452500, -0.550000, -0.380000, -0.170000, -0.135000, -0.372500, -0.127500, 0.037500, 0.150000, 0.125000, 0.015000, 0.030000, 0.225000, 0.160000, 0.012500
#
# -0.487500, -0.505000, -0.300000, -0.127500, -0.142500, -0.160000, -0.170000, 0.102500, 0.172500, 0.110000, 0.020000, 0.130000, 0.157500, 0.095000, 0.012500
## -0.460000, -0.525000, -0.297500, -0.082500, -0.092500, -0.125000, -0.065000, 0.012500, 0.222500, 0.177500, 0.055000, 0.147500, 0.265000, 0.212500, 0.012500
#
# -0.502500, -0.537500, -0.292500, -0.090000, -0.070000, -0.120000, -0.292500, 0.137500, 0.230000, 0.140000, 0.137500, 0.195000, 0.312500, 0.260000, 0.092500
## -0.497500, -0.540000, -0.547500, -0.100000, -0.055000, -0.117500, -0.047500, 0.195000, 0.250000, 0.262500, 0.115000, 0.227500, 0.330000, 0.310000, 0.105000
#
# -0.452500, -0.412500, -0.225000, -0.067500, -0.032500, -0.077500, 0.002500, 0.202500, 0.262500, 0.255000, 0.055000, 0.245000, 0.337500, 0.310000, 0.105000
## -0.417500, -0.562500, -0.365000, -0.047500, 0.000000, -0.062500, -0.025000, 0.192500, 0.317500, 0.270000, 0.172500, 0.237500, 0.355000, 0.327500, 0.167500
#
# -0.400000, -0.420000, -0.227500, -0.010000, 0.020000, -0.037500, 0.022500, 0.260000, 0.337500, 0.295000, 0.227500, 0.295000, 0.380000, 0.257500, 0.217500
## -0.412500, -0.415000, -0.227500, -0.012500, 0.015000, -0.040000, 0.037500, 0.260000, 0.375000, 0.322500, 0.275000, 0.332500, 0.442500, 0.200000, 0.222500
#
# -0.380000, -0.382500, -0.180000, 0.017500, 0.050000, -0.017500, 0.090000, 0.287500, 0.415000, 0.360000, 0.257500, 0.360000, 0.460000, 0.385000, 0.257500
## -0.377500, -0.367500, -0.137500, 0.040000, 0.092500, 0.030000, 0.117500, 0.300000, 0.425000, 0.375000, 0.285000, 0.332500, 0.455000, 0.327500, 0.252500
#
# -0.397500, -0.390000, -0.145000, 0.057500, 0.105000, -0.117500, 0.157500, 0.377500, 0.432500, 0.417500, 0.337500, 0.410000, 0.500000, 0.467500, 0.292500
## -0.462500, -0.362500, -0.177500, 0.032500, -0.067500, 0.065000, 0.150000, 0.375000, 0.502500, 0.420000, 0.357500, 0.177500, 0.550000, 0.475000, 0.307500
#
# -0.417500, -0.377500, -0.147500, 0.062500, 0.105000, 0.097500, 0.175000, 0.377500, 0.507500, 0.460000, 0.385000, 0.257500, 0.557500, 0.537500, 0.385000
## -0.425000, -0.375000, -0.217500, 0.085000, 0.152500, 0.105000, 0.220000, 0.295000, 0.502500, 0.435000, 0.365000, 0.425000, 0.540000, 0.462500, 0.312500
#
# x_count = 15
## y_count = 15
#
# mesh_x_pps = 2
## mesh_y_pps = 2
#
# algo = bicubic
## tension = 0.2
#
# min_x = 15.0
## max_x = 229.9
#
# min_y = 15.0
## max_y = 229.9
#
#
## [bed_mesh 25 hot]
#
# version = 1
## points =
#
# -0.722500, -0.252500, -0.117500, -0.047500, -0.055000, 0.010000, 0.020000, 0.050000, 0.177500, 0.360000, 0.435000, 0.490000, 0.492500, 0.495000, 0.445000, 0.560000, 0.607500, 0.732500, 0.732500, 0.762500, 0.737500, 0.602500, 0.587500, 0.592500, 0.582500
## -0.325000, -0.200000, -0.070000, 0.017500, 0.030000, 0.030000, 0.052500, 0.100000, 0.200000, 0.242500, 0.432500, 0.487500, 0.497500, 0.470000, 0.455000, 0.490000, 0.637500, 0.720000, 0.765000, 0.725000, 0.750000, 0.645000, 0.582500, 0.607500, 0.680000
#
# -0.365000, -0.150000, -0.005000, 0.010000, 0.050000, 0.052500, -0.017500, 0.115000, 0.225000, 0.352500, 0.425000, 0.315000, 0.525000, 0.507500, 0.480000, 0.517500, 0.527500, 0.750000, 0.755000, 0.770000, 0.442500, 0.622500, 0.600000, 0.650000, 0.585000
## -0.385000, -0.282500, -0.022500, 0.017500, 0.075000, -0.155000, 0.112500, 0.125000, 0.240000, 0.355000, 0.480000, 0.550000, 0.507500, 0.482500, 0.515000, 0.505000, 0.647500, 0.620000, 0.792500, 0.707500, 0.742500, 0.657500, 0.600000, 0.255000, 0.642500
#
# -0.362500, -0.190000, -0.097500, 0.025000, 0.060000, -0.190000, 0.082500, 0.110000, 0.270000, 0.397500, 0.477500, 0.505000, 0.552500, 0.520000, 0.507500, 0.587500, 0.682500, 0.617500, 0.820000, 0.822500, 0.802500, 0.712500, 0.395000, 0.497500, 0.692500
## -0.510000, -0.402500, -0.095000, -0.047500, -0.132500, -0.092500, 0.097500, 0.142500, 0.255000, 0.405000, 0.437500, 0.512500, 0.522500, 0.542500, 0.550000, 0.577500, 0.682500, 0.785000, 0.745000, 0.790000, 0.765000, 0.710000, 0.657500, 0.662500, 0.722500
#
# -0.495000, -0.167500, -0.142500, 0.002500, -0.040000, 0.007500, 0.082500, 0.105000, 0.212500, 0.395000, 0.472500, 0.567500, 0.530000, 0.472500, 0.562500, 0.627500, 0.727500, 0.830000, 0.725000, 0.875000, 0.785000, 0.750000, 0.757500, 0.755000, 0.802500
## -0.287500, -0.142500, -0.002500, 0.072500, 0.080000, 0.085000, 0.107500, 0.102500, 0.257500, 0.390000, 0.520000, 0.592500, 0.610000, 0.560000, 0.580000, 0.620000, 0.750000, 0.852500, 0.885000, 0.812500, 0.837500, 0.762500, 0.747500, 0.755000, 0.805000
#
# -0.485000, -0.155000, -0.005000, 0.050000, 0.087500, 0.087500, 0.080000, -0.027500, 0.277500, 0.157500, 0.520000, 0.560000, 0.595000, 0.540000, 0.555000, 0.735000, 0.757500, 0.842500, 0.872500, 0.547500, 0.820000, 0.777500, 0.700000, 0.457500, 0.817500
## -0.232500, -0.070000, -0.107500, 0.080000, 0.115000, 0.080000, 0.120000, 0.000000, 0.287500, 0.427500, 0.555000, 0.612500, 0.615000, 0.565000, 0.605000, 0.630000, 0.727500, 0.820000, 0.910000, 0.877500, 0.852500, 0.647500, 0.677500, 0.767500, 0.817500
#
# -0.397500, -0.167500, -0.237500, 0.092500, 0.092500, 0.107500, 0.110000, 0.182500, 0.315000, 0.457500, 0.600000, 0.577500, 0.600000, 0.587500, 0.610000, 0.657500, 0.755000, 0.867500, 0.900000, 0.872500, 0.867500, 0.795000, 0.470000, 0.755000, 0.802500
## -0.235000, -0.080000, 0.012500, 0.112500, 0.125000, 0.122500, -0.345000, 0.235000, 0.335000, 0.482500, 0.562500, 0.625000, 0.615000, 0.572500, 0.612500, 0.400000, 0.602500, 0.877500, 0.905000, 0.915000, 0.842500, 0.455000, 0.780000, 0.787500, 0.825000
#
# -0.245000, -0.085000, -0.177500, 0.027500, 0.097500, -0.010000, 0.170000, 0.230000, 0.265000, 0.472500, 0.530000, 0.610000, 0.620000, 0.580000, 0.470000, 0.697500, 0.787500, 0.900000, 0.907500, 0.932500, 0.890000, 0.822500, 0.802500, 0.855000, 0.885000
## -0.212500, -0.117500, 0.042500, 0.135000, 0.170000, 0.127500, 0.162500, 0.237500, 0.362500, 0.485000, 0.597500, 0.610000, 0.665000, 0.617500, 0.642500, 0.707500, 0.837500, 0.912500, 0.957500, 0.910000, 0.910000, 0.867500, 0.830000, 0.840000, 0.877500
#
# -0.215000, -0.075000, 0.045000, 0.115000, 0.157500, 0.145000, 0.105000, 0.197500, 0.242500, 0.507500, 0.607500, 0.585000, 0.672500, 0.640000, 0.640000, 0.705000, 0.697500, 0.920000, 0.965000, 0.975000, 0.897500, 0.885000, 0.810000, 0.865000, 0.947500
## -0.160000, -0.165000, -0.272500, 0.100000, 0.132500, 0.172500, 0.192500, 0.255000, 0.395000, 0.545000, 0.627500, 0.667500, 0.685000, 0.667500, 0.682500, 0.750000, 0.567500, 0.957500, 0.995000, 1.000000, 0.937500, 0.842500, 0.837500, 0.655000, 0.920000
#
# -0.187500, -0.055000, 0.087500, 0.162500, 0.145000, -0.072500, 0.202500, 0.277500, 0.402500, 0.557500, 0.647500, 0.717500, 0.652500, 0.647500, 0.652500, 0.735000, 0.837500, 0.965000, 0.962500, 0.995000, 0.920000, 0.885000, 0.865000, 0.875000, 0.762500
## -0.130000, -0.032500, 0.080000, 0.037500, 0.207500, 0.210000, 0.187500, 0.292500, 0.407500, 0.515000, 0.670000, 0.717500, 0.722500, 0.667500, 0.677500, 0.740000, 0.637500, 0.925000, 1.007500, 1.007500, 0.952500, 0.872500, 0.865000, 0.910000, 0.952500
#
# -0.285000, -0.412500, 0.030000, 0.067500, 0.232500, 0.192500, 0.162500, 0.192500, 0.430000, 0.592500, 0.667500, 0.725000, 0.732500, 0.515000, 0.722500, 0.797500, 0.910000, 0.792500, 1.007500, 1.027500, 0.947500, 0.907500, 0.880000, 0.885000, 0.955000
## -0.207500, -0.035000, 0.020000, 0.165000, 0.040000, 0.227500, 0.227500, 0.317500, 0.482500, 0.567500, 0.710000, 0.727500, 0.630000, 0.735000, 0.740000, 0.760000, 0.902500, 0.830000, 1.017500, 1.037500, 0.985000, 0.920000, 0.907500, 0.897500, 0.970000
#
# -0.227500, -0.077500, 0.075000, 0.197500, 0.170000, 0.197500, 0.245000, 0.325000, 0.445000, 0.610000, 0.482500, 0.760000, 0.752500, 0.745000, 0.732500, 0.822500, 0.895000, 1.030000, 1.065000, 1.082500, 1.000000, 0.957500, 0.940000, 0.595000, 0.930000
## -0.210000, -0.032500, 0.045000, 0.120000, 0.110000, 0.202500, 0.255000, 0.330000, 0.435000, 0.600000, 0.702500, 0.770000, 0.750000, 0.732500, 0.747500, 0.832500, 0.930000, 0.905000, 1.040000, 1.057500, 1.015000, 0.870000, 0.915000, 0.957500, 1.007500
#
# -0.242500, -0.032500, -0.377500, -0.077500, 0.000000, 0.200000, 0.265000, 0.350000, 0.482500, 0.605000, 0.725000, 0.777500, 0.767500, 0.722500, 0.760000, 0.735000, 0.960000, 0.875000, 1.075000, 1.072500, 1.002500, 0.952500, 0.790000, 0.950000, 1.022500
## -0.200000, -0.042500, 0.082500, 0.027500, 0.235000, 0.227500, 0.272500, 0.352500, 0.485000, 0.640000, 0.715000, 0.757500, 0.777500, 0.750000, 0.740000, 0.465000, 0.962500, 1.050000, 1.047500, 0.787500, 0.997500, 0.535000, 0.945000, 0.945000, 1.032500
#
# -0.240000, -0.050000, 0.055000, 0.100000, 0.272500, 0.200000, 0.082500, 0.362500, 0.502500, 0.637500, 0.715000, 0.795000, 0.787500, 0.762500, 0.787500, 0.870000, 0.542500, 1.137500, 1.067500, 1.065000, 1.000000, 0.945000, 0.527500, 0.625000, 0.960000
## x_count = 25
#
# y_count = 25
## mesh_x_pps = 2
#
# mesh_y_pps = 2
## algo = bicubic
#
# tension = 0.2
## min_x = 15.0
#
# max_x = 229.8
## min_y = 15.0
#
# max_y = 229.8
##
#
# [bed_mesh new]
## version = 1
#
# points =
## -0.342500, -0.135000, -0.162500, -0.137500, -0.345000, 0.042500, 0.235000, 0.050000, 0.130000, 0.280000, 0.192500, 0.317500, 0.395000, 0.400000, 0.560000, 0.530000, 0.565000, 0.585000, 0.512500, 0.467500, 0.477500, -0.377500, 0.475000, 0.617500, 0.572500
#
# -0.132500, -0.042500, -0.167500, -0.175000, -0.067500, 0.072500, 0.200000, 0.290000, 0.155000, 0.275000, 0.240000, 0.242500, 0.262500, 0.397500, 0.422500, 0.552500, 0.582500, 0.520000, 0.372500, 0.427500, 0.390000, -0.302500, 0.587500, 0.565000, 0.592500
## -0.090000, -0.090000, -0.037500, -0.255000, -0.002500, 0.072500, 0.205000, 0.270000, 0.287500, 0.322500, 0.257500, 0.242500, 0.277500, 0.400000, 0.480000, 0.552500, 0.550000, 0.562500, 0.397500, 0.425000, 0.437500, 0.485000, 0.572500, 0.547500, 0.572500
#
# -0.127500, -0.085000, -0.122500, -0.145000, -0.020000, 0.000000, 0.157500, 0.292500, 0.310000, 0.310000, 0.192500, 0.245000, 0.312500, 0.360000, 0.482500, 0.567500, 0.590000, 0.527500, 0.527500, 0.460000, 0.437500, 0.490000, 0.582500, 0.490000, 0.442500
## -0.040000, -0.085000, -0.165000, -0.040000, -0.035000, 0.082500, 0.230000, 0.305000, 0.287500, 0.270000, 0.207500, 0.240000, 0.280000, 0.362500, 0.485000, 0.192500, 0.592500, 0.442500, 0.442500, 0.480000, 0.395000, 0.452500, 0.562500, 0.602500, 0.532500
#
# -0.077500, -0.100000, -0.137500, -0.205000, 0.000000, 0.060000, 0.167500, 0.215000, 0.315000, 0.310000, 0.192500, 0.280000, 0.277500, 0.415000, 0.480000, 0.542500, 0.602500, 0.545000, 0.432500, 0.447500, 0.495000, 0.550000, 0.515000, 0.550000, 0.562500
## -0.110000, -0.167500, -0.092500, -0.037500, -0.047500, 0.037500, 0.195000, 0.200000, 0.265000, 0.277500, 0.272500, 0.277500, 0.282500, 0.375000, 0.475000, 0.600000, 0.555000, 0.555000, 0.500000, 0.457500, 0.475000, 0.547500, 0.530000, 0.455000, 0.622500
#
# -0.075000, -0.130000, -0.070000, -0.090000, -0.087500, 0.112500, 0.115000, 0.267500, 0.347500, 0.325000, 0.285000, 0.277500, 0.067500, 0.440000, 0.520000, 0.537500, 0.557500, 0.552500, 0.472500, 0.480000, 0.442500, 0.527500, 0.615000, 0.632500, 0.620000
## -0.030000, -0.040000, -0.160000, -0.075000, -0.045000, -0.040000, 0.202500, 0.247500, 0.300000, 0.282500, 0.245000, 0.232500, 0.282500, 0.430000, 0.450000, 0.600000, 0.497500, 0.582500, 0.460000, 0.495000, 0.475000, 0.522500, 0.562500, 0.550000, 0.562500
#
# -0.070000, -0.077500, -0.147500, -0.082500, -0.085000, 0.082500, 0.225000, 0.307500, 0.327500, 0.250000, 0.260000, 0.275000, 0.310000, 0.455000, 0.497500, 0.550000, 0.577500, 0.555000, 0.437500, 0.482500, 0.440000, 0.527500, 0.555000, 0.635000, 0.557500
## -0.080000, -0.075000, -0.130000, -0.127500, -0.032500, -0.142500, 0.200000, 0.312500, 0.325000, 0.315000, 0.285000, 0.232500, 0.310000, 0.405000, 0.537500, 0.522500, 0.610000, 0.557500, 0.472500, 0.445000, 0.472500, 0.555000, 0.607500, 0.622500, 0.550000
#
# -0.032500, -0.040000, -0.122500, -0.082500, 0.000000, 0.122500, 0.237500, 0.312500, 0.112500, 0.285000, 0.230000, 0.247500, 0.290000, 0.425000, 0.547500, 0.607500, 0.582500, 0.577500, 0.517500, 0.497500, 0.487500, 0.545000, 0.617500, 0.430000, 0.605000
## -0.095000, -0.012500, -0.022500, -0.005000, -0.012500, 0.122500, 0.205000, 0.320000, 0.350000, 0.305000, 0.200000, 0.295000, 0.280000, 0.315000, 0.557500, 0.595000, 0.562500, 0.547500, 0.462500, 0.422500, 0.467500, 0.442500, 0.620000, 0.547500, 0.630000
#
# -0.042500, -0.087500, -0.210000, -0.067500, 0.032500, 0.130000, 0.242500, 0.315000, 0.320000, 0.310000, 0.312500, 0.160000, 0.320000, 0.422500, 0.515000, 0.600000, 0.632500, 0.477500, 0.555000, 0.430000, 0.480000, 0.537500, 0.617500, 0.645000, 0.530000
## -0.010000, -0.037500, -0.065000, -0.127500, 0.000000, 0.120000, 0.245000, 0.315000, 0.360000, 0.332500, 0.322500, 0.252500, 0.325000, 0.445000, 0.560000, 0.275000, 0.637500, 0.570000, 0.517500, 0.427500, 0.522500, 0.627500, 0.685000, 0.642500, 0.545000
#
# 0.005000, -0.082500, -0.040000, -0.370000, 0.035000, 0.167500, 0.227500, 0.275000, 0.232500, 0.355000, 0.315000, 0.265000, 0.385000, 0.480000, -0.070000, 0.590000, 0.655000, 0.610000, 0.470000, 0.470000, 0.552500, 0.597500, 0.670000, 0.660000, 0.667500
## -0.077500, -0.140000, -0.077500, -0.077500, -0.042500, 0.157500, 0.282500, 0.267500, 0.385000, 0.377500, 0.237500, 0.355000, 0.385000, 0.487500, 0.592500, 0.672500, 0.550000, 0.535000, 0.520000, 0.485000, 0.517500, 0.552500, 0.582500, 0.565000, 0.625000
#
# -0.085000, -0.182500, -0.122500, -0.085000, 0.075000, 0.190000, 0.272500, 0.375000, 0.307500, 0.400000, 0.225000, 0.262500, 0.407500, 0.517500, 0.472500, 0.677500, 0.647500, 0.557500, 0.560000, 0.497500, 0.550000, 0.595000, 0.632500, 0.707500, 0.680000
## -0.085000, -0.172500, -0.072500, -0.087500, 0.082500, 0.167500, 0.330000, 0.355000, 0.437500, 0.390000, 0.392500, 0.325000, 0.437500, 0.530000, 0.517500, 0.722500, 0.692500, 0.500000, 0.565000, 0.550000, 0.562500, 0.590000, 0.685000, 0.722500, 0.532500
#
# -0.005000, -0.402500, -0.020000, 0.030000, 0.042500, 0.195000, 0.285000, 0.387500, 0.432500, 0.417500, 0.407500, 0.397500, 0.392500, 0.272500, 0.567500, 0.685000, 0.725000, 0.622500, 0.562500, 0.572500, 0.605000, 0.705000, 0.682500, 0.585000, 0.640000
## 0.035000, 0.002500, -0.002500, -0.047500, 0.080000, 0.127500, 0.325000, 0.440000, 0.470000, 0.407500, 0.392500, 0.432500, 0.472500, 0.555000, 0.680000, 0.720000, 0.717500, 0.670000, 0.650000, 0.590000, 0.607500, 0.670000, 0.715000, 0.757500, 0.687500
#
# -0.005000, -0.035000, 0.002500, -0.002500, -0.005000, 0.220000, 0.325000, 0.432500, 0.480000, 0.440000, 0.440000, 0.380000, 0.480000, 0.582500, 0.567500, 0.727500, 0.755000, 0.695000, 0.675000, 0.547500, 0.582500, 0.627500, 0.727500, 0.775000, 0.765000
## -0.047500, -0.042500, -0.040000, 0.035000, 0.037500, 0.215000, 0.292500, 0.435000, 0.477500, 0.455000, 0.380000, 0.357500, 0.440000, 0.562500, 0.700000, 0.712500, 0.727500, 0.637500, 0.602500, 0.550000, 0.602500, 0.672500, 0.597500, 0.757500, 0.710000
#
# -0.005000, 0.007500, -0.080000, -0.165000, 0.120000, 0.245000, 0.342500, 0.432500, 0.485000, 0.475000, 0.397500, 0.400000, 0.477500, 0.605000, 0.687500, 0.705000, 0.705000, 0.557500, 0.667500, 0.637500, 0.627500, 0.637500, 0.722500, 0.755000, 0.722500
## -1.887500, 0.032500, -0.027500, 0.002500, 0.037500, 0.157500, 0.290000, 0.395000, 0.397500, 0.400000, 0.440000, 0.475000, 0.440000, 0.597500, 0.672500, 0.702500, 0.715000, 0.717500, 0.625000, 0.637500, 0.590000, 0.710000, 0.630000, 0.755000, 0.795000
#
# x_count = 25
## y_count = 25
#
# mesh_x_pps = 2
## mesh_y_pps = 2
#
# algo = bicubic
## tension = 0.2
#
# min_x = 15.0
## max_x = 229.8
#
# min_y = 15.0
#*# max_y = 229.8

@ChipCE
Copy link
Author

ChipCE commented Oct 21, 2023

@Shaneweston seem like you use the wrong version of the post processcing script.

use this https://raw.githubusercontent.com/ChipCE/Slicer-profile/master/cura-slicer/scripts/KlipperPrintArea.py

@tc60045
Copy link

tc60045 commented Oct 30, 2023

I am with @Shaneweston -- some probs with Cura (v5.5 in my case). Fix below

Error shows up in cura log:
2023-10-30 14:00:06,919 - ERROR - [MainThread] PostProcessingPlugin.PostProcessingPlugin.loadScripts [227]: Exception: Exception occurred while loading post processing plugin: module 'PostProcessingPlugin.PostProcessingPlugin.MeshPrintSize' has no attribute 'MeshPrintSize'

Note that this is when copying in the "frankbags" python script referenced.

The trick is to (a) clean up unnecceary line breaks that demonstrate Frank Bags needs to read PEP8, as who puts a double line break under a def?! (Guido and I curse your name from our high horses), then (b) name the file KlipperPrintArea.py.

Cura will then load the KlipperPrintArea.py script when it restarts, and you can add the script to post processing in the menu.

@frankbags
Copy link

@tc60045

First, this isn't my version of the script. My version ( https://gist.github.com/frankbags/c85d37d9faff7bce67b6d18ec4e716ff ) , while not optimal doesn't have a double line break after the def. Only the version @ChipCE has modified and linked to.

Second, screw Python and the horse it rode in on.

@tc60045
Copy link

tc60045 commented Oct 30, 2023

Ha! @frankbags -- touche!

@ChipCE
Copy link
Author

ChipCE commented Oct 30, 2023

@tc60045 It's my fault, not frankbags's. Thanks for point out the problem!

@frankbags Thanks for the script. It works wonderfully. I don't remember and understand why I have to make my copy of it in the first place.

@gitvisual
Copy link

gitvisual commented Jan 1, 2024

Hi!

Im having some weird issue. I know the bed is perfectly leveled from the printheads POV since i used one of those micrometer gauge attached on printhead.
When i print a first-layer-level-test without bed mesh enabled it gets really good. But when i enable it it drags the nozzle on the bed on some areas
image

It's almost as it's misreading the probes and tries to compensate down when it's not needed.

What am i doing wrong?
Can i add something to make it run better?

(I'm running Klipper on a Creality Sonic Pad, printing on a Ender 3 S1 Pro)

Below are my printer.cfg and macro.cfg (or rather the parts from those files with relevant information)

Printer.cfg:

[bltouch]
sensor_pin: ^PC14       #signal check port ^stand for pull up
control_pin: PC13       #singal control prot
x_offset: -30.0
y_offset: -40.0
#z_offset: 0          #z off_set configuration
speed: 20
stow_on_each_sample = false #high speed for bltoch,
samples: 1
samples_result: median
#probe_with_touch_mode = true

[bed_mesh]
probe_count = 6,6
algorithm = lagrange
# probe_count = 6,6
# algorithm = lagrange
# # probe_count = 20,20
# # algorithm = bicubic
# # # probe_count = 20,20
# # # algorithm = bicubic
speed: 150
mesh_min: 15,30         #need to handle head distance with bl_touch
mesh_max: 210,190       #max probe range
# # # # probe_count: 5,5
fade_start: 1
fade_end: 10
fade_target: 0
# # # # algorithm: bicubic

[bed_screws]
screw1: 25, 33
screw2: 202, 33
screw3: 202, 202
screw4: 25, 202

[gcode_macro G29]				#界面中增加G29指令
gcode:
  G28
  bed_mesh_calibrate
  G1 X0 Y0 Z10 F4200
  # save_config

[gcode_arcs]
#resolution: 1.0

#*# <---------------------- SAVE_CONFIG ---------------------->
#*# DO NOT EDIT THIS BLOCK OR BELOW. The contents are auto-generated.
#*#
#*# [bltouch]
#*# z_offset = 2.325
#*#
#*# [input_shaper]
#*# shaper_type_x = mzv
#*# shaper_freq_x = 53.4
#*# shaper_type_y = mzv
#*# shaper_freq_y = 40.8
#*#
#*# [bed_mesh default]
#*# version = 1
#*# points =
#*# 	  -0.170000, -0.157500, -0.107500, -0.121250
#*# 	  -0.097500, -0.120000, -0.092500, -0.063750
#*# 	  -0.086250, -0.061250, -0.022500, -0.055000
#*# 	  -0.036250, -0.072500, -0.056250, -0.042500
#*# x_count = 4
#*# y_count = 4
#*# mesh_x_pps = 2
#*# mesh_y_pps = 2
#*# algo = lagrange
#*# tension = 0.2
#*# min_x = 68.6
#*# max_x = 181.4
#*# min_y = 48.599999999999994
#*# max_y = 161.4

Macro.cfg:

# Cura start G-Code:
# START_PRINT EXTRUDER_TEMP={material_print_temperature_layer_0} BED_TEMP={material_bed_temperature_layer_0} AREA_START=%MINX%,%MINY% AREA_END=%MAXX%,%MAXY%
[gcode_macro START_PRINT]
variable_parameter_EXTRUDER_TEMP: 200
variable_parameter_BED_TEMP: 60
; gcode parameters for area bed mesh
variable_parameter_AREA_START : 0,0
variable_parameter_AREA_END : 0,0
gcode:
  G92 E0 ; Reset Extruder
  {% set BED_TEMP = params.BED_TEMP|default(60)|float %}
  {% set EXTRUDER_TEMP = params.EXTRUDER_TEMP|default(190)|float %}

  
  M104 S{EXTRUDER_TEMP} ; Start heating extruder
  M140 S{BED_TEMP} ; Start heating bed
  G28 ; Home all axes
  M190 S{BED_TEMP} ; Wait for bed to reach temp before proceeding
  
  
  BED_MESH_CALIBRATE AREA_START={params.AREA_START|default("0,0")} AREA_END={params.AREA_END|default("0,0")} ; Auto bed leveling
  G1 Z2.0 F3000 ; Move Z Axis up little to prevent scratching of Heat Bed
  G1 X0.1 Y20 Z0.3 F5000.0 ; Move to start position
  M109 S{EXTRUDER_TEMP} ; Wait for extruder to reach temp before proceeding
  G1 X0.1 Y200.0 Z0.3 F1500.0 E15 ; Draw the first line
  G1 X0.4 Y200.0 Z0.3 F5000.0 ; Move to side a little
  G1 X0.4 Y20 Z0.3 F1500.0 E30 ; Draw the second line
  G92 E0 ; Reset Extruder
  G1 Z2.0 F3000 ; Move Z Axis up little to prevent scratching of Heat Bed
  G1 X5 Y20 Z0.3 F5000.0 ; Move over to prevent blob squish

[gcode_macro BED_MESH_CALIBRATE]
rename_existing: BED_MESH_CALIBRATE_BASE
; gcode parameters
variable_parameter_AREA_START : 0,0
variable_parameter_AREA_END : 0,0
; the clearance between print area and probe area 
variable_mesh_area_offset : 5.0
; number of sample per probe point
variable_probe_samples : 3
; minimum probe count
variable_min_probe_count : 4
; scale up the probe count, should be 1.0 ~ < variable_max_probe_count/variable_min_probe_count
variable_probe_count_scale_factor : 1.0
; enable preference index
variable_enable_reference_index : False
gcode:
    {% if params.AREA_START and params.AREA_END %}
        {% set bedMeshConfig = printer["configfile"].config["bed_mesh"] %}
        {% set safe_min_x = bedMeshConfig.mesh_min.split(",")[0]|float %}
        {% set safe_min_y = bedMeshConfig.mesh_min.split(",")[1]|float %}
        {% set safe_max_x = bedMeshConfig.mesh_max.split(",")[0]|float %}
        {% set safe_max_y = bedMeshConfig.mesh_max.split(",")[1]|float %}

        {% set area_min_x = params.AREA_START.split(",")[0]|float %}
	{% set area_min_y = params.AREA_START.split(",")[1]|float %}
	{% set area_max_x = params.AREA_END.split(",")[0]|float %}
	{% set area_max_y = params.AREA_END.split(",")[1]|float %}

	{% if bedMeshConfig.probe_count.split(",")|length == 2 %}
            {% set meshPointX = bedMeshConfig.probe_count.split(",")[0]|int %}
            {% set meshPointY = bedMeshConfig.probe_count.split(",")[1]|int %}
        {% else %}
            {% set meshPointX = bedMeshConfig.probe_count.split(",")[0]|int %}
            {% set meshPointY = bedMeshConfig.probe_count.split(",")[0]|int %}
        {% endif %}

	{% set meshMaxPointX = meshPointX %}
	{% set meshMaxPointY = meshPointY %}


        {% if (area_min_x < area_max_x) and (area_min_y < area_max_y) %}
            {% if area_min_x - mesh_area_offset >=  safe_min_x %}
                {% set area_min_x = area_min_x - mesh_area_offset %}
            {% else %}
                {% set area_min_x = safe_min_x %}
            {% endif %}

            {% if area_min_y - mesh_area_offset >=  safe_min_y %}
                {% set area_min_y = area_min_y - mesh_area_offset %}
            {% else %}
                {% set area_min_y = safe_min_y %}
            {% endif %}

            {% if area_max_x + mesh_area_offset <=  safe_max_x %}
                {% set area_max_x = area_max_x + mesh_area_offset %}
            {% else %}
                {% set area_max_x = safe_max_x %}
            {% endif %}

            {% if area_max_y + mesh_area_offset <=  safe_max_y %}
                {% set area_max_y = area_max_y + mesh_area_offset %}
            {% else %}
                {% set area_max_y = safe_max_y %}
            {% endif %}

            {% set meshPointX = (meshPointX * (area_max_x - area_min_x) / (safe_max_x - safe_min_x) * probe_count_scale_factor)|round(0)|int %}
            {% if meshPointX < min_probe_count %}
                {% set meshPointX = min_probe_count %}
            {% endif %}
	    {% if meshPointX > meshMaxPointX %}
                {% set meshPointX = meshMaxPointX %}
            {% endif %}

            {% set meshPointY = (meshPointY * (area_max_y -area_min_y ) / (safe_max_y - safe_min_y) * probe_count_scale_factor )|round(0)|int %}
            {% if meshPointY < min_probe_count %}
                {% set meshPointY = min_probe_count %}
            {% endif %}
	    {% if meshPointY > meshMaxPointY %}
                {% set meshPointY = meshMaxPointY %}
            {% endif %}

            {% set algorithm = "bicubic" %}
	    {% if "algorithm" in bedMeshConfig %}
	        {% set algorithm = bedMeshConfig.algorithm %}
            {% endif %}
            {% if meshPointX >=7 or meshPointY >=7 %}
                {% set algorithm = "bicubic" %}
            {% endif %}

            {% if enable_reference_index %}
                {% set referenceIndex = (meshPointX * meshPointY / 2 - 1 )|round(0)|int %}
                BED_MESH_CALIBRATE_BASE mesh_min={area_min_x},{area_min_y} mesh_max={area_max_x},{area_max_y} probe_count={meshPointX},{meshPointY} samples={probe_samples|int} algorithm={algorithm} relative_reference_index={referenceIndex}
            {% else %}
                BED_MESH_CALIBRATE_BASE mesh_min={area_min_x},{area_min_y} mesh_max={area_max_x},{area_max_y} probe_count={meshPointX},{meshPointY} samples={probe_samples|int} algorithm={algorithm}
            {% endif %}
        {% else %}
            BED_MESH_CALIBRATE_BASE
        {% endif %}
    {% else %}
        BED_MESH_CALIBRATE_BASE
    {% endif %}

@frankbags
Copy link

Can you run PROBE_ACCURACY and see if it's giving constant readings, your probe could be broken. If it's consistent can you run the PROBE_CALIBRATE command again and make sure that your x/y offsets are correct, the bl touch should move to where the nozzle was after it homes.

@gitvisual
Copy link

It is very consistent and the offsets are spot on 👌🏻.
Todat I thought I found the issue, the gantry was somewhat tilted. I fixed that and hopes for the best, but no. If the bed itself is warped the auto-bed-leveling should compensate for that, right? I can feel the z-axis compensating, but everyone the nozzle goes over one of those areas (where the heightmap says its higher), the nozzle drags on the bed. Is it not compensating enough?

@numanair
Copy link

numanair commented Jan 2, 2024

@gitvisual That sounds like you have some twist to your motion. The closer/more aligned the probe is (XY) with the nozzle the better for dealing with twist.

@gitvisual
Copy link

@numanair I'm sorry but I don't really understand, can you explain that for me?

@numanair
Copy link

numanair commented Jan 4, 2024

@gitvisual Let's say your x axis rail/extrusion has a twist to it and you have a probe which is offset from the nozzle on the x-direction. This twist causes the carriage to rotate as it moves left-right, which causes the nozzle to move in the z-direction a little. Since the probe is offset, the carriage is at a different location when probing as it is when printing at the same probed point. Hence there is a difference in what the probe and the nozzle "see".

@gitvisual
Copy link

gitvisual commented Jan 4, 2024

@numanair Thank you for the explanation. I read about klippers new function (from 0.12.0) "Axis_twist_compensation". Unfortunately I run klippy on a sonic pad that only has klipper 0.11.0.
I tried ssh into the pad and wget the axis_twist_compensation.py - file (along with probe.py) directly from klipper3d GitHub page.
This made it possible to use the function from my sonic pad but I'm not sure it actually uses the calibration or not since it doesn't make the prints any better (or worse).

@dagno-IT
Copy link

Hi, thank you for your amazing work!!!
Works perfectly for mine with cura, but it probes the wrong area, it doesn't use the bltouch y_offset parameter so it probes the area "in front" of the print area.

Thank you in advance for your help

############ printer.cfg ###############
[bltouch] # enable for BLTouch
control_pin: PA8
sensor_pin: ^PA11
#control_pin: PA4
#sensor_pin: ^PC4
#pin_up_touch_mode_reports_triggered: False
Probe_with_touch_mode: True
stow_on_each_sample: False
y_offset: 27.5
samples: 3
samples_result: median
sample_retract_dist: 5.0
samples_tolerance: 0.01
samples_tolerance_retries: 3

[safe_z_home]
home_xy_position: 112, 157 # Change coordinates to the center of your print bed
speed: 50
z_hop: 10 # Move up 10mm
z_hop_speed: 5

[bed_mesh]
speed: 120
horizontal_move_z: 5
mesh_min: 12, 80
mesh_max: 212, 225
probe_count: 5, 5
mesh_pps: 2, 3
algorithm: bicubic
bicubic_tension: 0.2

######### Cura start gcode ##########
G21 ; metric values
G90 ; absolute positioning
M82 ; set extruder to absolute mode
M107 ; start with the fan off
G92 E0 ; Reset Extruder
M104 S140 ; extruder pretemp
M190 S{material_bed_temperature_layer_0} ; wait for bed temp
G28 ; Home all axes
BED_MESH_CALIBRATE AREA_START=%MINX%,%MINY% AREA_END=%MAXX%,%MAXY%
G1 Z1 F3000 ;
G1 X1 Y20 F3000 ;
G1 Z0.4 F300 ; Move Z Axis DOWN little
M109 S{material_print_temperature_layer_0} ; wait for extruder temp
G1 Z2.0 F3000 ; Move Z Axis up little to prevent scratching of Heat Bed
G1 X0.1 Y25 Z0.3 F5000.0 ; Move to start position
G1 X0.1 Y200.0 Z0.3 F1500.0 E15 ; Draw the first line
G1 X0.4 Y200.0 Z0.3 F5000.0 ; Move to side a little
G1 X0.4 Y25 Z0.3 F1500.0 E30 ; Draw the second line
G92 E0 ; Reset Extruder
G1 Z2.0 F3000 ; Move Z Axis up little to prevent scratching of Heat Bed
G1 X5 Y25 Z0.3 F5000.0 ; Move over to prevent blob squish

@mohalsa
Copy link

mohalsa commented Jan 25, 2024

I am using a single line Gcode in Orca slicer and a macro in my klipper, I can't seem to get it to work with ORCA Slicer, What would be the start and end Gcode in Orca slicer in order to make it parse the correct data and act upon it.

This is my current Machine Code in Orca slicer:

START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] BED_TEMP=[bed_temperature_initial_layer]

This is my klipper START_PRINT macro:

[gcode_macro START_PRINT]
variable_parameter_EXTRUDER_TEMP: 220
variable_parameter_BED_TEMP: 65
variable_parameter_AREA_START : 0,0
variable_parameter_AREA_END : 0,0
gcode:
  {% set BED_TEMP = params.BED_TEMP|default(60)|float %}
  {% set EXTRUDER_TEMP = params.EXTRUDER_TEMP|default(200)|float %}
  M190 S{BED_TEMP}
  ;Set and wait for nozzle to reach temperature
  M109 S{EXTRUDER_TEMP}
  G28
  ;Enable the below line to allow auto bed mesh generation for the object being printed.
  BED_MESH_CALIBRATE AREA_START={params.AREA_START|default("0,0")} AREA_END={params.AREA_END|default("0,0")}
  G92 E0 #Reset Extruder
  G1 Z2.0 F300 #Move Z Axis up
  G1 X10.1 Y20 Z0.28 F5000.0 #Move to start position
  G1 X10.1 Y200.0 Z0.28 F1500.0 E15 #Draw the first line
  G1 X10.4 Y200.0 Z0.28 F5000.0 #Move to side a little
  G1 X10.4 Y20 Z0.28 F1500.0 E30 #Draw the second line
  G92 E0 #Reset Extruder
  G1 Z2.0 F3000 #Move Z Axis up

@DDen87
Copy link

DDen87 commented Jan 27, 2024

@ChipCE do you have some advice on getting this working with the Orca Slicer? I believe it has something to do with the START G-code. This is how mine look like:
START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer]
BED_TEMP=[bed_temperature_initial_layer_single] MATERIAL=[filament_type]
AREA_START=%MINX%,%MINY% AREA_END=%MAXX%,%MAXY%

@frankbags
Copy link

@ChipCE do you have some advice on getting this working with the Orca Slicer? I believe it has something to do with the START G-code. This is how mine look like: START_PRINT EXTRUDER_TEMP=[nozzle_temperature_initial_layer] BED_TEMP=[bed_temperature_initial_layer_single] MATERIAL=[filament_type] AREA_START=%MINX%,%MINY% AREA_END=%MAXX%,%MAXY%

This is the wrong start g-code for PrusaSlicer flavors. You are using the Cura one.

@DDen87
Copy link

DDen87 commented Jan 28, 2024

@frankbags thanks for the help! It worked!

@wwian
Copy link

wwian commented Feb 27, 2024

Hello @ChipCE!

I saw on the KLIPPER Configuration Changes (20230619) that RELATIVE_REFERENCE_INDEX is no longer available as a parameter for the BED_MESH_CALIBRATE gcode command.

Would you please update the Klipper bed mesh on print area only macro readme.md sample code to reflect this deprecation?

@andchisar
Copy link

For Cura users version 5.7 on Windows, To make the slicer work with the plugin I made it work by putting the file in:
C:\Program Files\UltiMaker Cura 5.7.0\share\cura\plugins\PostProcessingPlugin\scripts.

To put it there you need to be the admin of your PC.
The file must have the same name as the class. (KlipperPrintArea.py)

Finally, select the plugin from Extension->Post Processing->Modify G-Code.

The file I'm referring to is the one reported at the point:
#(Cura slicer plugin) To make the macro to work in Cura slicer, you need to install the post process plugin click here to download (based on frankbags's script)

@Xilophon3
Copy link

Hi, got this issue: !! {"code":"key112", "msg": "Move exceeds maximum extrusion (0.709mm^2 vs 0.640mm^2)
See the 'max_extrude_cross_section' config option for details", "values": [0.709, 0.640]} can you helpme ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment