Leveling your 3D Printer’s Bed with Klipper

Posted on Jun 1, 2023

It’s almost a cliché in the 3D printing community: if there’s a problem, level your bed! Indeed, this does actually fix a surprising number of problems. However, anyone who has done it will tell you it is an absolute pain in the neck to level your bed over and over again. While there are auto-bed-leveling probes, all these do is compensate for variations in height on an already fairly-level bed (within 0.3mm or so). Thankfully, the alternative firmware Klipper has a feature that nearly completely automates this process.

For the unaware, Klipper is an interesting take on 3D printer firmware. With most firmware, like the ubiquitous Marlin, the MCU on the printer performs both kinematic calculations and drives the steppers. This is a tried and true method, but it can be beneficial, especially on older 8-bit MCUs, to offload these calculations to a coprocessor, like a Raspberry Pi. With this extra computing power, Klipper can bring modern features to older printers, or be used to achieve stupid-fast printing speeds on already well-tuned printers. 1

Back to bed-leveling. One feature that Klipper adds is called “screw tilt adjust”. By making use of your auto-bed-leveling probe, Klipper will not only determine how level your bed is, but can tell you exactly how much to turn each of your leveling knobs to level the bed. Using this feature requires some configuration, but it’s quite minimal. In order for Klipper to perform the necessary measurements, it must know the coordinates (in mm) of your bed screws, and their threading. Here is the configuration I have in my Ender 3’s printer.cfg

screw1: 72.5, 42
screw1_name: front left screw
screw2: 240, 42
screw2_name: front right screw
screw3: 240, 212
screw3_name: rear right screw
screw4: 72.5, 212
screw4_name: rear left screw
horizontal_move_z: 10.
speed: 50.
screw_thread: CW-M4

When the adjustment is activated, klipper will move the print-head such that your auto-bed-leveling probe is directly above each of these points to measure their height. It is worth noting that these coordinates are the location that the probe must move to, not the nozzle. If you are already using the bed_screws configuration, these are not the same value; bed_screws describes the position the print-head must move to put the nozzle above the screws. 2

Enough talk, let’s do this thing! To perform our measurements, we can run G28 to home the print-head, followed by SCREWS_TILT_CALCULATE to perform our calibration. Once the measurement is complete, Klipper will give us instructions on how to level our bed.

10:59:29 PM  // probe at 72.500,42.000 is z=0.804000
10:59:34 PM  // probe at 72.500,42.000 is z=0.804000
10:59:43 PM  // probe at 240.000,42.000 is z=0.821500
10:59:48 PM  // probe at 240.000,42.000 is z=0.824000
10:59:57 PM  // probe at 240.000,212.000 is z=0.794000
11:00:02 PM  // probe at 240.000,212.000 is z=0.791500
11:00:11 PM  // probe at 72.500,212.000 is z=0.816500
11:00:16 PM  // probe at 72.500,212.000 is z=0.814000
11:00:16 PM  // 01:20 means 1 full turn and 20 minutes, CW=clockwise, CCW=counter-clockwise
11:00:16 PM  // front left screw (base) : x=72.5, y=42.0, z=0.80400
11:00:16 PM  // front right screw : x=240.0, y=42.0, z=0.82275 : adjust CCW 00:02
11:00:16 PM  // rear right screw : x=240.0, y=212.0, z=0.79275 : adjust CW 00:01
11:00:16 PM  // rear left screw : x=72.5, y=212.0, z=0.81525 : adjust CCW 00:01

My bed is already quite level, so the adjustments Klipper asks me to make are relatively minor, but this may not always be the case. Here, Klipper is instructing me to turn the front-right screw counter-clockwise “two minutes”, the rear-right screw clockwise “one minute”, and the rear-left screw “one minute” clockwise. This is different than the mathematical unit of arcminutes, though. Instead, Klipper wants us to visualize turning the knob the same distance a clock hand would move in “two minutes”, in the case of the front-right screw. If Klipper had told me to adjust my front-right screw by thirty minutes (“00:30”), I would turn the knob half of a revolution.

That’s all there is to it! You may consider running this calibration several times to ensure you have everything bang-on, but I usually find I don’t need to do it more than once or twice. As someone with a warped bed, which can be a bit challenging to level by hand, I definitely appreciate this feature, and hope it can help ease some of your 3D printing woes. Happy printing!

  1. My understanding is that when you reach these obscene speeds, the small MCUs just simply cannot keep up with calculating the next moves and driving the steppers at the same time. That said, this is definitely out of my wheel-house :) ↩︎

  2. It’s interesting to me that this is the case, because in order to use an auto-bed-leveling probe, you must configure an offset between the probe and the nozzle, so it stands to reason that Klipper should be able to calculate this screws_tilt_adjust for you… oh well ↩︎