メインコンテンツへスキップ
見出し画像

製品レビュー|電子機器3:温湿度・気圧センサ(BME280)

    1.概要

     購入した製品の使い方および感想用記事です。
     今回は「BME280使用 温湿度・気圧センサモジュールキット(1,380円/個(税込))」をレビューしました。

    画像

    1-1.製品の仕様

     ボッシュ社のBME280を搭載したセンサモジュールで、温度、湿度、気圧の3つの環境情報を同時に測定できます。各詳細情報は下記リンク参照。

    【仕様】
     仕様は下記の通りです。

    1. 基本仕様:下図の通り

    2. ハードウェア:

      • ADC:内部で計測値(アナログ)をデジタル値に変換

      • IIR Filter:圧力センサのように値の変動が大きいものに対して、値の極端な変動(脈動)を抑制

    3. モード:BME280は”sleep”, ”normal”, ”forced”の3つのPowerモードがある

    4. 電気関係の情報は下図の通り

    【基本仕様】
     基本仕様は下図の通り

    画像
    画像
    https://www.bosch-sensortec.com/media/boschsensortec/downloads/product_flyer/bst-bme280-fl000.pdf

    【センサモード】
     BME280は”sleep”, ”normal”, ”forced”の3つのPowerモードがある

    画像

    【電気仕様】

    画像

    【ブロック図】

    画像
    https://www.bosch-sensortec.com/media/boschsensortec/downloads/datasheets/bst-bme280-ds002.pdf

    1-2.製品原理

     センサーはBOSCH製BME280を使用しており、本センサ1個で湿度、圧力(気圧)、温度を計測します。

    画像

     Final Data Sheetで記載を見つけることが出来なかったのですが、下記サイトで測定原理の記載がありました。

    【温度:ダイオード電圧方式】
     
    SiダイオードのVf(順方向電圧)には-2mV/℃の温度係数があり、温度が上がるほどVfは下がります。ダイオードの両端の電圧を測定することで温度が測定できます。

    【圧力(気圧):抵抗方式(詳細不明)】
     
    気圧センサの代表的なものとして、シリコン半導体を使用したピエゾ抵抗方式がある。

    【湿度:静電容量方式】
     
    静電容量式湿度センサーは湿度の変化に応じて静電容量(コンデンサーの蓄電力を表す量)が変化する仕組みを持つセンサーです(nippo 湿度センサーの種類と選び方。測定原理と使用例を解説)。
     静電容量式湿度センサーは、向かい合った1対の電極が感湿膜(高分子感湿材)を挟み込む構造になっており、片方の電極には空気中の水分を透過する電極が使用されます。セルロースやポリビニルアルコールなどからなる高分子膜に水分が吸着すると静電容量が増加するため、この変化を測定することで湿度を検知します。

    画像

    2.部材の購入

    2-1.購入品

     今回は秋月電子よりで下記購入しました。

    1. BME280使用 温湿度・気圧センサモジュールキット:

      • Raspberry Pi/Picoで使用するなら本キットのみで動作可能

    2-2.準備必須品

     その他必需品は下記の通りです。

    • マイコン/シングルボード(Raspberry Pi/Pico)

    • ブレッドボード

    • ジャンピングワイヤー

    3.環境構築

    3-1.マイコン準備

     センサを制御するためのシングルボードやマイコンの準備を行います。
    Raspberry PiやPicoの準備は下記記事参照のこと

     Raspberry PiにGPIOを制御するためのライブラリが無い場合は”RPi.GPIO”を事前にインストールしておきます。
     Picoの場合はMicropythonを使用できるようにしておきます。

    [Terminal]
    pip install rpi.gpio

    3-2.ライブラリ

     今回はPypiで公開されている"RPi.bme280"ライブラリを利用し、I2C(シリアル通信)用にsmbus2もインストールしました。
     なおBME280用のライブラリは複数公開されているため、参考記事に合わせて環境構築したらよいと思います。

    [Terminal]
    pip install smbus2
    pip install RPi.bme28
    画像

    4.使用前の準備

    4-1.はんだ付け

     本キットは基板とピンソケットが別で袋詰めされています。私の購入品はピンソケットのヘッダが8ピンだったため、ニッパでカットしてからはんだ付けしました。

    画像

    4-2.部品の組付け

    【結論】
     結論として、I2Cを使用するためCSBに3.3V電源も供給し下図としました。

    画像

    【通信方法の選択】
     BME280は(シリアル)通信の方法をSPIとI2Cから選択でき、選択は配線を変えることで実現できます。SPIでは「クロック(SCLK)、データ入力(SIN)、データ出力(SOUT)、チップセレクト(CS)」の4本の信号線を用いて通信するのに対し、I2Cは「クロック(SCL)、データ入出力(SDA)」の2本の信号線でよいため、こちらを選択しました。

     I2Cを選択するためのピン仕様は下記の通りです。

    1. BME280のCSB(ピン3)にはVDD(ピン1)を接続

      • J3をはんだジャンパするとあるが、特に問題なく動作しました。

      • Qiita記事「Arduino NanoとBME280を使って温度・湿度・気圧を計測する」より判断するとJ3をはんだジャンパ(J3にはんだ付け)すればCSBには電圧の印加が不要になると思われます。

    2. SDO(ピン5)をVDD/GNDに繋ぐかでアドレスを選択可能

      • 今回はGNDに接続したためアドレスは0x76

    3. その他は名称通りに接続

    画像

    4-3.詳細な仕様確認

     参考用で確認する仕様を記載しておきました。

    【メモリマップ】
     メモリマップは下図の通りです。自分でライブラリを作成する場合は必要になりますが、今回は他の方が作成したライブラリを使用するため詳細確認は不要です。

    画像
    https://www.bosch-sensortec.com/media/boschsensortec/downloads/datasheets/bst-bme280-ds002.pdf

    【I2Cインターフェースの詳細】
     I2Cに関して「BME280 Datasheet」の6章に記載がありますのでご参考までに。

    • デバイスアドレスは7bitであり、最上位ビット(MSB:Most Significant Bit)の6桁は固定(111011x)であり、最後のビットはSDOピンで調整できる

      • SDOをGND接続時は1110110(0x76)

      • SDOをVDDIOV_{DDIO}接続時は1110111(0x77)

    • I2CではSDOピンを浮かした状態は不可(GNDかVDDIOV_{DDIO}に接続)

    • I2Cインターフェースを選択するため、CSBはVDDIOV_{DDIO}に接続しておく

    画像

    【BME280の設置環境】
     設置環境(Mounting Recommendations)などの情報は「BME280 HSMI」に記載がありますのでご参考までに。

    5.Pythonスクリプトの作成

    5-1.任意:デバイス接続の確認

     センサがI2Cで接続されていることを確認するため”sudo i2cdetect -y 1”を実行します。
     仕様書どおりGNCに接続しているためアドレス:0x76が確認できます。

    [Terminal]
    sudo i2cdetect -y 1
    画像

    5-2.コード作成(実装)

     設計思想は下記の通りです。

    1. スクラッチでの実装は手間なので、Pypiに公開されている「RPi.bme280」を利用し、サンプルコードもそのまま利用

    2. 測定値は、データの分解能に合わせて小数点区切りで表示

    3. 細かい部分(時刻)は後で調整

    [IN]
    import smbus2
    import bme280
    
    #初期設定
    port = 1 
    address = 0x76 #BME280のI2Cアドレス
    bus = smbus2.SMBus(port) #I2Cオブジェクト
    
    
    calibration_params = bme280.load_calibration_params(bus, address)
    
    data = bme280.sample(bus, address, calibration_params) #dataの取得
    #dataオブジェクトの属性確認
    print([i for i in dir(data) if not i.startswith("_")]) 
    
    #各値の確認
    print(f'ID:{data.id}')
    print(f'Timestamp:{data.timestamp}')
    print(f'温度:{data.temperature:.2f}℃')
    print(f'{data.pressure:.1f}hPa')
    print(f'{data.humidity:.2f}%')
    
    # there is a handy string representation too
    print(type(data))
    print(data)

    5-3.実行

     実行結果は下記の通りであり、温度、気圧、湿度を計測できました。

    1. BME280オブジェクトからid, 時間、温度、気圧、湿度を属性で取得可

    2. 取得したデータはprint()で文字情報として出力も可能

      • 型はStringでなくclass 'bme280.compensated_readings'である

    3. TimestampはUTC(協定世界時)であり日本と9時間の時差がある。

      • 欲しい時間に合わせて調整

    [IN]
    同上
    [OUT]
    ['humidity', 'id', 'pressure', 'temperature', 'timestamp', 'uncompensated']
    
    ID:9f7469c9-0bf5-41ca-933c-101ed6b4d9ea
    Timestamp:2024-04-14 05:57:21.467902+00:00
    温度:25.21℃
    1019.6hPa
    43.81%
    
    <class 'bme280.compensated_readings'>
    compensated_reading(id=9f7469c9-0bf5-41ca-933c-101ed6b4d9ea, timestamp=2024-04-14 05:57:21.467902UTC, temp=25.208 °C, pressure=1019.65 hPa, humidity=43.81 % rH)

     While文を使用すれば連続計測も可能です。”convert_time_UTC2JST”関数を用いて時差9時間を調整して出力しました。

    [IN]
    import smbus2
    import bme280
    import time
    import datetime
    
    #初期設定
    port = 1 
    address = 0x76 #BME280のI2Cアドレス
    bus = smbus2.SMBus(port) #I2Cオブジェクト
    
    #BME280のキャリブレーションデータの取得
    calibration_params = bme280.load_calibration_params(bus, address)
    datas_dict = {'timestamp': [], 'temperature': [], 'pressure': [], 'humidity': []}
    
    def convert_time_UTC2JST(UTC_time):
        #datetime.datetime型データに9時間を足す
        JST_time = UTC_time + datetime.timedelta(hours=9)
        return JST_time
    
    while True:
        data = bme280.sample(bus, address, calibration_params) #dataの取得
        datas_dict['timestamp'].append(convert_time_UTC2JST(data.timestamp))
        datas_dict['temperature'].append(data.temperature)
        datas_dict['pressure'].append(data.pressure)
        datas_dict['humidity'].append(data.humidity)
        print(f'Timestamp:{data.timestamp}, 温度:{data.temperature:.2f}℃, 気圧:{data.pressure:.1f}hPa, 湿度:{data.humidity:.2f}%')
        time.sleep(1)
    
    
    画像

     保存形式はPandasで表形式にできますので必要に応じてCSVなどにも出力可能です。

    [IN2]
    import pandas as pd
    df = pd.DataFrame(datas_dict)
    df
    
    [OUT]
    -

    6.参考:ライブラリをスクラッチ作成

     時間があれば、追って下記記事参考にしながらやってみます。

    7.所感

     簡単な所感は下記の通り

    • I2C通信は他のセンサ(温度センサ:ADT7410、モーター制御:PCA9685)のためある程度理解してきた。

    • センサの計測原理のところが十分理解できていないので、外乱の影響や校正方法が十分でない。

    • 他の人がライブラリ作ってくれていると計測がめちゃくちゃ簡単な反面、理解が浅くなるので別途読み込みは必要。


    参考資料

    別添1:Rasberry Pi/Pico関係

    別添2:技術関係

    あとがき

     全然時間がないけど購入したセンサ類は一通り記事におこしたい。


     
     

    KIYO

     
     
    普段は製造業で企画/開発/設計しております。記事はプログラミング・機械学習、IoT関係の記事をメインで作成し、なるべく1つの記事で知りたいことを網羅していきます。内容は学術的より実装・アウトプット(ほしくなるもの)を重視して作成しています。 面白そうな仕事があればやりたいです!

    あなたへのおすすめ