Raspberry Pi3とHDC1000というセンサーで温度、湿度を測定し、IoTデーター可視化サービス「Ambient」に送って可視化(グラフ化)しました。プログラムはPythonで書きました。
PythonでRaspberry Pi3からHDC1000にアクセスする
Raspberry Pi3とHDC1000の接続
HDC1000は温度と湿度を測定するセンサーチップです。I2Cというインタフェースでアクセスすることができます。今回はこのHDC1000の載った秋月電子さんの「HDC1000使用 温湿度センサーモジュール」を使いました。
Raspberry Pi3とHDC1000とは次のように接続します。
Raspberry Pi | HDC1000 |
---|---|
01(3.3v) | 1(+V) |
03(GPIO02) | 2(SDA) |
05(GPIO03) | 3(SCL) |
07(GPIO04) | 4(RDY) |
06(Ground) | 5(GND) |
+V、SDA、SCL、GNDはI2Cで定義された信号線で、HDC1000はこの他にRDYというピンがあります。HDC1000は温度、湿度を測定するのに2.5m秒から6.5m秒程度の時間がかかります。時間は分解能に依存します。RDYピンは測定中はHIGH、測定が完了するとLOWになるので、それをRaspberry PiのPin7(GPIO04)につなぎ、測定完了を確認するようにしました。
Raspberry Pi3の準備
Raspberry Pi 3を買ってMacを使ってWiFi接続とSSHの接続するまでなどを参考にRaspberry Pi3をWiFiに接続します。
次に、Raspberry Pi の I2C を有効化する方法 (2015年版)などを参考にI2Cを有効化します。次のようにアドレス0x40にHDC1000が検出されました。
pi$ sudo i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
プログラムはPythonで書くことにしたので、PythonでI2CをアクセスするWiringPi for Pythonというモジュールをインストールしました。
pi$ sudo apt-get install python-dev python-setuptools swig
pi$ git clone --recursive https://github.com/WiringPi/WiringPi-Python.git
pi$ cd WiringPi-Python
pi$ ./build.sh
pi$ pip freeze | grep wir
wiringpi==2.32.1
これでPythonがビルドされインストールされます。私がビルドしたバージョンは2.32.1でした。
PythonのHDC1000モジュール
HDC1000をアクセスするモジュールを書きました。__init__メソッドはこんな感じです。
import wiringpi
import os
import struct
class Hdc1000:
def __init__(self, addr, rdyPin):
wiringpi.wiringPiSetup() #setup wiringpi
self.i2c = wiringpi.I2C() #get I2C
self.dev = self.i2c.setup(addr) #setup I2C device
self.rdy = rdyPin
wiringpi.pinMode(self.rdy, 0) # set ready pin to INPUT
self.i2c.writeReg16(self.dev, 0x02, 0x0000)
# Config reg を設定 MODE=0 温度、湿度を個別に読み込む
コンフィグレーションレジスター(0x02)のModeビットを0にすると温度、湿度16ビットを個別に読み込み、1にすると温度、湿度を32ビットデーターとして一度に読み込むようになります。今回は個別に読み込むようにしました。ちなみに、wiringpiのI2Cライブラリーでは上位バイトと下位バイトがひっくり返って読み書きされるようです。HDC1000のModeビットは最下位ビットを0とするとビット12で、これを1にすると16ビットでは0x1000になりますが、I2Cライブラリーで書き込むときには0x0010を書き込みます。
温度を取得するメソッドはこんな感じです。
def getTemp(self):
self.i2c.writeReg8(self.dev, 0x00, 0x00)
while wiringpi.digitalRead(self.rdy) == 1:
pass
data = struct.unpack('BB', os.read(self.dev, 2))
temp = (data[0] << 8) | data[1]
temp = temp * 165.0 / 65536.0 - 40.0
return temp
HDC1000はレジスター0x00に何かを書くと温度の測定が始まり、RDYピンがHIGH(1)になり、測定が完了するとLOW(0)になります。PythonではwriteReg8()でレジスター0x00に0x00を書き、次のwhile文でRDYピンが0になるまで待っています。RDYピンが0になったら、レジスター0x00を読むのですが、wiringpiのI2CライブラリーのreadReg8()やreadReg16()ではデーターが読み出せず、代わりにos.read()関数で2バイト読むとデーターが読み出せました。
使い方はこんな感じです。HDC1000のI2Cアドレス(0x40)とRDYピンのピン番号(7)を指定してインスタンスを作り、getTemp()、getHumid()で温度、湿度を読み込みます。
import hdc1000
hdc1000 = hdc1000.Hdc1000(0x40, 7)
temp = hdc1000.getTemp()
humid = hdc1000.getHumid()
print 'temp: %.1f, humid: %.1f' % (temp, humid)
Raspberry Pi3からAmbientにデーターを送り、可視化する
AmbientはIoTクラウドサービスで、マイコンなどから送られたデーターを受信し、蓄積し、可視化(グラフ化)します。
Ambientにデーターを送るSDKとしてArduino用のCライブラリー、mbed用のCライブラリー、node.jsライブラリー、Node-REDノードがありますが、これに加えてPythonライブラリーを作りました。
AmbientのPythonライブラリーのインストール
AmbientのPythonライブラリーはGithubに公開しました。Githubからは次のようにライブラリーをインストールできます。例はRaspberry Pi3で実行したものですが、Mac上のPythonにも同様にインストールして、使うことができます。
pi$ sudo pip install git+https://github.com/AmbientDataInc/ambient-python-lib.git
pi$ pip freeze | grep ambient
ambient==0.1.0
Pythonでの使い方
import ambient
ambi = ambient.Ambient(100, "your_writeKey") # ご自分のチャネルID、ライトキーに置き換えてください
r = ambi.send({"d1": temp, "d2": humid})
まずambientライブラリーをimportし、データーを送るチャネルIdとライトキーを指定してインスタンスを作り、send()メソッドでデーターを送信します。データーは上記のような辞書形式で渡します。キーは"d1"から"d8"までのいずれかを指定します。
Ambientはデーターを受信すると、受信時のタイムスタンプをつけてデーターを蓄積し、リアルタイムにグラフ化します。例えば5分間隔で温度と湿度を送った場合、次のように温度と湿度の時系列の推移がグラフで確認できます。
まとめ
Ambientにデーター送信するPythonライブラリーとHDC1000で温度湿度を測定するサンプルプログラムをGithubに公開しました。