Creality

SCREWS_TILT_CALCULATE on the Creality K2, manual bed levelling, no extra hardware

Klipper's manual bed-level helper, ported to work with Creality's older probe-helper API on the K2 family. Uses the existing strain-gauge probe.

By Grant Harkness · published 2026-05-09

If you've tried to use Klipper's stock SCREWS_TILT_CALCULATE on a Creality K2, you'll have hit this:

``` AttributeError: 'list' object has no attribute 'bed_z' ```

…the first time you run it. Drop the upstream Klipper file in place, run the command, and Klipper crashes on its own probe-helper API. We've shipped a small fork that fixes it, K2-Screws-Tilt, bringing the manual bed-level helper to the K2 family using your printer's existing strain-gauge probe. No extra hardware.

Why it doesn't work out of the box

Upstream Klipper's screws_tilt_adjust.py was rewritten a while back to use a newer probe-helper API. The finalize callback now receives (phoming, offsets, positions) with positions as objects exposing a .bed_z attribute.

Creality's Klipper fork on the K2 is older: it still uses the 2-arg callback (offsets, positions) with positions as plain [x, y, z] lists. Drop in upstream's file and you get the AttributeError above the first time the probe finishes a position.

What this fork changes

Two minimal patches against upstream:

  • The finalize signature is swapped to the 2-arg form.
  • pos.bed_z is swapped to pos[2].

That's it. The actual tilt math, screw-thread calculation, and CW/CCW direction output are upstream Klipper code, unchanged.

Install (one line)

On Windows, in PowerShell:

```powershell iwr -useb https://raw.githubusercontent.com/grant0013/K2-Screws-Tilt/main/bootstrap.ps1 | iex ```

The script checks for Python (installs it via winget if missing), downloads the repo, installs paramiko, asks for your printer's IP, and runs the installer, no manual SSH needed.

On macOS or Linux:

```sh git clone https://github.com/grant0013/K2-Screws-Tilt cd K2-Screws-Tilt pip install paramiko python install_k2.py --host 192.168.x.x ```

The installer uses the Creality stock root password (creality_2024) by default; override with --password MYPASS if you've changed it.

Using it

Two-step workflow from the Fluidd / Mainsail gcode console:

``` G28 SCREWS_TILT_CALCULATE ```

Klipper probes each of the four bed-screw positions and prints something like:

``` front left : x=30.0, y=30.0, z=0.015 front right: x=230.0, y=30.0, z=0.048, CW 00:04, Adjust back left : x=30.0, y=230.0, z=-0.012, CCW 00:02, Adjust back right : x=230.0, y=230.0, z=0.031, CW 00:03, Adjust ```

The CW 00:04 notation means "turn clockwise by 4 minutes of an hour", i.e. 4/60 of a full turn. Adjust by hand, re-run SCREWS_TILT_CALCULATE, and repeat. Most K2 beds converge in 2-3 iterations from a fresh "loosen everything first" starting point.

For tighter tolerances, pass MAX_DEVIATION:

``` SCREWS_TILT_CALCULATE MAX_DEVIATION=0.05 ```

…and the helper warns when any screw is off by more than 0.05 mm. To force all adjustments in one direction (handy if you've over-tightened and want to back off everything together):

``` SCREWS_TILT_CALCULATE DIRECTION=CCW ```

Compatibility

| Printer | Board | Status | |---|---|---| | K2 Combo | CR0CN200400C10 (F021) | Confirmed working, firmware V1.1.4.1 | | K2 / K2 Pro | Same board | Should work, please report results | | K2 Plus | CR0CN240319C13 (F008) | Untested, you probably want [z_tilt] instead (dual Z) | | K1 / K1C / K1 Max | CR4CU220812S* | Untested |

The default [screws_tilt_adjust] section assumes a 4-screw layout at (30, 30), (230, 30), (30, 230), (230, 230), correct for the K2's 260 mm bed. K2 Plus and other variants should edit those coordinates after install.

Check your screw thread direction

The installer adds screw_thread: CW-M4 by default, meaning M4 bed screws that tighten clockwise. This is right for stock Creality K2 beds, but worth confirming on your machine. Valid values: CW-M3, CCW-M3, CW-M4, CCW-M4, CW-M5, CCW-M5, CW-M6, CCW-M6. If your screws tighten counter-clockwise (rare but possible), change it before running the helper or every direction you read will be backwards.

Reverting

Re-run the one-liner and pick option 2 from the menu, or:

```sh python install_k2.py --host 192.168.x.x --revert ```

The installer makes two backups on every install: one on the printer (/mnt/exUDISK/... or /mnt/UDISK/...) and one on your PC under %USERPROFILE%\K2-Screws-Tilt\backups\. Revert tries the printer-side first, falls back to the local backup if the on-printer one is missing, for example after a Creality firmware update wipes user files.

Companion: KAMP-K2

KAMP-K2 is the sister project, adaptive bed meshing and line purging for the same K2 family. After you've levelled the bed once with K2-Screws-Tilt, KAMP-K2 keeps the per-print mesh adaptive so you're not wasting 100+ seconds of probing for a 3 cm² part.

Both projects are GPL v3, free forever, and use the same install UX. Bug reports and confirmation reports welcome at the issues page.