跟思兼學用Klipper(36)低成本升級自動Z偏移校準實現(xiàn)完美首層
(篇一)
前言
原創(chuàng)文章,轉載引用務必著名鏈接,水平有限,如有疏漏,歡迎指正交流。
文章如有更新請訪問 DFRobot 社區(qū)及 cnblogs 博客園,前者內容較全,后者排版及閱讀體驗更佳。
感謝 DFRobot 社區(qū)美女的催更和我媳婦的鼓勵與支持,才有了這篇文章。近期實驗的多,整理成文的少,而人一旦停下來,(惰)慣性還是挺大的。
本系列文章的目的是介紹自動 Z 偏移校準的基本原理與兩種簡單實現(xiàn),屬于拋磚引玉。私以為自動 Z 偏移校準的廣泛應用是實現(xiàn)小白無痛使用 3D 打印機的重要變革之一,使得 3D 打印機從專業(yè)工具向家用數(shù)碼產品轉變,真正實現(xiàn)開機即打。
視頻演示:
本文主要介紹原理,詳細的示例請參考后續(xù)的文章。


硬件列表:
- 壓力薄膜開關:原理類似薄膜鍵盤輸出數(shù)字通斷信號,不是模擬壓力傳感器,觸發(fā)距離固定,0.25/0.3mm,此處作為一把精確的尺子取代 A4 紙。
- CR-Touch:創(chuàng)想三維的探針調平器,精度很高,而且目前價格非常便宜,只要幾塊錢
實際上以上都可以使用渦流傳感器、接近開關傳感器、壓力傳感器等替換,原理相同。其中壓力傳感器觸床時可以認為偏移為 0,因為直接噴嘴觸床。
一、背景
目前常見的自動 Z 偏移校準方法包括 Klicky,壓力噴嘴/壓力熱床,渦流傳感器等,其特點是無需用戶使用 A4 紙等工具手動調整,噴嘴移動到 Z=0 位置時正好觸碰熱床表面,從而獲得完美首層打印效果。

【圖 1】Z 限位開關偏移與調平器偏移示例 source: https://github.com/protoloft/klipper_z_calibration/wiki/Why-This
二、基本原理
首先說結論:
- 自動 Z 偏移校準需要噴嘴參與
- 限位開關的作用是歸位后獲得的坐標系 S’ 與熱床坐標系 S 重合(理想狀態(tài))
相比于 XY 軸,Z 軸對打印效果的影響最大,定位精度要求也最高,畢竟千里之行始于足下,打好地基 “房子” 才能建得好。
對于 Z 軸校準,主要分為三個階段:
- Phase 1 古法純手動操作
- 機械微動開關或光電開關作為 Z 軸限位
- 調整限位開關位置和熱床調節(jié)螺絲,借助 A4 紙,使得歸位 Z 軸觸發(fā)限位開關時,噴嘴接觸熱床
- 此方式很繁瑣,且更換打印打印板后需要重新調整
- Phase 2 增加靈活性:引入 Z Offset 偏移
- 機械微動開關或光電開關作為 Z 軸限位
- 一般歸位 Z 軸后噴嘴位于熱床外下方
- 引入 Z Offset 值,如 -0.5,代表歸位后噴嘴抬升 0.5mm 到達熱床表面(噴嘴當前位于熱床表面下方 0.5mm)
- 校準 Z Offset 值,歸位后,移動噴嘴到熱床上方,借助 A4 紙使噴嘴接觸熱床,根據(jù)當前 Z 坐標,計算出 Z Offset 值
- 此方式在更換不同厚度打印板(玻璃、PEI等)后,無需調整限位開關位置
- 類似的還有自動調平器僅做 Z 軸等高校準 + 熱床調平螺絲等高校準 + 床網數(shù)據(jù)生成,仍然使用物理開關作為 Z 限位開關
- Phase 3 自動調平器時代
- 使用自動調平器作為 Z 軸限位開關
- 調平器觸發(fā)后,繼續(xù)移動噴嘴,借助 A4 紙,使噴嘴接觸熱床,從而計算出 Probe Z Offset,此值代表調平器觸發(fā)后,噴嘴距離熱床距離。例如 2.0,代表噴嘴下降 2.0mm 觸床。
三、走進新時代——自動 Z 偏移校準
從上面可以看到,所有操作都需要借助 A4 紙(也有采用肉眼觀察的),來判斷噴嘴觸床,從而獲得 Z Offset 值,但是 A4 紙法每個人的主觀感受不同,且精度不高,所以追求每次都能獲得完美首層的話,需要新工具代替 A4 紙,且重復定位精度高,還可以被打印機控制系統(tǒng)讀取數(shù)值。

【圖 2】高精度微動開關接觸式調平器
除了 A4 紙,還有這種接觸式調平器,但是打印機控制系統(tǒng)無法讀取其數(shù)值。所以我們希望一個新的測量工具擁有如下特點:
- 比 A4 紙精確,重復定位精度高
- 數(shù)值可以被打印機控制系統(tǒng)讀取
在操作前,應使用 PROBE_ACCURACY 指令檢查調平器重復定位精度是否合格,一般 range < 0.025,標準差越低越好。看到有些 UP 主調這調那,熱床貼紙啥的,結果調平器都不準。
3.1 實例演示1:機械開關作為 Z 軸限位開關
此場景使用機械限位開關,在配置文件種指定其 endstop_position 值,從而告訴系統(tǒng),觸發(fā)限位時當前坐標為 endstop_position。
借助薄膜開關,由于其觸發(fā)距離已知(0.25/0.3mm,注意歸位速度不能太快),通過分別歸位 Z 軸以及觸發(fā) Probe,可以計算出真實的 endstop_position 值,使得移動到 Z=0 時噴嘴正好觸床,具體如下圖所示:

注意:
- Probe 前應清理噴嘴餐料
- Probe 時應不止探測一次,用于減少誤差影響
- 當使用 U 槽型光電開關時,由于 X 橫梁可以穿過光電開關,所以歸位后噴嘴可以位于熱床上方
- 上圖介紹歸位后噴嘴位于熱床下方的場景,實際上 a. 高于熱床低于薄膜高度 b. 高于熱床高于薄膜高度 時此等式仍然適用,具體請自行推導
# 準備;
# 1. 無感歸位坐標:-13,-7
# 2. position_endstop 啟用,初始0,可以校準兩次看看
# 3. 注釋原Probe
[mcu loadcell]
serial: /dev/serial/by-id/usb-Klipper_rp2040_fly-rht36-if00
[temperature_sensor FLY-RHT36]
sensor_type: temperature_mcu
sensor_mcu: loadcell
[probe]
# 去套,不壓緊
pin: ^!loadcell:gpio27
x_offset: 0
y_offset: 0
z_offset: 0.3
# 探測時Z軸移動速度
speed: 3
samples: 3
samples_result: median
sample_retract_dist: 2.0
# 超出此范圍可認為偏差過大
samples_tolerance: 0.025
samples_tolerance_retries: 3
# 1. pos 0, g offset 0.45
# 2. runtime pos -0.45 g offset 0.45
# 3. runtime pos -0.45 goff 0 壓死了
# 4. pos -0.45 goff0
# 結論:Z_OFFSET_APPLY_ENDSTOP, SAVE_CONFIG后生效,實時的就是Gcode_Offset
# 由于日常使用限位,所以默認pos0,日常使用要save_config
[gcode_macro _AUTO_Z_CALIBRATE_CALC]
description: 用于自動計算并應用 Gcode Offset
gcode:
# 以熱床平面為 Z=0, 壓力薄膜在熱床上觸發(fā)時的實際坐標。已知為 0.3/0.25 等
{% set REAL_PROBE_POS = printer.configfile.settings.probe.z_offset|float %}
{% set ESTOP_POS = printer.configfile.config.stepper_z.position_endstop|float %}
{% set PROBE_POS = printer["probe"].last_z_result|float %}
# 計算過程
# 1. 歸位后噴嘴位于熱床下,則偏移距離為負值。
# aka. AUTO_ESTOP_BED_OFFSET
{% set REAL_ESTOP_POS = REAL_PROBE_POS - PROBE_POS + ESTOP_POS |round(2) %}
# TODO: Gcode_Offset, 取反?
# SET_GCODE_OFFSET Z={ESTOP_POS + REAL_ESTOP_POS} MOVE=0
SET_GCODE_OFFSET Z={- ESTOP_POS - REAL_ESTOP_POS} MOVE=0
RESPOND MSG="壓力薄膜實際坐標(配置讀取): {REAL_PROBE_POS}"
RESPOND MSG="壓力薄膜偏移坐標(測量獲得): {PROBE_POS}"
RESPOND MSG="限位開關實際坐標(計算獲得): {REAL_ESTOP_POS}"
RESPOND MSG="限位開關偏移坐標(配置讀取): {ESTOP_POS}"
# RESPOND MSG="限位開關相對熱床偏移距離: {REAL_ESTOP_POS} {AUTO_ESTOP_BED_OFFSET}"
# SAVE_CONFIG 重啟前不生效。和限位開關實際坐標相同:REAL_ESTOP_POS
Z_OFFSET_APPLY_ENDSTOP
# 日常無壓力薄膜,無法每次都測試,故需要保存
# SAVE_CONFIG
[gcode_macro AUTO_Z_CALIBRATE]
description: 使用機械限位歸零,再使用壓力薄膜在左前方調平螺絲上方探測
# inspried by https://github.com/Ficik/extra-probe
gcode:
{% set SCREW_X = 30.0 %}
{% set SCREW_Y = 20.0 %}
G28
SET_GCODE_OFFSET Z=0 MOVE=0
G0 X{SCREW_X} Y{SCREW_Y} F12000
G91
G0 Z10 F1800
G90
RESPOND MSG="請安裝壓力傳感器...等待8s"
G4 P8000
PROBE
G91
G0 Z15 F1800
G90
_AUTO_Z_CALIBRATE_CALC
注意點:
- 薄膜壓力開關觸發(fā)距離固定,一般是0.25/0.3mm等
- 想要 Z Offset 實時生效請使用
SET_GCODE_OFFSET指令,而 Z_OFFSET_APPLY_ENDSTOP 指令需要 SAVE_CONFIG 重啟后生效 - 由于宏內部不更新坐標,所以使用獨立的
_AUTO_Z_CALIBRATE_CALC宏進行計算
3.2 實例演示2:調平器也作為 Z 軸限位開關

核心難點是定義一個額外的 probe, 因為默認 Klipper 僅支持一個 Probe。這里參考 https://github.com/Ficik/extra-probe/ 項目,但是由于 klipper 代碼有改動,需要修改后才能正常使用,具體修改如下:
pi@orangepipcplus:~$ diff extra_probe.py extra_probe.py_mod
125c125,126
< z_offset = self.printer.lookup_object('probe').z_offset
---
> probe = self.printer.lookup_object('probe', default=None)
> z_offset = probe.get_offsets()[2]
如果后續(xù)又變了,可以參考 https://github.com/protoloft/klipper_z_calibration 進行修改。
# 準備;
# 1. 無感歸位坐標:30,20
# 2. position_endstop 禁用
# 3. Probe offset定為2mm
[mcu loadcell]
serial: /dev/serial/by-id/usb-Klipper_rp2040_fly-rht36-if00
# 歸位XY坐標,修改無感歸位
[temperature_sensor FLY-RHT36]
sensor_type: temperature_mcu
sensor_mcu: loadcell
[extra_probe loadcell]
# 去套,不壓緊
pin: ^!loadcell:gpio27
z_offset: 0.3
samples: 5
speed: 3
sample_retract_dist: 2.0
samples_result: median
samples_tolerance: 0.025
samples_tolerance_retries: 3
[force_move]
enable_force_move: True
[gcode_macro _AUTO_Z_CALIBRATE_CALC]
description: 用于自動計算并應用 Gcode Offset
gcode:
# {% set REAL_PROBE_POS = printer.configfile.config.printer["extra_probe loadcell"].z_offset|float %}
# TODO: 讀取
# {% set REAL_EXPROBE_POS = printer["extra_probe loadcell"].z_offset|float %}
# {% set REAL_EXPROBE_POS = printer["extra_probe loadcell"].default_probe_z_offset|float %}
{% set REAL_EXPROBE_POS = 0.3 %}
{% set PROBE_POS = printer.configfile.config.probe.z_offset|float %}
{% set EXPROBE_POS = printer["extra_probe loadcell"].last_z_result|float %}
# 計算過程,REAL_PROBE_POS 也就是 Probe Z Offset
{% set REAL_PROBE_POS = REAL_EXPROBE_POS - EXPROBE_POS + PROBE_POS |round(2) %}
# TODO: Gcode_Offset, 取反?
SET_GCODE_OFFSET Z={ - REAL_PROBE_POS + PROBE_POS} MOVE=0
RESPOND MSG="壓力薄膜實際坐標(配置讀取): {REAL_EXPROBE_POS}"
RESPOND MSG="壓力薄膜偏移坐標(測量獲得): {EXPROBE_POS}"
RESPOND MSG="調平器實際坐標(計算獲得): {REAL_PROBE_POS}"
RESPOND MSG="調平器偏移坐標(配置讀取): {PROBE_POS}"
# RESPOND MSG="限位開關相對熱床偏移距離: {REAL_ESTOP_POS} {AUTO_ESTOP_BED_OFFSET}"
# SAVE_CONFIG 重啟前不生效。和限位開關實際坐標相同:REAL_ESTOP_POS
Z_OFFSET_APPLY_PROBE
# 日常無壓力薄膜,無法每次都測試,故需要保存
# SAVE_CONFIG
[gcode_macro AUTO_Z_CALIBRATE]
description: 探針G28熱床Z0, 探針Probe壓力POS1,噴嘴Probe壓力POS2
# inspried by https://github.com/Ficik/extra-probe
gcode:
# [TODO2]
# 設置噴嘴位于壓力傳感器正上方時的坐標
{% set NOZZLE_X = 30 %}
{% set NOZZLE_Y = 20 %}
# 設置探針位于壓力傳感器正上方時的坐標
# {% set TOUCH_X = 60 %}
# {% set TOUCH_Y = -6 %}
# NEW,避免干擾壓力傳感器,關閉擠出電機。TODO: 多擠出電機
SET_STEPPER_ENABLE STEPPER=extruder ENABLE=0
# 如果未歸位,提示歸位
G28 # 測試用
M400
# {% if printer.toolhead.homed_axes != "xyz" %}
# {action_respond_info("請首先歸位后繼續(xù)")}
# # G28
# {% else %}
# 清空 Gcode Offset
SET_GCODE_OFFSET Z=0 MOVE=0
# 使用噴嘴探測(5次,壓平可能的殘料)后抬 5mm
G0 X{NOZZLE_X} Y{NOZZLE_Y} F12000
G91
G0 Z10 F1800
G90
RESPOND MSG="請安裝壓力傳感器"
G4 P8000
EXTRA_PROBE PROBE=loadcell
G91
G0 Z20 F1800
G90
RESPOND MSG="請取下壓力傳感器"
# G4 P8000
# 使用探針探測后抬 5mm
# TODO: 不需要PROBE?因為就是offset
# G0 X{TOUCH_X} Y{TOUCH_Y} F12000
# PROBE
# G91
# G0 Z5 F1800
# G90
# 由于宏內部不更新坐標,所以使用獨立的宏進行計算
_AUTO_Z_CALIBRATE_CALC
# {% endif %}
3.3 實例演示3:機械限位開關 + 調平器組合
之前做的一個項目,具體不再贅述。注意壓力傳感器容易受干擾,使用時關閉擠出機電機和風扇。


浙公網安備 33010602011771號