Python
RaspberryPi

ラズパイでシャットダウンボタンを付ける(ついでに起動ボタン)

More than 1 year has passed since last update.


■動機

自分はラズパイ開発はMacからSSH接続で行っていて、かつ同一ネットワークのwifi接続なので電源のみの接続で開発できている。

開発しているときは良いものの、外出時にMac持ち運んだ時とか、寝落ちした時とか、

ラズパイが起動したままSSH接続が切れているときがよくある。

そんな時、ラズパイのシャットダウンのためだけにPC起動するのも面倒だし、かと言って電源ぶつ切りもシステム壊れそうでやりたくない・・・

そんなわけで、PCを起動しなくてもラズパイ本体だけでシャットダウンさせたかった。

探してみると、ボタン一個あればできるみたいなので挑戦。

やることは、

1. ピンの入力状態を変えるボタンを接続

2. シャットダウンするプログラムを作成

3. 2をラズパイ起動時に自動起動して、バックグラウンドで動作するサービスとして登録

という感じ。

3の自動起動は、昔は/etc/rc.localというのを使っていたらしいが、

最近はsystemdというのを使うのが主流になってきているらしいので、

今回はsystemdを使うことにする。


■参考サイト

RaspberryPiにshutdownボタンを付けよう

Raspberry Pi 3 にシャットダウン/リブート/再開ボタンを追加する

Raspbian jessieでSystemdを使った自動起動

毎度先達には感謝ばかりです。探せば絶対誰かやってるからなぁ・・・


■初期状態確認

GPIOのピン状態を確認。

初めて出したけど、きれいに整形している。

pi@raspberrypi:~ $ gpio readall

|-----|-----|---------|------|---|-Pi ZeroW-|---|------|---------|-----|-----|
| BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |
|-----|-----|---------|------|---|----------|---|------|---------|-----|-----|
| | | 3.3v | | | 1 || 2 | | | 5v | | |
| 2 | 8 | SDA.1 | ALT0 | 1 | 3 || 4 | | | 5v | | |
| 3 | 9 | SCL.1 | ALT0 | 1 | 5 || 6 | | | 0v | | |
| 4 | 7 | GPIO. 7 | IN | 1 | 7 || 8 | 1 | ALT5 | TxD | 15 | 14 |
| | | 0v | | | 9 || 10 | 1 | ALT5 | RxD | 16 | 15 |
| 17 | 0 | GPIO. 0 | IN | 0 | 11 || 12 | 1 | OUT | GPIO. 1 | 1 | 18 |
| 27 | 2 | GPIO. 2 | IN | 0 | 13 || 14 | | | 0v | | |
| 22 | 3 | GPIO. 3 | IN | 0 | 15 || 16 | 0 | IN | GPIO. 4 | 4 | 23 |
| | | 3.3v | | | 17 || 18 | 0 | IN | GPIO. 5 | 5 | 24 |
| 10 | 12 | MOSI | ALT0 | 0 | 19 || 20 | | | 0v | | |
| 9 | 13 | MISO | ALT0 | 0 | 21 || 22 | 0 | IN | GPIO. 6 | 6 | 25 |
| 11 | 14 | SCLK | ALT0 | 0 | 23 || 24 | 1 | OUT | CE0 | 10 | 8 |
| | | 0v | | | 25 || 26 | 1 | OUT | CE1 | 11 | 7 |
| 0 | 30 | SDA.0 | IN | 1 | 27 || 28 | 1 | IN | SCL.0 | 31 | 1 |
| 5 | 21 | GPIO.21 | IN | 1 | 29 || 30 | | | 0v | | |
| 6 | 22 | GPIO.22 | IN | 1 | 31 || 32 | 0 | IN | GPIO.26 | 26 | 12 |
| 13 | 23 | GPIO.23 | IN | 0 | 33 || 34 | | | 0v | | |
| 19 | 24 | GPIO.24 | ALT4 | 0 | 35 || 36 | 1 | OUT | GPIO.27 | 27 | 16 |
| 26 | 25 | GPIO.25 | IN | 0 | 37 || 38 | 0 | ALT4 | GPIO.28 | 28 | 20 |
| | | 0v | | | 39 || 40 | 0 | ALT4 | GPIO.29 | 29 | 21 |
|-----|-----|---------|------|---|----------|---|------|---------|-----|-----|

BCM 23 をIN、UPに設定してみる。

pi@raspberrypi:~ $ gpio -g mode 23 in

pi@raspberrypi:~ $ gpio -g read 23
0
pi@raspberrypi:~ $ gpio -g mode 23 up
pi@raspberrypi:~ $ gpio -g read 23
1

pi@raspberrypi:~ $ gpio readall
+-----+-----+---------+------+---+-Pi ZeroW-+---+------+---------+-----+-----+
| BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |
+-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
| | | 3.3v | | | 1 || 2 | | | 5v | | |
| 2 | 8 | SDA.1 | ALT0 | 1 | 3 || 4 | | | 5v | | |
| 3 | 9 | SCL.1 | ALT0 | 1 | 5 || 6 | | | 0v | | |
| 4 | 7 | GPIO. 7 | IN | 1 | 7 || 8 | 1 | ALT5 | TxD | 15 | 14 |
| | | 0v | | | 9 || 10 | 1 | ALT5 | RxD | 16 | 15 |
| 17 | 0 | GPIO. 0 | IN | 0 | 11 || 12 | 1 | OUT | GPIO. 1 | 1 | 18 |
| 27 | 2 | GPIO. 2 | IN | 0 | 13 || 14 | | | 0v | | |
| 22 | 3 | GPIO. 3 | IN | 0 | 15 || 16 | 1 | IN | GPIO. 4 | 4 | 23 |
| | | 3.3v | | | 17 || 18 | 0 | IN | GPIO. 5 | 5 | 24 |
| 10 | 12 | MOSI | ALT0 | 0 | 19 || 20 | | | 0v | | |
| 9 | 13 | MISO | ALT0 | 0 | 21 || 22 | 0 | IN | GPIO. 6 | 6 | 25 |
| 11 | 14 | SCLK | ALT0 | 0 | 23 || 24 | 1 | OUT | CE0 | 10 | 8 |
| | | 0v | | | 25 || 26 | 1 | OUT | CE1 | 11 | 7 |
| 0 | 30 | SDA.0 | IN | 1 | 27 || 28 | 1 | IN | SCL.0 | 31 | 1 |
| 5 | 21 | GPIO.21 | IN | 1 | 29 || 30 | | | 0v | | |
| 6 | 22 | GPIO.22 | IN | 1 | 31 || 32 | 0 | IN | GPIO.26 | 26 | 12 |
| 13 | 23 | GPIO.23 | IN | 0 | 33 || 34 | | | 0v | | |
| 19 | 24 | GPIO.24 | ALT4 | 0 | 35 || 36 | 1 | OUT | GPIO.27 | 27 | 16 |
| 26 | 25 | GPIO.25 | IN | 0 | 37 || 38 | 0 | ALT4 | GPIO.28 | 28 | 20 |
| | | 0v | | | 39 || 40 | 0 | ALT4 | GPIO.29 | 29 | 21 |
+-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
| BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |
+-----+-----+---------+------+---+-Pi ZeroW-+---+------+---------+-----+-----+


■配線

UNADJUSTEDNONRAW_thumb_10fe.jpg

ボタンを押したらBCM23番PINがGNDにつながるだけ。

(緑のケーブル。青ケーブルは一番下で解説)

(右側のケーブルの束はI2CのセンサやらLCDなので関係なし)

■動作確認。

#ボタンを離した状態

pi@raspberrypi:~ $ gpio -g read 23
1

#ボタン押した状態
pi@raspberrypi:~ $ gpio -g read 23
0

HIGHからLOWに落とす条件にしているので、

ボタンを押していない状態で1(HIGH:3.3V)、

ボタンを押した状態で0(LOW:GND)となっているのできちんと認識している様子。


■シャットダウンのプログラムを作成

ピン番号以外は完全コピペです。RaspberryPiにshutdownボタンを付けよう


/home/pi/pyhome/shutdownd.py

#!/usr/bin/python 

# coding:utf-8
import time
import RPi.GPIO as GPIO
import os

pinnumber=23
GPIO.setmode(GPIO.BCM)

#GPIO23pinを入力モードとし、pull up設定とします
GPIO.setup(pinnumber,GPIO.IN,pull_up_down=GPIO.PUD_UP)

while True:
GPIO.wait_for_edge(pinnumber, GPIO.FALLING)
sw_counter = 0

while True:
sw_status = GPIO.input(pinnumber)
if sw_status == 0:
sw_counter = sw_counter + 1
if sw_counter >= 50:
print("長押し検知!")
os.system("sudo shutdown -h now")
break
else:
print("短押し検知")
break

time.sleep(0.01)

print(sw_counter)


作成後にsudo chmod 755 Lchika.pyで権限付与も忘れずに。


■サービスファイルを作成

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

で以下を作成。


/usr/lib/systemd/system/shutdownbuttond.service

[Unit]

Description=Shutdown Daemon

[Service]
ExecStart =/home/pi/pyhome/shutdownd.py
Restart=always
Type=simple

[Install]
WantedBy=multi-user.target


■サービス有効化(これやらないと自動起動しないので重要)

pi@raspberrypi:~ $ systemctl enable shutdownbuttond.service

■デーモン再起動

sudo systemctl daemon-reload


■サービスが有効になっているか確認

systemctl status shutdownbuttond.serviceにてステータスが見れる

○成功時

pi@raspberrypi:~ $ systemctl status shutdownbuttond.service

● shutdownbuttond.service - Shutdown Daemon
Loaded: loaded (/usr/lib/systemd/system/shutdownbuttond.service; enabled)
Active: active (running) since 日 2017-10-08 19:25:47 JST; 4min 57s ago
Main PID: 1442 (shutdownd.py)
CGroup: /system.slice/shutdownbuttond.service
└─1442 /usr/bin/python /home/pi/pyhome/shutdownd.py

↑ で(/usr/lib/systemd/system/shutdownbuttond.service; enabled)

active (running)になっていれば起動しているはず。

×失敗時

disable,failedになっている。

このときはファイル名とか間違ってた。

pi@raspberrypi:~ $ systemctl status shutdownbuttond.service

● shutdownbuttond.service - Shutdown Daemon
Loaded: loaded (/usr/lib/systemd/system/shutdownbuttond.service; disabled)
Active: failed (Result: start-limit) since 日 2017-10-08 18:41:09 JST; 1min 30s ago

確認方法としては以下で全サービスを出すのもあり。Activeとして載っていればOK。

systemctl -t service

これにて、ボタンを0.5秒程度押すと自動でシャットダウンできるようになった。


■シャットダウン時から起動もさせられる!

Raspberry Pi 3 にシャットダウン/リブート/再開ボタンを追加する

こちらのサイトでは、シャットダウン時からの起動にも触れている。

左の上から3番目(BCM3、SCL)のピンをGNDに落とすとシャットダウン時から起動できるらしい。

コマンドでシャットダウンすると、USBケーブル抜かないと行けないから煩わしいと思っていたのだけど、抜き差しせずに起動できるのは助かる。

上の配線写真の、手前青い線がBCM3=SCLにつながっている。(I2Cで使っているので、そちら側から分岐させて持ってきた)

結果的に一個のボタンで、

起動時は長押しでシャットダウン、

停止時(かつ電源接続時)は短押しで起動

ができるようになった。