Arduino Pro Mini+BMP180でI2Cを試す

3.3V版のArduino Pro Mini互換ボードを使って、3.3V動作のI2Cデバイスの動作確認をしてみました。

今回はBMP180を使います。これはボッシュ社製のI2Cインターフェース気圧センサで、コストパフォーマンスの良さと省電力が特徴です。

# BMP180仕様確認

[データシート](https://www.adafruit.com/datasheets/BST-BMP180-DS000-09.pdf)から抜粋します。

- 電源電圧：1.8Vから3.6V
- ロジック電圧：別途入力できるが、このボードでは電源電圧と共有
- 動作気温：-20℃から85℃
- 正確さを保証できる気温：0℃から65℃
- 相対誤差：Typ. ±0.12hPa
- 絶対誤差：Typ. -1hPa（Min. -4hPa / Max. +2hPa）
- RMSノイズ：0.03hPa（Ultra high resolution mode時）

# 準備

- Arduino Pro Mini 互換ボード（3.3V/8MHz）
- FT232RL使用 USB-TTLシリアル変換ケーブル
- BMP180モジュール（eBayで$1.29で購入）
- ブレッドボードなど

Arduino Pro MiniはI2Cで使うA4/A5ピンが通常使う足とは別の位置にあるので注意が必要です。

# 配線例

![DSC01520.JPG](https://qiita-image-store.s3.amazonaws.com/0/46856/5cc4d8b0-3190-7c2e-dc7c-b6e5bc9cd9ef.jpeg)

オスーメスのジャンパワイヤを使いました。

# ライブラリ

データシートを見る限り、I2Cで取得できる値は気温や気圧そのものではなく、気圧を求めるには煩雑な計算が必要そうです（データシート15ページ参照）。ここは自分で頑張るより先人の知恵に頼りましょう。

BMP180用のライブラリを探すと次の3つが見つかりました。

- [adafruit/Adafruit-BMP085-Library](https://github.com/adafruit/Adafruit-BMP085-Library)
- [adafruit/Adafruit_BMP085_Unified](https://github.com/adafruit/Adafruit_BMP085_Unified)
- [sparkfun/BMP180_Breakout_Arduino_Library](https://github.com/sparkfun/BMP180_Breakout_Arduino_Library/)

ライブラリを提供しているのはArduino界隈では有名なベンダー2社、AdafruitとSparkfunです。どれを選んでも一定期間のサポートが期待できそうですが、1番上のものが既存ユーザーが多そうなので、今回はこちらを使うことにしました。

ちなみにBMP085はBMP180の前のモデルで、両者には互換性があるようです。

# 実行例

ライブラリ付属のサンプルコードを元に次のようなスケッチを実行してみました。

```
#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 BMP180 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");

    Serial.println();
    delay(5000);
}
```

`Adafruit_BMP085::begin()`の第一引数で測定モードの切り替えが出来ます。デフォルト値は`BMP085_ULTRAHIGHRES`で、最も高精度なモードです。

これを実行すると次のような結果が得られます。

```
Temperature = 28.30 *C
Pressure = 100692 Pa

Temperature = 28.30 *C
Pressure = 100689 Pa

Temperature = 28.30 *C
Pressure = 100694 Pa

Temperature = 28.30 *C
Pressure = 100684 Pa

Temperature = 28.30 *C
Pressure = 100689 Pa
```

眺めていると±0.08hPaくらいのブレが出ているように見えます。「RMSノイズ：0.03hPa」というのは1σの意味らしいので±3σくらいまでは不思議ではないものの、感覚的には若干ブレすぎている気もします。謎ですね。

ちなみに高度や海面気圧を求めるメソッドもありますが、無引数で使っても使い物になりません。これは「高度がわかっているときに海面気圧を求める」「海面気圧がわかっているときに高度を求める」というメソッドです。GPS情報などを元に現在位置の海面気圧が求まるようなら高度計として使えるというわけです。