屋外高度測定をするために気圧計を購入。本日届いた。
http://akizukidenshi.com/catalog/g/gI-04596/
関連 http://qiita.com/7of9/items/02433dfcda8c840b878f
資料
【きむ茶工房ガレージハウス】 : 旧モジュールの情報?
回路
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プルアップで動作。
ブレッドボードで実装。
黄色: SCL
黄色と交差するオレンジ: SDA
緑色: GND
赤色: VCC
code v0.1
【きむ茶工房ガレージハウス】
のコードを参考にデータシートを見ながら変更した。
平均化処理は未実装。
#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
#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にしている。