WebサーバーとしてRaspberry Piを動かしているとたまにサーバーがダウンしてアクセスできなくなることがあります。
SSHからもアクセスできないため、いつもしかたなくUSB電源を引っこ抜きます。今までUSB電源引っこ抜きても問題はなかったのですが、精神的に気分が悪いのでRaspberry Piにシャットダウンとリブートボタンを設置することにしました。
シャットダウンとリブートボタンを設置した完成図
超適当に配線図を描きました。
押しボタンを長押し(3秒以上)するとシャットダウンになって、ポチっと押すとリブートになります。シャットダウンのときはLEDが赤く一瞬光ります。リブートのときはLEDが数秒赤く光り続けます。
材料
・タクトスイッチ(押しボタンスイッチ) 1個10円
・LED 1個10円
・抵抗 100オーム 2個で4円
・ミニブレッドボード 1個で100円
・ジャンパーケーブルか配線ケーブル 2本で10円
・ピンヘッダーか抵抗の足 2個で1円
材料費的には150円くらいでシャットダウンとリブートボタンをつけることができます。LEDと抵抗と配線ケーブル(またはジャンバーケーブル)だけ必須です。あとは手動でやれば何とかなりますが、タクトスイッチやミニブレッドボードはあったほうがいいです。
そんなこんなで組み上げたのが下記の写真です。
下のほうにあるブレッドボードにシャットダウンとリブートの押しボタンとLEDが設置してあります。小さいブレッドボードが品切れだったので、少し大きめなブレッドボードを使いました。
スイッチ側にある抵抗は比較的どんな数値でも大丈夫です。100オームから1kオーム以内の抵抗を入れておけばいいと思います。LED側にある抵抗は60オームから200オームの抵抗を入れておけば良いです。それで普通に光ります。
シャットダウンとリブートボタンのプログラム
参考サイト:Raspberry Pi shutdown/reboot button
参考サイトのプログラムにプルアップを設定して、スイッチを押したあとにLEDが光るようにしました。シャットダウンなら一瞬、リブートなら数秒光る感じになります。
押しボタンの入力用にGPIO6(Pin31)、LEDの点灯用にGPIO5(Pin29)を使いました。開いているGPIOを適当に使えばいいです。
シャットダウンとリブートボタンのプログラム
vim switch.py import RPi.GPIO as GPIO import time import os GPIO.setmode(GPIO.BCM) GPIO.setup(6,GPIO.IN,pull_up_down=GPIO.PUD_UP) GPIO.setup(5,GPIO.OUT) GPIO.output(5,GPIO.LOW) button_previous = 1 button_current = 1 brojac = 0 flag_pressed = 0 while True: button_current = GPIO.input(6) flag_pressed = button_previous + button_current if (not(flag_pressed)): brojac += 1 else: brojac = 0 if(button_current and (not button_previous)): GPIO.output(5,GPIO.HIGH) os.system("sudo shutdown -r now") if((not flag_pressed) and brojac >= 100): GPIO.output(5,GPIO.HIGH) os.system("sudo shutdown -h now") break button_previous = button_current time.sleep(0.03) GPIO.cleanup()
最後のGPIO.cleanup()はいらないんじゃないかと思ったりするけど、まぁ動くから放置です。
このプログラム(switch.py)を保存して実行します。
sudo python switch.py
押しボタンをポチッと押すとLEDが数秒点灯してリブートします。押しボタンを3秒間押し続けるとLEDが一瞬光ってシャットダウンします。
次に起動時に押しボタンプログラムが自動起動するように設定します。
何かプログラムを間違えている状態で自動起動を設定するとリブートまたはシャットダウンの無限ループに陥る可能性があるので、まず最初に手動で実行してから問題ないようなら自動起動の設定を行いましょう。ここ重要です! 念のためRaspberry PiのマイクロSDカードのバックアップも取っておくといいと思います。
自動起動の設定
sudo vim /etc/rc.local //exit 0の前に記載する sudo python /home/your_username/switch.py & exit 0
これで次からはスイッチプログラムは起動時に実行されるので手動で実行しなくてもOKです。
Raspberry Piにシャットダウンとリブートボタンを設置するのは若干面倒くさそうだなーと思っていましたが、実際にやってみると簡単にできました。
シャットダウンとリブートボタンのプログラムの別バージョン(割り込み)
while Trueでひたすらボタンが押されていないかをチェックし続けさせていましたが、割り込みを使うとチェックし続ける必要がなくなります。
たぶんこんな感じで動くプログラム
vim switch.py import RPi.GPIO as GPIO import time import os GPIO.setmode(GPIO.BCM) GPIO.setup(6,GPIO.IN,pull_up_down=GPIO.PUD_UP) GPIO.setup(5,GPIO.OUT) GPIO.output(5,GPIO.LOW) button_previous = 1 button_current = 1 brojac = 0 flag_pressed = 0 try: GPIO.wait_for_edge(6, GPIO.FALLING) while True: button_current = GPIO.input(6) flag_pressed = button_previous + button_current if (not(flag_pressed)): brojac += 1 else: brojac = 0 if(button_current and (not button_previous)): GPIO.output(5,GPIO.HIGH) os.system("sudo shutdown -r now") if((not flag_pressed) and brojac >= 100): GPIO.output(5,GPIO.HIGH) os.system("sudo shutdown -h now") break button_previous = button_current time.sleep(0.03) except KeyboardInterrupt: GPIO.cleanup() GPIO.cleanup()
実際にチェックはしていませんが、たぶんこれで動くと思います。
ずっとwhileループをさせるよりも割り込みの方が負荷が少ないと思うので、負荷を減らしたいときなんかは割り込み用のプログラムを試してみてください。
再掲(“さいかつ”ではなく”さいけい”)
スイッチプログラムは何か間違えている状態で自動起動を設定してしまうとリブートまたはシャットダウンの無限ループに陥る可能性があります。
まず自動起動を解除(コメントアウト)して、最初に手動で実行してから問題ないようなら自動起動の設定を行いましょう。ここ重要です!
念のためRaspberry PiのマイクロSDカードのバックアップも取っておくといいと思います。
楽しく拝見させて頂いております。
私もラズパイでWEBサーバーを立ち上げようとしているのですが、
WEBサーバーが落ちる現象というのは頻発するものなのでしょうか?
またその原因はわかっていますでしょうか?
記事からはずれた質問になりますが、
よろしければご回答よろしくお願いします。
1台のPi2でサイトを5月初旬から2つ動かすようになってから、それから3回くらいサイトがダウンしました。サイト1つのときはサーバがダウンすることはほとんどなかったのですが、2つにすると調子が少し悪くなる感じがします。lighttpdの設定が甘くてメモリーを使い切ったのか、xmlrpc.phpへのPost攻撃か、他には何でしょう?
もう少し悪化したら原因を探し出そうかなと思います。
サイト1つだけならたぶん大丈夫だと思います。
Swapを切った状態でメモリー不足になると、Raspberry Piがフリーズする気がします。もともとメモリーをたくさん使っていたのですが、最近Pythonのプログラムをループで長時間動かしたのが、サーバーが落ちる最後の一押しになっている可能性が非常に高いです。