近接センサでRaspberryPi LCDのバックライトを点灯

Raspberry Pi 2に7インチタッチディスプレイをつけて、パッと見たい情報(天気予報とか時計とかバス時刻表とか)を表示するのに使っているのですが、常時つけっぱなしになっているのが気になっていました。周囲に人がいるときだけオンになったらいいなと思い、近接センサで一定範囲内(だいたい1.5m以内)に反応があった場合にバックライト点灯→しばらく反応がないと消灯するようにしました。


バックライトの制御コマンド

発売当初はバックライトON/OFFが制御できませんでしたが、最近のカーネルなら/sys/class/backlight/rpi_backlight/bl_power に0/1をwriteすることで ON/OFFができるようになっています(輝度変更は効きませんが)。また、XのDPMS (Energy Star)とも連動してON/OFFされます。今回は一定時間で消灯したいのと、タッチしたらONになって欲しいので、DPMSを使います。

Xが起動している状態で、

$ xset dpms force on
$ xset dpms force off

でバックライトのON/OFFが可能です。また、

$ xset dpms 120 120 120

とすると120秒間操作しないと自動でOFFになります。現在の状態確認はxset qを使います。

$ xset q
...
DPMS (Energy Star):
  Standby: 120    Suspend: 120    Off: 120
  DPMS is Enabled
  Monitor is Off

近接センサの接続

近接時の検出は以下の測距センサを使いました。距離に応じた電圧がアナログ出力されるものです。
シャープ測距モジュール GP2Y0A02YK: センサ一般 秋月電子通商 電子部品 ネット通販

Raspberry Piには直接アナログ入力することができないため、一旦Arduino Pro Miniを通して一定距離内に入った時にデジタルで信号を出力するようにしています。動画のRasPiの後ろで近接時にLEDが点灯しているのがArduino Pro Miniです。(別にデジタル変換はArduinoである必要は全くなく、ただのコンパレータでいいのですが、手持ちがなかったので。。)


上記のように接続してGPIOの17を読めば、近接検出ができます。GPIOへのアクセスは

# echo 17 > /sys/class/gpio/export

を実行しておき、

# cat /sys/class/gpio/gpio17/value

のようにすれば0または1として値を読み出すことができます。

近接センサでバックライト制御

以下のスクリプトでGPIOを定期的に監視し、近接時にxsetでバックライトの点灯させます。なお、点灯中にforce onしても無操作タイマーが更新されず、すぐに自動消灯してしまったりするので、近接中は定期的に時間を再設定することでタイマーをリスタートしておきます。

#!/usr/bin/perl
use Time::HiRes "sleep";
open my $in, "/sys/class/gpio/gpio17/value";
while (true) {
    seek $in, 0, 0;
    my $val = <$in>;
    if ($val == 1) {
        `xset dpms force on`;
        `xset dpms 120 120 120`;
        print "ON\n";
        sleep 60;
    } else {
        sleep 0.1;
    }
}