Skip to content

Instantly share code, notes, and snippets.

@dnahas
Forked from ChipCE/readme.md
Last active October 22, 2022 13:55
Embed
What would you like to do?
Klipper bed mesh on print area only macro install guide

Klipper mesh on print area only install guide

What this macro do

  • This macro will dymanic change the bed_mesh area based on the size of the printed part. 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 macrro 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 : 3
; 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 %}
	    
	    SET_GCODE_VARIABLE MACRO=RatOS VARIABLE=mesh_min_x VALUE={area_min_x}
	    SET_GCODE_VARIABLE MACRO=RatOS VARIABLE=mesh_min_y VALUE={area_min_y}


            {% 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 %}

		{% if meshPointX is divisibleby 2 %}
			{% set meshPointX = meshPointX + 1 %}
		{% endif %}
		{% if meshPointY is divisibleby 2 %}
			{% set meshPointY = meshPointY + 1 %}
		{% endif %}


            {% set algorithm = "lagrange" %}
            {% if "algorithm" in bedMeshConfig and meshPointX >=4 and meshPointY >=4 %}
                {% set algorithm = bedMeshConfig.algorithm %}
            {% 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 by frankbags - 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 Mesh Print Size

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]}

RatRig RatOS Print start Macro

[gcode_macro START_PRINT]
#added for variable bed mesh
variable_parameter_AREA_START : 0,0
variable_parameter_AREA_END : 0,0
#end added for variable bed mesh
description: Start print procedure, use this in your Slicer.
gcode:
  CLEAR_PAUSE
  SAVE_GCODE_STATE NAME=start_print_state
  # Metric values
  G21
  # Absolute positioning
  G90 
  # Set extruder to absolute mode
  M82
  # Home if needed
  MAYBE_HOME
  M117 Heating bed...
  RESPOND MSG="Heating bed..."
  # Wait for bed to heat up
  M190 S{params.BED_TEMP|default(printer.heater_bed.target, true) }
  # Run the customizable "AFTER_HEATING_BED" macro.
  _START_PRINT_AFTER_HEATING_BED
  # Run the customizable "BED_MESH" macro
  #Change for variable bed mesh
  #_START_PRINT_BED_MESH
  M117 Bed Mesh Calibrate..
  RESPOND MSG="Bed Mesh Calibrate....."
  BED_MESH_CALIBRATE AREA_START={params.AREA_START|default("0,0")} AREA_END={params.AREA_END|default("0,0")} PROFILE=ratos
  BED_MESH_PROFILE LOAD=ratos
  # end Change for variable bed mesh
  # Start heating extruder
  M104 S{params.EXTRUDER_TEMP|default(printer.extruder.target, true) }
  # Run the customizable "PARK" macro
  _START_PRINT_PARK
  # Wait for extruder to heat up
  M117 Heating Extruder...
  RESPOND MSG="Heating Extruder..."
  M109 S{params.EXTRUDER_TEMP|default(printer.extruder.target, true) }
  # Run the customizable "AFTER_HEATING_EXTRUDER" macro.
  _START_PRINT_AFTER_HEATING_EXTRUDER
  M117 Printing...
  RESPOND MSG="Printing..."
  RESTORE_GCODE_STATE NAME=start_print_state
  # Set extrusion mode based on user configuration
  {% if printer["gcode_macro RatOS"].relative_extrusion|lower == 'true' %}
    M83
  {% else %}
    M82
  {% endif %}
  G92 E0

RatRig RatOS prime line move

[gcode_macro PRIME_LINE]
description: Prints a primeline, used internally, if configured, as part of the START_PRINT macro.
gcode:
  SAVE_GCODE_STATE NAME=prime_line_state
  {% set speed = printer["gcode_macro RatOS"].macro_travel_speed|float * 60 %}
  # Absolute positioning
  G90 
  # Absolute extrusion
  M82
  M117 Priming nozzle with prime line..
  RESPOND MSG="Priming nozzle with prime line.."
  # Lift 5 mm
  G1 Z5 F3000
  # Move to prime area
  G1 X{printer["gcode_macro RatOS"].mesh_min_x} Y{printer["gcode_macro RatOS"].mesh_min_y} F{speed}
  # Get ready to prime
  G1 Z0.3 F3000
  # Reset extrusion distance
  G92 E0
  # Prime nozzle 
  G1 Y{printer["gcode_macro RatOS"].mesh_min_y + 80} E16 F1200
  # Wipe
  G1 Y{printer["gcode_macro RatOS"].mesh_min_y + 100} F{speed}
  RESTORE_GCODE_STATE NAME=prime_line_state

change logs

  • 2022/07/21
    • Added force lagrange algorithm for mesh with lower than 3 points
    • Added enable_reference_index config flag
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment