Raspberry Pi 2で温湿度センサ(BME280)から温度を取得して、その結果をTwitterにbotする

初「Lチカ」はそれで感動的だったのですが、実用的でないのかな？
と思ったので、温度センサーで温度を取得してみたいと思います。

#１．準備

- BME280搭載　温湿度・気圧センサモジュール ピンヘッダ実装済
  - ハンダ付けしないので、ピンヘッダ装着済みを購入
  - センサーにしては少し高めだと思いました
- ブレッドボード
- ジャンパワイヤ（オス-メス 4本、オス-オス 4本）

#２．配線・設定・確認
## （１）配線
図のように配線しました。
![BME280_ブレッドボード.png](https://qiita-image-store.s3.amazonaws.com/0/95868/54786e4f-b21b-d2be-c104-cf7ddafd0da8.png)

が実際に見ると「もっさもっさ」して美しくないです。
![IMG_20160307_234901.jpg](https://qiita-image-store.s3.amazonaws.com/0/95868/0fadb1ee-e93c-ae0f-a1a5-aee6cf1fa2e0.jpeg)

今後は配線が複雑になっていくので、美しく配信することも必要ですね。
でも、まず動けばいいかな。

あとBME280は、思い切って奥までグイっとブレッドボードに差し込む必要があります。
最初は恐る恐るでしたが。。。

## （２）設定
I2Cは有効化しているので、I2C関連のパッケージをインストールします。

```
$ sudo apt-get i2c-tools
$ sudo apt-get install python-smbus
```

## （３）確認
以下のコマンドを入れて、同じ結果が返ってくればOKです。

```
$ 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: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- 76 --
```

#３．温度・湿度・気圧の取得

スィッチサイエンスさんのBMEのリポジトリに温度・湿度・気圧を取得するプログラムがあったので、そのまま利用しました。

`$ wget https://raw.githubusercontent.com/SWITCHSCIENCE/BME280/master/Python27/bme280_sample.py`

これを実行すると

```
$sudo python bme280_sample.py
temp : 13.12  ℃
pressure :  850.66 hPa
hum :  46.04 ％
```
で取得できました。この部屋、寒いわけだ。

#４．twitterへbot
温度をTwitterにbotします。
## （１）準備
- twitterアカウントを持っていることが前提です。
- https://apps.twitter.com/へアクセスして、
 - 今回利用するアプリケーションの登録
 - Consumer Key,Consumer Secret,Access Token,Access Token Secretを取得
 する。
- twythonのイントール<br>
`$ sudo pip install twython`

## （２）プログラム変更

先ほどダウンロードした`bme280_sample.py`を以下のように変更し、`twitter_bot.py`という名前で保存します。

- 画面出力の停止（コメントアウト）
- 気温のみtwitterへbotするよう処理を追加

```twitter_bot.py
#coding: utf-8

import smbus
import time
import os
from twython import Twython

bus_number  = 1
i2c_address = 0x76

bus = smbus.SMBus(bus_number)

digT = []
digP = []
digH = []

t_fine = 0.0
ondo=0

def writeReg(reg_address, data):
        bus.write_byte_data(i2c_address,reg_address,data)

def get_calib_param():
        calib = []

        for i in range (0x88,0x88+24):
                calib.append(bus.read_byte_data(i2c_address,i))
        calib.append(bus.read_byte_data(i2c_address,0xA1))
        for i in range (0xE1,0xE1+7):
                calib.append(bus.read_byte_data(i2c_address,i))

        digT.append((calib[1] << 8) | calib[0])
        digT.append((calib[3] << 8) | calib[2])
        digT.append((calib[5] << 8) | calib[4])
        digP.append((calib[7] << 8) | calib[6])
        digP.append((calib[9] << 8) | calib[8])
        digP.append((calib[11]<< 8) | calib[10])
        digP.append((calib[13]<< 8) | calib[12])
        digP.append((calib[15]<< 8) | calib[14])
        digP.append((calib[17]<< 8) | calib[16])
        digP.append((calib[19]<< 8) | calib[18])
        digP.append((calib[21]<< 8) | calib[20])
        digP.append((calib[23]<< 8) | calib[22])
        digH.append( calib[24] )
        digH.append((calib[26]<< 8) | calib[25])
        digH.append( calib[27] )
        digH.append((calib[28]<< 4) | (0x0F & calib[29]))
        digH.append((calib[30]<< 4) | ((calib[29] >> 4) & 0x0F))
        digH.append( calib[31] )

        for i in range(1,2):
                if digT[i] & 0x8000:
                        digT[i] = (-digT[i] ^ 0xFFFF) + 1

        for i in range(1,8):
                if digP[i] & 0x8000:
                        digP[i] = (-digP[i] ^ 0xFFFF) + 1

        for i in range(0,6):
                if digH[i] & 0x8000:
                        digH[i] = (-digH[i] ^ 0xFFFF) + 1

def readData():
        data = []
        for i in range (0xF7, 0xF7+8):
                data.append(bus.read_byte_data(i2c_address,i))
        pres_raw = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4)
        temp_raw = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4)
        hum_raw  = (data[6] << 8)  |  data[7]

        compensate_T(temp_raw)
        compensate_P(pres_raw)
        compensate_H(hum_raw)

def compensate_P(adc_P):
        global  t_fine
        pressure = 0.0

        v1 = (t_fine / 2.0) - 64000.0
        v2 = (((v1 / 4.0) * (v1 / 4.0)) / 2048) * digP[5]
        v2 = v2 + ((v1 * digP[4]) * 2.0)
        v2 = (v2 / 4.0) + (digP[3] * 65536.0)
        v1 = (((digP[2] * (((v1 / 4.0) * (v1 / 4.0)) / 8192)) / 8)  + ((digP[1] * v1) / 2.0)) / 262144
        v1 = ((32768 + v1) * digP[0]) / 32768

        if v1 == 0:
                return 0
        pressure = ((1048576 - adc_P) - (v2 / 4096)) * 3125
        if pressure < 0x80000000:
                pressure = (pressure * 2.0) / v1
        else:
                pressure = (pressure / v1) * 2
        v1 = (digP[8] * (((pressure / 8.0) * (pressure / 8.0)) / 8192.0)) / 4096
        v2 = ((pressure / 4.0) * digP[7]) / 8192.0
        pressure = pressure + ((v1 + v2 + digP[6]) / 16.0)

#       print "pressure : %7.2f hPa" % (pressure/100)

def compensate_T(adc_T):
        global t_fine
        v1 = (adc_T / 16384.0 - digT[0] / 1024.0) * digT[1]
        v2 = (adc_T / 131072.0 - digT[0] / 8192.0) * (adc_T / 131072.0 - digT[0] / 8192.0) * digT[2]
        t_fine = v1 + v2
        temperature = t_fine / 5120.0
#       print "temp : %-6.2f ℃" % (temperature) 
        global ondo
        ondo = "%4.2f" % (temperature)
		
		def compensate_H(adc_H):
        global t_fine
        var_h = t_fine - 76800.0
        if var_h != 0:
                var_h = (adc_H - (digH[3] * 64.0 + digH[4]/16384.0 * var_h)) * (digH[1] / 65536.0 * (1.0 + digH[5] / 67108864.0 *$
        else:
                return 0
        var_h = var_h * (1.0 - digH[0] * var_h / 524288.0)
        if var_h > 100.0:
                var_h = 100.0
        elif var_h < 0.0:
                var_h = 0.0
#       print "hum : %6.2f ％" % (var_h)

def setup():
        osrs_t = 1                      #Temperature oversampling x 1
        osrs_p = 1                      #Pressure oversampling x 1
        osrs_h = 1                      #Humidity oversampling x 1
        mode   = 3                      #Normal mode
        t_sb   = 5                      #Tstandby 1000ms
        filter = 0                      #Filter off
        spi3w_en = 0                    #3-wire SPI Disable

        ctrl_meas_reg = (osrs_t << 5) | (osrs_p << 2) | mode

        config_reg    = (t_sb << 5) | (filter << 2) | spi3w_en
        ctrl_hum_reg  = osrs_h

        writeReg(0xF2,ctrl_hum_reg)
        writeReg(0xF4,ctrl_meas_reg)
        writeReg(0xF5,config_reg)


setup()
get_calib_param()


if __name__ == '__main__':
        try:
                readData()
        except KeyboardInterrupt:
                pass

#twitterの認証情報入力
CONSUMER_KEY = '*************************'
CONSUMER_SECRET =  '*************************'
ACCESS_KEY = '*************************'
ACCESS_SECRET =  '*************************'

api = Twython(CONSUMER_KEY,CONSUMER_SECRET,ACCESS_KEY,ACCESS_SECRET)

#現在時間取得
timestamp = 'date +%F_%H:%M:%S'
current_time = os.popen(timestamp).readline().strip()

#取得したCPU温度をツイート
api.update_status(status= current_time+'現在、温度は'+ str(ondo) +' ℃です。')
```
# （３）実行
最後に実行します。
`$ sudo python twitter_bot.py`

twitterにアクセスして以下のようにツィートされていればOKです。
![twitter2.png](https://qiita-image-store.s3.amazonaws.com/0/95868/902c3936-8e51-3e3a-3216-6fd3a993836a.png)

あとは、cronでスケジュール実行させれば、定期的にtwitter上にbotされます。

以下のサイトを参考にしました。ありがとうございます。

Raspberry Pi 2で温湿度・気圧センサのBME280をPythonから使う
http://qiita.com/masato/items/027e5c824ae75ab417c1

Twitter APIを使ってRaspberry PiにCPU温度と現在時刻を呟かせる
http://ysdyt.github.io/blog/2015/03/29/raspi-cputemp-bot/