物理ボタンを付けてRaspberry Piを安全にシャットダウンする方法

物理ボタンを付けてRaspberry Piを安全にシャットダウンする方法

Raspberry Piの電源をオフする場合にUSB電源コードをそのまま引っこ抜くと、運が悪い場合はSDカード内のOSが壊れる可能性があります(私もその経験あります)。かと言って、SSHでログインして $ sudo shutdown -h now を毎回実行するのも非常に面倒です。

そこでRaspberry Piに物理ボタンを外付けして、安全にシャットダウンする方法をご紹介します。

はじめに

ここで紹介する手順は次のとおりです。

  1. Raspberry PiのGPIOピンに物理ボタンを設置
  2. ボタンを監視するPythonコードを作成
  3. ②をシステムサービスへ登録

記事の後半ではさらにLEDも追加して、Raspberry Piの電源オンオフ状態を分かりやすく工夫しました!ぜひ最後までご覧ください。

Raspberry Piに物理ボタンとLED追加
Raspberry Piに物理ボタンとLED追加

Raspberry PiのGPIOピンに物理ボタンを設置

押している間だけ導通するモーメンタリー型のスイッチを使用しました。

このスイッチをRaspberry PiのGPIO27(物理番号13)とGround(物理番号14)に繋ぎます。

Raspberry Piとスイッチの配線
Raspberry Piとスイッチの配線

物理ボタンをRaspberry Piに繋ぐ
物理ボタンをRaspberry Piに繋ぐ

ボタンを監視するPythonコード

次に、適当な場所に shutdown_by_button.py としてボタンを監視するPythonコードを作成します。

#!/usr/bin/env python

import RPi.GPIO as GPIO
import os, time

GPIO.setmode(GPIO.BCM)

GPIO.setup(27, GPIO.IN, pull_up_down = GPIO.PUD_UP) # GPIO27とGNDにボタンスイッチを繋ぐ

def shutdown(channel):
  os.system("sudo shutdown -h now")


GPIO.add_event_detect(27, GPIO.FALLING, callback = shutdown, bouncetime = 3000)

while 1:
  time.sleep(100)

上記プログラムの内容はGPIO.add_event_detect でGPIOのイベントを検知し、shutdown 関数を呼び出して sudo shutdown -h now を実行させています。

さて、 shutdown_by_button.py の権限を変更してrootユーザーがスクリプトを実行可能にしておきます。

$ chmod 755 shutdown_by_button.py

プログラムをシステムサービスへ登録

最後に、先ほど作った shutdown_by_button.py をシステムサービスへ登録してデーモンとして実行させます。

$ sudo vi /usr/lib/systemd/system/shutdown_by_button.service を実行し、下記の内容を書き込みます。

[Unit]
Description=Shutdown/Reboot raspberry pi by GPIO button input
Wants=network.target

[Service]
ExecStart=/home/pi/src/shutdown_by_button.py
Restart=on-failure
RestartSec=10s

[Install]
WantedBy=multi-user.target

続いてこの設定ファイルを反映させます。

$ sudo systemctl daemon-reload

スクリプトを開始させます。

$ sudo systemctl start shutdown_by_button

Raspberry Piの起動時にスクリプトが自動起動するように設定します。

$ sudo systemctl enable shutdown_by_button

こちらのコマンドでサービスの状態が問題ないか調べておきます。

$ sudo systemctl status shutdown_by_button
● shutdown_by_button.service - Shutdown/Reboot raspberry pi by GPIO button input
     Loaded: loaded (/lib/systemd/system/shutdown_by_button.service; enabled; v>
     Active: active (running) since Thu 2023-07-20 14:56:26 JST; 57s ago
   Main PID: 825 (python)
      Tasks: 2 (limit: 3933)
        CPU: 46ms
     CGroup: /system.slice/shutdown_by_button.service
             └─825 python /home/pi/src/shutdown_by_button.py

Jul 20 14:56:26 raspberypi systemd[1]: Started Shutdown/Reboot raspberry pi by >
...

サービスに登録されていることが確認できました。この画面は control + c で終了できます。以上ですべての設定が終わりました。

一度 $ sudo reboot してから物理ボタンでRaspberry Piの電源がオフされるか確かめてみましょう。しっかり反応させるためにもボタンスイッチを2、3秒押し続けてください。なお再び電源をオンにする場合は、USB-Cの電源コードを一度抜いてから再度挿してRaspberry Piを起動させてください。

【発展】LEDも付けてみる

Raspberry Piの基板に実装されている2つのLEDだけですと、電源が入っているのかどうか判断しずらいです。そこでGPIOを使ってLEDを取り付けてみました。Raspberry Piが起動するとLEDが点灯し、シャットダウンさせるとLEDが消灯します。先ほど作った shutdown_by_button.py に追記する形で簡単に実現できました。

下図のようにLEDを追加して配線します。電流制御用の抵抗は1kΩを使いました。

LEDを追加
LEDを追加

shutdown_by_button.py を次のように修正します。

#!/usr/bin/env python

import RPi.GPIO as GPIO
import os, time

# BCM(GPIO番号)で指定する設定
GPIO.setmode(GPIO.BCM)

GPIO.setup(27, GPIO.IN, pull_up_down = GPIO.PUD_UP) # GPIO27とGNDに物理ボタンを繋ぐ

# LED点灯用
GPIO.setup(17, GPIO.OUT)
GPIO.output(17, 1)

def shutdown(channel):
  os.system("sudo shutdown -h now")


GPIO.add_event_detect(27, GPIO.FALLING, callback = shutdown, bouncetime = 3000)

while 1:
  time.sleep(100)

こちらの動画のように、電源オンオフが目視で非常に分かりやすくなりました!とても便利です!

Raspberry Piに物理ボタンとLED追加
Raspberry Piに物理ボタンとLED追加

▶︎ 類似した記事を探す #Raspberry Pi初心者

この記事が参考になりましたら
シェアをよろしくお願いします!

人気のRaspberry Pi
人気のRaspberry Pi周辺機器
Raspberry Piのオススメ入門書
関連記事