RaspberryPi + wiringPi-Python + HDC1000 で温湿度を取る

色々ハマったのでメモ。
RaspberryPiはI2Cが使えるので、色々繋げる。なのでHDC1000っていう温湿度センサを繋ごうとしたらこいつがちょいと曲者。i2c-toolsで適当に拾えるセンサもあるなかで、こいつはこちら側から読み出しを掛けないとダメ。

環境の準備

wiringPi(厳密にはwiringPi2)経由でI2Cを叩くので、それの準備。
この辺参考に-> https://blog.ymyzk.com/2015/02/enable-raspberry-pi-i2c/
PiPちょうべんり -> http://raspi.tv/how-to-install-wiringpi2-for-python-on-the-raspberry-pi
HDC1000は0x40に生えてくる。

読み出しコード

import wiringpi2
import os
import struct
from time import sleep

wiringpi2.wiringPiSetup()
i2c = wiringpi2.I2C()
dev = i2c.setup(0x40)
i2c.writeReg16(dev,0x02,0x10) #Temp + Hidi 32-bit transfer mode, LSB-MSB inverted, why?
i2c.writeReg8(dev,0x00,0x00) #start conversion.
sleep((6350.0 + 6500.0 +  500.0)/1000000.0) #wait for conversion.
#LSB-MSB inverted, again...
temp = ((struct.unpack('4B', os.read(dev,4)))[0] << 8 | (struct.unpack('4B', os.read(dev,4)))[1])
hudi = ((struct.unpack('4B', os.read(dev,4)))[2] << 8 | (struct.unpack('4B', os.read(dev,4)))[3])
os.close(dev) #Don't leave the door open.
print "Humidity %.2f" % (( hudi / 65535.0 ) * 100)
print "Temperature %.2f" % (( temp  / 65535.0) * 165 - 40 )

wiringPiを使うとデバイスファイル(ファイルディスクリプタ)にI2Cのデバイスが生えてくるので、そこからデータを拾えばいい。これに気がつくまでに3時間くらいロスした。それと多バイト(2バイト)の通信をするときに、LSBとMSBがひっくり返るのが謎(readReg16でマニファクチャIDとか読み出すとわかる)。これで1時間くらいロスした気がする。どうにもSMBusでのバッファの扱い方がHDC1000と逆っぽいのだけれど。

追記:LSB/MSBはByteの方の話です。

あとstrでデータが返ってくるので、適切にunpackするのにも手間取った。8x4=32bitで返ってくるので、それを4byte分のタプルに突っ込んで(os.readの仕様ではある)そこから引っ張り出したのをビットシフトした後にORを取るという変なやり方でLSBとMSBを正常な順番に入れ替えている。もう少しイケてるやり方がある気がする。

別にリアルタイム性を要求されるような場面でも無いし、配線が増えるのが嫌なので、変換待ちは適当にwaitを突っ込んでいる。RasPiとHDC1000の間は千石で売ってるQiコネクタ(5ピンのやつ)を使って30cm位リード線を伸ばして温湿度を取っている感じです。EngineerのPA-20で圧着しているけれど、綺麗に出来て良い感じ。ケーブルはハンダ付けより圧着が圧倒的に綺麗に作れるしきちんと出来れば接触抵抗も小さくなるはずなので圧着がオススメ。

就活とかでこう迫られているとこういうのが捗りますね(アカン)

2015/5/3 close.os() を追記、開けっ放しだった。