LoginSignup
2
2

More than 5 years have passed since last update.

ESP8266 > I2C通信が失敗する > SCLがでなくなっている > プルアップ抵抗をプルアップしてなかった

Last updated at Posted at 2016-05-31
動作環境
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切り替わっている。

qiita.png

SCLライン (失敗時)

SCLがHのままとなっている。

qiita.png

SCLが切り替わらなくなる原因は要調査。

ブレッドボード実装したときに、気圧計のICを一度反対に挿して通電してしまったが、それと関係があるのだろうか。
途中まで通信できて、途中から通信できなくなる、という現象はこれまで未経験だ。

関係するかどうか http://stackoverflow.com/questions/17287232/arduino-i2c-data-stream-stopped-unexpectedly

ブレッドボード実装

ブレッドボードでの実装をやり直した。
プルアップ抵抗もブレッドボード側にするため3枚目のユニバーサル基板を流用した。

DSC_0171.JPG

AD2でSCLラインを測定した所、綺麗な波形となっている。平坦部分もきちんと出ている。

qiita.png

使用しているプルアップ抵抗(4.7k for SCL, SDA)とCAP用コンデンサ(105)はそれぞれ同じ値を今回のブレッドボードとユニバーサル基板でも使用しているつもりだが、何か見落としている事項があるのかもしれない。

ユニバーサル基板で通信が失敗していたときは30回程度しか通信できていなかったが、今回は600回の通信でもエラーが出ない。

再度、通信が失敗するユニーバーサル基板を見なおして気づいたのは、、、プルアップ抵抗をVccでプルアップしてない。

再度、ユニバーサル基板

プルアップしてない抵抗(シリーズに入っていた)をVccプルアップするように変更した。

以下のようにきちんとした波形となった。通信も途切れない。

qiita.png

@forth83 さん
お騒がせしました。
ありがとうございました。

2
2
6

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
2
2