LoginSignup
1
3

More than 5 years have passed since last update.

AD2 > I2Cロジックを見てみた | アドレス0xA4の罠

Last updated at Posted at 2016-07-30
動作環境
ESP8266 (気圧計で使用したユニバーサル基板. I2Cは4.7kでプルアップ)
Analog Discovery 2 (以下AD2)
WaveForms 2015 on Windows 8.1 pro(64bit)

エピローグ

6:30の7of9
「先週に届いた某I2Cデバイスをサクッと動かそう。I2Cはいくつかやってきたので、もはや朝飯前(a peace of cake)だ」

9:30の7of9 (朝飯はもちろん食べ終わっている)
「UARTでの動作は確認した。配線も正しいようだ。I2Cのアドレスは取説に従い0xA4にしている。何が問題なのか。。。」

そして、Analog Discovery 2を使うことにした。

AD2でのI2Cロジック測定

配線

AD2のケースの下敷きに以下のような配線の説明図がある。
今回は「Digital I/O Signals」の0(ピンク色)と1(緑色)を使うことにした。

qiita.png

  • AD2 > Digital I/O Signals 0
    • I2CデバイスのSCLに接続
    • ESP8266のIO5(SCL)に接続
  • AD2 > Digital I/O Signals 1
    • I2CデバイスのSDAに接続
    • ESP8266のIO4(SDA)に接続

WaveFormsの設定

  • 左側のメニューの「Logic」を選択する
    • Logic 1のタブが開く
  • Logic 1ウィンドウの左側の「Click to Add channels」を選択し、I2Cを選択
    • Data: DIO 1
    • Clock: DIO 0
    • Addを選択
  • SCLの項目のT(初期値X)をクリックして、「Rising Edge」にする

RunボタンまたはSingleボタンでI2Cの波形が見れる。
波形を確定したいのでSignleボタンを使った。

Code v0.1

取説を参照して、以下のESP8266用コードにしてみた。

esp8266_160730_MSC-MOD20p1.ino
#include <Wire.h>

#define DEVICE_ADDRESS (0xA4)

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

  Wire.begin();
  Wire.setClock(100000L); // 100kHz
}

void loop() {
  helloWorld();
  delay(3000); // msec
}

void readData() {
  Wire.requestFrom(DEVICE_ADDRESS, /* length= */1);  
  char code = Wire.read();
  delayMicroseconds(30);

  Serial.println(code);
}

void helloWorld()
{
  Wire.beginTransmission(DEVICE_ADDRESS);
  Wire.write(0x0A);
  Wire.endTransmission(); 
  delayMicroseconds(30);

  for(int loop=0; loop<3; loop++) {
    readData();
  }
}

以下の動作になるはずだったが、ならなかった。

  • 0x0Aを送信
  • !00というコードを受信

波形

AD2で測定した波形。

qiita.png

AD2で確認したところ以下の点に気づいた。

  • アドレスが0xA4なのに0x24となっている

アドレス0xA4の問題

I2C通信をするとき、7ビットのアドレスを指定する。

取説に「アドレス0xA4」と書かれているとする。

「7ビットの0xA4アドレス」というのはあり得ないと気づいた。
0xA4は0b 1010 0100になるので、8ビットは必要となる。

おそらく、「Read/Writeビットを足して8ビットとした上での0xA4」というのが正しいのだろう、と思った。

code v0.2 > アドレス指定変更

code

#define DEVICE_ADDRESS (0xA4 >> 1)
とすることにより7ビットのアドレス値にした。

esp8266_160730_MSC-MOD20p1.ino
#include <Wire.h>

#define DEVICE_ADDRESS (0xA4 >> 1)

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

  Wire.begin();
  Wire.setClock(100000L); // 100kHz
}

void loop() {
  helloWorld();
  delay(3000); // msec
}

void readData() {
  Wire.requestFrom(DEVICE_ADDRESS, /* length= */1);  
  char code = Wire.read();
  delayMicroseconds(30);

  Serial.println(code);
}

void helloWorld()
{
  Wire.beginTransmission(DEVICE_ADDRESS);
  Wire.write(0x0A);
  Wire.endTransmission(); 
  delayMicroseconds(30);

  for(int loop=0; loop<3; loop++) {
    readData();
  }
}

結果

I2C通信ができるようになった。

qiita.png

シリアル出力
G
H
I

E
l
e
c
t
r
o
n
i
c
s
,

L
L
C



-
-
-
-
-
-
-
-
-
-
-
-

AD2がなかったら上記で1日をつぶしていたかもしれない。
これまででAD2の定価の3倍くらいは活躍している気がする。

1
3
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
3