【Raspberry Pi Pico入門 – 応用編】気温、気圧センサー

Raspberry Pi Pico入門,応用編Arduino,Raspberry Pi Pico

概要

今回は気温・気圧センサーのBMP280を使ってみます。気圧が計測できるとインターネットを使わずに天気を予測したり標高を計算したりするのに役に立ちます。またネット上では低気圧による頭痛の予測をしている方も見つかりました。

BMP280はI2C通信・SPI通信のどちらでも使えますが、標準設定ではIC内部の測定回数が1秒間に2回なので高速通信が特徴のSPI通信はメリットがないかと思い、通信線の本数が少ないI2C通信で動かしてみます。

実行環境

IDE:Arduino IDE 2.2.1
MCU:Raspberry Pi Pico

センサー:BMP280
秋月電子でも購入出来ますし、Amazonでも安く購入できます。

Amazon購入ページより引用

回路

以下のように配線します。
I2C通信で使用するためにCSBとVCCを接続しておきます。(CSBをLOWにするとSPI通信モードになる)
またI2C通信でのデバイスアドレスを決めるためにSDOとGNDを接続しておきます。(GND:0x76、Vcc:0x77)

回路図は下のようになっています。

ライブラリのインストール

ライブラリーマネージャーの検索欄に「BMP280」と入力し、以下のライブラリをインストールしてください。

コーディング

新しくスケッチを作成し、以下の内容をコピペしてください。

#include <Adafruit_BMP280.h>

Adafruit_BMP280 bmp;

void setup() {
  // シリアル通信初期化
  Serial.begin(115200);
  delay(2000);

  // BMP280初期化
  bool status = bmp.begin(BMP280_ADDRESS_ALT, BMP280_CHIPID);
  if (status = false) {
    Serial.println(F("Could not find a valid BMP280 sensor."));
    while (1) { // 無限ループ
      delay(1000);
    }
  }

  /* BMP280の設定 */
  bmp.setSampling(Adafruit_BMP280::MODE_NORMAL,     /* 動作モード:ノーマル */
                  Adafruit_BMP280::SAMPLING_X2,     /* 温度のオーバーサンプリング: 2回*/
                  Adafruit_BMP280::SAMPLING_X16,    /* 気圧のオーバーサンプリング: 16回*/
                  Adafruit_BMP280::FILTER_X16,      /* IIRフィルターの係数: 16 */
                  Adafruit_BMP280::STANDBY_MS_500); /* スタンバイ時間: 500ms */
}

void loop() {
  // 温度
  Serial.print(F("気温 = "));
  Serial.print(bmp.readTemperature());
  Serial.println(" *C");

  // 気圧
  // 測定結果の単位がPaなのでhPaに換算して表示
  Serial.print(F("気圧 = "));
  Serial.print(bmp.readPressure() / 100);
  Serial.println(" hPa");

  Serial.println();
  delay(2000);
}

動作確認

Arduino IDEのシリアルモニタを開き、2秒ごとに気温と気圧が表示されていれば成功です。

解説

関数の解説

begin()

センサーの初期化のための関数。内部で「Wire.begin()」が実行されているため、I2C通信の初期化は不要。

第一引数デバイスアドレスBMP280_ADDRESS(SDO=Vcc)
BMP280_ADDRESS_ALT(SDO=GND)
第二引数チップIDBMP280_CHIPID(デフォルト値)

setSampling()

センサーの設定をする関数。サンプリングと名前が付いているだけあって基本的には測定頻度に関する設定を行う。
BMP280は内部的には常に設定した周期で測定を行って、測定値を内部メモリに保存しています。I2C通信ではこの内部メモリに保存された値を受け取っていることになります。

第1引数以外は数字を大きくすると測定時間が長くなって精度が上がり、小さくすると測定時間が短くなり測定回数も減って消費電力が下がる。(デフォルトは1秒に1回以下の頻度で測定した時に最適になるよう調整していると思われる)

第1引数動作モードMODE_SLEEP
MODE_FORCED
MODE_NORMAL(デフォルト)
MODE_SOFT_RESET_CODE
第2引数温度のオーバーサンプリングSAMPLING_NONE
SAMPLING_X1
SAMPLING_X2(デフォルト)
SAMPLING_X4
SAMPLING_X8
SAMPLING_X16
第3引数気圧のオーバーサンプリングSAMPLING_NONE
SAMPLING_X1
SAMPLING_X2
SAMPLING_X4
SAMPLING_X8
SAMPLING_X16(デフォルト)
第4引数IIRフィルターの係数FILTER_OFF
FILTER_X2
FILTER_X4
FILTER_X8
FILTER_X16(デフォルト)
第5引数スタンバイ時間
(内部での測定周期)
STANDBY_MS_1
STANDBY_MS_63
STANDBY_MS_125
STANDBY_MS_250
STANDBY_MS_500(デフォルト)
STANDBY_MS_1000
STANDBY_MS_2000
STANDBY_MS_4000

readTemperature()

気温のデータを読み取ります。変数型がfloatなので注意してください。

readPressure()

気圧のデータを読み取ります。変数型がfloatなので注意してください。

今回使わなかった関数

readAltitude()

気圧データから標高を計算します。1気圧を基準に計算しているため天気が変わると誤差が出ます。また計算式がググって調べたものと異なっているので精度は不明。
実際に使うなら標高がわかっている場所でキャリブレーションが必要かも。