Raspberry Piには電源ボタンがありません。起動するにはMicro USBの電源コードを挿すだけでよいため、電源ボタンがなくても特に不自由することはありません。しかし電源を切る際、いきなりMicro USBの電源コードを抜くと、メモリカードのデータが壊れてしまう可能性があります。そのため電源を切る際は、シャットダウンコマンドを実行しなくてはなりません。

shutdown-btn-ledそこで今回は、電源を切るためのボタンを作ってみます。電源ボタンは写真のようにGPIOポートに接続しました。DOS/Vパソコン用のリセットボタンを使ってもかまいません。
ボタン入力はGPIO22を使用し、ボタンが押されたらGPIO22に3.3Vを加えるようにします。

【接続例】
[PIN15] GPIO22 ---- ボタン ---- [PIN17] +3.3V
Raspberry Pi内部のプルダウン抵抗を使用しているため、ボタンにはプルダウン抵抗を接続していません。WiringPIのmodeオプションの引数にdownを指定すると、内部のプルダウン抵抗が有効になります。upとすればプルアップ、offとすれば無効になります。

電源ボタンは軽く触れただけでは作動しないように、5秒以上押し続けないと作動しないようにします。これを制御するプログラムは、以下のシェルスクリプトで行います。

【サンプルスクリプト】shutdown-daemon2.sh
#!/bin/sh
GPIO=22     #使用するGPIOポート
PUSHTIME=5  #シャットダウンを実行する秒数

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

## ACT LEDの制御
set_led_mode () {
  echo $1 > /sys/class/leds/led0/trigger
}
set_led_value () {
  echo $1 > /sys/class/leds/led0/brightness
}

## 5秒間押されるまで待つ
cnt=0
while [ $cnt -lt $PUSHTIME ] ; do
  if [ `gpio -g read $GPIO` -eq "1" ] ; then
    cnt=`expr $cnt + 1`
    [ $cnt -eq 1 ] && set_led_mode heartbeat
  else
    [ $cnt -gt 0 ] && set_led_mode mmc0
    cnt=0
  fi
  sleep 1
done

## シャットダウンの合図(LED)
set_led_mode none
set_led_value 1
sleep 2
set_led_value 0
set_led_mode mmc0

## シャットダウンの実行
shutdown -h now

こ のスクリプトでは、まずはじめにGPIO22を入力ポートとして使用するための初期設定を行います。次にボタンが5秒間押されるまで繰り返すループがあり ます。ここではGPIO22の状態を読み込んで、ボタンが押されていたらカウンターの値を+1します。1秒待機して再びGPIO22の状態を読み込みま す。これを繰り返して5秒になるまで待機しています。もしボタンを途中で離してしまった場合は、カウンターは0に戻ります。5秒以上押した場合はこのルー プを抜けますので、その下のシャットダウンコマンドが実行されるという仕組みです。

またボタンを押してからシャットダウンするまで、実際 に動作しているのかをわかりやすくするため、ACT LEDを光らせるようにしました。ボタンを押して1秒以上たつと「チカチカ…チカチカ」と光り、5秒以上押してシャットダウンの体勢に入ると2秒間点灯し ます。そしてシャットダウンが始まると、通常通りメモリカードの読み書きに応じて光るようになります。



実 はACT LEDはコマンドラインから簡単に制御することができます。/sys/class/leds/led0/trigger をcatコマンドで見ると、mmc0が [] で囲われています。これは現在、ACT LEDをメモリカードの読み書きに応じて光らせるようになっていることを意味します。
$ cat /sys/class/leds/led0/trigger
none [mmc0] timer oneshot heartbeat backlight gpio cpu0 default-on
heartbeatモード(心臓の鼓動)にすると、「チカチカ…チカチカ」と点滅します。スーパーユーザーで実行する必要があります。
# echo heartbeat > /sys/class/leds/led0/trigger
またLチカのように、任意にON/OFFさせることもできます。
# echo none > /sys/class/leds/led0/trigger
# echo 1 > /sys/class/leds/led0/brightness
# echo 0 > /sys/class/leds/led0/brightness
元に戻すには mmc0モードにします。これでメモリカードの読み書きに応じて点滅するようになります。
# echo mmc0 > /sys/class/leds/led0/trigger
このように簡単に制御できるので、状態の確認用としてACT LEDを使うのも便利です。


それでは実際にプログラムをインストールしてみましょう。スクリプトを保存したら、実行できるようにパーミッションを設定します。
$ chmod 755 shutdown-daemon2.sh
起動時にこのスクリプトが実行されるように、/etc/rc.local に以下の行を追加します。(スクリプトを/home/pi/の下に置いた場合の例です)このファイルの編集はスーパーユーザーで行います。
# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
  printf "My IP address is %s\n" "$_IP"
fi

/home/pi/shutdown-daemon2.sh &
exit 0

Raspberry Piを再起動すれば、自動的にこのスクリプトがバックグラウンドで走り続けます。最後の & を付け忘れると起動処理がここで止まってしまいますので、& を付け忘れないように気をつけてください。

これで、電源ボタンを押すだけでシャットダウンできるようになりました。ディスプレイやキーボードを接続せずに使用している場合など、本体側で電源が切れるようになると便利です。


※この記事は2013年10月に書いた記事『ボタン長押しでシャットダウンする電源ボタンを作ろう』に、ACT LEDの点滅機能を加えたものです。