LoginSignup
14
16

More than 5 years have passed since last update.

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

Posted at

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

1.準備

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

2.配線・設定・確認

(1)配線

図のように配線しました。
BME280_ブレッドボード.png

が実際に見ると「もっさもっさ」して美しくないです。
IMG_20160307_234901.jpg

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

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

(2)設定

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

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

(3)確認

以下のコマンドを入れて、同じ結果が返ってくれば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 --

3.温度・湿度・気圧の取得

スィッチサイエンスさんの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 %

で取得できました。この部屋、寒いわけだ。

4.twitterへbot

温度をTwitterにbotします。

(1)準備

  • twitterアカウントを持っていることが前提です。
  • https://apps.twitter.com/へアクセスして、
    • 今回利用するアプリケーションの登録
    • Consumer Key,Consumer Secret,Access Token,Access Token Secretを取得 する。
  • twythonのイントール
    $ sudo pip install twython

(2)プログラム変更

先ほどダウンロードした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) +' ℃です。')

(3)実行

最後に実行します。
$ sudo python twitter_bot.py

twitterにアクセスして以下のようにツィートされていればOKです。
twitter2.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/

14
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
16