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(緑色)を使うことにした。
- 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用コードにしてみた。
# 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で測定した波形。
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ビットのアドレス値にした。
# 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通信ができるようになった。
G
H
I
E
l
e
c
t
r
o
n
i
c
s
,
L
L
C
-
-
-
-
-
-
-
-
-
-
-
-
AD2がなかったら上記で1日をつぶしていたかもしれない。
これまででAD2の定価の3倍くらいは活躍している気がする。