MENU

Raspberry pi 2でTSL2561を使ってpythonで照度を取得する

サバフェス2016の課題をコリコリといじっております。いなばです。

会場でセンサーとしてTSL2561という照度センサーを頂いているので、これを使ったものを作りたいわけですが、ちょっとハマったところもあるので、メモがてらまとめておこうと思います。

目次

TSL2561をラズパイ2につなぐ

まずはこれ。

Fritzing のパーツ画像がないので後で時間のあるときにでも作ってみますが、文字ベースで言うなら、

  • ラズパイの1番からTSL2561の3vo
  • ラズパイの3番からTSL2561のSDA
  • ラズパイの5番からTSL2561のSLC
  • ラズパイの6番からTSL2561のGND

にそれぞれ配線してあげればいいみたいです。

I2C関係

TSL2561とラズパイ2はI2Cという方法で接続します。I2Cについては、Wikipediaの説明をざっと見てみましたが、要するに複数のセンサーを繋いだりするときに簡単にできるやり方、というくらいの理解で良さそうです。

ラズパイ2でI2Cを使うにはいくつか準備が必要です。

ラズパイ2 本体の設定

「本体」という表現も語弊がありますが、要はラズパイのカーネルで、I2Cを有効にしてあげないと使えません。

色々方法はあるようですが、ここではターミナルで

sudo raspi-config

を実行し、「9 Advanced Options」から「A7 I2C」を選択してやるのが一番簡単そうです。

上記を実行したあと、再起動が必要なので、

sudo reboot

します。

再起動後、

lsmod

してやると、以下のように出力が出ると思います。

Module                  Size  Used by
cfg80211              407580  0
rfkill                 16036  2 cfg80211
8192cu                519604  0
bcm2835_rng             1763  0
snd_bcm2835            19802  3
i2c_bcm2708             4920  0
snd_pcm                73474  1 snd_bcm2835
bcm2835_gpiomem         2860  0
snd_timer              18848  1 snd_pcm
snd                    50779  9 snd_bcm2835,snd_timer,snd_pcm
uio_pdrv_genirq         2944  0
uio                     7753  1 uio_pdrv_genirq
i2c_dev                 5671  0
fuse                   80694  3
ipv6                  338660  36

細かい出力は違うかもしれませんが、i2c_bcm2708とi2c_devが見えていれば良いようです。

接続と動作の基本的な確認

上記で一応カーネルモジュールが読み込まれたところまでは分かるのですが、やはり念のため通信して確認してみたいところです。

てことで、i2c-toolsというパッケージをインストールし、i2cdetectというコマンドで確認します。

sudo apt-get install i2c-tools
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: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

こんな感じで、39番が見えていれば良いと思います。

Pythonから照度をとる

2016/3/21追記

一つ書き忘れていました。PythonからI2Cデバイスを使うにあたり、

sudo apt-get install python-smbus

が必要です。

2016/3/21追記ここまで

ここでちょっとハマりました。後述するように、TSL2561 からデータを取るための実装は複数あるようで、実装によって精度というかクセが異なるようです。

当初は、

Qiita
Raspberry Piでデジタル照度センサーのTSL2561を使う - Qiita 温度や湿度のセンサーの他に手軽に扱えるセンサーに照度センサーがあります。単位はルクスで計測できます。今回はAdafruit TSL2561デジタル照度センサーを用意しました。光...

でも紹介されている

GitHub
rpihacks/tsl2561-lux.py at master · spotrh/rpihacks Code and config files to go along with the Raspberry Pi Hacks book. - spotrh/rpihacks

を使ってみたのですが、どうもこちらではなかなかうまく行きませんでした。

上記のスクリプト(に手を加えたもの)で、連続して値を取ることはできるのですが、急激に明るさが変わるとそこからデータが不安定になるようで、例えば動作中に部屋の明かりを消す、であるとか、強い照明を当てる、といった刺激を与えると、その後、同じ明るさの状態に戻しても取得できる照度が異なったりしていました。

で、その辺りについても触れている

下林明正のブログ
Raspberry Pi 2でAdafruit TSL2561を正しく使うメモ - 下林明正のブログ 普通に調べてやると RaspberryPi - Raspberry Piでデジタル照度センサーのTSL2561を使う - Qiitaqiita.com 瞬間の計測のためかバラツキがあるデータになりました。 となる...

を参考にしてみたところ、うまい具合に行きました。

具体例は上記のサイトで公開されているとおりですが、念のためこちらにも手順を貼っておきます。

まず、

GitHub
GitHub - janheise/TSL2561: Example code to use an Adafruit TSL2561 light sensor with Python on a Ras... Example code to use an Adafruit TSL2561 light sensor with Python on a RaspberryPi - janheise/TSL2561

にあるものを使うので、zipファイルをwgetで入手しておきます。

wget https://github.com/janheise/TSL2561/archive/master.zip

次に、入手したzipファイルを展開します。

unzip master.zip

展開したディレクトリに移動して実行してみると…

cd TSL2561-master
./TSL2561.py

以下のように、quick2wireがない、と怒られます。

Traceback (most recent call last):
  File "./TSL2561.py", line 3, in <module>
    import quick2wire.i2c as i2c
ImportError: No module named 'quick2wire'

ざっと調べてみたところ、quick2wire はI2Cデバイスをラズパイ上のPythonから扱うためのライブラリのようです。

で、さっそくquick2wireをインストールしてみます。

git clone https://github.com/quick2wire/quick2wire-python-api.git
cd quick2wire-python-api/
sudo python3 setup.py install

これでOKです。参考にしたサイトでは、quick2wireのインストール時にsetup-toolsというパッケージのインストールが必要だったようですが、2016年3月時点の環境では不要でした。

さて、改めて先ほどのスクリプトを実行してみますが…

./TSL2561.py

今度は別の内容で怒られます。どうやら、/dev/i2c-0 がない、と怒っているようです。

Traceback (most recent call last):
  File "./TSL2561.py", line 300, in <module>
    with i2c.I2CMaster(0) as bus:
  File "/usr/local/lib/python3.4/dist-packages/quick2wire_api-0.0.0.2-py3.4.egg/quick2wire/i2c.py", line 48, in __init__
FileNotFoundError: [Errno 2] No such file or directory: '/dev/i2c-0'

この問題についても、参考にしたサイトに記載されていたので恐れるに足らず、ということで、同じようにシンボリックリンクを張って対応してみます。

sudo ln -s /dev/i2c-1 /dev/i2c-0

3/21追記

上記の方法で作成したシンボリックリンクは、何故か再起動すると消えちゃってました。

なので、/etc/rc.local に上記のコマンドを記述しておいたところうまいこといっているようです。

3/21追記ここまで

さて、三度目の正直ということで、改めて実行してみます。

./TSL2561.py

お、なんかイイ感じに出力されてます。

0a
b6 00
39 04
Full:     0439
Infrared: 00b6
Visible:  0383

念のため、上記のスクリプトを連続して呼んでみましたが、出力は安定しています。

この実装が大丈夫そうなことは確認できたので、同梱されているTSL2561.example.pyも試してみます。

./TSL2561.example.py

出力はこんな感じになります。

0a
79 00
98 03
Full:     0398
Infrared: 0079
Visible:  031f
0a
Found sensor...
Full luminosity value: 1048699
Full luminosity value: 0x10007b
IR: 10
Full: 7a
Visible: 0x6b
Visible, calculated: 0x6a
Lux: 1526

先ほどの出力結果と似ていますが、最後にLuxという形で照度らしきデータが数値化されているのがイイ感じです。

今回私が作ろうとしている課題では、明るさのデータを連続して取得できればいいので、TSL2561.example.pyを適当な名前のファイルにコピーしたうえで、以下のように編集してみました。

#!/usr/bin/env python3
from TSL2561 import *
import time
tsl = TSL2561()
if tsl.foundSensor():
    #print("Found sensor...")
    while 1:
        tsl.setGain(tsl.GAIN_16X);
        tsl.setTiming(tsl.INTEGRATIONTIME_13MS)
        x = tsl.getFullLuminosity()
        #print("Full luminosity value: %d" % x)
        #print("Full luminosity value: %#08x" % x)
        full = tsl.getLuminosity(tsl.FULLSPECTRUM)
        visible = tsl.getLuminosity(tsl.VISIBLE)
        infrared = tsl.getLuminosity(tsl.INFRARED)
        #print("IR: %x" % infrared)
        #print("Full: %x" % full )
        #print("Visible: %#x" % visible )
        #print("Visible, calculated: %#x" % (full - infrared) )
        print("Lux: %d" % tsl.calculateLux(full, infrared) )
        time.sleep(1.0)
else:
    print("No sensor?")

クラス自体がデバッグ的にいくつか文字列を出力してしまいますが、とりあえずこれは後で対処するとして、出力はこんな感じになります。実行中の環境としては、最初の5秒は部屋の中の普通の灯りで、次の5秒は手でセンサー部分を軽く覆っています。その後、覆っていた手をどけて5秒後に、iPhoneのLEDでセンサー部分を照らしています。

0a
7b 00
ab 03
Full:     03ab
Infrared: 007b
Visible:  0330
0a
Lux: 1571
Lux: 1566
Lux: 1566
Lux: 1551
Lux: 1566
Lux: 202
Lux: 156
Lux: 156
Lux: 156
Lux: 156
Lux: 1556
Lux: 1551
Lux: 1571
Lux: 1571
Lux: 1551
Lux: 13147
Lux: 15072
Lux: 15977
Lux: 16522
Lux: 16008
Lux: 1571
Lux: 1535
Lux: 1571
Lux: 1556
Lux: 1556

通常時が1500ルクス強、というのは、例えばこちらなどを参照すると、かなり明るすぎるのですが、私の自室がそんなに明るすぎる気はしていないので、照度センサが明るい方向に取りすぎているような気はします。ですが、今回の私の使い方では、明るさの変化さえ取れればいいので、その観点では、上記の出力は、明るい状態→暗い状態→明るい状態→すごく明るい状態→明るい状態ときちんと数字が推移しており、かなり安定しているように思えます。

ひとまず、ラズパイで明るさを取得する、ということについては、これで良いことにしようと思います。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

CAPTCHA


このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

目次