記事
Toshihiko Minamoto · 2021年1月19日 6m read

2個のBME280で気象データを取得する

みなさん、こんにちは。

前回の記事では1個のBME280で気象データを取得したのですが、気温のブレが大きかったので基板から
ただ、基板につけたBME280のはんだを外すのが大変なので、別のBME280を外付けすることにしました。
当初、ESP8266の別のIO端子と接続することを考えていたのですが、Wire.hが複数のバスに対応していない
ため、以下の配線図のようにカスケード接続することにしました。

 

カスケード接続するということは、外付けのBME280でI2Cのアドレスを変えないといけません。幸いBME280は0x76と0x77の切り替えができるようです。
こちらの資料を見ると、基板上に3つの端子があり、左2つがつながると0x76,右2つがつながると0x77になるそうで、左2つの端子はつながっているので、ナイフで切断しなさいとなっていました。
で今回購入したセンサーを見ると、端子はあるけど左2つの端子の間はつながっていません。よく見るとセンサーの左下の端子の左側がつながっており、これで左2つの端子がショートしていることになります。
 
なので、センサーの左下端子の左側をカッターで切断しました。ルーペが無かったので、カミさんのスマホスタンドを借りて、スマホのカメラで拡大しながら、慎重に切断、テスターで抵抗値を確認... 50歳を過ぎたオッサンの作業としては非常に辛いものとなりました(笑)。

切断が確認されると今度は右2つの端子をはんだでつなぎました。加工後が以下の写真です。

  

プログラムは以下の通りです。前回のものから外付けBME280のインスタンスbme2を作成し、初期値としてbme2settingsを作成、I2Cのアドレスとして0x77を代入しています。

初期化はインスタンスbmeと同じでbme2.begin()で初期化を行い、bme2.read()で気象データを読み込み、編集に代入しています。
外付けBME280のデータは元々のbme280で使用しているトピック名の後ろに-2を取り付けて、別途MQTTブローカーにpublishしています。
また、電池が2日弱しかもたず省電力設定をする必要があったのですが、プログラムの作り直しは面倒でしたので、とりあえずsetup()の最初の方で

  wifi_set_sleep_type(LIGHT_SLEEP_T)

を実行し、Light sleepモードにしています。この1行で3日弱持つようになったので、およそ1日分長くなりました。

#include <PubSubClient.h>
#include <ESP8266WiFi.h>
#include <Wire.h>
#include <BME280I2C.h>

// 接続情報
const char *ssid = "********";
const char *password = "********";
const char *mqtt_server = "********";
const int mqtt_port = 8883;
const char *mqtt_user = "mqttclient";
const char *mqtt_pass = "********";

// 計測間隔 (60秒)
unsigned short interval = 60;
// クライアントID
char clientID[10];

// WiFiオブジェクト
WiFiClientSecure wifiClient;
// MQTTクライアントオブジェクト
PubSubClient mqttClient(wifiClient);

// BME280 外付けの設定
BME280I2C::Settings bme2settings(
   BME280::OSR_X1,
   BME280::OSR_X1,
   BME280::OSR_X1,
   BME280::Mode_Forced,
   BME280::StandbyTime_1000ms,
   BME280::Filter_16,
   BME280::SpiEnable_False,
   0x77
);

// BME280オブジェクト
BME280I2C bme, bme2(bme2settings);

void init_wifi();
void init_mqtt();

// センサーからの情報を集める
void collectSensors() {
   float temp(NAN), hum(NAN), pres(NAN);

   BME280::TempUnit tempUnit(BME280::TempUnit_Celsius);
   BME280::PresUnit presUnit(BME280::PresUnit_hPa);

  // トピック名
  String topic=String("point/")+String(clientID);

  // ボード直付けセンサーからの読み込み
   bme.read(pres, temp, hum, tempUnit, presUnit);

  Serial.println("センサー(ボード)");
  Serial.print("気温:");
  Serial.print(temp);
  Serial.println(" ℃");
  Serial.print("湿度:");
  Serial.print(hum);
  Serial.println(" %");
  Serial.print("気圧:");
  Serial.print(pres);
  Serial.println(" hPa");

  // データ
  String str=String(temp,2);
  str += String(",");
  str += String(hum,3);
  str += String(",");
  str += String(pres,5);

  // MQTTでサーバに送信
  mqttClient.publish((char *)topic.c_str(),(char *)str.c_str());

  // 外付けセンサーのトピック名
  topic=String("point/")+String(clientID)+String("-2");

  // 外付けセンサーからの読み込み
   bme2.read(pres, temp, hum, tempUnit, presUnit);

  Serial.println("センサー(外付け)");
  Serial.print("気温:");
  Serial.print(temp);
  Serial.println(" ℃");
  Serial.print("湿度:");
  Serial.print(hum);
  Serial.println(" %");
  Serial.print("気圧:");
  Serial.print(pres);
  Serial.println(" hPa");

  // データ
  str = String(temp,2);
  str += String(",");
  str += String(hum,3);
  str += String(",");
  str += String(pres,5);
  
  // MQTTでサーバに送信
  mqttClient.publish((char *)topic.c_str(),(char *)str.c_str());
}

 // 初期化処理
void setup() {
  Serial.begin(115200);
  Serial.println("起動");
  // 省電力モード(Light sleepモード)
  wifi_set_sleep_type(LIGHT_SLEEP_T);
  // I2Cインターフェースの初期化.
  Wire.begin(5,4);    // Define(SDA, SCL)
  init_wifi();
  init_mqtt();

  Serial.println("bmpの初期化(GPIO5[SDA],GPIO4[SCL]");
  while (!bme.begin()) 
  {
    Serial.println("ボード上のBME280センサーが見つかりました");
    delay(1000);
  }

  while (!bme2.begin()) 
  {
    Serial.println("外付けのBME280センサーが見つかりません");
    delay(1000);
  }
  
}
// WiFiの初期化
void init_wifi() {
    Serial.println("WiFiインターフェースを初期化します");
    WiFi.mode(WIFI_STA);

    connect_wifi();
}
void connect_wifi(){
   
    WiFi.begin(ssid,password);
    while( WiFi.status() != WL_CONNECTED ) {
      delay(500);
      Serial.print(".");
    }
  wifiClient.setInsecure();
    Serial.println("");
    Serial.println("WiFiネットワークに接続しました");
}

// MQTTの初期化
void init_mqtt() {
  // ClientIDの生成
  for (int i = 0; i < 8; i++) {
    clientID[i] = random(26)+65;
  }
  clientID[8]=0;

  mqttClient.setServer(mqtt_server, mqtt_port);
  
}

// メインループ
void loop() {
  // 計測開始時刻を取得
  unsigned long st = millis();
  if (!mqttClient.connected()) {
    reconnect();
  }
  collectSensors();
  // 計測終了時刻を取得
  unsigned long ed = millis();

  // 計測間隔から計測や転送に要した時間を差し引いた分Waitする
  delay(interval * 1000 - ( ed - st ));
}

void reconnect() 
{
  
  // Loop until we're reconnected
  while (!mqttClient.connected()) 
  {
    Serial.print("Attempting MQTT connection...");

    // Connect to the MQTT broker
    if (mqttClient.connect(clientID,mqtt_user,mqtt_pass)) 
    {
      Serial.println("connected");
    } else 
    {
      Serial.print("failed, rc=");
      Serial.print(mqttClient.state());
      Serial.println(" try again in 5 seconds");
      delay(5000);
    }
  }
}

これで測定した同じ日のデータを見比べてみると、左の外付けセンサーの方が温度が安定していることがわかりました。

外付けセンサー 基板設置センサー

    

00
1 0 0 37
Log in or sign up to continue