Saturday, April 8, 2023

Configuring the EZABL with Klipper on a Creality Ender 3 Pro

Trying to get my EZABL bed leveling sensor to work with Klipper on a Creality Ender 3 Pro took several hours and about 50 open browser tabs. Here is what I learned from this exercise so you don't have to go through the same thing. Here are the changes you'll need to make in your printer.cfg file:
  • Reconfigure the [stepper_z] section
  • Add a new [probe] section
  • Determine the correct pin configuration for [probe]
  • Add a new [safe_z_home] section
  • Configure the bed mesh

Reconfigure the [stepper_z] Section


The default [stepper_z] section for a Creality Ender 3 Pro looks like this:

[stepper_z]
step_pin: PB6
dir_pin: !PB5
enable_pin: !PC3
microsteps: 16
rotation_distance: 8
endstop_pin: ^PA7
position_endstop: 0.0
position_max: 250

Since the EZABL acts as a Z-axis endstop, we will make the following changes:

[stepper_z]
step_pin: PB6
dir_pin: !PB5
enable_pin: !PC3
microsteps: 16
rotation_distance: 8
endstop_pin: probe:z_virtual_endstop  #see note (1)
position_max: 250
position_min: -7  #see note (2)
  • (1) The endstop_pin setting will be replaced with 'probe:z_virtual_endstop', which is described in the excellent Klipper documentation here.  This basically tells the z axis that it will get it's endstop info from the probe section.
  • (2) The position_min setting will allow the Z axis to descend below zero while printing, depending on bed height variation.
  • If you followed the EZABL guide when you installed the sensor, you will remember that the sensor is positioned 1-2 mm above the nozzle.  You will also remember that you had to calibrate the sensor during installation by raising the nozzle another 2mm off the bed.  This means, if you followed all of the installation instructions, the sensor will be triggered when the nozzle is 2mm away from the bed.  We will deal with this later.


Add a new [probe] section


A section called [probe] will need to be added to your printer.cfg file.  Here is mine:

[probe]
# Pin for the z-min endstop input
pin: ^!PA7  #see note (1)
# Offset between the nozzle and the EZABL sensor, see note (2)
x_offset: 48.0  # (+) right of nozzle
y_offset: -2.0  # (-) behind nozzle
z_offset: 2.0   # (+) 2 mm above nozzle
speed: 5.0
lift_speed: 30.0
sample_retract_dist: 1.0
samples: 2
samples_tolerance_retries: 6

  • (1) the pin used for the Z-axis limit switch is used here.  Note that we added an exclamation point so that it reads ^!PA7 now!  We will determine the correct setting for the pin later, which is critical.
  • (2) I am using the Petsfang Bullseye cooling duct (went back to stock cooling in November, my updated config is linked below) and I also have a MicroSwiss printhead, so the position of my EZABL sensor is probably different from yours.  Adjust these to match your setup!

Determine the correct pin configuration for [probe]


⚠️This step is critical, not following these instructions can cause damage, be ready to switch the printer off in case the z-axis is lowered too far!

Position something underneath the EZABL probe (you can use your hand) such that the red light on the probe comes ON.  With the red light on, issue a M119 command in the Octoprint terminal:



You should see:

Send: M119
Recv: x:open y:open z:TRIGGERED

Great, the pin is configured correctly!

If you see this instead:

Send: M119
Recv: x:open y:open z:open

...then the pin configuration for the [probe] is incorrect.  The Z axis will probably only move UP, thinking that the z limit has been reached.  In this case, remove the exclamation from the pin configuration so that it reads:  pin: ^PA7, restart Klipper, and try this exercise again. It should read z:TRIGGERED when the sensor detects an object.

Add a new [safe_z_home] section


This section determines where the printhead will jog to before it starts to plunge downward and detect where the bed is.  

[safe_z_home]
home_xy_position: 110, 110 #see note (1)
speed: 200
z_hop: 10
z_hop_speed: 60

  • (1) you may want to adjust this for the size of your bed.

Perform z-axis offset calibration

Follow the steps here to calibrate the z probe offset.  After following the z offset calibration steps, you will see something like this automatically added to your printer.cfg:


#*# <---------------------- SAVE_CONFIG ---------------------->
#*# DO NOT EDIT THIS BLOCK OR BELOW. The contents are auto-generated.
#*#
#*# [probe]
#*# z_offset = 2.700

 

Configure the bed mesh


Add [bed mesh] to config.  This specifies how many mesh points for bed leveling and where those points are.  For more details see the Klipper documentation.

⚠️ You may want to tweak the mesh_min and mesh_max points for your setup.

[bed_mesh]
speed: 120  #how fast to move between points 
horizontal_move_z: 5  #how much the z axis rises between points
mesh_min: 60, 20  #the x,y location of the first mesh point
mesh_max: 200, 200   #the x,y location of the last mesh point
probe_count: 3  # 3x3 grid


Make Klipper understand the G29 command


The G29 command is the bed-leveling command that you may have set already in your slicer start code.  Unfortunately, this command is not natively understood by Klipper.  Fortunately, this is easy to fix.  You can make Klipper understand G29 by adding these lines to your config file:

[gcode_macro G29]
gcode:
 BED_MESH_CALIBRATE

That should be it.  If you already had the EZABL working before, it should work almost exactly the same way now.

Update 28-May-2023; Improved G29 command


This is an update to the G29 command that will grab the target temps of the extruder and the bed, turn off the heaters before meshing, and then turn the heaters back on, waiting for them to reach temp before continuing.  

[gcode_macro G29]
gcode:
  {% set BED_TEMP = printer.heater_bed.target %}
  {% set EXTRUDER_TEMP = printer[printer.toolhead.extruder].target %}
  TURN_OFF_HEATERS
  BED_MESH_CALIBRATE
  # turn on heaters
  M140 S{BED_TEMP} ; set bed temp
  M104 S{EXTRUDER_TEMP} ; set extruder temp
  M190 S{BED_TEMP} ; wait for bed
  M109 S{EXTRUDER_TEMP} ; wait for extruder

Update 19-Nov-2023

Here is my Klipper config file as a github.com gist.