独BOSCH社から気圧センサーがシリーズでリリースされてますが、その中で比較的性能が良くて安価な[BMP180]を使っていろいろと遊んでみたいと思います、気圧センサーなので当たり前ですが大気圧測定ができます、更に代表的な応用例として気圧から現在地点の標高を計算で求めることもできます。更に展開して、垂直方向移動速度(飛行機、エレベーターなど)の測定、GPS測位の3D化などいろいろと応用範囲があります。

今回は、

  1. 圧力センサーの基本知識の紹介
  2. サンプル・プログラムを使ってまずは気温・大気圧・標高をシリアルモニタ表示

の2つを記事にしてみました。

気圧センサー

方式はMEMSピエゾ抵抗式

従来からある水銀柱、アネロイド式などの機械式に対して今回使用するのは電子式のものでいわゆるMEMS(メムス、Micro Electro Mechanical Systems)というものです、電子式の中にも方式が何種類ありますが(ROHMマメ知識より)使用するBMP180気圧センサーはピエゾ抵抗式になります。この方式のものが代表的なようです。

下図にオムロン(株)のサイト掲載の構成図を引用しましたが、圧力変化でダイヤフラムが歪み、このダイヤフラムの歪を測定することで圧力値を求めます、歪量の測定にはダイヤフラムの表面にピエゾ抵抗体を貼りつけて電気信号に変換します。

ピエゾ抵抗式の気圧センサーは国内ではオムロン、ROHMTDKなどの各メーカーから供給されています。

注)MEMS(メムス)についてはこのサイトに判り易く説明が書いてあります。

BMP180モジュール仕様

今回使用するのは3.3Vレギュレータ搭載のBMP180モジュールです、BMP180単体は電源電圧が1.8V~3.6Vの範囲ですが5Vでも使えるように3.3VDCコンバータを搭載してます。

  • 電源電圧:2.0V~5.0V(モジュール) / 1.8V~3.6V(BMP180単体)
  • 気圧測定範囲:300~1100hPa
  • インタフェース:I2C(アドレス=0x77)
  • 圧力測定精度(相対):±0.12hPa(±1.0m) (@25℃/950~1050hPa)
  • 圧力測定精度(絶対):-4.0~2.0hPa (@25℃/950~1050hPa)
  • 温度測定精度(絶対):±1.0℃ typ. / ±2.0℃ max.  (0℃~65℃)
  • 測定分解能:0.01hPa(圧力)/ 0.1℃(温度)
  • BMP180は2015年から市場に投入されているが現在はディスコンで、後継のBP280に生産が引き継がれている。

BMP180データシート(BOSCHサイト)

BMP180の測定精度

圧力測定精度(絶対)の方は誤差が大きいですが圧力測定精度(相対)の方は±0.12hPaで高度換算で±1.0mの精度で測位可能です、絶対値の方は測定の都度に較正すれば良いので実質的には相対値測定が大きな意味を持ちます。

気圧は気温の影響を受けるので、気圧測定生データを補正するために温度センサーが内蔵されています。

ちなみに。オムロン製の最近のセンサーは±5cmが測定可能です。(但しフィルタ処理が必要ですが)

BMP180モジュール回路図

回路図というほどのものではないですが購入先からダウンロードしたものを下に示します。

  • DCコンバータ:5V→3.3Vに降圧、部品マーキングからすると多分これではと思います。
  • I2Cプルアップ抵抗:4.7KでSCL、SCKをプルアップ。

+

大気圧と標高の関係

カシオの計算サイト(地学)に計算式が載ってます。(計算式に至るまでの経過も記したサイトがこちら)

  • h=現在地点の標高(m)
  • T=現在地点気温(℃)
  • P=現在地点気圧(Pa)
  • P0=平均海面気圧(Pa)

 

 

 

 

この計算式に従ってプログラムに計算して標高を求めることになりますが、実際にはライブラリーが用意されているのでライブラリー関数を呼び出すだけで標高が求めらるので、自身で上式の計算をするプログラムコードを書く必要はありません。

 

BMP180モジュール外観

モジュールの画像です、左端に実装されている4ピンヘッダーで外部とI2C接続します。尚、供給電源は+5Vです。

BP180自身は3.3V仕様のためDCコンバータで5V→3.3Vへの変換をしてます。

 

 

 

こちらは裏面の外観画像です。4ピンヘッダー以外の部品実装はありません。

 

 

 ロジックレベル変換(双方向)モジュール(4ch)

  

5V系信号線と3.3V系信号線の電圧レベル変換を行うモジュールです。BMP180モジュール基板にはDCコンバータが内蔵されているため当初はこの変換モジュールは不要と踏んでいたのですが結果的には使うことになりました。

前述の様にBMP180単体の電源仕様は3.3v系列のチップ仕様となっていますがArduinoNanoの5V系でも使用できる様にBMP180モジュールはDCコンバータ(5V→3.3V)を内蔵しておりI2Cプルアップ抵抗も3.3Vに接続されています。

しかしながらArduinoNanoのデジタルピン出力がオープンドレイン仕様でないためArduinoNanoの信号出力5Vがプルアップ抵抗を経由してダイレクトにBMP180に印加されてしまうことが判りました、ということでArduinoNanoとBMP180間の信号線2本(SDA&SCL)に対しロジックレベル変換モジュールを追加。

下の画像が示すように信号線は独立して4チャンネルあり、各信号線は双方向です。

 

ブレッドボード組立&配線

ブレッドボード上で回路組立&配線をしていきます。

必要な部品は

  • ArduinoNano
  • BMP180モジュール
  • ロジックレベル変換モジュール
  • ブレッドボード
  • ジャンパー線

完成状態の画像を2方向から撮影(画像クリックで拡大)

 

回路図

作成中

ブレッドボード配線

ジャンパー線が混み入ってるので数段回にわけて画像を撮影。

①部品の配置

画像と同じように部品を配置する

ロジックレベル変換モジュール基板は方向性があるので配置の向きに注意のこと。

②SDA信号とSCL信号の接続(Arduino ⇔ レベル変換モジュール 間)

SDA[A4](緑)とSCL[A5](黄)をレベル変換モジュールに配線する

 

③SDA信号とSCL信号の接続(レベル変換モジュール ⇔ BMP180 間)

SDA[A4](緑)とSCL[A5](黄)をレベル変換モジュールからBMP180へ接続する

④BMP180の電源配線

+5V(赤) とGND(黒)を接続する

 

⑤ロジックレベル変換モジュール基板への電源配線(+5V)

+5V(赤) の配線をする

 

⑥ロジックレベル変換モジュール基板への電源配線(+3.3V & GND) —ここで完了—

+3.3V(橙) とGND(黒)を接続する

ここまでで配線は完了です、次はプログラミングに入ります。

スケッチの作成

ライブラリ

このBP180を使うには以下の2種類のライブラリーが必要です、

  • Wire.h=I2Cプロトコル制御ライブラリ
  • Adafruit_BMP085.h=BMP85/180共通制御ライブラリー

Wire.h:

I2Cプロトコル制御のライブラリです、I2Cプロトコルについてはこのサイトに詳しくかいてあるのでこちらを参照してください。BMP180は外部とのインターフェイスにI2Cを採用してまして、このI2Cプロトコルを簡単に使えるように用意されているライブラリーがWire.hです。尚、このライブラリーはArduinoIDEに標準でインストールされるので特に追加インストールする必要はありません。

ちなみに、種々のセンサー(デジタルタイプ:例えば温度センサー、加速度センサーなど)のものはほとんどがI2Cインタフェースを採用してます。

Adafruit_BMP085.h:

ライブラリ名はBMP85となってますが、BMP180と共通になっているライブラリーです、温度値読み取り関数[readTemperature()]、気圧読み取り関数[readPressure()]、標高読み取り関数[readAltitude()]などが用意されてます。

このライブラリはライブラリマネージャーを使い追加インストールする必要があります。入手先はAdafruits-BMP85-Libraryです。(ライブラリーインストール方法は省略、他のサイトを参照してください)

BMP180が使えるライブラリーは他にもSparkfan 社などからもリリースされてますが、どれを使うかはライブラリの中味をよく見て個人の好み等で選択すればよいと思います。

 

スケッチ本体

今回はライブラリサイト内に用意されているTest用スケッチを動作確認用として使用します。

ブラウザで(BMP085test.ino)を開きテキストデータをArduinoIDEにコピペしてください。

  • 39行:bmp.readTemperature()関数を使い現在地の温度(℃)を測定する
  • 43行:bmp.readPressure()関数を使い現在地の気圧(㎩)を測定する
  • 49行:bmp.readAltitude()関数を使い現在地の標高(m)を温度測定値と気圧測定値から計算する(但し海面気圧=101325Pa、現在地気温=15℃として計算)
  • 53行:bmp.readSealevelPressure()関数を使い海面気圧を計算する。
  • 61行:bmp.readAltitude()関数を使い現在地の標高(m)を温度測定値と気圧測定値から計算する(但し海面気圧=101500Pa、現在地気温=15℃として計算)

 

#include <Wire.h>
#include <Adafruit_BMP085.h>

/*************************************************** 
  This is an example for the BMP085 Barometric Pressure & Temp Sensor

  Designed specifically to work with the Adafruit BMP085 Breakout 
  ----> https://www.adafruit.com/products/391

  These displays use I2C to communicate, 2 pins are required to  
  interface
  Adafruit invests time and resources providing this open source code, 
  please support Adafruit and open-source hardware by purchasing 
  products from Adafruit!

  Written by Limor Fried/Ladyada for Adafruit Industries.  
  BSD license, all text above must be included in any redistribution
 ****************************************************/

// Connect VCC of the BMP085 sensor to 3.3V (NOT 5.0V!)
// Connect GND to Ground
// Connect SCL to i2c clock - on '168/'328 Arduino Uno/Duemilanove/etc thats Analog 5
// Connect SDA to i2c data - on '168/'328 Arduino Uno/Duemilanove/etc thats Analog 4
// EOC is not used, it signifies an end of conversion
// XCLR is a reset pin, also not used here

Adafruit_BMP085 bmp;
  
void setup() {
  Serial.begin(9600);
  if (!bmp.begin()) {
	Serial.println("Could not find a valid BMP085 sensor, check wiring!");
	while (1) {}
  }
}
  
void loop() {
    Serial.print("Temperature = ");
    Serial.print(bmp.readTemperature());
    Serial.println(" *C");
    
    Serial.print("Pressure = ");
    Serial.print(bmp.readPressure());
    Serial.println(" Pa");
    
    // Calculate altitude assuming 'standard' barometric
    // pressure of 1013.25 millibar = 101325 Pascal
    Serial.print("Altitude = ");
    Serial.print(bmp.readAltitude());
    Serial.println(" meters");

    Serial.print("Pressure at sealevel (calculated) = ");
    Serial.print(bmp.readSealevelPressure());
    Serial.println(" Pa");

  // you can get a more precise measurement of altitude
  // if you know the current sea level pressure which will
  // vary with weather and such. If it is 1015 millibars
  // that is equal to 101500 Pascals.
    Serial.print("Real altitude = ");
    Serial.print(bmp.readAltitude(101500));
    Serial.println(" meters");
    
    Serial.println();
    delay(500);
}

 

実行結果

ArduinoIDEのシリアルモニタ画面を使い気温・気圧・標高を表示させる。

注)スケッチの説明でも書きましたが、Altitude、SeaLevelPressure、RealAltitudeは計算パラメータに参考値を使用しているため実測値とは異なります。

今回はここで終了、次回の記事ににBMP180ライブラリの使用方法詳細を書く予定です。