Creality K2 Series
Creality K2 Series Support
Section titled “Creality K2 Series Support”HelixScreen has a cross-compilation target for the Creality K2 series of enclosed CoreXY printers. The K2 series runs Klipper with stock Moonraker, making it a natural fit for HelixScreen.
Supported Models
Section titled “Supported Models”All K2 models use Allwinner ARM Cortex-A7 dual-core processors running Tina Linux (OpenWrt-based).
| Model | Build Volume | Display | Chamber Heater | CFS | Status |
|---|---|---|---|---|---|
| K2 | 260 mm cubed | 4.3” 480x800 | No | Optional | Untested |
| K2 Pro | 300 mm cubed | 4.3” 480x800 | Yes (60C) | Optional | Community-confirmed running (2026-09) |
| K2 Plus | 350 mm cubed | 4.3” 480x800 | Yes (60C) | Yes (CFS) | Hardware confirmed |
| K2 SE | 220x215x245 mm | Unknown | No | Unknown | User-confirmed install (wget) |
Detection has an entry for the K2, K2 Pro and K2 Plus (plus the K2 Plus k2-improvements variant),
all sharing the k2 preset. They are told apart by the model hostname or by the bed size the
firmware declares in gcode_macro product_param (250-270, 290-310 and 340-360 mm). The base K2
entry is the preset’s preset_default, so a K2 preset install that identifies no K2 machine
persists “Creality K2”. Its image is a copy of the K2 Plus photo until one of the base model exists.
Hardware (Confirmed on K2 Plus — 2026-03-23)
Section titled “Hardware (Confirmed on K2 Plus — 2026-03-23)”| Spec | Value |
|---|---|
| SoC | Allwinner T113 - allwinner,t113_iarm,sun8iw20p1 (ARM Cortex-A7, dual-core, 57 BogoMIPS) |
| Board | OpenWrt DISTRIB_TARGET=t113_i-CR0CN240110C10/generic, DISTRIB_ARCH=arm_cortex-a7_neon |
| Display | 480x800 portrait (U:480x800p-58), 32bpp, stride 1920, fbdev (/dev/fb0); double-buffered → 480x1600 virtual fb. No DRM (/dev/dri absent) |
| Touch | Goodix gt9xxnew_ts on I2C (Bus=0018), sole input node /dev/input/event0 |
| Rotation | 270° in software, from assets/config/presets/k2.json (display.rotate: 270, rotation_probed: true) |
| Stock UI | /usr/bin/display-server (must be stopped to use framebuffer) |
| RAM | 488 MB total |
| Storage | 27.5 GB on /mnt/UDISK |
| OS | OpenWrt 21.02-SNAPSHOT (Tina Linux), Linux 5.4.61 armv7l |
| Device libc | glibc 2.29 (ld-linux-armhf.so.3), libstdc++ 6.0.25. We ship a fully static musl binary, so it does not matter |
| Init System | procd (OpenWrt-style, NOT systemd) |
| MCU | GD32F303RET6 on /dev/ttyS2 @ 230400 baud |
| Nozzle MCU | GD32F303CBT6 on /dev/ttyS3 @ 230400 baud |
| Moonraker | Port 7125 (direct), port 4408 (nginx proxy) |
| Klipper UDS | /tmp/klippy_uds |
| SSH | root / creality_2024 (enable via Settings menu) |
| Config path | /mnt/UDISK/printer_data/config/ |
| Klipper path | /usr/share/klipper/ |
| Logs path | /mnt/UDISK/printer_data/logs/ |
| Gcode path | /mnt/UDISK/printer_data/gcodes/ (also /root/klipper/gcodes/) |
| Web server | web-server on ports 80, 443, 9998, 9999 |
| ADB | adbd on port 5037 |
| WebRTC | webrtc_local on port 8000 (camera) |
- No curl — BusyBox wget only (no HTTPS support). Use
python3 urllibfor HTTP requests. - armv7l — Dual-core Cortex-A7 (NOT Cortex-A53). Lower performance than K1 series.
- 480x800 display — The panel is 480x800 portrait, same as all other K2 models. The controller behind it varies by variant (
lcm_id=gc9503cv_ue_480_800on a K2 Plus,st7701_9bit_mipi_tjc_480_800on a K2 Pro) at identical geometry, depth and stride, so it changes nothing above the framebuffer. HelixScreen software-rotates portrait→landscape (applies to all K2). The 480x1600 seen in/sys/class/graphics/fb0/virtual_sizeis a double-buffered virtual framebuffer (two stacked 480x800 buffers), not a taller panel. - Python 3.9 — Available at
/usr/bin/python3. - Moonraker’s config is outside the file API — stock firmware launches
moonraker.py -c /usr/share/moonraker/moonraker.conf, while the file manager’s only writableconfigroot is/mnt/UDISK/printer_data/config. SoGET /server/files/config/moonraker.confis a 404 and no HTTP call can edit Moonraker’s configuration on this printer. HelixScreen falls back to writing the file locally; it is the only supported printer that needs to. See MOONRAKER_ARCHITECTURE.md § Locating Moonraker’s Config File. Amoonraker.confdoes sometimes exist under the writable root — left by earlier HelixScreen releases — and it is a decoy: it shares the stock section set with the real config and Moonraker never reads it.
Cross-Compilation
Section titled “Cross-Compilation”The K2 target uses Bootlin’s armv7-eabihf musl toolchain with fully static linking. We target armv7 (32-bit) because Tina Linux uses 32-bit userland.
Build via Docker (Recommended)
Section titled “Build via Docker (Recommended)”# Build the Docker toolchain and cross-compile (first time only — cached after)make k2-dockerThe Docker image (docker/Dockerfile.k2) downloads Bootlin’s armv7-eabihf musl toolchain (stable-2024.02-1).
Build Directly (Requires Toolchain)
Section titled “Build Directly (Requires Toolchain)”make PLATFORM_TARGET=k2 -jBuild Configuration
Section titled “Build Configuration”| Setting | Value |
|---|---|
| Architecture | armv7-a (hard-float, NEON VFPv4) |
| Toolchain | arm-buildroot-linux-musleabihf-gcc (Bootlin musl) |
| Linking | Fully static (musl) |
| Display backend | fbdev (/dev/fb0) |
| Input | evdev (auto-detected) |
| SSL | Disabled (Moonraker is local on port 4408) |
| Optimization | -Os with LTO (size-optimized) |
| Platform define | HELIX_PLATFORM_K2 |
CI/Release Status
Section titled “CI/Release Status”The K2 target is included in the GitHub Actions release pipeline (.github/workflows/release.yml). Release artifacts are built automatically:
# Manual packagingmake package-k2Installation
Section titled “Installation”Prerequisites
Section titled “Prerequisites”- A Creality K2, K2 Pro, or K2 Plus printer
- Stock firmware with root access — no custom firmware (Guilouz, etc.) required
- Root access enabled: Settings > “Root account information” > acknowledge disclaimer > wait 30 seconds > press “Ok”
- SSH access:
ssh root@<printer-ip>(password:creality_2024) - Find your printer’s IP: Settings > Network on the printer touchscreen
Important: K2 hostname does NOT resolve via mDNS — always use the IP address.
Quick Install
Section titled “Quick Install”# 1. Build the K2 binary (Docker — works on any host OS)make k2-docker
# 2. Deploy and run in foreground (first time — watch the output)make deploy-k2-fg K2_HOST=192.168.x.x
# 3. For production: deploy in backgroundmake deploy-k2 K2_HOST=192.168.x.xAll Deploy Targets
Section titled “All Deploy Targets”# Full deploy (binary + assets + config + platform hooks)make deploy-k2 K2_HOST=192.168.x.x
# Deploy and run in foreground with debug loggingmake deploy-k2-fg K2_HOST=192.168.x.x
# Deploy binary only (fast iteration during development)make deploy-k2-bin K2_HOST=192.168.x.x
# SSH into the printermake k2-ssh K2_HOST=192.168.x.x
# Full build + deploy + run cyclemake k2-test K2_HOST=192.168.x.xDeploy directory: /mnt/UDISK/helixscreen (override with K2_DEPLOY_DIR). SSH credentials: root/creality_2024 (override with K2_USER/K2_PASS).
Note: The K2 uses BusyBox (OpenWrt), so deployment uses tar/ssh transfer instead of rsync.
What Happens on Deploy
Section titled “What Happens on Deploy”- Stops any running HelixScreen processes
- Deploys platform hooks (
assets/config/platform/hooks-k2.sh→ /mnt/UDISK/helixscreen/platform/hooks.sh) - Transfers binaries, assets, XML layouts, and config
- Installs SysV init script at
/etc/init.d/S99helixscreenfor boot persistence - Installs the web-server carve-out at
/etc/init.d/helix-k2-webserver(config/k2-webserver.init, a USE_PROCD starter). Once its instance is registered, procd’s respawn keepsweb-serveralive; the hook’s restore registers it at every HelixScreen start — the stock app’sstopruns killall -9 over the stock set and takes anyweb-serverdown (ours included), whiledisableonly removes the app’s rc.d links. The carve-out’s own rc.d boot entry is belt-and-braces. It serves the LAN web interface: ports 80/443 redirect to Fluidd on :4408, 9999 is the local status websocket (prestonbrown/helixscreen#1617) - Platform hooks stop the stock Creality UI (
display-server,Monitor, etc.) via procd - Platform hooks start
wpa_supplicantto replace the stockwifi-server - Starts HelixScreen on the framebuffer
Reverting to Stock UI
Section titled “Reverting to Stock UI”To restore the stock Creality touchscreen:
ssh root@<printer-ip>killall helix-screen helix-splash helix-watchdog 2>/dev/nullkillall web-server 2>/dev/null # Free port 80 for the stock instance/etc/init.d/helix-k2-webserver disable # Drop the carve-out's boot symlink (NOT the # /etc/rc.d/S99... spelling: rc.common derives # link names from basename $0, so that one # computes S99S99... and removes nothing)/etc/init.d/app enable # Re-enable stock UI on boot/etc/init.d/app start # Start stock UI nowDisplay Backend
Section titled “Display Backend”HelixScreen renders directly to /dev/fb0. The platform hooks stop the stock display-server to release the framebuffer. This is handled automatically by the deploy targets.
The K2 Plus panel is 480x800 portrait; the framebuffer is double-buffered (480x1600 virtual). HelixScreen rotates it 270° to landscape and transforms touch coordinates to match. The rotation ships in assets/config/presets/k2.json with rotation_probed: true, so the interactive orientation probe never runs on a K2. HELIX_DISPLAY_ROTATION or --rotate override it.
Touch Input
Section titled “Touch Input”HelixScreen uses evdev and auto-detects the capacitive touch controller. Running as root (default) avoids permission issues on /dev/input/event*.
The K2 Plus reports a Goodix gt9xxnew_ts on /dev/input/event0, which is the only input node on the machine. The name contains no “touch” substring, so grep -i touch /proc/bus/input/devices returns nothing on a healthy K2 - match on gt9/goodix or just read the whole file.
Selection is scored, not name-matched: src/api/input_device_scanner.cpp#"find_touch_device(const" (shared by the fbdev and DRM backends) requires ABS capabilities, then adds points for a known name (include/touch_calibration.h#is_known_touchscreen_name), INPUT_PROP_DIRECT, and USB. Some K2 hardware revisions carry a tlsc6x controller instead. Its kernel name tlsc6x_touch matches the generic touch pattern, so it scores as a known panel (the Snapmaker U1 uses the same controller). No K2 with that variant has been observed yet.
Spaghetti Detection
Section titled “Spaghetti Detection”Installing HelixScreen stops the stock AI failure-detection loop: the launcher hook stops and disables /etc/init.d/app (the procd service whose Monitor/master-server/app-server children run Creality’s detect loop), and the camera module hands /dev/video0 to ustreamer. HelixScreen ships its own detector for that gap, so a K2 running HelixScreen is still watched.
K2StockDetectionSource (src/printer/k2_stock_detection_source.cpp) is capable only on a Creality K2 with /usr/bin/detection present and executable. The probe re-runs on every WebSocket connect (the printer type is read from the wizard’s saved config, not cached at boot), so a first install that picks K2 in the wizard gets detection without a restart. During an active print it fetches a camera snapshot, runs the stock /usr/bin/detection binary on it, and parses the label:/prob: lines for the maximum spaghetti probability. Detection is edge-triggered: it fires once per spaghetti episode, stays quiet while it persists, and re-arms when the frame goes clean or a new print starts.
The interval and threshold are the printer’s own, read from /mnt/UDISK/creality/userdata/config/user_print_refer.json (ai_control.pastaTime = poll period, clamped 5-600s; ai_control.pastaTruth = confidence threshold). Nothing writes that file.
The source only reports. Whether a detection pauses the print is decided above it, from the two settings in Settings > Safety & Alerts:
- Spaghetti Detection (on/off)
- Pause on Detection (pause the print, or only warn)
On the first start after install, both are seeded once from the printer’s own stored choice in the same ai_control block (switch -> enabled, pausePrint -> pause). The copy happens that one time: later changes on Creality’s side (the stock UI or a hand-edited user_print_refer.json) are not followed, and HelixScreen’s toggles are authoritative from then on. HelixScreen never writes that file. A confirmed detection with pausing on sends PAUSE, shows the spaghetti modal (Resume / Abort / Reduce Sensitivity / Turn off detection); with pausing off it only warns. The Reduce Sensitivity button sends the stock DEFECT_DETECTION_CONFIG NOODLE_SENSITIVITY=low macro.
For desktop development, HELIX_MOCK_DETECTION_CAPABLE=1 forces the capability probe true (mock printers are never a K2), so the Settings rows and the detection loop can be exercised in --test runs.
CFS (Creality Filament System)
Section titled “CFS (Creality Filament System)”The CFS is a multi-material system on RS-485: four spools per unit, up to four units chained for
16 colours. All protocol logic lives in Creality’s closed Cython module box_wrapper.cpython-39.so;
Klipper exposes it as the box object (plus filament_rack and motor_control). HelixScreen’s
backend is described in FILAMENT_BACKEND_CFS.md.
The firmware-side reference (box.cfg, the box schema variants and field encodings, the BOX_*
and M8200 command surface, error codes, runout and auto-refill, and the community Kalico port)
is CREALITY_CFS_K2_INTERNALS.md.
Auto-Detection
Section titled “Auto-Detection”HelixScreen auto-detects K2 printers using heuristics from config/printer_database.json:
| Heuristic | Confidence | Description |
|---|---|---|
Hostname k2plus / k2pro |
90 | Hostname contains “K2Plus” / “K2Pro” |
Hostname k2 |
85 | Hostname contains “k2” |
motor_control object |
75 | K2-specific motor control module |
chamber_temp sensor |
70 | Chamber temperature sensor |
heater_generic chamber_heater |
70 | Active chamber heater |
fan_feedback object |
65 | Creality fan-tachometer module — a captured real K1C reports it too, so it corroborates rather than distinguishes |
filament_rack object |
65 | K2 filament rack module |
Hostname creality |
60 | Hostname contains “creality” |
load_ai object |
60 | AI print monitoring |
box object |
45 | CFS box object — every CFS-equipped Creality carries it, so it corroborates |
build_volume_range |
55 | Build volume within the K2 envelope |
| CoreXY kinematics | 40 | CoreXY motion system |
These identify the printer, not its firmware. A community Kalico port trips every one of them — box, motor_control, fan_feedback and the hostname are all still present — so model detection reports a stock K2 Plus. Anything that varies with firmware rather than hardware (the CFS box schema, the macro dialect) must therefore be detected from the payload or the macro list, never from PrinterDetector. See Community Kalico port.
Note that chamber_temp is not universal on K2 hardware either: the Kalico port drops temperature_sensor chamber_temp and exposes chamber temperature through heater_generic chamber_heater instead.
Known Limitations
Section titled “Known Limitations”Display
Section titled “Display”- 480x800 portrait panel (double-buffered framebuffer → 480x1600 virtual) — presented landscape by a 270° software rotation; same as all other K2 models.
- Closed-source protocol — CFS communication relies on
box_wrapper.cpython-39.sobinary blob. Protocol has been reverse-engineered from strings but full reimplementation is not yet available. - Material database is cloud-fetched — The material database at /mnt/UDISK/creality/userdata/box/material_database.json is downloaded from Creality’s cloud. HelixScreen should include a fallback mapping for common material type codes.
- Community Kalico ports require Box API v1 for control — the flat status layout still parses without it, but load/unload/tool-change stay gated until
api_version == 1identifies the supported command dialect. See Community Kalico port.
Platform
Section titled “Platform”- Low CPU — Dual Cortex-A7 at ~57 BogoMIPS. Performance-sensitive features (bed mesh 3D, animations) may need throttling.
- No curl — BusyBox wget only, no HTTPS support.
- Web-server carve-out —
web-serverserves the LAN web interface (ports 80/443 redirect to Fluidd on :4408; 9998 is its HTTPS listener, 9999 the local status websocket) and must keep serving with HelixScreen installed. The platform hooks’/etc/init.d/appstop takes it down with the rest of the stock set (killall -9 in the stock stop_service;disableonly removes rc.d links), so liveness is supervised:config/k2-webserver.initis a USE_PROCD starter whose registered instance procd respawns, andplatform_stop_competing_uis(hooks-k2.sh) re-registers it at the end of every HelixScreen start — after every boot, service restart, and watchdog-driven start. The installer (install_k2_webserver_backend),make deploy-k2, and uninstall (as asysv-createdservice) all carry the script; its own rc.d boot entry is belt-and-braces only (prestonbrown/helixscreen#1617, prestonbrown/helixscreen#1665). - WiFi managed by platform hooks — The stock
wifi-serveris killed when HelixScreen takes over the display. Platform hooks (hooks-k2.sh) startwpa_supplicantdirectly using credentials at/etc/wifi/wpa_supplicant/wpa_supplicant.conf. WiFi configuration changes made via the stock UI are preserved. - Non-standard control socket —
hooks-k2.shlauncheswpa_supplicantwithout-O, so the control socket lands at thectrl_interface=from the stock conf —/etc/wifi/wpa_supplicant/sockets/wlan0on K2 — not the usual/run/wpa_supplicant. The WiFi backend searches that location (and auto-detects any-Opath from the live process), so network discovery works without manual symlinks. Firmware that uses yet another path can be pointed at it viaHELIX_WPA_SOCKET_DIR. Surfaced by a community K2 Plus report.
Related Resources
Section titled “Related Resources”- CrealityOfficial/K2_Series_Klipper — Creality’s official (incomplete) Klipper fork
- Guilouz/Creality-K2Plus-Extracted-Firmwares — Extracted stock firmware images
- ityshchenko/klipper-cfs — Community open-source CFS module
- K2 Plus Research — Detailed hardware and software research
- K1 vs K2 Community Comparison — Analysis of community ecosystem differences
- Creality Wiki — Official K2 Plus documentation
- Creality Forum — Official K2 Plus community forum