Faster Klipper Bed Probing Macro
I recently found an awesome Klipper macro made by ChipCE which makes probing faster and more efficient so I thought an article would be helpful.
This macro will allow you to probe the bed only over the zone where the model is printed. For example, if you print a 3D Benchy, only a few points will be probed, instead of the whole bed. But when you decide to print a larger object, the probed section of the bed automatically be increased.
The Raise3D E2 probes the bed in a similar fashion, and I loved that feature, so being able to do it using Klipper is awesome. In the video below, you can see a comparison between the regular BED_MESH_CALIBRATE macro, and the fast probing macro in this article.
How to setup the bed probing macro?
Edit the printer.cfg
The installation process for the bed probing macro is really easy. First, we need to open the printer.cfg file and add the macro to the bottom of the file.
[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
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 %}
{% set meshPointX = bedMeshConfig.probe_count.split(",")[0]|int %}
{% set meshPointY = bedMeshConfig.probe_count.split(",")[1]|int %}
{% 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 %}
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}
{% else %}
BED_MESH_CALIBRATE_BASE
{% endif %}
{% else %}
BED_MESH_CALIBRATE_BASE
{% endif %}
I added the macro between the CANCEL_PRINT and the SAVE_Config section.
After adding the macro, we need to update the start g-code in our slicer, to call this macro and probe the bed before each print. This is how I set up my slicer profiles for the printers which are running Klipper.
Update the Start G-code in your slicer
IdeaMaker Start G-code
In IdeaMaker, we need to edit the printer profile and navigate to GCode -> Start GCode and add the following code like shown in the image below:
BED_MESH_CALIBRATE AREA_START={print_pos_min_x},{print_pos_min_y} AREA_END={print_pos_max_x},{print_pos_max_y}
Click on OK to save the change. Now every time you start a new print, the printer will home then probe the bed only over the section where the model will be printed.
Prusa Slicer Start G-code
In Prusa Slicer, we need to edit the printer profile and navigate to Printer Settings -> Custom G-code -> Start G-code and add the following code like shown in the image below:
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]}
Click on OK to save the change. Now every time you start a new print, the printer will home then probe the bed only over the section where the model will be printer.
Wrapping Up
This faster bed probing macro is really useful and saves quite a bit of time when probing the bed before a print. I added this macro on all of my Klipper printers and I love it. As previously mentioned, all the credits should go to ChipCE who made this awesome klipper macro.
Check back soon, because I am working on a dedicated article which covers my favorite Klipper macros to automate some of the 3D printing tasks. If you have other awesome macros to use with Klipper, feel free to leave a comment. I’m quite interested in seeing what other people use with Klipper.
You can also join the 3DPrintBeginner Forum where there’s a dedicated thread for Klipper Firmware, with Klipper enthusiasts ready to help.
Liked it?
|
|
Does this automatically update the bed mesh data for the current print? If you run the bed leveling manually you have to save and update the printer.cfg file to take effect?
nope.
Can Fade height be used with this macro?
can this be used with Cura?
Any information? I have the same question…
How do I change the timing the probe comes out? It works, but when the probe goes out it hits the bed as it’s slightly too close.
Add a [probe] section to your config and increase the sample_retract_dist.
Can I use prusaslicer gcode for superslicer?
Yes, it should work
Do I need to use the m420 s1 z2 command as seen in the screenshot? That recalls the mesh?
Nope.
This sounds like a great time saver thank you for sharing this Macro
Does this work also for delta printers like flsun SR? Can I use the same code?
There is no use for this on a delta printer.
Why not? Should be usable on a delta too?
Are you going to install the leveling sensor every time you start a print?
Hi nice write up, I have a bed mesh already in my CFG that dosent run before a print, do i just delete that and replace it with this one, also there would be no need to save a heightmap calibration? also what config would work with Cura , the idea maker one or?
Check the documentation on github
This is too funny. I just last night made multiple probe points in my config to circumvent this, since I have a large bed and I like A LOT of probe points. Only problem with my solution was commenting in and out the probe points I wanted before each print. Not the worst thing ever, but this is much better! I’ll give it a go. Thanks!
Side note: yours looks like it could go much faster if you a) traveled faster and b) didn’t stow the probe between points.
Since I made the video, I also tuned my probe speeds and it goes much faster. But this is a good start point.
Any chance you’d be willing to share the updated code?
Very good one! Thank you for sharing