ラズパイに長押しでシャットダウンをするボタンを付けてみた | そう備忘録

ラズパイに長押しでシャットダウンをするボタンを付けてみた

ラズパイのシャットダウン

ラズパイは Linux OS の為、いきなり電源をオフにすることは出来ない。

ssh で接続するかキーボードとモニターを接続して shutdown コマンドで OS を終了させる必要がある。

しかし IoT用に製造現場に設置したラズパイは必ずしもきちんと shutdown をして貰える訳ではない。

ラズパイに Shutdown 用のボタンを追加したのでその時の事を備忘録として記事にしておく。

ラズパイにシャットダウンボタンを付けた

ボタンについて

機能

  • ボタンをうっかり触ってしまった時に Shutdown されない様に “長押し” した時だけ Shutdown する様にした
  • LED ライト付きのボタンを選択した
  • プログラム起動中はボタンの LED ライトを点灯、長押しで Shutdown した時に消灯するようにした

型番

オムロンの押ボタンスイッチ(型番=A165L-JRM-5D-1)を購入した。

型番の意味は以下の通り。

A16

ボタンの種類(型)を表す。

5

防水や保護のIP規格の等級を表す。

  • なし:IP40(ワイヤーなどからの保護、水の浸入に対しては保護されていない)
  • 5:IP66(粉塵の侵入が完全に防護されている、いかなる方向からの水の強い直接噴流によっても有害な影響を受けない)

L

照光タイプかどうかを表す。

  • なし:非照光
  • L:照光

LEDライト付きのボタンが欲しかったので照光タイプを選択した。

J

ボタンの形を表す。

  • J:長方形
  • A:正方形
  • T:丸形

R

ボタンの色を表す。

  • R:赤
  • Y:黄
  • PY:ピュアイエロー
  • G:緑
  • W:白
  • A:青
  • PW:ピュアホワイト
  • B:黒(非照光のみ)

M

押した時のボタンの動作を表す。

  • M:モメンタリ(ボタンを押している時だけオンになる)
  • A:オルタネイト(ボタンを押して離した後もオン状態を保持する)

5D

LEDの電圧を表す。

  • なし:非照光
  • 5D:DC5V
  • 12D:AC/DC12V
  • 24D:AC/DC24V

1

端子配列を表す。

回路的にはa接点で良かったのだが手に入ったのがc接点のボタンだったので接点が1つだけあるタイプのボタンを選択した。

  • 1:1c(はんだ付け端子)
  • 2:2c(はんだ付け端子)
  • 1P:1c(プリント基板端子)
  • 2P:2c(プリント基板端子)
  • 2S:2C(クイックコネクタ)

1c の端子配置は以下の通り(オムロンマニュアルより)

端子配置

配線図

NCは使用してない。

実質a接点のボタンとして使用している。

押しボタンスイッチによるシャットダウン配線図

試した環境

今回、以下の環境でテストした。

ラズパイ

Raspberry Pi 4B

OS

Raspberry Pi OS 32Bit

プログラム

以下のプログラムを .local/shutdown_test に保存した。

ソースコード

shutdown_button.py

# -*- coding: utf-8 -*-
"""
Created on Sat Jun  5 08:24:26 2021

・ボタン長押しでシャットダウン
・プログラム稼働中はLED点灯、シャットダウン時に消灯

@author: Souichirou Kikuchi
"""

import os
import RPi.GPIO as GPIO
from time import sleep

PIN_BUTTON_LED = 4 # ボタンのLED
PIN_BUTTON_SD = 22 # シャットダウンボタン

def shut_down(channel): # ボタン長押しでシャットダウン
    if channel == PIN_BUTTON_SD:
        sw = 0
        for _ in range(15):
            sleep(0.2) # 0.2秒 × 15回 = 3秒
            sw = GPIO.input(channel)
            if sw == 0: # 15回中1回でもLOWがあればシャットダウンしない
                break
        if sw == 1:
            GPIO.output(PIN_BUTTON_LED, GPIO.LOW) # ボタンのLED消灯
            os.system('sudo shutdown -h now') # シャットダウン

GPIO.setmode(GPIO.BCM)
GPIO.setup(PIN_BUTTON_LED, GPIO.OUT)
GPIO.setup(PIN_BUTTON_SD, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.add_event_detect(PIN_BUTTON_SD, GPIO.RISING, callback=shut_down, bouncetime=200)

if __name__ == "__main__":
    try:
        print('ShutDown Test Program Start') # プログラム開始
        GPIO.output(PIN_BUTTON_LED, GPIO.HIGH) # ボタンのLED点灯
        while True:
            sleep(0.001)
    except:
        pass
    finally:
        GPIO.cleanup()
        print('ShutDown Test Program End') # プログラム終了

補足説明

プログラム中にコメントを入れているが少しだけ補足しておく。

GPIO.setup(PIN_BUTTON_SD, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

はボタンの NO から接続された GPIO22 なのだが pull_down抵抗を指定している。

pull_down抵抗については以前の記事を参照して欲しい。

また、

GPIO.add_event_detect(PIN_BUTTON_SD, GPIO.RISING, callback=shut_down, bouncetime=200)

では、同じく GPIO22 の電圧がLOWからHIGHに上がった(RISING)した際にshuto_down関数を呼ぶ指定を行っている。

電圧は一直線に上昇しないので何度も shut_down関数を呼ばれないようにbouncetime=200 で次回呼ばれるまで200ミリ秒の間隔を空けている。

詳細は以前の記事を参照して欲しい。

実行結果

以下のコマンドでプログラムを実行する。

cd ~/.local/shutdown_test
python shutdown_button.py
シャットダウンのテストプログラムの実行

LEDが点灯するので長押し(約3秒)するとシャットダウンする事が確認できた。

ボタンの長押しでOSのシャットダウン

終わりに

以上で今回のボタンによるシャットダウンの記事は終了とする。

尚、そもそも何故ラズパイ(Linux)をいきなりシャットダウン出来ないのかというと、 OS 動作中にはSDカードに様々な OS で使用するファイルの書き込みを行っている。

ファイルの書き込み中にいきなり電源オフをしてしまうとそれらのファイルが破損してしまうことがあり、次回の OS の起動時に影響を与えて起動できない可能性が出てくる。

この為の対策として今回は「シャットダウンボタンをつける」という方法を記事にしたが、その他には

  1. ファイルシステムをRead Only(読み込み専用)にする
  2. リレー回路で OS シャットダウンまで猶予を与える

等の方法もある様なのでそのうち試してみたいと思っている。

最後に

この記事が何処かで誰かの役に立つことを願っている。

尚、当記事中の商品へのリンクはAmazonアソシエイトへのリンクが含まれています。Amazonのアソシエイトとして、当メディアは適格販売により収入を得ていますのでご了承ください。

souichirou

やった事を忘れない為の備忘録 同じような事をやりたい人の参考になればと思ってブログにしてます。 主にレゴ、AWS(Amazon Web Services)、WordPress、Deep Learning、RaspberryPiに関するブログを書いています。 仕事では工場に協働ロボットの導入や中小企業へのAI/IoT導入のアドバイザーをやっています。 2019年7月にJDLA(一般社団法人 日本デイープラーニング協会)Deep Learning for GENERALに合格しました。 質問は記事一番下にあるコメントかメニュー上部の問い合わせからお願いします。

おすすめ

質問やコメントや励ましの言葉などを残す

名前、メール、サイト欄は任意です。
またメールアドレスは公開されません。