Raspberry PiとWebIOPiでセンサを使ってみる

webiopi-2

前回まででWebIOPi+motion+Bootstrapで基本的なライブ配信のWebUIまでは整えたので、もう少し便利になるように、諸々のセンサのセンシング結果を表示するようにしたいと思います。

 今回用意したのは以下の3つです。

できるだけ配線をスッキリさせたかったので、温度センサと照度センサはI2C接続のものを選んでいます。ということで、まずI2Cを使えるようにします。

$ sudo raspi-config
# 8. Advanced Options -> A7 I2C で利用可能に設定
$ sudo apt-get update
$ sudo apt-get install i2c-tools

 以上。早速接続して使ってみましょう。

 th_webiopi-3

うーん、とてもbusyになってきました。I2Cにしてなかったらアウトだったかも。まだ何の準備もできていないTWE-Liteがブレッドボードのスペースの半分を占めていますが、これはこの後きっと役に立ってくれる … ハズ。

実際の接続とは多少異なりますが、論理的(?)には、以下のような接続になっています。

webiopi

人感センサの接続がこれで本当にいいのか疑問ですが、一旦はこれで。

とりあえず、I2Cデバイスが認識されているかをまず確認します。

$ sudo i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- 39 -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- 48 -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

大丈夫そうですね。0x39が照度センサ、0x48が温度センサです(それぞれ、アドレスを変更することもできます)。

さて、それではさっそくプログラムしていきます。

実は今回利用する温度センサモジュールTMP102と照度センサモジュールTSL2561はWebIOPiが正式にサポートしてくれているので、簡単に利用することができます。その準備として、”/etc/webiopi/config”に以下のように追記します。

...
[DEVICES]
...
#temp0 = TMP102
#temp1 = TMP102 slave:0x49
#temp2 = DS18B20
#temp3 = DS18B20 slave:28-0000049bc218
temp = TMP102 slave:0x48
...
#light0 = TSL2561T
#light1 = TSL2561T slave:0b0101001
light = TSL2561 slave:0x39
...

“temp = TMP102 slave:0x48″と”light = TSL2561 slave:0x39″が追記したところです。

以下、WebIOPiのデバイス制御用Pythonファイルで追記が必要なところだけ抜粋します。

from webiopi import deviceInstance
...
temp = deviceInstance("temp")
light = deviceInstance("light")
...
@webiopi.macro
def getTemperature():
  return str(temp.getCelsius())

@webiopi.macro
def getIlluminance():
  return str(light.getLux())

温度と照度の値をJavaScript上で計算するつもりはないので、Python側で文字列にして返すようにしています。後は、これをJavaScriptから呼び出すようにすればOKです。例えばこんな感じです。

...
<div class="row">
  <div class="text-center">
    <p>温度:<span id="temperature">0</span> °C</p>
  </div>
</div>
<div class="row">
  <div class="text-center">
    <p>照度:<span id="illuminance">0</span> lx</p>
  </div>
</div>
...
...
$(function() {
  ...

  webiopi().callMacro("getTemperature",[], function(macro, args, response){
    var temp = response.split(".");
    $("#temperature").text(temp[0]);
  });

  webiopi().callMacro("getIlluminance",[], function(macro, args, response){
    var lx = response.split(".");
    $("#illuminance").text(lx[0]);
  });
});
...

値(文字列)は小数で得られますが、整数値さえあれば充分なので、”.”で分割して整数値だけ表示するようにしています。

温度センサと照度センサについてはこれでOKなので、あとは焦電型赤外線センサモジュール(人感センサ)SB612です。これはWebIOPiでサポートしているデバイスではありませんが、単純にGPIOポートの値を読んでやれば使えそうです。こんな感じです。

from webiopi import deviceInstance
...
temp = deviceInstance("temp")
light = deviceInstance("light")
GPIO = webiopi.GPIO
MOTION_PIN = 4
...
@webiopi.macro
def getTemperature():
  return str(temp.getCelsius())

@webiopi.macro
def getIlluminance():
  return str(light.getLux())

@webiopi.macro
def getMotion():
  return str(GPIO.digitalRead(MOTION_PIN))
...
<div class="row">
  <div class="text-center">
    <p>温度:<span id="temperature">0</span> °C</p>
  </div>
</div>
<div class="row">
  <div class="text-center">
    <p>照度:<span id="illuminance">0</span> lx</p>
  </div>
</div>
<div class="row">
  <div class="text-center">
    <p>動作:<span id="motion">False</span></p>
  </div>
</div>
...
...
$(function() {
  ...

  webiopi().callMacro("getTemperature",[], function(macro, args, response){
    var temp = response.split(".");
    $("#temperature").text(temp[0]);
  });

  webiopi().callMacro("getIlluminance",[], function(macro, args, response){
    var lx = response.split(".");
    $("#illuminance").text(lx[0]);
  });

  webiopi().callMacro("getMotion",[], function(macro, args, response){
    $("#motion").text(response);
  });
});
...

 これで一応、全部完成です。早速WebUIを表示してみますと、

webiopi-1

こんな感じになりました。温度は、部屋にあるアナログ温度計と同じ値を示しているので大丈夫そうです。照度は51lxで、また、何かしらの動作を検知している状態のようです。

光を強くしてリロードしてみると、

webiopi-2

照度が548lxまで増えました。また、動作も検知していない状態になっています。

今のところページをリロードしないと値が更新されないのが問題ですが、温度と照度に関してはモニタリング画面を表示した時の値がわかれば充分なので、これでOKです。動作については瞬間の値をとってもあんまり意味がないので、別の利用方法を考えた方がいいですね。

あと、動作の検出に使っている焦電型赤外線センサモジュール(人感センサ)SB612の特性が、仕様書を見てもよくわかりません。このモジュール、3つのパラメータ(DELAY_TIME, DARK_ADJ, SENS)を可変抵抗を使って調整できるみたいなのですが、それぞれどういじればどうなるのかが全然わかりません。

th_webiopi-4

th_webiopi-5

これがとりあえず動いた、という時の設定状態です。2枚目で設定しているのがDELAY_TIMEで、調整器がこの位置の時に値の保持期間が最小(2秒)になっている … はず。1枚目の2つ(DARK_ADJ, SENS)の調整具合はよくわかりません。

あとなんだか動作が不安定で、全然センサが反応しない時に調整器をちょっと初期位置から動かすだけで反応するようになるとか、わからないことが多いです。うーん、このセンサは今のところ明確な利用目的があるわけではないので、いっそ外してしまっても良いかもしれない…ケチらずにNaPiOn買っとけば良かったかな…高いけど、あっちの方が使い易いです。

 

ちなみに、WebIOPiを起動していると、今回使ったセンサの計測値はREST APIでも取得することができます。

  • 温度 … http://(Raspberry Pi IPアドレス):8000/devices/temp/sensor/temperature/c
  • 照度 … http://(Raspberry Pi IPアドレス)::8000/devices/light/sensor/luminosity/lx
  • 動作 … http://(Raspberry Pi IPアドレス)::8000/GPIO/4/value

WebIOPiのドキュメント上ではこれで値が取得できるはずで、実際に温度と動作は取得できたのですが、照度だけは”Not Found”になってしまいました。バグ?? 便利な機能なだけに残念。

 

というわけで、WebIOPiで色々センサをいじってみました。WebIOPi対応のセンサデバイスを使えば、センサの計測値を簡単に取得できるようになるので、大変ありがたいです。是非是非対応デバイスをもっともっと増やして欲しい…のですが、気になっているのは、WebIOPiの最新版のリリースが2015/2/10で止まってしまっていることです。うーん、もったいないなあ…WebIOPi自体はとても便利なので、是非とも開発継続していただきたいところです。