Klipper calibration procedure: seven steps that must not be reordered

Typical story: a person buys an ADXL345, sticks it on the hotend, runs SHAPER_CALIBRATE, gets a nice graph — and the print doesn’t get better. A week later he tugs the belt, and the whole calculation can be thrown away: the frequency has moved.

Klipper provides a dozen calibration tools, and almost all of them yield plausible results regardless of whether the machine is ready. That’s the trap: a number appears every time, but its meaning only matters if what lies beneath it is already fixed. Below is a seven-step sequence with an explanation of why each step has exactly that place.

Important:

Rule one: calibration measures an effect. If the cause is still wandering, you’ll need to repeat the measurement. So the order goes from bottom to top — from hardware to software compensations, not the other way around.


Diagram based on the documentation klipper3d.org

Step 0. What you do before any calibration

Official Klipper documentation starts not with quality settings but with a safety-check list — and rightly so. None of them are about printing, but each could cost a printer.

Success:
  1. Temperatures. Nozzle and bed graphs show room temperature and don’t rise by themselves.
  2. M112. Emergency stop should put firmware into shutdown state; FIRMWARE_RESTART brings it back to normal, temperatures continue updating.
  3. Heaters. Set the nozzle to 50 °C — the temperature should rise within ~30 seconds. Turn off — return to room temperature in a few minutes.
  4. Enable pins. After M84 all axes should move manually. If motors are locked — an inverted pin is required in the config: enable_pin: !PA1.
  5. Endstops. QUERY_ENDSTOPS with axes moved — open, when pressed manually — TRIGGERED. Inversion — the same !.
  6. Motor direction. STEPPER_BUZZ STEPPER=stepper_x wiggles the axis by 1 mm ten times. Check direction, return to origin point and the distance itself.
  7. Extruder. Heat to working temperature, press “Extrude”, ensure the motor spins in the correct direction.
Error:

Do not skip item 2 under any circumstances. A non-working emergency stop is the only failure on this list that ends with a burnt part rather than a fire.

Step 1. Mechanics: what cannot be fixed by configuration

There are no Klipper commands here, which is why this step is often skipped. Yet everything that will be measured next is a derivative of the stiffness of the construction.

What’s checked: belt tension on X and Y (equal, without “stringing” and without sag), pulley tightness on shafts — the screw should sit on the groove, not on the rounded part, play in carriages and eccentric, frame tightness, no table wobble.

Why this first: the chassis and carriage’s natural frequency is what you will measure in step 6. It directly depends on belt tension and carriage mass. Tightening the belt after calibrating the rapper will give a different frequency and old coefficients.

Note:

There’s a handy side tool: TEST_RESONANCES AXIS=1,1 OUTPUT=raw_data and TEST_RESONANCES AXIS=1,-1 OUTPUT=raw_data (on CoreXY this corresponds to movement along one belt and the other). Comparing the two plots shows the difference in belt tension. But this is mechanical diagnostics, not a calibration of the rapper — don’t confuse these two uses of the same command.

Step 2. rotation_distance: geometry and extrusion

rotation_distance is the distance the axis travels for one full rotation of the stepper motor. For belt-driven axes it is calculated, not tuned:

rotation_distance = belt_pitch × number_of_pulley_teeth

For a typical GT2 belt (pitch 2 mm) and a 20-tooth pulley you get exactly 40 mm. If you have 16 teeth — 32 mm, and no “calibration by printing a cube” is needed here: the value is known exactly.

If the axis still moves where you didn’t request, correction is calculated by:

rotation_distance = old_value × actual_distance / requested_distance

With an extruder it’s different — there the “measure and trim” method is appropriate because slip and filament deformation don’t come out of geometry:

G91
G1 E50 F60

Sequence: mark the filament about 70 mm from entering the extruder, push out 50 mm at slow feed (F60 — about 1 mm/s so as not to count nozzle pressure), measure the new mark position with calipers. The actual distance is the difference between the initial and final measurement; then use the same formula, rounding to three places.

Info:

If you have a gearbox in the extruder, don’t recalculate the gear ratio by hand — use gear_ratio for that. Then rotation_distance describes the movement of the output gear, not the motor shaft, and the config remains human-readable.

The “measure and trim” method is not recommended by the documentation for X, Y, and Z: the accuracy of measurements there isn’t enough, and the geometry formula gives the exact answer.

Step 3. PID: stable temperature — stable viscosity

Two calls and saving:

PID_CALIBRATE HEATER=extruder TARGET=170
PID_CALIBRATE HEATER=heater_bed TARGET=60
SAVE_CONFIG

Why calibrate before flow and pressure advance, and not after: melt viscosity depends strongly on temperature. If the nozzle drifts by ±5 °C, the width of the extruded line also drifts — and you’ll be “calibrating flow” while actually measuring a loose heater.

SAVE_CONFIG will overwrite the [extruder] section at the end of printer.cfg and reboot the firmware. Calibrate at a temperature close to the working temperature for your main filament — the coefficients are not universal.

Step 4. First layer and bed geometry

Z-offset and bed_mesh are the only step that will have to be done in parts and revisited when changing the bed or nozzle surface. What matters here is not so much the exact number as repeatability: if the bed heats up and the gap moves, there’s nothing left to calibrate.

Practical readiness criterion: the first layer has the same thickness and the same width in the center and in all four corners, with no “transparent” areas and no squeezed ridges.

Warning:

The bed mesh compensates for surface curvature but not for thermal behavior. Use it on a preheated bed at the temperature you print at — otherwise you’ll be recording a cold-bed shape and applying it to a hot bed.

Step 5. Pressure advance: wall width during accelerations

Pressure advance compensates for pressure in the melt: when accelerating the nozzle you need to feed a bit more plastic, when decelerating a bit less. Without it corners get blown out and line starts become thin.

Preparation — remove anything that could skew the result:

SET_VELOCITY_LIMIT SQUARE_CORNER_VELOCITY=1 ACCEL=500

Then run the tower. For direct drive and for Bowden the steps differ:

# direct drive
TUNING_TOWER COMMAND=SET_PRESSURE_ADVANCE PARAMETER=ADVANCE START=0 FACTOR=.005

# bowden
TUNING_TOWER COMMAND=SET_PRESSURE_ADVANCE PARAMETER=ADVANCE START=0 FACTOR=.020

Print the square_tower.stl from the documentation set: speed 100 mm/s, infill 0%, layer height about 75% of nozzle diameter, dynamic acceleration and seam tuning — disable.

Then find the height at which the wall looks the most even, and compute:

pressure_advance = <START> + <height in mm> × <FACTOR>

Пример из документации: 0 + 12.90 × 0.020 = 0.258. Типичные значения лежат в диапазоне 0,050–1,000, причём верхняя часть диапазона — это обычно боуден.

Note:

Значение зависит от филамента и в меньшей степени от температуры. Разумная практика — держать pressure advance не в printer.cfg, а в профилях слайсера через SET_PRESSURE_ADVANCE в стартовом G-коде: у PETG и PLA он отличается заметно.

Шаг 6. Резонансы: два пути к одной цифре

Ringing (он же ghosting) — это следы затухающих колебаний рамы на стенке детали после резкой смены направления. Input shaper не глушит колебания механически: он разбивает команду на несколько импульсов так, чтобы вторая волна пришла в противофазе к первой и погасила её.


Схема на основе описания резонансной компенсации в документации Klipper


Тестовая печать с ringing. Иллюстрация из документации Klipper

Путь А. Без акселерометра — башня с ускорениями

Печатается ringing_tower.stl: слой 0,2–0,25 мм, 1–2 периметра или ваза, внешние периметры на 80–100 мм/с, минимальное время слоя не больше 3 секунд, динамическое ускорение выключено. Команда:

TUNING_TOWER COMMAND=SET_VELOCITY_LIMIT PARAMETER=ACCEL START=1500 STEP_DELTA=500 STEP_HEIGHT=5

Дальше — линейка или штангенциркуль: измеряем расстояние D (мм) между несколькими колебаниями и считаем их количество N на этом отрезке. Частота:

частота (Гц) = V × N / D

где V — скорость внешнего периметра в мм/с. Считается отдельно для X и Y по меткам на модели.


Замер расстояния D между колебаниями. Иллюстрация из документации Klipper

Путь Б. С акселерометром

Klipper работает с ADXL345, MPU-9250, LIS2DW и LIS3DH-совместимыми датчиками. ADXL345 — только SPI, MPU и LIS умеют и SPI, и I²C.

Пример подключения ADXL345 напрямую к Raspberry Pi:

[mcu rpi]
serial: /tmp/klipper_host_mcu

[adxl345]
cs_pin: rpi:None

[resonance_tester]
accel_chip: adxl345
probe_points:
    100, 100, 20

Тот же датчик через RP2040:

[mcu adxl]
serial: /dev/serial/by-id/usb-Klipper_rp2040_<серийник>

[adxl345]
cs_pin: adxl:gpio1
spi_bus: spi0a
axes_map: x,z,y

[resonance_tester]
accel_chip: adxl345
probe_points:
    147, 154, 20

Проводку документация советует делать экранированной витой парой (cat5e и лучше), проверять сопротивление подтяжек I²C (ориентир — от 900 Ом до 1,8 кОм) и подключать экран к земле MCU. Перед подачей питания проверьте распиновку дважды: ошибка убивает датчик.

Проверка связи и шума:

ACCELEROMETER_QUERY
MEASURE_AXES_NOISE

ACCELEROMETER_QUERY должен вернуть три числа, где по вертикальной оси видно ускорение свободного падения — примерно так:

// adxl345 values (x, y, z): 470.719200, 941.438400, 9728.196800

MEASURE_AXES_NOISE в норме даёт значения примерно от 1 до 100.

Warning:

Значения выше 1000 в MEASURE_AXES_NOISE — это не «шумный датчик, сойдёт». Это либо проблема с питанием и проводкой, либо разбалансированный вентилятор, который трясёт всю раму. Мерить резонансы в таком состоянии бессмысленно: вы снимете спектр вентилятора.

Сам замер (input shaper на время теста должен быть выключен):

TEST_RESONANCES AXIS=X
TEST_RESONANCES AXIS=Y

CSV попадут в /tmp/resonances_x_*.csv и /tmp/resonances_y_*.csv. Обработка:

~/klipper/scripts/calibrate_shaper.py /tmp/resonances_x_*.csv -o /tmp/shaper_calibrate_x.png
~/klipper/scripts/calibrate_shaper.py /tmp/resonances_y_*.csv -o /tmp/shaper_calibrate_y.png

Вывод выглядит так:

Fitted shaper 'mzv' frequency = 34.6 Hz (vibrations = 0.0%, smoothing ~= 0.170)
To avoid too much smoothing with 'mzv', suggested max_accel <= 3500 mm/sec^2
Recommended shaper is mzv @ 34.6 Hz

Автоматический вариант — SHAPER_CALIBRATE (на «качельке» имеет смысл гонять по одной оси: SHAPER_CALIBRATE AXIS=Y), затем SAVE_CONFIG. Результат в конфиге:

[input_shaper]
shaper_freq_x: 57.8
shaper_type_x: zv
shaper_freq_y: 34.6
shaper_type_y: mzv

[printer]
max_accel: 3000

Если тряска при тесте кажется чрезмерной, снизьте accel_per_hz (по умолчанию 75):

[resonance_tester]
accel_chip: adxl345
accel_per_hz: 50
probe_points: ...

Какой шейпер выбирать

Шейпер Длительность Полоса подавления (порог 5 %) Сглаживание
ZV 0,5 / freq минимальное
MZV 0,75 / freq ±4 % от частоты низкое
ZVD 1 / freq ±15 % среднее
EI 1 / freq ±20 % среднее
2HUMP_EI 1,5 / freq −40…+45 % высокое
3HUMP_EI 2 / freq −50…+60 % очень высокое

Логика простая: чем длиннее шейпер, тем шире полоса частот, которую он гасит, и тем сильнее размывает мелкие детали. Скрипт calibrate_shaper.py уже взвешивает этот компромисс, но если сглаживание не устраивает, его можно ограничить явно:

~/klipper/scripts/calibrate_shaper.py /tmp/resonances_x_*.csv -o /tmp/shaper_calibrate_x.png --max_smoothing=0.2
Note:

Документация отдельно предупреждает: гонять автокалибровку шейпера часто — например, перед каждой печатью или ежедневно — не стоит. Тестовые прогоны сильно трясут машину, ускоряя износ и ослабляя крепёж. После калибровки имеет смысл пройтись по винтам.

Шаг 7. max_accel: минимум из двух пределов

Последний шаг — и единственный, где SAVE_CONFIG вам не поможет: значение подбирается глазами по тестовой печати.

Пределов два, и брать надо меньший:

  1. Предел по ringing — максимальное ускорение, при котором следы колебаний ещё приемлемы.
  2. Предел по сглаживанию — максимальное ускорение, при котором не теряются детали. Индикатор в тестовой модели — зазор 0,15 мм в стенке: чем сильнее сглаживание, тем шире он выглядит.


Тот самый зазор 0,15 мм, по которому оценивают сглаживание. Иллюстрация из документации Klipper


Чем выше ускорение, тем шире выглядит зазор. Иллюстрация из документации Klipper

square_corner_velocity при этом трогать не надо: документация советует оставить значение по умолчанию 5 мм/с, потому что его увеличение добавляет сглаживания ровно там, где мы его только что убирали.

Шпаргалка: полный проход

Success:
# 0. checks
M112 / FIRMWARE_RESTART
QUERY_ENDSTOPS
STEPPER_BUZZ STEPPER=stepper_x

# 2. feeding
G91
G1 E50 F60

# 3. heaters
PID_CALIBRATE HEATER=extruder TARGET=170
PID_CALIBRATE HEATER=heater_bed TARGET=60
SAVE_CONFIG

# 5. pressure advance
SET_VELOCITY_LIMIT SQUARE_CORNER_VELOCITY=1 ACCEL=500
TUNING_TOWER COMMAND=SET_PRESSURE_ADVANCE PARAMETER=ADVANCE START=0 FACTOR=.005

# 6. resonances
MEASURE_AXES_NOISE
SHAPER_CALIBRATE
SAVE_CONFIG

# 7. ceiling of acceleration — by hand, from test print

Returning to the start will be necessary after any mechanical intervention: replacing the hotend changes the carriage mass and frequency, replacing the belt changes tension, a new bed surface alters Z-offset. It isn’t a reason to recalibrate everything every week, but a reminder of what you just reset.

Question:

Interested in comparing real numbers: what are your shaper_freq for X and Y, on which kinematics and with what max_accel do you end up printing? And was there a case when after tightening belts the frequency moved so much that the old shaper started to get in the way?

Sources