Raspberry Pi 電源をシャットダウンする

当サイトのPC環境は99.9%Raspiで運用しています。Win10ノートも1台ありますが電源を入れるときは充電とアップデートがほとんどです。

Raspberry Piも立派なLinuxマシンですのでpoweroff(shutdown)で終了するのですがPi自体は赤いLedが点灯したままです。通常はスイッチ付きコンセントでオフにしていますが、これは大した手間では無いのですがどうもこの一手間が気に入りません。
なんとか通常のPC同様shutdown後はPi自体の電源もオフにしてみたいと思います。

といってもPi自体の電源を落とすので外部からの制御及びその電源が必要になります。
制御にはAVRを電源はオーディオ用に携帯充電器を使用しているのでこれを常時稼働させることにします。また電源OFFのタイミングを計るためPiにも設定を加えます。

環境

raspberry pi 3 2017-08-16-raspbian-stretch
GPIOの仕様はすべて共通のためPiであれば同様に動作すると思います。
余談
8月16日はDebian Day(24周年)ということみたいですね。
Raspberry Piの成功は一重にraspbian=debianの成果といっても過言ではないと思います。8月16日のリリースとはなかなか粋な計らいではないでしょか。

回路

今回はAC100Vを直接制御します。感電、ショート、落雷には充分注意して作業することにします。(ブレーカーを落とすと稀に雷(親父)が落ちることがあります)

AC100Vの制御は秋月のSSRキットを参考にしました。
制御回路にはattiny13a-pu(8pin DIP)を用いPiのGPIO端子(2端子)を監視します。
PiのGPIOはshutdown後はデフォルトに戻るという特性を利用して電源オフのタイミングを計ります。
タクトSWは1クリックで電源ON、長押しで電源OFF(ハングアップ時の強制終了)
通常の電源OFFはPiのシャットダウンコマンドを実行、正常終了後に実行します。
またPi側にも設定が必要なため新規インストールや設定のないカード使用時はジャンパーピンを切り替えて今までどおりの常時ONとすることにします。


ACラインの回路はSSRキットそのものですがZNRの代わりに電源用セラミックコンデンサを取り付けています。今回は誘導性の負荷はないため問題ないと思います。
AVRはPiとI/Oをとるため3.3Vで駆動しています。
LED D3(赤)点灯電源ON
LED D4(緑)点灯電源3.3V
確認、テストで使用します。


壊れたカーステのヒートシンクを切り出して使いましたが当サイトの環境ではほとんど発熱はみられませんでした。モニターの消費電力次第ですが簡単な放熱器(もしくは無し)でも充分と思います。


Pi側には下駄を作成して履かせます。その上にスイッチモジュールを載せています。(直挿しにスイッチモジュールを作成してもOK)
GPIOは物理ピンの33と40を使用(使いやすいピンで)
LED D5は起動時GPIO33をHにして点灯
GPIO40はreboot時の制御で使用

#下駄がうまく作成できるようになればハンダーマン、ソルダーウーマンの仲間入りです!

Piの設定

今回のstretchにはWiring Piが含まれていないのでインストールします。(パッケージがありましたね)

# apt install wiringpi

/etc/rc.local編集

-- snip --
fi
gpio -1 mode 33 out
gpio -1 write 33 1
gpio -1 mode 40 out
gpio -1 write 40 1
exit 0
# systemctl daemon-reload
# systemctl restart rc.local


$ gpio readall

起動時にrc.localが読み込まれGPIOの設定が適用されるタイミングはスプラッシュスクリーンが表示された直後位、LEDが点灯します。それまでは電圧なしとなります。
shutdownコマンドを実行、正常に終了するとLEDが消灯、その後数秒SDカードにアクセスがあります。
AVRはGPIO33ピンの値を検出してパワーオフの実行を開始します。

さてreboot時ですがやはりrebootの際もGPIO33ピンは一旦ローになってしまいます。AVRはshutdownかrebootかは判断がつきません。そのため何らかの方法でAVRにrebootだよシグナルを送ってやる必要があります。(デフォルトのプログラムでrebootを実行するとパワーオフします)
poweroff-helper
このダイアログはwheezyからjessie初期まで使われていたzenityを利用したshutdownプログラムです。
こちらはスクリプト形式になっているので条件を付加することができます。
stretchでも問題なく動作します。

sudo rebootの前に1行追加してやります。

gpio -1 write 40 0
sudo reboot


ファイル名はpoweroff-helper 実行権限を付けて保存します。(ユーザーのホームディレクトリでもOK)当方ではopenboxの右クリックメニューに登録していますがメニューエディタで登録してディスクトップにも追加可能です。

$ chmod a+x poweroff-helper

プログラム

プログラムの作成、書き込みもPiで実行するためライブラリをインストールします。(AVR自体への書き込みは別途書込器が必要です)

# apt install gcc-avr avr-libc avrdude

プログラム(pi3-shutdown.c) 拡張子はtxtにしています。
プログラムは100msのタイマーで割り込み処理していますが計算とあいません。(・・;)計算式間違えてるかも
内蔵RCは誤差もあるのでTCNT0の値を調整します。(実測で合わしてます)
Pi shutdown時のGPIOの電圧なし(L)はGNDレベルではなくフロート状態と思いますのでAVRのPB1,PB2入力はプルアップできません。
基本はGPIO 33番ピンの値を監視しているだけですが微妙にタイミングをとってやる必要があります。
変数(status)を用意して想定される動作を書いています。
status 0 デフォルト
status 1 sw1クリックでパワーオン
status 2 GPIO33がHになるまで約15秒前後+αの時間稼ぎ(60秒 この間GPIO見ない)
status 3 監視(運転)モード GPIO40 L検出でstatus 1へ
status 4 GPIO33 L検出で8秒後パワーオフ
status 5 sw1を3秒長押しで強制オフ
raspbianのshutdownはデバイスをアンマウントできなかった時など90秒待ってからshutdownを開始します。GPIO33番ピンがLになればパワーオフしますが2分経過してもGPIO33 Lにならない時はハングアップしている可能性が高いと思われます。
時間稼ぎの60秒はしばらく様子をみて変更の可能性もあります。

プログラムをビルドしてAVRに書込をします。(書込器はusbaspを使っています)

$ avr-gcc -mmcu=attiny13 -Wall -Os pi3-shutdown.c
$ avr-objcopy -O ihex -R .eeprom a.out pi3-shutdown.hex

AVRへの書込(書込は5VでOK)

$ avrdude -p t13 -c usbasp -U flash:w:pi3-shutdown.hex:a

確認、テスト

AC制御ラインのテスト(感電注意
入力にAC100V、出力に通電の確認できる機器を接続します。(テーブルタップが便利)
基板に5Vを加えるとLED(緑)点灯、ジャンパーピンを差し替え3.3VをON-OFFすることでAC100Vの制御を確認します。

AVR制御基板のテスト
AC100Vラインは危険なので外しておきます。Piと基板を接続、一連の動作はLEDの動作で確認することができます。(5VはPiから利用)(ジャンパーピンはAVR)
Piを起動、基板のLED(緑)点灯 3.3V OK
SW1クリック 基板のLED(赤)点灯 PB3 H OK
15秒前後でSWモジュールのLED点灯 GPIO33 H OK
起動後shutdown実行 SWモジュールのLED消灯 GPIO33 L
8秒後 基板のLED(赤)消灯 PB3 L OK
再起動、同様reboot実行 基板のLED(赤)点灯のまま OK
SW1長押し 基板のLED(赤)消灯 PB3 L OK


テストがOKだったら基板を適当なケースに収めてPiに取り付けます。(貼り付け)

ジャンパーピンによる常時稼働の切り替えは感電の危険があるためケースの外側に小型のスライドスイッチを設けています。
AVRのリセットスイッチも取り付けていますが特に必要ありません。


AVRの待機消費電流は10mA位、オーディオを含めると18mA位と効率を考えてもそれほどでもないと思います。
長時間使用しない時はこれまで通りコンセントスイッチで切っておきます。

コマンドラインからのshutdownは同じように動作しますがrebootはGPIO40をLにしてからrebootを実行します。

$ gpio -1 write 40 0 | sudo reboot

快適なPi3ディストップ環境になりました。