気圧センサー(MPL115A2)で大気圧と標高を測定して見ます

〔MPL115A1〕 〔LPS331AP/LPS25H〕   〔Arduinoの動かせ方入門に戻る〕


前の頁ではSPI接続のセンサーMPL115A1を使った記事でした、
ですので大気圧に標高(高度)やスケッチなどの少し詳しい話は前の頁を参照して下さい。
この頁では、ArduinoとI2C接続のMPL115A2センサーを使った記事で回路図とサンプルスケッチのみ記載します。

センサーモジュールはこちら(販売終了)を秋月電子で購入していますが、 *3) *5)
データシートはこちらを見て下さい、レビジョン(Rev 8, 06/2012)が新しいです。
新しいデータシートは校正係数のC11とC22は使用しない様に変更されています。
PS. *5)
モジュールは販売終了なのでストロベリーリナックスこちらを使いましょう、データシートもこのページに
あります。(ピン名称は大体同じ様ですが配置が異なります、"CAP"キャパシタはボード内に配線済み)

また、ArduinoでI2Cの基本概要等はこちらを参考にして下さい。
尚、PIC16F1938でMPL115A2(I2C)の記事はこちらを参照下さい。

《 配線図 》

配線図 左図のMPL115A2は左下がピン1番です。

I2C用プルアップ抵抗はデータシートに
47KΩと書いて有ったのでそれを使いました。
  ピンの構成図
 モジュールの電源ラインにはパスコン付きです。

 SHDNピンについて
 通常はVDDに接続します、GNDに接続するとスリープ
 状態に移行し1uAの消費電流になる様です。

 RSTピンについて
 通常はVDDに接続します、GNDに接続すると
 I2C接続ピンがハイ・インピーダンスになり
 I2C通信が出来なくなります。

 NCピンについて
 使用しないピンです。

注意
2013年3月現在、センサーモジュールが新型になっていますが、ここでは旧モジュールでの記述です。
新型は、電源通電用LEDが追加になっただけで端子配列は変わりません。 *1)

《arduinoのスケッチ》

@上記の回路の様に配線を行います。

Aarduinoボード(Arduino Duemilanove 328)はUSBケーブルで接続して、arduino IDEを起動させます

BIDEに下記のスケッチプログラムをコピーペーストして貼り付けて下さい。
 スケッチをダウンロードしたい方はこちら。(Arduino IDE 1.0.1にてコンパイル)
 ダウンロードスケッチの保存先と開き方はこちらを参照下さい。
---------------------------------------------------------------------
#include <Wire.h>

#define SENSOR_ADRS 0x60                  // MPL115A2のI2Cアドレス
#define AVE_NUM     20                    // 圧力・温度のA/D変換値を平均化する回数
#define H_CORRECT   80                    // 自宅でのセンサと実際の高度差補正値(My自宅の標高は100m)

float a0 , b1 , b2 , c12 ;                // 係数のデータを保存する変数
unsigned long Press , Temp ;              // 圧力および温度の変換値を保存する変数

void setup()
{
     // シリアルモニターの設定
     Serial.begin(9600) ;
     // I2Cの初期化
     Wire.begin() ;                       // マスターとする

     delay(3000) ;                        // 3Sしたら開始
     CoefficientRead() ;                  // メモリーマップから係数を読み出して置く
}
void loop()
{
     int i ;
     float ans ;
     unsigned long p , t ;

     p = t = 0 ;
     for (i=0 ; i < AVE_NUM ; i++) {      // 20回読み込んで平均化する
          PressureRead() ;                // メモリーマップから圧力および温度のA/D変換値を読み出す
          p = p + Press ;
          t = t + Temp ;
     }
     Press = p / AVE_NUM ;
     Temp  = t / AVE_NUM ;

     ans = PressureCalc() ;               // 気圧値の計算を行う
     Serial.print(ans) ;                  // 気圧値の表示を行う
     Serial.print(" hPa    ") ;
     ans = AltitudeCalc(ans,H_CORRECT) ;  // 高度の計算を行う
     Serial.print(ans) ;                  // 高度の表示を行う
     Serial.println(" m") ;

     delay(1000) ;                        // 1秒後に繰り返す
}
// メモリーマップから係数を読み出す処理
int CoefficientRead()
{
     int ans ;
     unsigned int h , l ;

     Wire.beginTransmission(SENSOR_ADRS) ;        // 通信の開始
     Wire.write(0x04) ;                           // 係数の読出しコマンド発行
     ans = Wire.endTransmission() ;               // データの送信と通信の終了
     if (ans == 0) {
          ans = Wire.requestFrom(SENSOR_ADRS,8) ; // 係数データの受信を行う
          if (ans == 8) {
               // a0の係数を得る
               h = Wire.read() ;
               l = Wire.read() ;
               a0 = (h << 5) + (l >> 3) + (l & 0x07) / 8.0 ;
               // b1の係数を得る
               h = Wire.read() ;
               l = Wire.read() ;
               b1 = ( ( ( (h & 0x1F) * 0x100 ) + l ) / 8192.0 ) - 3 ;
               // b2の係数を得る
               h = Wire.read() ;
               l = Wire.read() ;
               b2 = ( ( ( ( h - 0x80) << 8 ) + l ) / 16384.0 ) - 2 ;
               // C12の係数を得る
               h = Wire.read() ;
               l = Wire.read() ;
               c12 = ( ( ( h * 0x100 ) + l ) / 16777216.0 )  ;
               ans = 0 ;
          } else ans = 5 ;
     }

     return ans ;
}
// メモリーマップから圧力および温度のA/D変換値を読み出す処理
int PressureRead()
{
     int ans ;
     unsigned int h , l ;

     // 圧力および温度の変換を開始させる処理
     Wire.beginTransmission(SENSOR_ADRS) ;        // 通信の開始
     Wire.write(0x12) ;                           // 圧力・温度の変換開始コマンド発行
     Wire.write(0x01) ;
     ans = Wire.endTransmission() ;               // データの送信と通信の終了
     if (ans != 0) return ans ;
     delay(3) ;                                   // 変換完了まで3ms待つ

     // A/D変換値を得る処理
     Wire.beginTransmission(SENSOR_ADRS) ;        // 通信の開始
     Wire.write(0x00) ;                           // 圧力のHighバイトから読込むコマンド発行
     ans = Wire.endTransmission() ;               // データの送信と通信の終了
     if (ans == 0) {
          ans = Wire.requestFrom(SENSOR_ADRS,4) ; // A/D変換値データの受信を行う
          if (ans == 4) {
               // 圧力のA/D変換値を得る
               h = Wire.read() ;
               l = Wire.read() ;
               Press = ( ( h * 256 ) + l ) / 64 ;
               // 温度のA/D変換値を得る
               h = Wire.read() ;
               l = Wire.read() ;
               Temp = ( ( h * 256 ) + l ) / 64 ;
               ans = 0 ;
          } else ans = 5 ;
     }

     return ans ;
}
// 気圧値(hPa)を計算する処理
float PressureCalc()
{
     float ret , f ;

     f = a0 + ( b1 + c12 * Temp ) * Press + b2 * Temp ;
     ret = f * ( 650.0 / 1023.0 ) + 500.0 ;
     return ret ;
}
// 気圧値(hPa)から高度を計算する処理
float AltitudeCalc(float pressure,int Difference)
{
     float h ;

     h = 44330.8 * (1.0 - pow( (pressure/1013.25) ,  0.190263 )) ;
     h = h + Difference ;
     return h ;
}
---------------------------------------------------------------------
CIDEツールバーの赤枠部分「Upload」ボタンをクリックしてコンパイルとarduinoボードに書込みを行い
 ます。

upload

D正常終了後、画面の右側に有るアイコン「SerialMonitor」ボタンをクリックしてシリアルモニター画面
 を起動させると大気圧と高度が表示されます。

スケッチについて

スケッチはArduinoのWireライブラリを使用しています、Wireライブラリについては
「Arduino 日本語リファレンス」を参照下さい、または、こちらの頁を参照下さい。

関数のPressureRead( )とCoefficientRead( )から返される戻り値を下に記述しておきます。
  戻り値、0=正常終了 それ以外I2C通信エラー下記
       1=送ろうとしたデータが送信バッファのサイズを超えた
       2=スレーブ・アドレスを送信し、NACKを受信した
       3=データ・バイトを送信し、NACKを受信した
       4=その他のエラー
       5=データ受信エラー

その他は前の頁の記述を参照下さい。

ライブラリについて

上記のサンプルスケッチを簡単に利用出来る様にライブラリ化して置きました。
ライブラリを利用したい人は↓からダウンロードして下さい。
skMPL115A2.zip(2013/01/05)

解凍すると下の様に展開されます。
[skMPL115A2]─┬─[examples]───[Pressure]--- Pressure.pde
        ├ skMPL115A2.cpp
        ├ skMPL115A2.h
        └ keywords.txt
ArduinoIDE 1.0.1 がインストールされているフォルダー、インストール先を変更していないなら
[C:\Program Files\arduino-1.0.1\libraries]です。
この場所に上記解凍ファイルを[skMPL115A2]ディレクトリ丸ごと移動します。
また、ライブラリの登録や利用方法などの話はこちらを参考にして下さい。

I2Cスレーブアドレスについて  *2)

アドレス設定  アドレスは7ビットで表します、左図の1〜7ビットです。
 0ビット目はR/Wでこれはスレーブに対する読書き指示ビットです。
 R/W=0 : 書き込み要求です(スレーブは受信モード)
 R/W=1 : 読み込み要求です(スレーブは送信モード)

今回のMPL115A2アドレスは、7ビット"1100000"(0x60)です。("1100000"+R/W)
データシートには、
R/W=0 : "1100000"+"0"で0xc0
R/W=1 : "1100000"+"1"で0xc1
と8ビットで記載されています注意しましょう。
よってここでは
#define SENSOR_ADRS 0x60 // MPL115A2のI2Cアドレス
となっています。


※ このセンサーから読み出した"係数"につては、(私の記事は怪しい!)
  セッピーナさんの"PICでI2C - MPL115A2の大気圧計算法"を読んで下さい、詳しいです。 *4)




リンク切れ見直し(*5) 2020/03/21
記事一部追記(*4) 2018/03/20
リンク切れ見直し(*3) 2017/01/10
追記(*2) 2013/08/25
追記(*1) 2013/03/30


【きむ茶工房ガレージハウス】
Copyright (C) 2006-2020 Shigehiro Kimura All Rights Reserved.