温度や湿度のセンサーの他に手軽に扱えるセンサーに照度センサーがあります。単位はルクスで計測できます。今回はAdafruit TSL2561デジタル照度センサーを用意しました。光センサーには赤外線を使う人感センサーもあります。組み合わせて使うとIoTっぽいことができそうです。
ブレッドボード配線
ブレッドボードの配線はAdafruitのlernサイトにArduino版ですが、TSL2561 Luminosity Sensorにあります。
- GND (TSL2561) -> GPIO04 P09 (Raspberry Pi)
- VCC (TSL2561) -> 3.3v P1 (Raspberry Pi)
- SDA (TSL2561) -> GPIO02 SDA1 P03 (Raspberry Pi)
- SCL (TSL2561) -> GPIO03 SCL1 P04 (Raspberry Pi)
正常に配線ができると0x39アドレスに確認ができます。
$ 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: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
I2Cドライバ
Python 2
I2Cバスからデータを取得するドライバはAdafruit-Raspberry-Pi-Python-CodeリポジトリにあるPythonのAdafruit_I2C.pyを使います。このドライバはRaspberry PiにデフォルトでインストールされているPython 2で動作します。
$ cd ~/python_apps
$ git clone https://github.com/adafruit/Adafruit-Raspberry-Pi-Python-Code
$ cd Adafruit-Raspberry-Pi-Python-Code/Adafruit_I2C
Python 3
Quick2WireはRPi-Light-Sensorなどでも利用されています。Python 3をRaspberry Piにインストールしていないのでvirtualenvを用意して次回使ってみようと思います。
TSL2561プログラム
TSL2561から照度を計測するプログラムはTSL2561 and Raspberry PiのフォーラムでTSL2561.pyが紹介されています。
またRaspberry Pi Hacksにはtsl2561-lux.pyを使った方法が掲載されています。どちらもほぼ同じコードですが今回はrpihacksリポジトリからtsl2561-lux.py
をAdafruit_I2C
ディレクトリにダウンロードして使います。
$ cd ./Adafruit_I2C
$ wget https://raw.githubusercontent.com/spotrh/rpihacks/master/tsl2561-lux.py
$ chmod +x tsl2561-lux.py
tsl2561-lux.py
の最後をコメントアウトしてもモジュールとして外部から呼び出せるようにします。
...
#oLuxmeter=Luxmeter()
#print "LUX HIGH GAIN ", oLuxmeter.getLux(16)
#print "LUX LOW GAIN ", oLuxmeter.getLux(1)
#print "LUX AUTO GAIN ", oLuxmeter.getLux()
残念ながらファイル名にハイフンが入っているため、Pythonではこのままimportできません。アンダースコアに置換してシンボリックリンクを作ります。
$ ln -s tsl2561-lux.py tsl2561_lux.py
Luxmeterクラスを使って照度を計測するエントリポイントとしてtsl2561.py
を作成します。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from time import sleep
from tsl2561_lux import Luxmeter
if __name__ == "__main__":
while True:
tsl=Luxmeter()
sensor_value = tsl.getLux()
print(sensor_value)
sleep(5)
実行
5秒間隔で照度を計測するプログラムを実行します。単位はルクスになります。瞬間の計測のためかバラツキがあるデータになりました。
$ chmod u+x tsl2561.py
$ ./tsl2561.py
1691.71324345
961.73944068
1274.95548759
690.479479419
14.30208
0
11.50656
388.866054431
1316.01531121
0
0
iPhoneの懐中電灯アプリでセンサーを照らすとルクスが上がります。次回は真っ暗な部屋で計測して安定したデータを取得してみます。
19088.793866
0
0
UPDATE 2015-05-25
プログラムを修正して500ルクスを超えたらMQTTにpublishするようにしました。計測間隔も3秒に短くしています。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from time import sleep
from tsl2561_lux import Luxmeter
import paho.mqtt.client as mqtt
import json
def sensor():
sensor = W1ThermSensor()
celsius = sensor.get_temperature()
return celsius
def on_connect(client, userdata, rc):
print("Connected with result code " + str(rc))
def on_publish(client, userdata, mid):
print("publish: " + str(mid))
def main():
client = mqtt.Client(client_id='',clean_session=True,
protocol=mqtt.MQTTv311)
client.username_pw_set("{username}","{password}")
client.connect("{mqtt_broker_host}", 1883, 60)
client.on_connect = on_connect
client.on_publish = on_publish
tsl=Luxmeter()
while True:
sensor_value = tsl.getLux()
print(sensor_value)
if sensor_value > 500.0:
message = json.dumps(dict(trigger="on"))
client.publish("data",message)
sleep(3)
if __name__ == '__main__':
main()
暗い部屋に移動してテストしてみました。照度が安定して暗いときは正確に計測できています。照度があまりに大きく変わると0になるようです。iPhoneのライトをゆっくり近づけて2回publishしました。
$ python ./publish.py
1.42263737647
1.42263737647
1.42263737647
1.42263737647
1.42263737647
1.42263737647
1.42263737647
781.750737506
publish: 1
1212.30526902
publish: 2
2.45526898227
1.48479374557
119.459947915
287.1274
45.49168
0
0
1.45533948132
1.41892978382
1.41892978382