1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

電子工作 > 気圧計到着 > MPL115A2(I2C接続) / ユニバーサル基板実装

Last updated at Posted at 2016-05-28

屋外高度測定をするために気圧計を購入。本日届いた。
http://akizukidenshi.com/catalog/g/gI-04596/

関連 http://qiita.com/7of9/items/02433dfcda8c840b878f

資料

DataSheet

【きむ茶工房ガレージハウス】 : 旧モジュールの情報?

回路

AQM0802接続に使ったユニーバサル基板を流用。
http://qiita.com/7of9/items/bf5a653d1925cbb38569

以下のように接続した。

  • ESP8266:SDA (IO4) <-> MPL115A2: SDA(Pin7)
  • ESP8266:SCL (IO5) <-> MPL115A2: SCL(Pin8)
  • EPS8266:VCC <-> MPL115A2: VDD(Pin1)
  • EPS8266:VCC <-> MPL115A2: SHDN(Pin4)
  • EPS8266:VCC <-> MPL115A2: RST(Pin5)
  • ESP8266:VSS <-> MPL115A2: GND(Pin3)
  • ESP8266:GND <-> 1uF <-> MPL115A2: CAP(Pin2)

SDAとSCLは4.7kでプルアップとデータシートにあるが、今回は基板の流用で10kプルアップで動作。

回路図 @ upverter

ブレッドボードで実装。
黄色: SCL
黄色と交差するオレンジ: SDA
緑色: GND
赤色: VCC

DSC_0168.JPG

code v0.1

【きむ茶工房ガレージハウス】
のコードを参考にデータシートを見ながら変更した。
平均化処理は未実装。

esp8266_160528_MPL115A2.ino
#include <Wire.h>

/*
 * v0.1 2016 May 28
 *   - add PrintPressure()
 *   - add ReadPressureAndTemperature()
 *   - add ReadCofficient()
 */

#define MPL_ADDR (0x60)

static float s_a0, s_b1, s_b2, s_c12; // 係数データ
unsigned long iPress, iTemp;

void setup() {
  Serial.begin(115200);
  Serial.println("");

  Wire.begin();
  delay(3000); // msec
  ReadCoefficient();
}

bool ReadCoefficient()
{
  int len;
  unsigned int hi, lw;

  Wire.beginTransmission(MPL_ADDR);
  Wire.write(0x04);
  len = Wire.endTransmission();
  if (len == 0) {
    len = Wire.requestFrom(MPL_ADDR, 8);
    if (len == 8) {
      hi = Wire.read();
      lw = Wire.read();
      s_a0 = (hi << 5) + (lw >> 3) + (lw & 0x07) / 8.0;
      hi = Wire.read();
      lw = Wire.read();
      s_b1 = ( hi & 0x1F) * 0x100 + lw;
      s_b1 = s_b1 / 8192.0 - 3.0;
      hi = Wire.read();
      lw = Wire.read();
      s_b2 = (hi & 0x80) << 8 + lw;
      s_b2 = s_b2 / 16384.0 - 2.0;
      hi = Wire.read();
      lw = Wire.read();
      s_c12 = (hi * 0x100) + lw;
      s_c12 = s_c12 / 16777216.0;

      Serial.println(s_a0);
      Serial.println(s_b1);
      Serial.println(s_b2);
      Serial.println(s_c12);      
      return true;
    }
  }
  return false;
}

bool ReadPressureAndTemperature()
{
  int len;
  unsigned int hi, lw;

  // 1. start conversion
  Wire.beginTransmission(MPL_ADDR);
  Wire.write(0x12);
  Wire.write(0x01);
  len = Wire.endTransmission();
  if (len != 0) return false;
  delay(3); // msec

  // 2. get values
  Wire.beginTransmission(MPL_ADDR);
  Wire.write(0x00);
  len = Wire.endTransmission();
  if (len == 0) {
    len = Wire.requestFrom(MPL_ADDR, 4);
    if (len == 4) {
      hi = Wire.read();
      lw = Wire.read();
      iPress = (hi * 256 + lw) / 64;
      hi = Wire.read();
      lw = Wire.read();
      iTemp = ( hi * 256 + lw) / 64;
      return true;      
    }
  }
  return false;
}

void PrintPressure()
{
  float prs, f0;
  f0 = s_a0 + ( s_b1 + s_c12 * iTemp) * iPress + s_b2 * iTemp;
  prs = f0 * ( (115.0 - 50.0) / 1023.0 ) + 50.0;
  Serial.print("Pressure=");
  Serial.println(prs);
}

void loop() {
  if (ReadPressureAndTemperature()) {
    PrintPressure();
  }
  delay(1000); // msec
}

結果 (v0.1) > 係数間違い

4つの係数と圧力(kPa)。

正しいのかは未確認。とりあえず通信はできている、という程度。
係数の計算式については要確認。

1905.00
-2.24
-2.00
0.00
Pressure=66.94
Pressure=66.83
Pressure=66.72
Pressure=66.83
Pressure=66.94
Pressure=66.72
Pressure=66.94
Pressure=66.94
Pressure=66.95
Pressure=66.71

code v0.2

係数がどうもおかしいようだった。

以下で係数の計算が詳しい。
http://seppina.cocolog-nifty.com/blog/2014/09/pici2c---mpl115.html

esp8266_160528_MPL115A2.ino
#include <Wire.h>

/*
 * v0.2 2016 May 29
 *   - fix bug > coefficients calculation
 * v0.1 2016 May 28
 *   - add PrintPressure()
 *   - add ReadPressureAndTemperature()
 *   - add ReadCoefficient()
 */

#define MPL_ADDR (0x60)

static float s_a0, s_b1, s_b2, s_c12; // 係数データ
unsigned long iPress, iTemp;

void setup() {
  Serial.begin(115200);
  Serial.println("");

  Wire.begin();
  delay(3000); // msec
  ReadCoefficient();
}

bool ReadCoefficient()
{
  int len;
  unsigned int hi, lw;

  Wire.beginTransmission(MPL_ADDR);
  Wire.write(0x04);
  len = Wire.endTransmission();
  if (len == 0) {
    len = Wire.requestFrom(MPL_ADDR, 8);
    if (len == 8) {
      hi = Wire.read();
      lw = Wire.read();
      s_a0 = (hi << 8) + lw;
      s_a0 /= 8.0;
      if (hi & 0x80) s_a0 -= 8192.0;
      hi = Wire.read();
      lw = Wire.read();
      s_b1 = (hi << 8) + lw;
      s_b1 /= 8192.0;
      if (hi & 0x80) s_b1 -= 8.0;
      hi = Wire.read();
      lw = Wire.read();
      s_b2 = (hi << 8) + lw;
      s_b2 /= 16384.0;
      if (hi & 0x80) s_b2 -= 4.0;
      hi = Wire.read();
      lw = Wire.read();
      s_c12 = (hi << 8) + lw;
      s_c12 /= 32768.0;
      if (hi & 0x80) s_c12 -= 2.0;
      s_c12 /= 512.0;

      Serial.println(s_a0);
      Serial.println(s_b1);
      Serial.println(s_b2);
      Serial.println(s_c12);      
      return true;
    }
  }
  return false;
}

bool ReadPressureAndTemperature()
{
  int len;
  unsigned int hi, lw;

  // 1. start conversion
  Wire.beginTransmission(MPL_ADDR);
  Wire.write(0x12);
  Wire.write(0x01);
  len = Wire.endTransmission();
  if (len != 0) return false;
  delay(3); // msec

  // 2. get values
  Wire.beginTransmission(MPL_ADDR);
  Wire.write(0x00);
  len = Wire.endTransmission();
  if (len == 0) {
    len = Wire.requestFrom(MPL_ADDR, 4);
    if (len == 4) {
      hi = Wire.read();
      lw = Wire.read();
      iPress = (hi * 256 + lw) / 64;
      hi = Wire.read();
      lw = Wire.read();
      iTemp = ( hi * 256 + lw) / 64;
      return true;      
    }
  }
  return false;
}

void PrintPressure()
{
  float prs, f0;
  f0 = s_a0 + ( s_b1 + s_c12 * iTemp) * iPress + s_b2 * iTemp;
  prs = f0 * ( (115.0 - 50.0) / 1023.0 ) + 50.0;
  Serial.print("Pressure=");
  Serial.println(prs);
}

void loop() {
  if (ReadPressureAndTemperature()) {
    PrintPressure();
  }
  delay(1000); // msec
}

結果(v0.2)

結果
1905.00
-2.24
-0.94
0.00
Pressure=100.48
Pressure=100.68
Pressure=100.60
Pressure=100.48
Pressure=100.60
Pressure=100.40
Pressure=100.60

気圧が100.48kPa = 1004.8hPa。
だいたいよく聞く気圧(1013hPa)のオーダーにはなった。

係数の4つ目は表示桁が少数2桁になってしまっている。

シリアル出力を続けていると途中で出力が止まってしまう。コードが悪いのか基板、電池が悪いのか要調査。

ユニーバサル基板実装

ユニバーサル基板実装した。

左はmicroSDで保存するための基板。
右が気圧計を実装した基板。

それぞれ、XHPコネクタから電源供給できるが、屋外使用のためにCR-123Aを直挿しできるようにした。
気圧計のプルアップ抵抗は4.7kにしている。

DSC_0170.JPG

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?