Voron Klipper Probe Temperature Compensation Guide
Calibration Klipper Probe
Temperature-dependent Z probe drift is one of the most common causes of first-layer inconsistency on Voron printers. As the bed heats up from room temperature to 100-110°C for ABS printing, the probe's sensing characteristics change. The metal bed surface expands, the probe electronics warm up, and the mounting structure experiences thermal expansion. Without temperature compensation, your Z-offset can shift by 0.05-0.30mm between a cold and hot bed — enough to ruin first-layer adhesion. This guide explains how different probe types behave with temperature, how to measure drift, and how to configure Klipper's probe temperature compensation to maintain consistent Z-offset across all printing temperatures. Last updated: May 2025.
Understanding Probe Drift
Probe drift refers to the change in the measured trigger point of a Z probe as temperature changes. Three factors contribute:
- Thermal expansion of the bed: As the aluminum bed heats up, it expands upward toward the probe. A 300mm aluminum bed heated from 20°C to 100°C expands approximately 0.18mm in thickness (assuming 6mm cast aluminum). The probe detects the surface closer than when cold.
- Probe electronic drift: Inductive probes contain oscillator circuits that change frequency with temperature. The trigger distance changes as internal components warm up.
- Mechanical thermal expansion: The probe mount, toolhead, and gantry expand with chamber temperature. This changes the physical relationship between the probe and the nozzle.
Probe Type — Temperature Behavior Comparison
| Probe Type | Typical Drift (20-100°C bed) | Compensation Method | Notes |
|---|---|---|---|
| Inductive (PL-08N, TL-Q5MC) | 0.05-0.15mm | Klipper TEMPERATURE_PROBE or manual config | Most common. Drift is predictable and linear. |
| Voron Tap | 0.01-0.05mm | Minimal compensation needed | Contact probe. Drift mostly from bed expansion only. |
| Klicky/Euclid (microswitch) | 0.02-0.08mm | Minimal to moderate compensation | Mechanical switch. Drift from bed expansion and mount thermal changes. |
| Eddy/Beacon contactless | 0.02-0.06mm | Built-in compensation in firmware | Newer probes handle drift internally. |
Inductive Probe Calibration — The Deep Dive
Inductive probes (Panasonic PL-08N, Omron TL-Q5MC2, or generic LJ12A3-4-Z) are the most common Z probes on Voron printers. They are affordable, reliable, and work well on smooth PEI sheets. However, they are the most temperature-sensitive probe type.
How Inductive Probes Work
An inductive probe creates a high-frequency electromagnetic field. When a metal target (the bed) enters this field, eddy currents are induced, and the oscillator circuit detects the power loss. The trigger distance depends on the oscillator frequency, which shifts with temperature. As the probe heats up, the trigger point moves closer to the target.
Measuring Drift on Your Printer
To measure your specific probe's drift:
- Home Z with a cold bed (about 25°C). Record the Z position with the probe triggered.
- Heat the bed to 60°C. Wait 10 minutes for thermal equilibrium.
- Home Z again and record the Z position. The difference is the drift at 60°C.
- Heat the bed to 100°C (or 110°C). Wait 10 minutes.
- Home Z and record the Z position. Calculate the drift from cold.
You can automate this with a Klipper macro:
[gcode_macro MEASURE_PROBE_DRIFT] gcode: SAVE_GCODE_STATE NAME=drift_state BED_MESH_CLEAR G28 G1 Z10 F300 M104 S0 # Cold measurement M140 S25 G4 P600000 G28 Z G1 Z10 F300 # 60C measurement M140 S60 TEMPERATURE_WAIT SENSOR="heater_bed" MINIMUM=60 MAXIMUM=61 G4 P600000 G28 Z G1 Z10 F300 # 100C measurement M140 S100 TEMPERATURE_WAIT SENSOR="heater_bed" MINIMUM=100 MAXIMUM=101 G4 P600000 G28 Z G1 Z10 F300 M140 S0 RESTORE_GCODE_STATE NAME=drift_state
Klipper Temperature Probe Compensation
Klipper supports automatic probe temperature compensation through the [temperature_probe] configuration section (available in Klipper 0.11+).
Basic Configuration
[temperature_probe my_probe] sensor_type: Generic 3950 sensor_pin: PB7 # Calibrated drift values (mm per degree C) calibrated_drift: 0.0018
The calibrated_drift value is the mm of drift per degree Celsius. Calculate it by dividing your measured total drift by the temperature change. For example, if you measured 0.12mm drift from 25°C to 105°C (80°C change): 0.12 / 80 = 0.0015 mm/°C.
Multi-Point Calibration
For more accurate compensation with non-linear probes, use a multi-point calibration file:
[temperature_probe my_probe] sensor_type: Generic 3950 sensor_pin: PB7 calibration_data: temp: 25, drift: 0.000 temp: 40, drift: 0.028 temp: 60, drift: 0.062 temp: 80, drift: 0.095 temp: 100, drift: 0.120
Klipper interpolates between these points. To generate the calibration data, run a script that measures probe Z position at multiple bed temperatures. A calibration can be automated using the Klipper API or by running manual probe tests at each temperature.
Configuration for Inductive Probe Models
For a standard Voron V2.4 with a PL-08N probe (300mm build):
[temperature_probe pl08n] sensor_type: Generic 3950 sensor_pin: z_probe_temperature calibrated_drift: 0.0015 # Example: 0.12mm drift over 80C change [probe_pin] pin: ^PB0 x_offset: 0.0 y_offset: 23.0 speed: 10.0 samples: 3 samples_result: median sample_retract_dist: 5.0 samples_tolerance: 0.010 samples_tolerance_retries: 3
The sensor_pin for the temperature probe must be a thermistor or temperature sensor mounted on or near the probe body. For best results, mount a small 100k NTC thermistor (glass bead type) on the inductive probe's metal body with thermal epoxy. This measures the actual probe temperature, which may differ from the bed temperature sensor reading.
Voron Tap Temperature Behavior
The Voron Tap is a contact-based Z probe that mechanically triggers a microswitch through the nozzle. Because Tap uses physical contact rather than electromagnetic sensing, it is largely immune to the electronic drift that affects inductive probes. However, Tap is not completely drift-free.
Tap Drift Sources
- Bed thermal expansion: The aluminum bed expands upward as it heats, reducing the distance between the nozzle and the bed surface. This is the primary drift source for Tap.
- Toolhead thermal expansion: As the hotend heats up, the nozzle expands downward slightly (0.01-0.03mm for a 50°C hotend temperature increase). This partially counteracts bed expansion.
- Probe mechanism wear: As the Tap mechanism wears, the trigger force and distance can change. This is a long-term drift effect, not temperature-related.
Tap Temperature Compensation
For most Tap users, temperature compensation is optional. The drift is typically under 0.05mm, which is within acceptable first-layer tolerance. If you want tighter control, use [temperature_probe] with a low drift coefficient of 0.0005-0.0008 mm/°C (measured from bed expansion only).
[temperature_probe tap] sensor_type: Generic 3950 sensor_pin: PB7 calibrated_drift: 0.0006
Klicky and Euclid Probe Considerations
Klicky and Euclid are dockable microswitch probe systems widely used on Voron printers. They use a mechanical microswitch that is unaffected by temperature electronics drift, but the dock, wiring, and mounting can introduce temperature-dependent behavior.
Dock Expansion
The Klicky dock is printed in ABS and mounted to the frame. As chamber temperature rises, the dock expands, which can shift the probe's resting position. This changes the probe's trigger point relative to the nozzle. For best results, ensure the dock is firmly mounted with metal hardware and use ABS+ or PC for the dock parts if you print at elevated chamber temperatures.
Wiring Resistance Changes
The microswitch is wired to the control board. Wire resistance changes slightly with temperature, but for a digital microswitch (open/closed signal), this has no effect on trigger accuracy.
Klicky/Euclid Compensation
If you observe drift with Klicky (more than 0.05mm from cold to hot), measure the drift and add temperature compensation. Many Klicky users find that compensation is unnecessary because the mechanical microswitch is inherently stable. Measure your specific setup to determine if compensation is needed.
Automated Temperature Compensation Setup
Klipper's [temperature_probe] can be combined with print start macros for fully automatic compensation:
[gcode_macro PRINT_START]
gcode:
# ...standard print start commands...
M190 S{params.BED_TEMP}
M109 S{params.EXTRUDER_TEMP}
# Run temperature probe calibration
TEMPERATURE_PROBE_CALIBRATE PROBE=pl08n TARGET=40
# Temperature compensated probing
G28 Z
# ...continue with bed mesh, etc.
The TEMPERATURE_PROBE_CALIBRATE command recalibrates the probe's drift compensation at the current temperature. Run this after the bed has fully soaked to temperature for best results.
Testing Your Compensation
After configuring temperature compensation, validate it with a simple test:
- Heat the bed to printing temperature (100°C for ABS).
- Wait 15 minutes for full thermal soak.
- Set Z-offset using paper or feeler gauge.
- Print a single-layer test pattern (300x300mm square, 0.2mm layer height).
- Check first-layer consistency across the entire print surface.
- Allow the bed to cool completely to room temperature.
- Repeat steps 1-5. The first layer should be identical to the hot test.
If the cold-start first layer is noticeably different from the hot-start first layer, your compensation needs adjustment.
Advanced: Klipper Probe Calibration Script
For automated multi-point calibration, use a Python script that communicates with the Klipper API via Moonraker:
#!/usr/bin/env python3
import requests
import time
import json
MOONRAKER_URL = "http://localhost:7125"
def probe_at_temp(target_temp):
# Set bed temperature
requests.post(f"{MOONRAKER_URL}/printer/gcode/script",
json={"script": f"M140 S{target_temp}"})
time.sleep(30) # Wait for temperature to stabilize
# Query probe Z position
status = requests.get(f"{MOONRAKER_URL}/printer/objects/query",
params={"probe": ""}).json()
return status["result"]["status"]["probe"]["z_position"]
cold_z = probe_at_temp(25)
hot_z = probe_at_temp(100)
drift = cold_z - hot_z
print(f"Total drift from 25C to 100C: {drift:.4f}mm")
print(f"Drift per degree C: {drift / 75:.6f}mm/C")
This script probes the bed at two temperatures and calculates the drift coefficient. Expand it to probe at multiple temperatures for non-linear compensation.