klipperに物理ボタンを設置する(gcode button)

 klipperマシンに物理ボタンを付ける話


1. MCUボードに物理ボタンを取り付けてGコードを実行させる

まずボードの使ってないピンを見つけてそこにボタンを物理ボタンを接続する必要がある

KP3Sの場合、SDカードを外部に延長するためのコネクタが生えているのでこれを利用したい

klipperはMCUボードのSDカード使わんので都合がいい

ピンアサインは次の通り

PC12”以外”のピンは10kΩの物理抵抗で外部プルアップ回路が構成されている
Robin_nano以外のボードは外部抵抗の無いピンから取ることの方が多いだろう

PC8はプルアップ抵抗回路なのでPC8ピンをGNDへ落とすよう配線すればPC8ボタンが作れる


物理ボタンが出来たらファームウェア上でボタンを宣言する
printer.cfgでの記述は次のようになる

#CPUの内部プルアップ抵抗を使用する場合
[gcode_button PC8]
pin: ^!PC8
press_gcode:
 
#CPUの内部プルダウン抵抗を利用する場合
[gcode_button PC8]
pin: ~PC8
press_gcode:
 
#外部プルアップ抵抗回路の場合
[gcode_button PC8]
pin: !PC8
press_gcode:
 
#外部プルダウン抵抗回路の場合
[gcode_button PC8]
pin: PC8
press_gcode:

CPUの内部プルアップ抵抗を利用する場合は「^」記号を記述する

CPUの内部プルダウン抵抗を利用する場合は「~」記号を記述する

外部抵抗回路の場合「^」は必要ない

プルアップ回路はピン番号の前に「!」を書いて入力を反転させる必要がある

今回は外部プルアップなので「!PC8」と記述すればいい

ちなみに宣言する名前、[gcode_button PC8]の部分は任意の名前で良い

例えば


[gcode_button btn1]
pin: !PC8
press_gcode:


とすることができる

動作確認

物理スイッチをprinter.cfgに追加できたらスイッチの動作を確認する

 Mainsailのコンソールタブを開きKlipper設定ファイルで宣言した名前で

QUERY_BUTTON button=PC8

とコマンドを送れば、gcode_button PC8の認識状況が返される
ボタンを押してない時に「PC8:RELEASED」が返されて、
ボタンを押しているとき「PC8:PRESSED」が帰ってくれば正しい設定で機能している

あとはpress_gcode;に好きな処理を箇条書きで書くだけ


[gcode_button PC8]
pin: !PC8
press_gcode:
{ action_emergency_stop(manual_btn) }

[gcode_button PD12]
pin: !PD12
press_gcode:
G28
G1 Z100
SET_HEATER_TEMPERATURE HEATER=extruder TARGET=100

このように書けば

PC8ボタンはemergency_stopを実行する緊急停止ボタン(非常停止ボタン)」になり、

PD12ボタンは「ホーミングしてZ100に移動してノズルを100℃に加熱するボタン」になる

使いたいコマンドは手動で動かした際のコンソールの応答をそのままコピペするか

公式リファレンスを参照して記述するといい

https://www.klipper3d.org/Config_Reference.html#gcode_button

https://www.klipper3d.org/G-Codes.html

https://www.klipper3d.org/Command_Templates.html

TIPS:M112を使用してはいけない

上記の例ではM112コマンドを使わずアクションコマンド{ action_emergency_stop() }を使用した

gcode butttonにおいてM112を使用した場合、今実行中の処理が終わらないと動作してくれない

(ブラウザのコンソールは即時停止してくれるのでなんか知らんけど挙動が違う)

一方のアクションコマンドはキューに割り込んで即時動作する


物理ボタンをを増やしていく


上のように配線して4つのボタンが出来た

動作確認用Gコード
ボタン1、ファンを回転させる
ボタン2、ファンを止める
ボタン3、XYZホーミング
ボタン4、緊急停止
[gcode_button PC8]
pin: !PC8
press_gcode:
M106 S100

[gcode_button PD12]
pin: !PD12
press_gcode:
M107

[gcode_button PC9]
pin: !PC9
press_gcode:
G28

[gcode_button PD2]
pin: !PD2
press_gcode:
{ action_emergency_stop() }

動作の様子

内部プルアップ抵抗を使う場合の注意点

内部プルアップ/ダウン回路は自分が検証した限りノイズにとても弱くGPIOに指で触るとノイズで誤作動してしまう
(回路形成してないのにもかかわらず)
例えば内部プルアップ時にGPIOを指で触ると電圧が0V付近まで下がりボタンが押された判定になる
外部プルアップ時にGPIOを指で触っても1Vまでしか電圧は下がらずボタンが押された判定にはならない
ファームウェアの宣言通りに内部プルアップ/ダウン抵抗のオンオフ自体は出来ているし、使えないこともないが誤作動が時々起こり今ひとつ安定しない
外部抵抗の無いピンにボタンを作る場合は外部プルアップ回路を用意した方がいい

2.Raspberry Piに3徳ボタンを設置する

緊急停止からの復帰などでmoonrakerを再起動するボタンが欲しい

下位のklipperからはそれができないので(仮に出来てもMUCの電源が切れてる)

どうしてもRaspberry Pi上にボタンを作り、OSで叩くしか無い

せっかくなのでRaspberryPIホストの電源ボタンと兼用してしまおう

GPIO3番は外部に物理プルアップ抵抗が付いているのでGPIOとGNDにボタンをつけるだけ以下の3つの機能が使えるようになる

・Raspberry Pi起動中に短押し→moonraker、klipperFW、klipperサービス再起動

(緊急停止させたプリンターが再起動する)

・Raspberry Pi起動中に長押し→MainsailOS(Raspberry Pi)のシャットダウン

・Raspberry Pi停止中に短押し→シャットダウン中のRaspberry Piを起動

作業はRaspberry PiにSSHで接続して行う

とりあえずMainsailOSにwiringpi をインストールする

(gpiodだけインストールすればいいのかもしれん)

sudo apt install wiringpi

ディレクトリの作成

mkdir button

 スクリプトファイルの作成

nano ~/button/gpio3_sw.sh

コードは次の通り

#!/bin/sh
GPIO=3 #使用するGPIOポート
PUSHTIME=60 #nagaosiカウント

## GPIO初期設定
gpio -g mode $GPIO in
gpio -g mode $GPIO up

## nagaosiされるまで待つ
cnt=0
while [ $cnt -lt $PUSHTIME ] ; do
if [ `gpio -g read $GPIO` -eq "0" ] ; then
cnt=`expr $cnt + 10`
[ $cnt -eq 1 ]
else
[ $cnt -gt 0 ] && service moonraker restart && sudo -u pi echo 'FIRMWARE_RESTART' | sudo -u pi tee /tmp/printer && sleep 1 && service klipper restart
cnt=0
fi
sleep 0.1
done

## シャットダウンコマンド
sudo shutdown -h now

実行権限付与

sudo chmod 755 ~/button/gpio3_sw.sh

サービスファイル作成

sudo nano /usr/lib/systemd/system/gpio3_sw.service

サービスファイルの内容

[Unit]
Description=Shutdown Daemon

[Service]
ExecStart =/home/pi/button/gpio3_sw.sh
Restart=always
Type=simple

[Install]
WantedBy=multi-user.target

サービス登録

sudo systemctl enable gpio3_sw.service

Raspberry Pi再起動

sudo reboot

これで3徳ボタンが完成した

参考サイト

https://sites.google.com/site/63rabbits05/rpi/gpio/shutdown_button

http://blog.livedoor.jp/victory7com/archives/42423877.html

https://qiita.com/clses/items/e701c1cb6490751a6040

3.klipperボタンをRaspberry Piにまとめる

本体MCUボードにklipperGコードボタンが付いて、Raspberry Piにファームウェアのリセットボタンができた

2ヶ所に別れたそれらをRaspberry PiのGPIO上に集約したい場合の話

物理配線

Raspberry PiのGPIOは

2、3は外部抵抗でプルアップされており

4〜8までは内部プルアップされており

9〜27までは内部プルダウンされている

らしい

参考サイト:https://hnw.hatenablog.com/entry/20150607

Raspberry Piで内部プルダウン抵抗を利用してみたが、MCUボード同様に意図せぬトリガーが発生して安定しなかった

GPIO3以外のボタンには10kΩの外部プルアップで回路を作りHATを作った


方法1

tmp/printerを叩く
たとえばPIユーザーで

echo G28 >> /tmp/printer

と入力すればプリンターのコンソールにG28コマンドを入力ときと同じ動作となる
serviceスクリプト上では

sudo -u pi echo 'G28' | sudo -u pi tee /tmp/printer

とすれば動く(リダイレクトだとパーミッションエラーになるからパイプで引き渡す)

gcode_macroを作ってマクロ名を指定すればgcode_macroが実行される

[gcode_macro RPI_button_1]
gcode: G28


echo RPI_button_1 >> /tmp/printer

さっき書いた3徳ボタンのスクリプトにボタンを追加するだけの話

(実も蓋もない話になってしまった)

gcodeマクロはMainsail上で自由に編集できるのでRaspberry Piの物理ボタンと対応するマクロ名さえ設定してしまえばいい

方法2

Raspberry PiをセカンダリMCUとしてklipperに設定すればRaspberry PiのGPIOにklipperGコードボタンを設置できる
公式リファレンス

https://www.klipper3d.org/RPi_microcontroller.html

この手順通りに作業すればいい
Raspberry PiホストをセカンダリMCUにできたら
klipper設定ファイルprinter.cfgへの次のように設定を書き足す
記述例

[mcu pi]
serial: /tmp/klipper_host_mcu

[gcode_button GPIO8]
pin: !pi:gpio8
press_gcode:

リファレンスにも書いてあるが
gpioinfoを叩いて指定したgpioが”klipper”に割り当てられていれば正しく設定されている

※余談
Raspberry PiのGPIOインターフェイスではプルアップ/プルダウン記号を書くとエラーになる

動作確認用Gコード
ボタン1、ファンを回転させる
ボタン2、ファンを止める
ボタン3、XYZホーミング
ボタン4、緊急停止
ボタン5、プリンタ再起動
おわり

コメント

このブログの人気の投稿

MoonrakerでSSRやスマートプラグを制御して3Dプリンタ本体電源と連動させる改造(Klipper、MainsailOS)

ホットエンド冷却性能比較

ヒートベッドの電流を外部MOSFETで分けてマザーボードへの電流負荷を分散させた