Prusa PA Tuner

Auto-tune Linear Advance on the MK4S via the nozzle loadcell.

1. Printer

2. Filament & temps

3. Sweep parameters

Max Flow — parameters

Free-air stepped flow ramp: extrudes at increasing volumetric flow rates and watches the loadcell back-pressure for the point where the hotend can't melt fast enough. Temperature + filament come from the shared cards above. This extrudes into the air, so expect a string/bird's-nest at high flow.
Advanced (settle, warm-up & tare)

Live loadcell

idle · · K=— · 0%

Live Map — print file

Upload a sliced ASCII .gcode (in PrusaSlicer, untick Export as binary G-code). We inject the metric preamble and print it, mapping the live nozzle loadcell force onto the gcode as it prints — the part geometry is untouched. The map is saved so you can scrub the layers again later.
idle · · 0%

Live Map — 2D nozzle-load map

Top-down view of one layer. The path is coloured by nozzle force (force mode) over a faint gcode backdrop; switch to feature mode to see what each region is (perimeter / infill / …). Live, it follows the layer being printed; grab the slider to study a finished layer, then Jump to live to resume.
no file loaded

Live Map — review & saved runs

Layer detection

How samples were assigned to layers. The staircase is the median-filtered streamed z; vertical lines are the detected layer boundaries (green = z step snapped to a travel, orange = z step only, red = arc-length fallback).

Nozzle load by feature

Tared force per feature type, aggregated over the run.

Touch Probe — lateral sensitivity test

Step 1: characterise the sensor before building the probe. This pushes the nozzle tip sideways (±X / ±Y) into a rigid target and records the Z loadcell while it creeps in, to find out whether lateral contact registers a clean, repeatable force at all. The loadcell is an axial (Z) sensor; lateral force reaches it only as a bending moment, so this is an open question we have to measure.

Safe by design: the creep is short (the creep distance is a hard cap on how far we can push past contact) and slow, and the nozzle is cold by default — so even if nothing stops the move, the worst case is a gentle lean, not a crash. Set up: clamp a rigid object so the nozzle just touches it partway through the creep, then point the probe at it with the standoff + axis below. Contact should land after the first ~20 % of the creep (that early part is used as the no-contact baseline).

Touch Probe — results

Force vs. probe-axis position, every touch overlaid. A usable lateral probe needs a clean knee: force flat (no contact), then a sharp, monotonic rise — landing at the same position on every touch. Vertical dashed lines mark the detected contact point per touch; tight clustering = good repeatability.

Verdict

—

Touch Probe — per-touch viewer

Inspect one touch at a time (or use ← / → keys). The dashed line is the detected contact position; the shaded band before it is the no-contact baseline window used to tare + set the noise floor.
no run loaded

Max Flow — results

Steady-state nozzle force vs flow rate. The fitted curve is the well-behaved power law F = a·Qᵇ + c; markers show where force breaks upward off it (melting limit), where per-level noise rises (instability onset), and where force collapses (extruder skipping). Recommended max = earliest soft breakdown, derated ~15%. The amber curve (right axis) is the per-step force σ (noise) — its axis is scaled to the quiet low-flow steps, so the post-skip σ explosion clips off the top rather than flattening the rest; hover for true values.

Recommended max flow

—
mm³/s — earliest soft breakdown, derated

Max Flow — per-step viewer

Sanity-check that each flow level was sliced correctly. Pick a step on the left (or use ← / → keys). The shaded band is the measured window (the settle portion is discarded); the dashed line is the steady-state force used for that point on the curve above.
no run loaded

Segment browser — step-response regions ported: markniu/bd_pressure

Step through every low-high-low segment (low_n + high_n + low_{n+1}) and inspect what the analyser saw. The 8-region step-response decomposition (R1 baseline … R8 recovery tail) is adapted from markniu's bd_pressure Klipper module, re-run offline on the Prusa loadcell stream. Click a K on the left to focus it; use prev/next buttons or ← / → keys to step through that K's segments. Segments excluded by the auto-quality gate are flagged with the reason.
no run loaded

Loadcell baseline (pre-sweep)

Held-idle window captured after heat-up, before priming. Mean is the static head load; std is the noise floor; drift is the difference between the 2nd-half and 1st-half means (high drift = thermal not yet settled). If mean ≈ 0, the firmware tared; if not, analysis still works (per-window mean-subtraction handles it) but an absolute scale becomes unreadable.
mean
—
std
—
drift
—
samples
—

Results — composite step-response cost metrics: markniu/bd_pressure weighting: this project

Composite cost = weighted sum of normalised per-K step-response metrics (median over included segments). The per-segment metrics follow bd_pressure's transient decomposition; the live re-weightable composite and the weight optimiser below are this project's extension. Sliders adjust weights live — K_opt recomputes without re-running the printer. The per-metric K_opts on the right show whether the metrics agree.

Recommended K (composite argmin)

—
parabolic interp around the cost minimum

per-metric K_opt

argmin of each metric in isolation

Weight optimiser this project

Tune the composite-cost weights against ground-truth K values you've measured from test prints. Annotate saved runs with your measured best K (the field above the weight sliders), then run this to fit weights that predict those K's under bootstrap resampling of the segments. Loss = bias² + α · variance summed across runs.
annotated runs available
—
Metrics included in the search (uncheck to exclude a metric — its weight is locked at 0):

Results — zero-crossing fits (comparison)

Alternative K_opt estimators to cross-check the composite cost above; each panel is tagged with its origin. The integral-area fits port the Snapmaker U1 flow-calibrator math (150 ms transition window ≈ one melt-pressure τ, per-cycle local mean); phase-lag and signed fall-area are this project's own estimators (phase-lag follows the Ellis 3DP under/over-PA framing). All fits consume the SAME cycle list as the step-response analysis above, so a cycle it excluded (dropouts in the critical zone, sample rate < 40 Hz, signal-below-noise) is excluded here too. Hover a point to see how many cycles survived for that K. Phase-lag and legacy-integral are kept for visual comparison only. The phase-lag fit is a quadratic (the lag response saturates at high K, which drags a straight line's crossing high); when the lag never crosses zero in-range it falls back to a global linear fit and the model label below reads "linear fallback".

Phase-lag fit this project

—
model=— · R²=—

Integral-area fit (centered) ported: Snapmaker U1

—
slope=— · R²=—

Integral (legacy sign(dC/dt)) Snapmaker U1 · original form

—
slope=— · R²=—

Signed fall-area fit (overshoot↔lag) this project

—
slope=— · R²=—
Per-K median of fall_signed_area = ∫(force − baseline) over the fall+recovery window. +area = force lingers above baseline (slow bleed / drool → under-PA); −area = force dips below (undershoot → over-PA). Crosses zero at K_opt — a sign-based estimator independent of the composite-cost argmin.

Diagnostics

Live UDP stats (auto-refreshes every second). If a metric you M331'd is missing or running at ~0 Hz, that name probably doesn't exist on this firmware build — the M331 handler writes "Metric not found" to serial and PrusaLink discards the reply, so the failure is invisible from gcode. Throttle is compile-time (the 4th arg of each METRIC_DEF); M331/M332 can only enable/disable, not re-rate. Power-cycling the printer reverts every metric to its compile-time enable/disable default.
packets / s
—
packets (total)
—
dropped (backpressure)
—
malformed lines
—
metric names seen
—
metric Hz (last 5s) total samples