湿度センサーBME280 温度・気圧も測って環境モニター【電子工作始めますか?】

タイトル
湿度センサーBME280をRaspberry PiにつないでI2C通信をしてみます。BME280は温度・湿度・気圧を測定できるセンサーです。

湿度センサーBME280をRaspberry PiにつないでI2C通信をしてみます。BME280はスマートフォンに使うことを想定した小型で省電力のセンサーです。湿度の他に気温と気圧も測ることができます。
とても小さいセンサーなのでブレークアウト基板に実装されたモジュールが売られています。
今回使ったのはこのモジュールです。

それではRaspberry Piにつないでみます。

配線

3.3Vの電源とI2C通信がつながれば良いので4本の電線をつなぐだけです。Raspberry PiのI2C通信をするピンは決まっています。次のように配線します。
Raspberry PiとBME280の接続図
ブレッドボードを使わず、ケーブルを作るだけでも良いです。BME280は4ピン、Raspberry Piは5ピンのコネクタを使えば良いでしょう。

動作確認

Raspberry Piに接続したらRaspberry PiのI2C機能を有効にします。
sudo raspi-config
インターフェース→I2Cと辿って有効にします。
I2C通信ができているか確認します。
i2cdetect -y 1
i2cdetect

このコマンドでI2Cで接続しているアドレスが表示されます。16進数で"76"の表示があれば通信できています。
もしも表示されていなければ配線を見直します。配線を間違えていないか、接触不良はないか確認します。

ソフトウエア

通信の確認ができたら動かします。BME280は検索すればたくさんの例が見つかるでしょう。Pythonで動かすものが多いようなのでここではNode-REDを使います。Node-REDはブラウザで表示するものを簡単に作れます。

BME280をNode-REDで動かすために追加のノードをインストールします。
Node-REDの"パレットの管理"を開き、"ノードの追加"を選びます。"bme280"で検索して追加するノードを探します。
”node-red-contrib-bme280”を追加してください。

もう1つNode-REDでダッシュボードを表示するモジュールを追加します。"dashboard"で検索して
”node-red-dashboard”を追加してください。

bme280ノードは動かせばすぐに値が返ってきます。特に設定はありません。もしもI2Cのアドレスが"76h"でないモジュールを使っている場合はノードの設定でアドレスを変えます。

サンプルプログラム

BME280のサンプルプログラムをここに置いておきます。BME280の計測値をダッシュボードに表示します。Node-REDはブラウザで動く開発環境なのでLAN内ならスマホのブラウザでダッシュボードを開いて計測値を見れます。
気温・湿度・気圧をチャートで表示しています。不快指数を計算して表示しています。不快指数を顔のマークにして表示しています。
ダッシュボード
Node-REDのコードはこちら。
[
{
"id": "5199c01b.98ca4",
"type": "tab",
"label": "Environmental Measurement",
"disabled": false,
"info": ""
},
{
"id": "2b381670.6e62ba",
"type": "inject",
"z": "5199c01b.98ca4",
"name": "",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "60",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 130,
"y": 80,
"wires": [
[
"911782ef.3a973"
]
]
},
{
"id": "29e1f667.02277a",
"type": "function",
"z": "5199c01b.98ca4",
"name": "Separate msg.",
"func": "var THI; //Temperature-Humidity Index\nTd = msg.payload.temperature_C;\nH = msg.payload.humidity\nTHI = 0.81*Td + 0.01*H*(0.99*Td - 14.3) + 46.3;\n\nvar out=[];\nout[0] = {\"topic\": \"temperature\", \"payload\": msg.payload.temperature_C, \"timestamp\": msg.timestamp};\nout[1] = {\"topic\": \"pressure\", \"payload\": msg.payload.pressure_hPa, \"timestamp\": msg.timestamp};\nout[2] = {\"topic\": \"humidity\", \"payload\": msg.payload.humidity, \"timestamp\": msg.timestamp};\nout[3] = {\"topic\": \"TemperatureHumidityIndex\", \"payload\": THI, \"timestamp\": msg.timestamp};\n\nreturn out;",
"outputs": 4,
"noerr": 0,
"initialize": "",
"finalize": "",
"x": 440,
"y": 300,
"wires": [
[
"6e1d26ee.89e198",
"da058ffb.3ddf5"
],
[
"74207c6a.3b1764",
"6e8941c4.82285"
],
[
"9bdee42b.44dda8",
"60d5e3f9.58254c"
],
[
"e0ca8f88.4af79",
"b347afc8.23483",
"3d24a117.9dd5fe"
]
]
},
{
"id": "a2a5b42c.b19598",
"type": "debug",
"z": "5199c01b.98ca4",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "auto",
"x": 970,
"y": 160,
"wires": []
},
{
"id": "74207c6a.3b1764",
"type": "ui_chart",
"z": "5199c01b.98ca4",
"name": "Pressure",
"group": "3c631f02.5e0e1",
"order": 3,
"width": "8",
"height": "4",
"label": "Pressure",
"chartType": "line",
"legend": "false",
"xformat": "HH:mm:ss",
"interpolate": "linear",
"nodata": "",
"dot": false,
"ymin": "",
"ymax": "",
"removeOlder": "2",
"removeOlderPoints": "",
"removeOlderUnit": "86400",
"cutout": 0,
"useOneColor": false,
"useUTC": false,
"colors": [
"#1f77b4",
"#aec7e8",
"#ff7f0e",
"#2ca02c",
"#98df8a",
"#d62728",
"#ff9896",
"#9467bd",
"#c5b0d5"
],
"outputs": 1,
"useDifferentColor": false,
"x": 840,
"y": 480,
"wires": [
[]
]
},
{
"id": "9bdee42b.44dda8",
"type": "ui_chart",
"z": "5199c01b.98ca4",
"name": "Humidity",
"group": "3c631f02.5e0e1",
"order": 2,
"width": "8",
"height": "4",
"label": "Humidity",
"chartType": "line",
"legend": "false",
"xformat": "HH:mm:ss",
"interpolate": "linear",
"nodata": "",
"dot": false,
"ymin": "20",
"ymax": "100",
"removeOlder": "2",
"removeOlderPoints": "",
"removeOlderUnit": "86400",
"cutout": 0,
"useOneColor": false,
"useUTC": false,
"colors": [
"#1f77b4",
"#aec7e8",
"#ff7f0e",
"#2ca02c",
"#98df8a",
"#d62728",
"#ff9896",
"#9467bd",
"#c5b0d5"
],
"outputs": 1,
"useDifferentColor": false,
"x": 840,
"y": 520,
"wires": [
[]
]
},
{
"id": "6e1d26ee.89e198",
"type": "ui_chart",
"z": "5199c01b.98ca4",
"name": "Temperature",
"group": "3c631f02.5e0e1",
"order": 1,
"width": "8",
"height": "4",
"label": "Temperature",
"chartType": "line",
"legend": "false",
"xformat": "HH:mm:ss",
"interpolate": "linear",
"nodata": "",
"dot": false,
"ymin": "0",
"ymax": "40",
"removeOlder": "2",
"removeOlderPoints": "",
"removeOlderUnit": "86400",
"cutout": 0,
"useOneColor": false,
"useUTC": false,
"colors": [
"#1f77b4",
"#aec7e8",
"#ff7f0e",
"#2ca02c",
"#98df8a",
"#d62728",
"#ff9896",
"#9467bd",
"#c5b0d5"
],
"outputs": 1,
"useDifferentColor": false,
"x": 850,
"y": 440,
"wires": [
[]
]
},
{
"id": "d6d84002.71a2b",
"type": "ui_button",
"z": "5199c01b.98ca4",
"name": "",
"group": "72f233bc.79569c",
"order": 6,
"width": 0,
"height": 0,
"passthru": false,
"label": "Clear",
"tooltip": "",
"color": "",
"bgcolor": "",
"icon": "delete",
"payload": "[]",
"payloadType": "json",
"topic": "topic",
"topicType": "msg",
"x": 550,
"y": 560,
"wires": [
[
"9bdee42b.44dda8",
"74207c6a.3b1764",
"6e1d26ee.89e198",
"60d5e3f9.58254c",
"6e8941c4.82285",
"da058ffb.3ddf5",
"e0ca8f88.4af79",
"b347afc8.23483"
]
]
},
{
"id": "da058ffb.3ddf5",
"type": "ui_gauge",
"z": "5199c01b.98ca4",
"name": "Temperature",
"group": "d2ce4849.232868",
"order": 1,
"width": "0",
"height": "0",
"gtype": "gage",
"title": "Temperature",
"label": "℃",
"format": "{{value | number:1}}℃",
"min": "-10",
"max": "50",
"colors": [
"#002db3",
"#0fe600",
"#ca3838"
],
"seg1": "",
"seg2": "",
"x": 850,
"y": 280,
"wires": []
},
{
"id": "6e8941c4.82285",
"type": "ui_gauge",
"z": "5199c01b.98ca4",
"name": "Pressure",
"group": "d2ce4849.232868",
"order": 3,
"width": 0,
"height": 0,
"gtype": "gage",
"title": "Pressure",
"label": "hPa",
"format": "{{value | number:0}}hPa",
"min": "900",
"max": "1100",
"colors": [
"#1543cb",
"#14b9f0",
"#66fff5"
],
"seg1": "",
"seg2": "",
"x": 840,
"y": 320,
"wires": []
},
{
"id": "3caff297.4240de",
"type": "ui_button",
"z": "5199c01b.98ca4",
"name": "Measure",
"group": "72f233bc.79569c",
"order": 4,
"width": 0,
"height": 0,
"passthru": false,
"label": "Measure",
"tooltip": "",
"color": "",
"bgcolor": "",
"icon": "developer_dashboard",
"payload": "",
"payloadType": "date",
"topic": "topic",
"topicType": "msg",
"x": 160,
"y": 40,
"wires": [
[
"911782ef.3a973"
]
]
},
{
"id": "60d5e3f9.58254c",
"type": "ui_gauge",
"z": "5199c01b.98ca4",
"name": "Humidity",
"group": "d2ce4849.232868",
"order": 2,
"width": "0",
"height": "0",
"gtype": "gage",
"title": "Humidity",
"label": "%",
"format": "{{value | number:1}}%",
"min": 0,
"max": "100",
"colors": [
"#e4f500",
"#17ed07",
"#cb3a5e"
],
"seg1": "",
"seg2": "",
"x": 840,
"y": 360,
"wires": []
},
{
"id": "376116be.105eea",
"type": "ui_text",
"z": "5199c01b.98ca4",
"group": "72f233bc.79569c",
"order": 1,
"width": 0,
"height": 0,
"name": "Timestamp",
"label": "",
"format": "{{msg.payload | date:\"'yyyy/MM/dd hh:mm:ss\"}}",
"layout": "col-center",
"x": 850,
"y": 80,
"wires": []
},
{
"id": "dcab6a13.2c3bb8",
"type": "Bme280",
"z": "5199c01b.98ca4",
"name": "",
"bus": "1",
"address": "0x76",
"topic": "bme280",
"extra": false,
"x": 240,
"y": 160,
"wires": [
[
"29e1f667.02277a",
"78bd8fac.a12b7"
]
]
},
{
"id": "e0ca8f88.4af79",
"type": "ui_gauge",
"z": "5199c01b.98ca4",
"name": "",
"group": "d2ce4849.232868",
"order": 4,
"width": 0,
"height": 0,
"gtype": "gage",
"title": "Temperature-Humidity Index",
"label": "units",
"format": "{{value|number:1}}",
"min": "60",
"max": "90",
"colors": [
"#00b500",
"#e6e600",
"#ca3838"
],
"seg1": "",
"seg2": "",
"x": 900,
"y": 400,
"wires": []
},
{
"id": "b347afc8.23483",
"type": "ui_chart",
"z": "5199c01b.98ca4",
"name": "",
"group": "3c631f02.5e0e1",
"order": 4,
"width": "8",
"height": "4",
"label": "Temperature-Humidity Index",
"chartType": "line",
"legend": "false",
"xformat": "HH:mm:ss",
"interpolate": "linear",
"nodata": "",
"dot": false,
"ymin": "60",
"ymax": "90",
"removeOlder": 1,
"removeOlderPoints": "",
"removeOlderUnit": "3600",
"cutout": 0,
"useOneColor": false,
"useUTC": false,
"colors": [
"#1f77b4",
"#aec7e8",
"#ff7f0e",
"#2ca02c",
"#98df8a",
"#d62728",
"#ff9896",
"#9467bd",
"#c5b0d5"
],
"outputs": 1,
"useDifferentColor": false,
"x": 900,
"y": 560,
"wires": [
[]
]
},
{
"id": "5a0a50c9.9191b",
"type": "file",
"z": "5199c01b.98ca4",
"name": "",
"filename": "/home/pi/data.json",
"appendNewline": true,
"createDir": false,
"overwriteFile": "false",
"encoding": "none",
"x": 810,
"y": 160,
"wires": [
[
"a2a5b42c.b19598"
]
]
},
{
"id": "911782ef.3a973",
"type": "change",
"z": "5199c01b.98ca4",
"name": "",
"rules": [
{
"t": "set",
"p": "timestamp",
"pt": "msg",
"to": "payload",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 350,
"y": 80,
"wires": [
[
"dcab6a13.2c3bb8",
"376116be.105eea"
]
]
},
{
"id": "4df9f636.c47268",
"type": "json",
"z": "5199c01b.98ca4",
"name": "",
"property": "payload",
"action": "",
"pretty": false,
"x": 650,
"y": 160,
"wires": [
[
"5a0a50c9.9191b"
]
]
},
{
"id": "78bd8fac.a12b7",
"type": "change",
"z": "5199c01b.98ca4",
"name": "",
"rules": [
{
"t": "set",
"p": "payload.timestamp",
"pt": "msg",
"to": "timestamp",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 460,
"y": 160,
"wires": [
[
"4df9f636.c47268"
]
]
},
{
"id": "440e5c27.3dee14",
"type": "ui_text",
"z": "5199c01b.98ca4",
"group": "72f233bc.79569c",
"order": 7,
"width": "0",
"height": "0",
"name": "THI",
"label": "",
"format": "",
"layout": "col-center",
"x": 830,
"y": 220,
"wires": []
},
{
"id": "3d24a117.9dd5fe",
"type": "ui_template",
"z": "5199c01b.98ca4",
"group": "72f233bc.79569c",
"name": "THI Face",
"order": 2,
"width": 0,
"height": 0,
"format": "<ng-md-icon icon=\"{{(msg.payload < 70) ? 'sentiment_very_satisfied' : (msg.payload < 75) ? 'sentiment_satisfied' : (msg.payload < 80) ? 'sentiment_neutral' : (msg.payload < 85) ? 'sentiment_dissatisfied' : 'sentiment_very_dissatisfied'}}\" size='2em' ></ng-md-icon>",
"storeOutMessages": false,
"fwdInMessages": false,
"resendOnRefresh": true,
"templateScope": "local",
"x": 640,
"y": 220,
"wires": [
[
"440e5c27.3dee14"
]
]
},
{
"id": "3c631f02.5e0e1",
"type": "ui_group",
"name": "History",
"tab": "74c2de11.17cd2",
"order": 3,
"disp": true,
"width": "8",
"collapse": false
},
{
"id": "72f233bc.79569c",
"type": "ui_group",
"name": "Interface",
"tab": "74c2de11.17cd2",
"order": 1,
"disp": true,
"width": "3",
"collapse": false
},
{
"id": "d2ce4849.232868",
"type": "ui_group",
"name": "Current Status",
"tab": "74c2de11.17cd2",
"order": 2,
"disp": true,
"width": "6",
"collapse": false
},
{
"id": "74c2de11.17cd2",
"type": "ui_tab",
"name": "Environment",
"icon": "dashboard",
"disabled": false,
"hidden": false
}
]

センサーの値がおかしい

BME280の計測値がおかしい事があるでしょう。多くの場合はBME280のリセットが正しく行われないのが原因です。Raspberry Piの電源を入れたままBME280をつないだりするとハードウエアリセットが正しく働かない場合があります。

ハードウエアリセットがかからなくともソフトウエアリセットを動かせば直せます。しかし、ソフトウエアリセットを独立のコマンドとして用意しているドライバは多くないようです。
今回使ったBME280ノードはフローをデプロイした直後にソフトウエアリセットが実行されます。フローを動かしたままBME280を外して付け直したりするとリセットがかからず計測値がおかしくなります。
Pythonのドライバでも同様な動作をするものが多いです。いろいろなドライバが公開されていますがソフトウエアリセットが無いものもあるようです。ソフトウエアリセットだけを呼び出す関数を持つドライバはほとんど見かけません。ご自分で調べてください。
ソフトウエアリセットが効かなければ、Raspberry Piの電源を切った状態でBME280を接続し、起動してください。ハードウエアリセットが働きます。

BME280の電源の接触不良が原因の場合もあります。BME280はスマートフォン用という事もありとても消費電力が少ないICです。こういうICは電源がほとんどつながっていないくともI2Cの電線からの電力でも動いてしまいます。

正しく値を取れたと思っても、本当の気温も湿度も判らないので正しいか判断できません。それでも湿度が10%くらいズレているように思えました。
BME280の湿度センサーは最初はオフセットを持っていしまうようです。それはBME280を基板にハンダ付けする際高温の状態になるのが原因のようです。これを直す手順がデータシートに書かれています。特定の温度と湿度に指定の時間置かなくてならないようですが、そんな設備がなくとも1週間ほど経つと直るようです。

ビデオ



コメント

最近のコメント

Threaded Recent Comments will be here.