chakokuのブログ(rev4)

テック・コミック・DTM・・・ごくまれにチャリ

WioTerminalからI2CでBME280と接続する

課題:IoTのサンプルシステムとして、温湿度を計測する(その後、IoT PFにアップしてグラフ化する)
取り組み:Wio TerminalとI2CでBME280で接続、温湿度を計測する
結論:2chあるI2Cの指定方法がちょっと腑に落ちなかったが、サンプルコードのお陰で温湿度計測まで試作できた

詳細:
I2CでBME280と接続したい。I2C通信する場合はWireモジュールを使うらしい。I2C用に2chあるようだが、無難にPIN_WIRE_SDA/Cを使うのがよかろうと。

/*
 * Wire Interfaces
 */
#define WIRE_INTERFACES_COUNT 2

#define PIN_WIRE_SDA (46ul)
#define PIN_WIRE_SCL (45ul)

#define PIN_WIRE1_SDA (78ul)
#define PIN_WIRE1_SCL (77ul)
  TwoWire Wire(&PERIPH_WIRE, PIN_WIRE_SDA, PIN_WIRE_SCL);

  void WIRE_IT_HANDLER(void) {
    Wire.onService();
  }
#endif

#if WIRE_INTERFACES_COUNT > 1
  TwoWire Wire1(&PERIPH_WIRE1, PIN_WIRE1_SDA, PIN_WIRE1_SCL);

  void WIRE1_IT_HANDLER(void) {
    Wire1.onService();
  }

と思ったが、I2C0に相当するWIREはうまくデバイスを発見できなかったので、I2C1に相当する、WIRE1を使うことにした。今回は時間をかけず効率良く作る必要があり、極力先人の公開ライブラリを使う方針。AdafruitのBME280のライブラリを使わせてもらう。

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

ほとんどサンプルそのままで何の工夫もノウハウもないのだが、動いたソースは以下

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

#define SERIAL_SPEED 115200
#define BME280_ADDR 0x76

//#define SEALEVELPRESSURE_HPA (1013.25)
#define SEALEVELPRESSURE_HPA (1020.5)    // sea level pressure at Osaka

Adafruit_BME280 bme;

int bme280_found = 0;

void setup() {
  // put your setup code here, to run once:

  extern int bme280_found;

  Serial.begin(SERIAL_SPEED);
  delay(10);

  //Wire.begin();
  //Wire1.begin();

  if (!bme.begin(BME280_ADDR, &Wire)) {       // spcifi Wire  (I2C0_SDA/SDC)
                                              // spcifi Wire1 (I2C1_SDA/SDC)
    Serial.println("Could not find a valid BME280 sensor, check wiring!");
    bme280_found = 0;
    //while (1);
  }else{
    bme280_found = 1;
  }
}

void loop() {

  extern int bme280_found;

  // put your main code here, to run repeatedly:
  //i2c_scan();

  Serial.println("--------------------------------------");
  if(bme280_found == 1){

    Serial.print("Temperature = ");
    Serial.print(bme.readTemperature());
    Serial.println("*C");

    Serial.print("Pressure = ");
    Serial.print(bme.readPressure() / 100.0F);
    Serial.println("hPa");

    Serial.print("Approx. Altitude = ");
    Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
    Serial.println("m");

    Serial.print("Humidity = ");
    Serial.print(bme.readHumidity());
    Serial.println("%");

  }else{

    Serial.println("Could not find a valid BME280 sensor, check wiring!");

  }

  //delay(1 * 1000); // wait  1 second for the next report
  delay(60 * 1000); // wait 60 seconds for the next report
}

変更した所としては、sea level pressureを大阪に合わせて、1020.5に変更したぐらいか
シリアルコンソールには以下と表示される

Temperature = 16.16*C
Pressure = 1017.04hPa
Approx. Altitude = 28.62m
Humidity = 54.81%

自分の部屋には、温湿度計が無いので上記が合っているか分からず、子供部屋の温湿度計を確認。
気温:13.6℃, 湿度:54% であった。大体あっている。
接続している外観は以下。裏側から線を出すのでちょっと収まりが悪い。GROVEポートからI2Cをつなぐと良いと思われる。

Wio TerminalとBME280の接続(何の疑問もなくI2Cを2.2Kでプルアップしているが、ひょっとするとWio terminalの基板に抵抗が付いているかも。。)

今回の実装上の不明点:
今回I2C0ではなく、I2C1を使っているのだが、BME280の初期化で、Wire1を指定するとデバイスが見つけられなかった。Workaroundとして、Wire1ではなくWireを指定。なぜWire1ではだめなのか?? ソースを追いかけないと分からない。
今後はこの計測値をJSON形式に変換して、IoT PFにアップロードする予定。MQTTは最低動いているのだが、Client証明書に対応しないと、まともなPFは受け取ってくれない。Wio Terminal の tutorialに Azure IoT Centralに接続する例があるので、Client証明書によるアップロードも資料があるのだろうと期待

■追記
Platform IOを2/23にインストールして、3日間でMQTT接続、I2Cによる温湿度計測まで試作できた。Arduinoの開発環境はライブラリが充実していて解説記事も多く、サクサク進む。すばらしい。

■参考URL
Interface BME280 Temperature, Humidity & Pressure Sensor with Arduino
GitHub - adafruit/Adafruit_BME280_Library: Arduino Library for BME280 sensors
Connecting to Microsoft Azure IoT Central - Seeed Wiki