Analog Discovery 2 (以下AD2)
http://qiita.com/7of9/items/09272fcfb56bd479c679
にて実装した気圧計基板。
通信を続けていると、ある時点から通信が失敗する。
AD2で通信をチェックしてみた。
code
http://qiita.com/7of9/items/09272fcfb56bd479c679#code-v02
を使用。
# 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
}
測定
SCLライン(正常時)
SCLがH/L切り替わっている。
SCLライン (失敗時)
SCLがHのままとなっている。
SCLが切り替わらなくなる原因は要調査。
ブレッドボード実装したときに、気圧計のICを一度反対に挿して通電してしまったが、それと関係があるのだろうか。
途中まで通信できて、途中から通信できなくなる、という現象はこれまで未経験だ。
関係するかどうか http://stackoverflow.com/questions/17287232/arduino-i2c-data-stream-stopped-unexpectedly
ブレッドボード実装
ブレッドボードでの実装をやり直した。
プルアップ抵抗もブレッドボード側にするため3枚目のユニバーサル基板を流用した。
AD2でSCLラインを測定した所、綺麗な波形となっている。平坦部分もきちんと出ている。
使用しているプルアップ抵抗(4.7k for SCL, SDA)とCAP用コンデンサ(105)はそれぞれ同じ値を今回のブレッドボードとユニバーサル基板でも使用しているつもりだが、何か見落としている事項があるのかもしれない。
ユニバーサル基板で通信が失敗していたときは30回程度しか通信できていなかったが、今回は600回の通信でもエラーが出ない。
再度、通信が失敗するユニーバーサル基板を見なおして気づいたのは、、、プルアップ抵抗をVccでプルアップしてない。
再度、ユニバーサル基板
プルアップしてない抵抗(シリーズに入っていた)をVccプルアップするように変更した。
以下のようにきちんとした波形となった。通信も途切れない。
@forth83 さん
お騒がせしました。
ありがとうございました。