Raspberry Pi3で温度湿度を測定し、Ambientで可視化する


Raspberry Pi3とHDC1000というセンサーで温度、湿度を測定し、[IoTデーター可視化サービス「Ambient」](https://ambidata.io)に送って可視化(グラフ化)しました。プログラムはPythonで書きました。

![RaspberryPi_hdc1000](http://ambidata.io/wp/wp-content/uploads/2016/10/IMG_5471.jpg)

## PythonでRaspberry Pi3からHDC1000にアクセスする

### Raspberry Pi3とHDC1000の接続

HDC1000は温度と湿度を測定するセンサーチップです。I2Cというインタフェースでアクセスすることができます。今回はこのHDC1000の載った秋月電子さんの[「HDC1000使用　温湿度センサーモジュール」](http://akizukidenshi.com/catalog/g/gM-08775/)を使いました。

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の接続するまで](http://qiita.com/toshihirock/items/8e7f0887b565defe7989)などを参考にRaspberry Pi3をWiFiに接続します。

次に、[Raspberry Pi の I2C を有効化する方法 (2015年版)](https://blog.ymyzk.com/2015/02/enable-raspberry-pi-i2c/)などを参考にI2Cを有効化します。次のようにアドレス0x40にHDC1000が検出されました。

```sh
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](https://github.com/WiringPi/WiringPi-Python)というモジュールをインストールしました。

```sh
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__メソッドはこんな感じです。

```python
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を書き込みます。

温度を取得するメソッドはこんな感じです。

```python
    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()で温度、湿度を読み込みます。

```python
import hdc1000

hdc1000 = hdc1000.Hdc1000(0x40, 7)

temp = hdc1000.getTemp()
humid = hdc1000.getHumid()
print 'temp: %.1f, humid: %.1f' % (temp, humid)
```

## Raspberry Pi3からAmbientにデーターを送り、可視化する

[Ambient](https://ambidata.io)はIoTクラウドサービスで、マイコンなどから送られたデーターを受信し、蓄積し、可視化(グラフ化)します。

![Ambient structure](https://ambidata.io/wp/wp-content/uploads/2016/09/AmbientStructure.jpg)

Ambientにデーターを送るSDKとしてArduino用のCライブラリー、mbed用のCライブラリー、node.jsライブラリー、Node-REDノードがありますが、これに加えてPythonライブラリーを作りました。

### AmbientのPythonライブラリーのインストール

AmbientのPythonライブラリーはGithubに公開しました。Githubからは次のようにライブラリーをインストールできます。例はRaspberry Pi3で実行したものですが、Mac上のPythonにも同様にインストールして、使うことができます。

```sh
pi$ sudo pip install git+https://github.com/AmbientDataInc/ambient-python-lib.git

pi$ pip freeze | grep ambient
ambient==0.1.0
```

### Pythonでの使い方

```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 chart](https://ambidata.io/wp/wp-content/uploads/2016/09/fig3-1024x651.jpg)

## まとめ

Ambientにデーター送信するPythonライブラリーとHDC1000で温度湿度を測定するサンプルプログラムをGithubに公開しました。

* [AmbientのPythonライブラリーとサンプルプログラム](https://github.com/AmbientDataInc/ambient-python-lib)