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.
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_zis swapped topos[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.