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.

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.