Voron Adaptive Printing — Pressure Advance, Flow, and Temperature Auto-Calibration
Klipper Calibration Advanced
Getting the perfect print on your Voron requires dialing in Pressure Advance (PA), flow rate, temperature, and retraction. Traditionally this means hours of manual testing — print a tower, measure, adjust, repeat. Klipper's adaptive calibration features automate most of this process. From PA auto-calibration with the built-in tuning tower to filament-specific profiles that adjust on the fly, this guide covers everything you need to set up fully automated print quality optimization for your Voron. Last updated: May 2025.
The Problem with Manual Calibration
Every time you change filament brand, color, or batch, you potentially need to recalibrate pressure advance and flow. A different ABS from a different manufacturer can have significantly different melt flow characteristics. Manual calibration involves:
- Printing a PA tower (1-2 hours)
- Visual inspection and measurement
- Updating printer.cfg
- Printing a flow tower (another 1-2 hours)
- Repeating for temperature and retraction
- Total: 4-8 hours per filament type
With Klipper's adaptive calibration tools, you can reduce this to under 30 minutes per filament — and with the right setup, you can automate the entire process so it happens during the first print of any new filament.
Pressure Advance Auto-Calibration
Klipper v0.11.0 introduced the PRESSURE_ADVANCE_CALIBRATE command, which generates a test pattern and analyzes it to determine the optimal PA value automatically.
Single-Filament PA Calibration
The basic workflow:
# 1. Heat the nozzle to your normal printing temperature
M104 S240
M109 S240
# 2. Run the PA calibration tool
# This prints a series of lines with increasing PA values
PRESSURE_ADVANCE_CALIBRATE
# 3. Examine the printed pattern
# Choose the line that shows the smoothest corner without bulging
# Note the PA value printed next to that line
# 4. Save the result
SAVE_CONFIG
The calibration prints a pattern of lines at the perimeter of a small rectangle. Each line segment uses a different PA value. Inspect the corners — the correct PA value produces crisp corners with no bulging at the start of the line and no gaps at the end.
For a Voron with a standard Rapido or Dragon hotend, typical PA values are:
- PLA: 0.020 — 0.040
- ABS: 0.035 — 0.060
- PETG: 0.040 — 0.070
- PA-CF / Nylon: 0.060 — 0.100
- TPU: 0.100 — 0.200
These are starting points — your specific hotend, nozzle size, and filament will vary. Always use the calibration tool rather than guessing.
Automatic PA with SAVE_CONFIG
After running PRESSURE_ADVANCE_CALIBRATE, if you're happy with the result, save it with:
SAVE_CONFIG
# OR save to a specific section
SAVE_CONFIG VARIABLE=pressure_advance VALUE=0.045 SECTION=extruder
This updates your printer.cfg directly. No manual editing needed.
Multi-Filament PA Profiles
For Vorons with toolchangers (StealthChanger, TapChanger, or similar), you can set PA per tool:
[extruder]
pressure_advance: 0.045 # Default for ABS
[extruder1]
pressure_advance: 0.030 # Different for PLA in tool 2
[extruder2]
pressure_advance: 0.080 # For flexible filament in tool 3
For single-extruder printers, use filament-specific G-code commands in your slicer:
# In OrcaSlicer filament settings → Start G-code:
SET_PRESSURE_ADVANCE ADVANCE=0.045 # For this specific filament
This overrides the printer.cfg value during the print, so each filament profile carries its own PA value.
Flow Rate Calibration (Extrusion Multiplier)
Klipper doesn't have a built-in flow calibration command, but you can use a combination of G-code routines and post-print measurement to automate it. The key is measuring the extrusion volume per millimeter of filament.
Method 1: Single-Wall Flow Calibration
This is the traditional method, automated with macros:
[gcode_macro FLOW_CALIBRATE]
gcode:
# Prints a single-wall cube for flow measurement
# Measures wall thickness with calipers to determine flow
M104 S{params.TEMP|default(240)}
M109 S{params.TEMP|default(240)}
G28
G1 Z5 F3000
# Draw a 20x20mm single-wall square, 10 layers tall
M117 Printing flow test cube...
G1 X10 Y10 F6000
G1 Z0.2 F300
G91 ; Relative mode
G1 X20 Y0 Z0.2 E10 F300 ; Wall 1
G1 X0 Y20 Z0.2 E10 ; Wall 2
G1 X-20 Y0 Z0.2 E10 ; Wall 3
G1 X0 Y-20 Z0.2 E10 ; Wall 4
; Repeat for 10 layers...
G90
M117 Measure wall thickness with calipers
Measure the wall thickness of the printed cube. The expected wall should be 2x nozzle width (0.8mm for a 0.4mm nozzle). Calculate the correction:
New flow = Current flow * (Expected thickness / Measured thickness)
Example: New flow = 1.0 * (0.80 / 0.76) = 1.053
Method 2: Extrusion Volume Verification
A more precise method:
[gcode_macro EXTRUDE_VERIFY]
gcode:
# Mark filament at 120mm from extruder entry
# Then extrude 100mm and measure actual vs commanded
M83 ; Relative extruder
G1 E100 F300 ; Extrude 100mm
M82 ; Absolute extruder
M117 Measure distance from mark to extruder entry
; If you marked at 120mm and measured 22mm after extrusion:
; Actual extrusion = 120 - 22 = 98mm
; Correction = 100 / 98 = 1.0204
; Apply: M221 S102.04 (flow rate 102.04%)
Automated Flow Calibration via Macros
For fully automated flow calibration, use a macro that measures extruder rotation distance:
[gcode_macro CALIBRATE_EXTRUDER_ROTATION]
gcode:
# 1. Heat nozzle
M104 S240
M109 S240
# 2. Mark filament 100mm above extruder
M117 Mark filament at 100mm above extruder
# 3. Extrude 50mm at slow speed
M83
G1 E50 F60
M82
# 4. Measure remaining distance from mark
M117 Measure distance from mark to extruder entry
# 5. Calculate new rotation_distance
# Commanded: 50mm, Actual: measured difference
# New rotation_distance = (commanded / actual) * current rotation_distance
# Update printer.cfg accordingly
Enter your measurement result and the macro can calculate and apply the new value.
Temperature Auto-Tuning
Finding the ideal printing temperature for a new filament typically requires a temperature tower — a multi-level print where each level uses a different temperature. While Klipper doesn't have a built-in temperature tower generator, you can automate temperature changes during a print.
G-Code Temperature Tower
Use a temperature tower STL from resources like Filament Stories or Teaching Tech, then add temperature change G-code at specific Z heights:
; Temperature tower using CHANGE_TOOL command or M104/M109
; At Z=10mm: Set temperature
{if layer_z == 10}M104 S255{endif}
{if layer_z == 20}M104 S250{endif}
{if layer_z == 30}M104 S245{endif}
{if layer_z == 40}M104 S240{endif}
{if layer_z == 50}M104 S235{endif}
{if layer_z == 60}M104 S230{endif}
{if layer_z == 70}M104 S225{endif}
In OrcaSlicer, add these to "After layer change G-code". Better yet, create a Klipper macro that handles the temperature changes for you:
[gcode_macro TEMP_TOWER]
gcode:
# Usage: TEMP_TOWER BASE=250 STEP=-5 EVERY=10
{% set BASE_TEMP = params.BASE|default(250) %}
{% set STEP = params.STEP|default(-5) %}
{% set EVERY_MM = params.EVERY|default(10) %}
{% set current_z = printer.toolhead.z_position %}
{% set step_num = (current_z / EVERY_MM)|int %}
{% set new_temp = BASE_TEMP + (STEP|int * step_num) %}
M104 S{new_temp}
M117 Temp tower: {new_temp}C at Z={current_z}mm
Call this in your slicer's "After layer change G-code":
TEMP_TOWER BASE=250 STEP=-5 EVERY=10
Putting It All Together: Adaptive Print Start Macro
The ultimate setup is a PRINT_START macro that detects which filament is loaded, looks up its pre-calibrated profile, and applies PA, flow, and temperature automatically:
[gcode_macro PRINT_START]
gcode:
{% set BED_TEMP = params.BED|default(100) %}
{% set EXTRUDER_TEMP = params.EXTRUDER|default(250) %}
{% set FILAMENT = params.FILAMENT|default("ABS") %}
# Apply filament-specific calibration
{% if FILAMENT == "ABS" %}
SET_PRESSURE_ADVANCE ADVANCE=0.045
M221 S100 ; Flow 100%
M117 Profile: ABS (PA=0.045, Flow=100%)
{% elif FILAMENT == "PLA" %}
SET_PRESSURE_ADVANCE ADVANCE=0.025
M221 S102 ; Flow 102%
M117 Profile: PLA (PA=0.025, Flow=102%)
{% elif FILAMENT == "PETG" %}
SET_PRESSURE_ADVANCE ADVANCE=0.055
M221 S98 ; Flow 98%
M117 Profile: PETG (PA=0.055, Flow=98%)
{% elif FILAMENT == "PA_CF" %}
SET_PRESSURE_ADVANCE ADVANCE=0.085
M221 S105 ; Flow 105%
M117 Profile: PA-CF (PA=0.085, Flow=105%)
{% else %}
# Unknown filament — use defaults
M117 WARNING: No profile for {FILAMENT}, using defaults
{% endif %}
# Heat bed and nozzle
M140 S{BED_TEMP}
M104 S{EXTRUDER_TEMP}
# Home and level
G28
QUAD_GANTRY_LEVEL
G28 Z
# Optionally run PA calibration for unknown filaments
{% if params.CALIBRATE|default("no") == "yes" %}
PRESSURE_ADVANCE_CALIBRATE
{% endif %}
# Bed mesh
BED_MESH_CALIBRATE ADAPTIVE=1
# Heat soak
M190 S{BED_TEMP}
M109 S{EXTRUDER_TEMP}
# Purge
G92 E0
G1 X10 Y10 Z0.3 F3000
G1 X100 Y10 E20 F300
G92 E0
In your slicer, call it with the filament type:
PRINT_START BED=100 EXTRUDER=245 FILAMENT=ABS
Per-Filament Profile System
Store profiles as a save variable in Klipper:
[save_variables]
filename: ~/printer_data/config/filament_profiles.cfg
[gcode_macro SAVE_FILAMENT_PROFILE]
gcode:
{% set NAME = params.NAME %}
{% set PA = params.PA %}
{% set FLOW = params.FLOW %}
{% set TEMP = params.TEMP %}
SAVE_VARIABLE VARIABLE=filament_{NAME}_pa VALUE={PA}
SAVE_VARIABLE VARIABLE=filament_{NAME}_flow VALUE={FLOW}
SAVE_VARIABLE VARIABLE=filament_{NAME}_temp VALUE={TEMP}
M117 Saved profile for {NAME}
[gcode_macro LOAD_FILAMENT_PROFILE]
gcode:
{% set NAME = params.NAME %}
{% if printer.save_variables.variables.filament_{NAME}_pa is defined %}
SET_PRESSURE_ADVANCE ADVANCE={printer.save_variables.variables.filament_{NAME}_pa}
M221 S{printer.save_variables.variables.filament_{NAME}_flow}
M104 S{printer.save_variables.variables.filament_{NAME}_temp}
M117 Loaded profile: {NAME}
{% else %}
M117 ERROR: No profile for {NAME}
{% endif %}
Usage:
SAVE_FILAMENT_PROFILE NAME=ABS_SUNLU PA=0.045 FLOW=100 TEMP=245
LOAD_FILAMENT_PROFILE NAME=ABS_SUNLU
Retraction Calibration
While there's no single Klipper auto-calibration for retraction, you can build a macro that tests different retraction values in a single print:
[gcode_macro RETRACTION_CALIBRATE]
gcode:
# Prints small tower segments with varying retraction
{% set BASE_RETRACT = params.BASE|default(0.5) %}
{% set STEP = params.STEP|default(0.1) %}
{% set SEGMENTS = params.SEGMENTS|default(10) %}
{% set current_z = printer.toolhead.z_position %}
{% set seg = (current_z / 5)|int %}
{% if seg < SEGMENTS|int %}
SET_RETRACTION RETRACT_LENGTH={BASE_RETRACT + (seg * STEP|int)}
M117 Retraction: {BASE_RETRACT + (seg * STEP|int)}mm
{% endif %}
Use a retraction tower STL and call this in your slicer's layer change G-code. Each 5mm section of the tower tests a different retraction distance.
Voron-Specific Tuning Considerations
Voron printers have specific characteristics that affect adaptive calibration:
- Direct drive extruder: Vorons use direct drive (Clockwork, Galileo, Orbiter), which means very short Bowden tubes. This gives better PA response but requires precise PA values — overshoot is more visible than on Bowden setups.
- High acceleration: Vorons run at 5,000-20,000 mm/s^2. High acceleration amplifies PA issues. Always calibrate PA at the acceleration you actually print at.
- Enclosed chamber: ABS/ASA in an enclosed Voron can drift in temperature over a long print. Consider adding chamber temperature compensation:
[gcode_macro CHAMBER_COMP] gcode: {% set chamber_temp = printer.temperature_sensor_chamber.temperature %} {% if chamber_temp > 60 %} # Reduce PA by 5% at high chamber temps SET_PRESSURE_ADVANCE ADVANCE={printer.configfile.settings.extruder.pressure_advance * 0.95} {% endif %} - Long hotend zones: Dragon, Rapido, and other Voron hotends have longer melt zones than typical Creality hotends. This increases the PA value needed but also gives smoother flow curves.
Verification and Fine-Tuning
After running auto-calibration, always verify with a real print. Look for:
- Corners: Sharp corners should be crisp with no blobs. Slightly rounded corners indicate too little PA. Blobs at corners indicate too much PA.
- First layer: Consistent extrusion width across the first layer indicates correct flow. Too much flow causes elephant's foot; too little causes gaps.
- Overhangs: If overhangs curl or string, your temperature may be too high. Drop by 5 degrees and re-test.
- Bridging: Sagging bridges indicate too little cooling or too high temperature. PA doesn't affect bridging much, but flow does.
Keep a calibration notebook (or a text file in your printer_data/config directory) with notes for each filament brand and color. Over time, you'll build a library of profiles that make every new filament setup faster.
Troubleshooting
- PRESSURE_ADVANCE_CALIBRATE gives inconsistent results: Make sure your nozzle is clean and not partially clogged. Run a cold pull to clean the nozzle before calibrating. Also ensure your extruder rotation_distance is accurately calibrated — PA calibration is sensitive to extruder accuracy.
- Flow calibration changes after changing filament color: Even same-brand filaments can vary by 2-5% between colors. White pigments often require slightly higher flow. Black filaments sometimes flow more easily (lower flow needed).
- Temperature tower shows no noticeable difference: Your temperature steps may be too small. Use 5-10C steps instead of 3C. For ABS, the usable range is typically 230-260C — test across the full range.
- Profile isn't being applied: Check that your slicer's start G-code includes the FILAMENT parameter:
PRINT_START BED=100 EXTRUDER=245 FILAMENT=ABS. Verify the variable names match in your macro. - PA value changes over time: Nozzle wear changes the flow characteristics. Replace your nozzle every 3-6 months and re-run calibration. Also check for extruder gear wear.
Example: Complete Adaptive Calibration Workflow
New filament arrives (e.g., eSun ABS+ Gray)
1. Load filament and heat to 245C
2. Run PRESSURE_ADVANCE_CALIBRATE → optimal PA = 0.048
3. Print single-wall cube → wall measures 0.78mm (target 0.80) → flow adjustment = 1.026
4. Print temperature tower from 255C to 225C → best surface finish at 245C
5. Save profile: SAVE_FILAMENT_PROFILE NAME=ESUN_ABS_PLUS_GRAY PA=0.048 FLOW=102.6 TEMP=245
6. In OrcaSlicer, create filament preset with:
- Start G-code: PRINT_START BED=100 EXTRUDER=245 FILAMENT=ESUN_ABS_PLUS_GRAY
7. First real print — verify and adjust if needed
8. Total time: ~45 minutes (vs 4-6 hours manual)
Next time you print with this filament:
1. Select the filament preset in OrcaSlicer
2. Start the print — profile auto-loads
3. Perfect results every time
With adaptive calibration, you treat each filament as a known quantity with a known profile rather than guessing and hoping for the best. The upfront time investment pays off every time you switch filaments.