SPIでセンサ情報を取得しようとして挫折したので、
より簡単そうな?I2Cセンサに鞍替えした。
■完成図

■環境
raspberry pi zero w(raspbian-jessie)
python3
mac
センサを接続してi2cdetectでアドレス確認。
pi@raspberrypi:~ $ i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- 39 -- -- -- -- 3e --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- 76 --
■I2C接続機器
39: TSL2561 (照度センサー)
3e: LCDディスプレイ (AE-AQM0802)
76: AE-BME-280 (温度・湿度・大気圧計)
I2Cの認識はOK
■TSL2561 I2C照度センサーの導入
AWS と Azure と Raspberry Pi (ラズパイ) で IoT してみた (1)
を参考にさせていただきました。
pipからtsl2561をインストール
pi@raspberrypi:~ $ pip install tsl2561
Collecting tsl2561
Downloading tsl2561-3.3-py2.py3-none-any.whl
Installing collected packages: tsl2561
Successfully installed tsl2561-3.3
参考サイトでは、以下を使っていたので、自分のプログラム(I2CSensor.py)に組み込んでみた。
from tsl2561 import TSL2561
if __name__ == "__main__":
tsl = TSL2561(debug=True)
print(tsl.lux())
実行してみる。
pi@raspberrypi:~ $ sudo python pyhome/I2CSensor.py
Traceback (most recent call last):
File "pyhome/I2CSensor.py", line 4, in <module>
from tsl2561 import TSL2561
ImportError: No module named tsl2561
モジュールが無いと言われたので、pip show
でtsl2561の場所を探す。
pi@raspberrypi:~ $ pip show tsl2561
Name: tsl2561
Version: 3.3
Summary: Driver for the TSL2561 digital luminosity (light) sensors
Home-page: https://github.com/sim0nx/tsl2561
Author: Georges Toth
Author-email: georges@trypill.org
License: BSD
Location: /home/pi/.pyenv/versions/3.5.1/lib/python3.5/site-packages
Requires:
場所がわかったので、プログラムの冒頭に以下を記載して読み込ませる
sys.path.append('/home/pi/.pyenv/versions/3.5.1/lib/python3.5/site-packages')
表示できた。※左がLuxデータ、右が抜けがないか確認するためのカウンタ。
pi@raspberrypi:~ $ sudo python pyhome/I2CSensor.py
(422, 1)
(421, 2)
(421, 3)
(420, 4)
(420, 5)
(420, 6)
(420, 7)
(421, 8)
(423, 9)
(421, 10)
(420, 11)
■AE-BME280(温度・湿度・大気圧計)の導入
bme280.pyというのがあるらしいのでwgetにて取得。
pi@raspberrypi:~ $ wget https://bitbucket.org/MattHawkinsUK/rpispy-misc/raw/master/python/bme280.py
--2017-10-01 19:19:57-- https://bitbucket.org/MattHawkinsUK/rpispy-misc/raw/master/python/bme280.py
bitbucket.org (bitbucket.org) をDNSに問いあわせています... 2401:1d80:1010::150, 104.192.143.3, 104.192.143.2, ...
bitbucket.org (bitbucket.org)|2401:1d80:1010::150|:443 に接続しています... 接続しました。
HTTP による接続要求を送信しました、応答を待っています... 200 OK
長さ: 5057 (4.9K) [text/plain]
`bme280.py' に保存中
bme280.py 100%[=====================>] 4.94K --.-KB/s 時間 0s
2017-10-01 19:19:58 (11.6 MB/s) - `bme280.py` へ保存完了 [5057/5057]
実行してみると、何も変えなくても表示できた!!!
pi@raspberrypi:~ $ sudo python bme280.py
Chip ID : 96
Version : 0
Temperature : 25.71 C
Pressure : 1018.94496737 hPa
Humidity : 63.7514647032 %
中を見てみると、readBME280All()
の関数内で気温・大気圧・湿度をreturnで返しているので、bme280をメインのプログラムと同じ場所において、そのままモジュールにできそう。
なので
import bme280
temperature, pressure, humidity = bme280.readBME280All()
と加えてやるとtemperature, pressure, humidityそれぞれ取得できる。便利!
というわけで、それを元に以下作成。(コピペの集大成)
# !/path/to/python
# -*- coding: utf-8 -*-
import sys
sys.path.append('/home/pi/.pyenv/versions/3.5.1/lib/python3.5/site-packages')
import BME280 #airpressure,temp,humidity sensor
import bme280
from tsl2561 import TSL2561 #light sensor
import smbus # sudo apt-get install python-smbus
import time
CHANNEL = 0
GAIN = 1
bus = smbus.SMBus(1) # Rev 2 Pi, Pi 2 & Pi 3 uses bus 1
class i2clcd:
i2c = smbus.SMBus(1)
addr = 0x3e
contrast = 30 # 0~63
def __init__(self):
self.i2c.write_byte_data(self.addr, 0, 0x38) # function set(IS=0)
self.i2c.write_byte_data(self.addr, 0, 0x39) # function set(IS=1)
self.i2c.write_byte_data(self.addr, 0, 0x14) # internal osc
self.i2c.write_byte_data(self.addr, 0, (0x70 | (self.contrast & 0x0f))) # contrast
self.i2c.write_byte_data(self.addr, 0, (0x54 | ((self.contrast >> 4) & 0x03))) # contrast/icon/power
self.i2c.write_byte_data(self.addr, 0, 0x6c) # follower controlß
time.sleep(0.2)
def clear(self):
self.i2c.write_byte_data(self.addr, 0, 0x38) # function set(IS=0)
self.i2c.write_byte_data(self.addr, 0, 0x0C) # Display On
self.i2c.write_byte_data(self.addr, 0, 0x01) # Clear Display
self.i2c.write_byte_data(self.addr, 0, 0x06) # Entry Mode Set
time.sleep(0.2)
def puts(self, msg):
self.i2c.write_byte_data(self.addr, 0, 0x38) # function set(IS=0)
[self.i2c.write_byte_data(self.addr, 0x40, ord(c)) for c in msg]
def setaddress(self, line, col):
self.i2c.write_byte_data(self.addr, 0, 0x38) # function set(IS=0)
self.i2c.write_byte_data(self.addr, 0, 0x80 | (0x40 if line > 0 else 0) | col)
def setcg(self, no, cg):
self.i2c.write_byte_data(self.addr, 0, 0x38) # function set(IS=0)
self.i2c.write_byte_data(self.addr, 0, 0x40 | (no << 3))
[self.i2c.write_byte_data(self.addr, 0x40, c) for c in cg]
def putcg(self, line, col, no):
self.setaddress(line, col)
self.i2c.write_byte_data(self.addr, 0x40, no)
if __name__ == "__main__":
count=0
errcount = 0
while True:
lcd = i2clcd()
lcd.clear()
temperature, pressure, humidity = bme280.readBME280All()
tsl = TSL2561(debug=True)
light = tsl.lux()
count += 1
pressure = int(pressure)
temperature = round(temperature,1)
humidity = round(humidity,1)
try:
lcd.setaddress(0, 0)
lcd.puts(str(light).rjust(5)+"Lux") #rjust(5)で5桁の右揃え
lcd.setaddress(1, 0)
lcd.puts(str(pressure).rjust(5)+"hPa")
# lcd.puts("c:"+str(count))
time.sleep(2)
lcd.clear()
lcd.setaddress(0, 0)
lcd.puts(str(temperature).rjust(5)+"'C")
lcd.setaddress(1, 0)
lcd.puts(str(humidity).rjust(5)+"%")
print("OUT :L"+str(light),"P"+str(pressure),"T"+str(temperature),"H"+str(humidity))
except IOError:
errcount +=1
lcd.setaddress(1, 4)
lcd.puts("e")
lcd.setaddress(1, 5)
lcd.puts(str(errcount))
print(light, count,errcount)
time.sleep(2)
こんな感じで表示できました。(2秒毎に表示が切り替わる)


このあとcsvで書き出したりとか、センサやLCDのプログラムを
モジュールにしたりしているが、とりあえずベースはできた感じ。
■備忘(失敗バージョン)
最初は、以下のサイトを参考にさせていただき、順に追っていったのだが途中で止まってしまった。備忘も兼ねてこちらも簡単に載せておく。
Raspberry pi 2でTSL2561を使ってpythonで照度を取得する
ダウンロード
wget https://github.com/janheise/TSL2561/archive/master.zip
'quick2wire'が無いと言われる。
pi@raspberrypi:~ $ python TSL2561-master/TSL2561.py
Traceback (most recent call last):
File "TSL2561-master/TSL2561.py", line 3, in <module>
import quick2wire.i2c as i2c
ImportError: No module named 'quick2wire'
'quick2wire'をインストール
pi@raspberrypi:~ $ cd TSL2561-master/
pi@raspberrypi:~/TSL2561-master $ cd ~
pi@raspberrypi:~ $ git clone https://github.com/quick2wire/quick2wire-python-api.git
Cloning into 'quick2wire-python-api'...
remote: Counting objects: 1674, done.
remote: Total 1674 (delta 0), reused 0 (delta 0), pack-reused 1674
Receiving objects: 100% (1674/1674), 3.10 MiB | 678.00 KiB/s, done.
Resolving deltas: 100% (916/916), done.
Checking connectivity... done.
pi@raspberrypi:~ $ cd quick2wire-python-api/
pi@raspberrypi:~/quick2wire-python-api $ sudo python3 setup.py install
running install
Checking .pth file support in /usr/local/lib/python3.4/dist-packages/
/usr/bin/python3 -E -c pass
TEST PASSED: /usr/local/lib/python3.4/dist-packages/ appears to support .pth files
running bdist_egg
running egg_info
.
.
.
.
i2c-0が無いと言われるのでシンボリックリンクにする(よく分かってない)
pi@raspberrypi:~ $ sudo python3 TSL2561-master/TSL2561.py
Traceback (most recent call last):
File "TSL2561-master/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'
pi@raspberrypi:~ $ sudo ln -s /dev/i2c-1 /dev/i2c-0
↑リンク先では、ここまでやると動作しているが、自分の場合は下記エラーが出た。
OSError: [Errno 95] Operation not supported
pi@raspberrypi:~ $ sudo python3 TSL2561-master/TSL2561.py
Traceback (most recent call last):
File "TSL2561-master/TSL2561.py", line 324, in <module>
i2c.reading(address, 2)
File "/usr/local/lib/python3.4/dist-packages/quick2wire_api-0.0.0.2-py3.4.egg/quick2wire/i2c.py", line 78, in transaction
OSError: [Errno 95] Operation not supported
ここから先のエラーの対処ができなかったのでこちらは諦め。