BME280 をフォースモードで使う設定方法

以前BMP280センサーを使ったときに時間と共に温度データが上がってしまうので それを回避するためにCopilotからフォースモードの提示がありました。
———————-ここから—————————
// センサー初期化
if (!bmp.begin(0x76)) { Serial.println(“Could not find BMP280 sensor!”); while (1); } bmp.setSampling(Adafruit_BMP280::MODE_FORCED, Adafruit_BMP280::SAMPLING_X1,
// 温度オーバーサンプリング Adafruit_BMP280::SAMPLING_X1,
// 圧力オーバーサンプリング Adafruit_BMP280::FILTER_OFF);
——————————————————–
これを参考にBME280で下記のようにしてみました。
———————-ここから—————————
I2CBME.begin(I2C_SDA, I2C_SCL, 100000); bool status;
// Passing a &Wire2 to set custom
I2C ports status = bme.begin(0x76, &I2CBME);
if (!status) { Serial.println(“Could not find a valid BME280 sensor, check wiring!”); while (1); }
// BME280をフォースモードで使いたい
bme.setSampling(Adafruit_BME280::MODE_FORCED, Adafruit_BME280::SAMPLING_X1, // 温度オーバーサンプリング
Adafruit_BME280::SAMPLING_X1, // 湿度オーバーサンプリング Adafruit_BME280::SAMPLING_X1, // 圧力オーバーサンプリング Adafruit_BME280::FILTER_OFF);
——————————————————–
この記述はエラーになってしまいました。

ChatGPT:

BME280をフォースモードで使いたいという目的はとても良いアプローチです。温度上昇の問題は、センサーの連続動作(通常モード)によって自身の発熱が影響している可能性があり、**フォースモード(MODE_FORCED)**はその回避に有効です。

さて、ご提示いただいたコードでエラーになってしまった原因ですが、Adafruit_BME280::setSampling() は、BMP280と違って オーバーロードの定義が異なるため、引数の数・順序・型が一致しない可能性があります。

BME280の setSampling() 正しい使い方

Adafruit の Adafruit_BME280 ライブラリでは、setSampling() の定義は以下のようになっています:

void setSampling(sensor_mode mode             = MODE_NORMAL,
                 sensor_sampling tempSampling = SAMPLING_X16,
                 sensor_sampling pressSampling = SAMPLING_X16,
                 sensor_sampling humSampling   = SAMPLING_X16,
                 sensor_filter filter          = FILTER_OFF,
                 standby_duration duration     = STANDBY_MS_0_5);

つまり、湿度の設定が pressSampling の後に来る必要があります。
あなたのコードでは順序が異なっているため、コンパイルエラーが発生しています。


✅ 正しい書き方(修正版)

bme.setSampling(Adafruit_BME280::MODE_FORCED, 
                Adafruit_BME280::SAMPLING_X1, // 温度
                Adafruit_BME280::SAMPLING_X1, // 圧力
                Adafruit_BME280::SAMPLING_X1, // 湿度
                Adafruit_BME280::FILTER_OFF,
                Adafruit_BME280::STANDBY_MS_0_5);

これでエラーは解消されるはずです。


🔁 補足:フォースモードでのデータ取得方法

フォースモードは、都度センサーに測定を指示する必要があります。以下のように、測定→待機→取得 の手順を踏む必要があります。

bme.takeForcedMeasurement();  // 測定をトリガー
float temperature = bme.readTemperature();
float humidity = bme.readHumidity();
float pressure = bme.readPressure() / 100.0F;

測定直後に readTemperature() などを呼び出せば最新データが取得できます。


💡まとめ

  • setSampling() の引数順序を正しくする
  • takeForcedMeasurement() を使って明示的に測定する

よかったらフォースモードでのサンプルループも一緒に提示しますよ!要ります?

あなた:

なるほど、コンパイルエラーはなくなりましたが、同じデータを表示し続けるようになりました。 補足:フォースモードでのデータ取得方法 に書かれていたようにしないといけないわけですね。 ということでサンプルコードをお願いします。

ChatGPT:

了解です!
フォースモードでは「測定を命令しないとデータが更新されない」ため、ループの中で takeForcedMeasurement() を毎回呼び出すのがポイントです。


✅ BME280 フォースモードでのサンプルコード

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

#define I2C_SDA 21  // 適宜変更
#define I2C_SCL 22  // 適宜変更
TwoWire I2CBME = TwoWire(0);  // 複数I2Cポートを使う場合

Adafruit_BME280 bme;  // BME280 オブジェクト

void setup() {
  Serial.begin(115200);
  delay(1000);

  I2CBME.begin(I2C_SDA, I2C_SCL, 100000);

  bool status = bme.begin(0x76, &I2CBME);
  if (!status) {
    Serial.println("Could not find a valid BME280 sensor, check wiring!");
    while (1);
  }

  // フォースモードでの設定
  bme.setSampling(Adafruit_BME280::MODE_FORCED,
                  Adafruit_BME280::SAMPLING_X1,  // 温度
                  Adafruit_BME280::SAMPLING_X1,  // 圧力
                  Adafruit_BME280::SAMPLING_X1,  // 湿度
                  Adafruit_BME280::FILTER_OFF,
                  Adafruit_BME280::STANDBY_MS_0_5);
}

void loop() {
  // 測定をトリガー(データ更新)
  bme.takeForcedMeasurement();

  // データ取得
  float temperature = bme.readTemperature();
  float humidity = bme.readHumidity();
  float pressure = bme.readPressure() / 100.0F;  // hPaに変換

  // 表示
  Serial.print("Temperature = ");
  Serial.print(temperature);
  Serial.println(" *C");

  Serial.print("Humidity = ");
  Serial.print(humidity);
  Serial.println(" %");

  Serial.print("Pressure = ");
  Serial.print(pressure);
  Serial.println(" hPa");

  Serial.println("-----------------------");

  delay(2000);  // 2秒ごとに更新
}

🔍 ポイントまとめ

  • bme.takeForcedMeasurement() を毎回呼ばないとデータが更新されない
  • delay() を入れてループ間隔を調整(最小でも数百ミリ秒あけるのが無難)
  • センサーが応答しないときは false を返すので、必要ならチェックも可能

これでセンサーの発熱による温度上昇の影響を抑えられると思います。
試してみて、気になる挙動があればいつでもどうぞ!

あなた:

ありがとうございました。 期待通りの結果が得られるようになりました。

ChatGPT:

おおっ、それはよかったです!✨
期待通りに動いてくれると気持ちいいですよね〜!

BME280は多機能だけど、フォースモードとかちょっとクセある設定があるので、今回のようにうまく使いこなせると強い味方になります💪

また何かあればいつでも気軽に聞いてくださいね〜!
電子工作、楽しんでください😄🔧📡

ChatGPT の回答は必ずしも正しいとは限りません。重要な情報は確認するようにしてください。


最終的なコードをコピーできるように再掲する。

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

#define I2C_SDA 21  // 適宜変更
#define I2C_SCL 22  // 適宜変更
TwoWire I2CBME = TwoWire(0);  // 複数I2Cポートを使う場合

Adafruit_BME280 bme;  // BME280 オブジェクト

void setup() {
  Serial.begin(115200);
  delay(1000);

  I2CBME.begin(I2C_SDA, I2C_SCL, 100000);

  bool status = bme.begin(0x76, &I2CBME);
  if (!status) {
    Serial.println("Could not find a valid BME280 sensor, check wiring!");
    while (1);
  }

  // フォースモードでの設定
  bme.setSampling(Adafruit_BME280::MODE_FORCED,
                  Adafruit_BME280::SAMPLING_X1,  // 温度
                  Adafruit_BME280::SAMPLING_X1,  // 圧力
                  Adafruit_BME280::SAMPLING_X1,  // 湿度
                  Adafruit_BME280::FILTER_OFF,
                  Adafruit_BME280::STANDBY_MS_0_5);
}

void loop() {
  // 測定をトリガー(データ更新)
  bme.takeForcedMeasurement();

  // データ取得
  float temperature = bme.readTemperature();
  float humidity = bme.readHumidity();
  float pressure = bme.readPressure() / 100.0F;  // hPaに変換

  // 表示
  Serial.print("Temperature = ");
  Serial.print(temperature);
  Serial.println(" *C");

  Serial.print("Humidity = ");
  Serial.print(humidity);
  Serial.println(" %");

  Serial.print("Pressure = ");
  Serial.print(pressure);
  Serial.println(" hPa");

  Serial.println("-----------------------");

  delay(2000);  // 2秒ごとに更新
}