Ender5Pro+SKR3+OctoPrint+Klipperの設定【BLTouch編】

# 記事一覧
[その他の3Dプリンタ記事はこちら。](https://qiita.com/tanutanup/items/be6a6166d814a5882c7f)

[前回](https://qiita.com/tanutanup/items/41a7c24650bbcfc6ac0e)に引き続き、今回はBLTouchを使った各種機能を設定します。
# 今回の目的
- BLTouchを動作させる
- Z軸エンドストップをBLTouchに変更する
- AutoLeveling機能を用いてベッドの傾きを補正して印刷する

# (一応おさらい)BLTouchとは
　BLTouchはベッドのZ方向距離を計測する装置です。
　3Dプリンタの印刷成否・品質はノズルとベッドの距離に大きく依存します。通常の3Dプリンタでは、ベッドのレベリングネジでノズルの間隔を調整(コピー用紙が引っかかるくらいに）しますが、ベッド4角すべてを調整しなければならないので意外と面倒です。しかも、調整は段々ずれてしまうのでこまめに調整する必要があるのですが、ついついサボってしまい肝心なところで失敗してしまいます。
　そこで、BLTouchを使うとベッド高さを何箇所か計測・補正することでノズルとベッドの距離を自動的に保つことができます。
　もちろん、本来平らでなければならないベッドが歪んでいると、正しい形状の印刷ができなくなるのですが印刷品質・印刷成功率に向上には確実に寄与します。

# BLTouchの設定
BLTouchの接続設定は例によってprinter.cfgで行います。

## BLTouchの接続
BLTouchのSIGNALをPE5、Z-StopをPC13に接続します。

![スクリーンショット 2023-03-25 153329.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269597/1794a77c-0148-8777-ff73-8ac6da16d6dd.png)
sensor_pinはプルアップが必要ですが、SKR3の回路上には設定が無いのでソフト設定でプルアップ( ^ )しておかないと誤検出に繋がります。

Offsetの値は後述。

```printer.cfg
[bltouch]
sensor_pin: ^PC13
control_pin: PE5
x_offset = -44.5
y_offset = -15
z_offset = 2.5
```

### 接続確認
printer.cfgを読み込ませたあと、Terminalに`BLTOUCH_DEBUG COMMAND=pin_up`や`BLTOUCH_DEBUG COMMAND=pin_down`と打ち込むとプローブが出入りします。
飛び出たプローブはなにかが当たると引っ込みますが、このとき`QUERY_PROBE`を入力すると`probe: TRIGGERED`と返ってくるはずです。

### Offset計測
ノズルとプローブ先端の位置のズレを計測します(測りやすい位置に動かすためM84等でモータを無効化）。
XY軸は定規を当てればそのまま測れますが、Z軸は計測が難しいです。オススメとしては、ノズルをベッドの端まで移動。`BLTOUCH_DEBUG COMMAND=pin_down`がプローブを出した状態でZ軸を手で上昇。プローブが引っ込む位置でノズルとベッドの高さを測ると良いです。
<img width="480" alt="Z軸オフセット計測.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269597/784e5914-cadf-14fb-1633-1e140e6ffc04.jpeg">

# エンドストップの変更
Z軸の高さ基準をエンドスイッチからはBLTouchへ変更することで、基準を統一させます。
（予めZ軸エンドストップをBLTouchより早く当たらないように調整します。）

## エンドスイッチの無効化
まず、物理的なエンドスイッチ情報を無視し、BLTouchからの仮想的なエンドスイッチ情報を参照するように書き換えます。
```printer.cfg
# endstop_pin: PC0 disable for bltouch endstop
endstop_pin: probe:z_virtual_endstop
# position_endstop: 0.5 disable for bltouch endstop
```
## BLTouchを用いたZ軸ホーミング
ベッドの(大体)真ん中の座標(100,100)でホーミングを行う設定です。

```printer.cfg
[safe_z_home]
home_xy_position: 100, 100    # ホーミング実施座標
speed: 50                     # Z軸移動速度
z_hop: 10                     # ホーミング実施座標へ移動時の高さ
z_hop_speed: 5                # プローブ検出後の再検出速度
```
なお、Z軸のホーミングがXY軸位置に依存するようになったので、XY軸のホーミング後、Z軸のホーミングを行うようになります。
(XY軸ホーミングが未完の場合、Z軸ホーミングでエラーを出すはずです)

## z_offsetの調整
z_offsetはきちんと計測していない仮値のためちゃんと調整します。
まずは仮にZ軸の限界移動量をマイナス方向に拡張します。
(Z軸設定が不完全なので、調整中にZ軸がマイナスの値を取る場合がありますが、拡張しないとロックがかかります）

```printer.cfg
[stepper_z]
#### 中略 ####
position_min: -10
#### 後略 ####
```

X/Y/Z軸をホーミング後に、z_offsetの調整を行います。
Terminalに`PROBE_CALIBRATE`と入力すると以下のように返答があります。

```
Recv: // probe at 100.000,100.000 is z=2.620000
Recv: // Starting manual Z probe. Use TESTZ to adjust position.
Recv: // Finish with ACCEPT or ABORT command.
Recv: // Z position: ?????? --> 7.620 <-- ??????
```

この状態でノズルとベッドを近づけ、紙を挟んで動かなくなるまで動かします。コマンドは以下のとおりです。
（ノズルを強くぶつけないよう、移動量は欲張らないように）
```
TESTZ Z= -移動量
```
今度は紙が引っかかる程度にノズルを遠ざけます。
```
TESTZ Z= 移動量
```
この動作で、プローブの検出点とノズルの適切な距離が検出されます。
```
Recv: // Z position: 7.654 --> 7.754 <-- 7.854
```
調整が終わったら、`ACCEPT`でモードを抜け、`SAVE_CONFIG`で設定を保存します。やり直す場合は`ABORT`で抜けてください。
設定が終わると、printer.cfgに調整値が自動的に書き込まれます。
(最初に定規で仮決めしたz_offsetは自動的にコメントアウトされます）

```printer.cfg
#### 前略 ####
#z_offset = 2.5

#### 中略 ####

#*# <---------------------- SAVE_CONFIG ---------------------->
#*# DO NOT EDIT THIS BLOCK OR BELOW. The contents are auto-generated.

#### 中略 ####

#*# [bltouch]
#*# z_offset = 2.625
```

# AutoLevelingの設定

## Bed Mesh
ベッドの何箇所かをプローブで当たって、傾きや歪みを計測してくれます。計測位置と、mesh_min、mesh_max、probe_countとの関係は図とおりです。

[bed_mesh]
speed: 120
horizontal_move_z: 5
mesh_min: 5, 5        ;
mesh_max: 150, 180    ;
probe_count: 3, 3     ;
mesh_pps: 3, 3
<img width="480" alt="bedmesh.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269597/017d974a-8626-fb6e-ec15-94d92b222dd3.png">
当然、ベッドの端から端まで計測したほうがキャリブレーションの精度が上がりますが、ノズルがはみ出ないように注意が必要です。ノズルがはみ出るような設定の場合、エラーで止まります。
(この3Dプリンタの場合は、ベッドが220mm✕220mm、x_offset=44.5[mm]、y_offset=15[mm]のため、220-44.5-5 =170[mm]、220-15-5 = 200[mm]までとなります）

### テスト
Terminalに`BED_MESH_CALIBRATE`と入力すると計測が開始されます（事前にホーミングが必要です）。

```
Send: BED_MESH_CALIBRATE
Recv: // probe at 49.500,20.000 is z=2.607500
Recv: // probe at 122.000,20.000 is z=2.678750
Recv: // probe at 194.500,20.000 is z=2.622500
Recv: // probe at 194.500,107.500 is z=2.510000
Recv: // probe at 122.000,107.500 is z=2.608750
Recv: // probe at 49.500,107.500 is z=2.677500
Recv: // probe at 49.500,195.000 is z=2.886250
Recv: // probe at 122.000,195.000 is z=2.702500
Recv: // probe at 194.500,195.000 is z=2.502500
Recv: // Mesh Bed Leveling Complete
Recv: // Bed Mesh state has been saved to profile [default]
Recv: // for the current session.  The SAVE_CONFIG command will
Recv: // update the printer config file and restart the printer.
```
## Bed Visualizer
ベッドの傾きや歪みを可視化できるOctoPrintのプラグインです。
計測後、`BED_MESH_OUTPUT`を実行すると表示可能になります。

![スクリーンショット 2023-03-25 202100.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269597/8c0e30dd-db80-7438-8a0d-c8ed04a6f863.png)

また、レベリングネジをどちらにどれだけ回すかの目安も計算してくれます。
![スクリーンショット 2023-03-25 202129.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269597/65678b98-883f-a34d-c66f-5b8284b1c63b.png)

## AutoLeveling
Bed Meshまではうまくいきましたが、実際の印刷でどのように適応するか、調べてもいまいちよくわかりませんでした。
(日本語の情報が少ないのがklipperの辛いところ。また、情報を公開しているユーザーがレベルが高すぎて、何をやっているのか分からないという問題も。[公式](https://www.klipper3d.org/Bed_Mesh.html)や[Reddit](https://www.reddit.com/r/klippers/comments/xfdacs/bed_mesh/)を何度も行ったり来たりしました。)
一応、この方法でできることは確認できてますが、まだまだブラッシュアップが必要な認識です。

### gcode_macro
Marlinでは`G29`というGコードをサポートしているのですが、標準のKlipperではサポートされません。幸い、klipperはコマンドを組み合わせたマクロを設定可能です。
(変数や条件分岐、スライサからの情報取得などもサポートしているらしい)

```printer.cfg
[gcode_macro G29]
gcode:
    G28 X0 Y0 ;move X/Y to min endstops
    G28 Z0 ;move Z to min endstops
    BED_MESH_CALIBRATE PROFILE=default METHOD=automatic
    BED_MESH_PROFILE LOAD=default
    SAVE_CONFIG                       ;取ると多分だめ(?)
```

### モデルの修正
モデルに ~~G28の代わりに~~ G28のあとにG29を追記し、レベリングとその結果を保存するようにします。
（G29マクロ内のHomingがムダ。Homing未実施時にのみHomingを実施するように改善予定)

```test.gcode
;MAXX:202.864
;MAXY:202.864
;MAXZ:10.16
;Generated with Cura_SteamEngine 4.11.0
G28 ; Home
G29 ; ABL
M140 S60
M105
M190 S60
M104 S220
M105
M109 S220
```

### テストプリント
レベリングネジをあえて大きくずらした状態で、ベッドの端から端までを使う薄いモデルを印刷します。このとき、X/Y軸の移動に伴いZ軸が回転。薄く均一な印刷ができればOKです。

![IMG_6800.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269597/dda8805a-bbb1-1cf6-1890-a906b9c534c0.jpeg)

# 感想と今後
意外と苦労しましたが、ようやくMarlinを使っていたころの機能まで実現できるようになりました。あまりに高機能なので完全に理解した感はないですが、分かってきた部分も増えてきて楽しく感じています。
一方で、ディスプレイの接続ができておらず、実運用上では煩わしく感じる状況です。
（いちいちパソコンからコマンドを送っているので）
Marlinと同じ様なディスプレイを使う方法、スマホ・タブレットを使う方法、RaspberryPiにディスプレイを繋ぐ方法色々あるようなので迷うところです。

今後は、
- (当初の予定通り)フィラメントセンサ取り付け
- スライサとの連携設定
- ディスプレイ接続

このあたりをトライしたいと思います。