BME680とESPHomeで作る室内環境センサー

ESP32につないだBME680は、温度・湿度・気圧を測るだけでなく、部屋の空気がどれだけよどんでいるかも感じ取ります。BoschのライブラリBSEC2がそれを空気質指数に変換し、Home Assistantが換気のタイミングを知らせてくれます。組み立ては1時間ほど。その後センサーが部屋の空気に慣れるまで、1〜2日かかります。
概要
材料: ESP32ボード、BME680ブレイクアウトボード、ケーブル4本、ESPHome入りのHome Assistant。
結果: Home Assistantに7つのエンティティ。温度、湿度、気圧、空気質(IAQ)とその評価、推定CO₂とVOC、そしてIAQ値の現在の信頼度です。
1 配線Aufbau
目標: センサーをESP32のI²Cバスにつなぐ。
| BME680 | ESP32 |
|---|---|
| VCC | 3V3 |
| GND | GND |
| SDA | GPIO 21 |
| SCL | GPIO 22 |
残りのピン(CS、SDO)は、一般的なブレイクアウトボードではすでにI²C用に配線されています。

2 設定を書き込むAufbau
目標: BSEC2入りのESPHomeファームウェアをESP32に書き込む。
なぜなぜ自作の計算式ではなくBSEC2なのか
センサー自体が出すのはガス抵抗値だけです。空気がきれいなら高く、汚れていれば低くなります。何を「きれい」とするかは部屋によって違います。BSEC2はこの基準を学習して指数を調整します。固定の計算式では値が20前後にとどまり、ほとんど反応しません。
まず wifi_ssid、wifi_password、ap_password、api_key を記した secrets.yaml を作ります。続いてデバイスの設定です。
esphome:
name: room-climate
friendly_name: Room Climate
esp32:
variant: esp32
framework:
type: esp-idf
logger:
api:
encryption:
key: !secret api_key
ota:
- platform: esphome
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
ap:
ssid: "Room Climate Fallback Hotspot"
password: !secret ap_password
captive_portal:
i2c:
- id: i2c_1
sda: 21
scl: 22
scan: true # 検出したアドレスをログに表示
bme68x_bsec2_i2c:
i2c_id: i2c_1
address: 0x77 # SDO未接続: 0x77、SDOをGNDへ: 0x76
model: bme680
operating_age: 28d # 初回キャリブレーションには 4d
sample_rate: LP # 3秒ごと。ULP(5分)ではほぼ校正されない
supply_voltage: 3.3V
temperature_offset: 0 # ステップ5で決める
state_save_interval: 6h # キャリブレーションをフラッシュに保存
sensor:
- platform: bme68x_bsec2
temperature:
name: "Temperature"
pressure:
name: "Pressure"
humidity:
name: "Humidity"
iaq:
name: "Air Quality"
on_value:
- text_sensor.template.publish:
id: iaq_rating
state: !lambda |-
if (isnan(x)) return "不明";
if (x <= 50) return "とても良い";
if (x <= 100) return "良い";
if (x <= 150) return "やや汚れている";
if (x <= 200) return "汚れている";
if (x <= 250) return "かなり汚れている";
if (x <= 350) return "ひどく汚れている";
return "非常に汚れている";
co2_equivalent:
name: "CO2 (estimated)"
breath_voc_equivalent:
name: "VOC (estimated)"
text_sensor:
- platform: bme68x_bsec2
iaq_accuracy:
name: "Calibration"
- platform: template
id: iaq_rating
name: "Air Quality Rating"
update_interval: neverエンティティ名(name)は英語のままにしています。ESPHomeはこの名前からエンティティIDを作るため、日本語だけの名前は避けます。表示名はHome Assistant側で変更できます。
最初の書き込みはUSBで行い、以降の更新はOTA(無線)で行います。
3 Home Assistantに追加Aufbau
目標: 測定値をHome Assistantのエンティティとして使う。
デバイスはたいてい自動で検出されます。検出されない場合は 設定 → デバイスとサービス → ESPHome から追加します。
4 キャリブレーションを待つEinregeln
目標: Calibration が 3 – Calibrated になる。
なぜなぜ時間がかかるのか
BSEC2が基準を決めるには、きれいな空気と汚れた空気の 両方 を経験する必要があります。状態がフラッシュに保存されるのはレベル3になってから。それより前に再起動すると、最初からやり直しです。
センサーを部屋の中で覆わずに動かし、再書き込みや再起動はしないでおきます。においの刺激を一度与えると効果的です。フェルトペンや少量の消毒液を数秒間近づけ、そのあとしっかり換気します。新品のセンサーには、さらに最大48時間のエージングが必要です。
| Calibration | 意味 |
|---|---|
| 0 – Stabilizing | 起動直後の安定化 |
| 1 – Uncertain | 基準がまだ決まっていない |
| 2 – Calibrating | キャリブレーション中 |
| 3 – Calibrated | 値が信頼できる |
5 ケースと温度補正Einregeln
目標: ESP32の熱に影響されない測定値。
なぜなぜ別の区画が必要なのか
ESP32は動作中に数度温まります。センサーがその近くや排気の通り道にあると、温度は高く、湿度は低く測ってしまいます。また、部屋の空気は拡散によってしかセンサーに届きません。空気がよどんでいると反応が鈍く、キャリブレーションもうまく進みません。
- センサーは壁で仕切った専用の区画に入れ、ESP32の 下か横 に置く。上には置かない。
- センサー区画には少なくとも二面に大きめの開口部を設け、金属カバーの穴を室内の空気に向ける。
- 3Dプリントしたケースは、センサーを入れる前に数日間置いて臭いを抜く。揮発成分が基準を狂わせる。
- 直射日光、暖房、コンロの近くは避ける。
ケースに入れて1〜2時間たったら、基準温度計と比べ、その差を temperature_offset に入力します(例:-2.5)。保存済みのキャリブレーション状態は、再書き込みしても保たれます。
値の読み方
| IAQ | 評価 |
|---|---|
| 0–50 | とても良い |
| 51–100 | 良い |
| 101–150 | やや汚れている |
| 151–200 | 汚れている |
| 201–250 | かなり汚れている |
| 251–350 | ひどく汚れている |
| 350超 | 非常に汚れている |
一つひとつの値よりも、変化の傾向のほうが参考になります。値が上がってきたら、換気のサインです。
トラブルシューティング
| 症状 | 原因 | 対処 |
|---|---|---|
| IAQが50前後から動かない | キャリブレーション中 | そのまま動かし続ける(ステップ4) |
| Calibrationが Uncertain のまま | 空気の変化が少ない、再起動、ULP | においの刺激、再起動しない、LP |
| 温度が数度高い | ESP32の発熱 | 離して設置、temperature_offset(ステップ5) |
| センサーが見つからない | アドレスか配線 | ログのI²Cスキャン、0x76/0x77、SDA/SCL |
| ケースに入れたあとIAQがおかしい | 造形材料からの揮発成分 | 臭いを抜き、再キャリブレーション |