google-site-verification: google3bd66dd162ef54c7.html

I2Cレジスタダンプ(i2cdumpもどき)も作った

 前回の記事でArduinoを使ったI2Cのデバイスが存在するアドレスを発見するスキャナーを作りました。

 せっかくアドレススキャナーのデバッグ用の回路をブレッドボードで作ったので、I2Cのデバイスに入って中のレジスタの内容をダンプする次のようなスケッチも作ってみました。これ、Linuxだとi2cdumpというコマンドと似た動きになっているはずです。(LinuxのI2C関係コマンドの解説ページの例)

/* 
 I2Cスキャン&ダンプ
 I2Cにデバイスが存在するアドレスを探し、
 そのデバイスのレジスタの内容を全部シリアルモニタに表示する。 
 2014/12/24 ラジオペンチ 
 http://radiopench.blog96.fc2.com/ 
 */

#include <Wire.h> 

void setup() 
{ 
  Wire.begin(); 
  Serial.begin(9600); 
  Serial.println(); 
  Serial.println("I2C Scan & Dump");        // 開始メッセージ 
} 

void loop() {
  byte i2cAdr;                               // I2Cアドレス

  for(i2cAdr = 8; i2cAdr <=0x77; i2cAdr++){  // 0x08~0xF7の範囲を探す
    if(IsExist(i2cAdr)==true){               // デバイスを発見したら
      Serial.print("Device found at 0x");
      Serial.println(i2cAdr,HEX);           // そのアドレスを表示

      dump(i2cAdr);                          // アドレス内のデーターをダンプ
    }  
  }
  Serial.println("END");
  for(;;){                                   // 無限ループで停止
  }
}  //loop

boolean IsExist(byte adr){
  byte dummy;
  Wire.beginTransmission(adr); 
  Wire.write(&dummy, 0);                     // 試しに書いてみて
  if (Wire.endTransmission() == 0) {         // 書き込みが正常終了していたら 
    return true;                             // アドレスが存在するのでtrueを返す 
  } 
  else{
    return false;
  } 
}  //IsExist

void dump(byte adr){                         // adr内のレジスタの内容をダンプ表示
  char moji[16];
  int i, p;
  byte n, data;
  Serial.println("     0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  < visible char >"); 
  for(i=0; i <= 0xFF; i++){                  // 全データ(0x00~0xFF)範囲
    n = i;
    if( (n & 0x0F) == 0){                    // 行の先頭なら
      print_hex2chr(n);                      // 行のアドレス表示
      Serial.print(":");
      for(p=0; p <=15; p++){                 // 文字表示バッファ初期化
        moji[p]=' '; 
      }
      p=0;
    } 

    Serial.print(" ");                      // データ間にスペース入れる 
    Wire.beginTransmission(adr); 
    Wire.write(n);                           // レジスタアドレス指定
    Wire.endTransmission();
    Wire.requestFrom(adr, 1U);               // 1バイトデーターリクエスト
    data =Wire.read();                       // データ読み出し
    print_hex2chr(data);                     // 表示
    if((data > 0x20) & (data < 0x7F)){       // 表示可能文字なら
      moji[p]=data;                            // バッファに記録
    }
    p++;

    if((n & 0x0F) == 0x0F){                  // 行末だったら、
      Serial.print("  ");
      for(p=0; p<=15; p++){
        Serial.print(moji[p]);              // バッファの文字を表示
      }
      Serial.println();                     // 改行
    }
  }
  Serial.println();
}  //dump

void print_hex2chr(byte x){                  // 16進2桁で出力 
  Serial.print((x >> 4),HEX);               // 上位 
  Serial.print((x & 0x0F),HEX);             // 下位 
}  // print_hex2chr
 このスケッチを実行するとI2Cアドレスをスキャンし、デバイスが存在するアドレスを発見したら、その中のレジスタを全部表示します。Linuxのコマンドでは表示するアドレスを指定しますが、Arduinoのプログラムでアドレス入力機能を付けるのは面倒なのでこういう仕様にしてみました。

 実際の実行結果は以下の通りです。この例ではアドレスの0x51にリアルタイムクロック(RTC-8564)、0x5Cに気圧センサ(LPS331)があり、そのレジスタの内容が表示されています。右側は対応するAsciiコードの文字です。


I2C Scan & Dump
Device found at 0x51
     0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  < visible char >
00: 08 80 B7 89 80 80 B0 21 00 88 81 90 92 B4 37 60         !      7`
10: 08 80 B7 89 80 80 B0 21 00 88 81 90 92 B4 37 60         !      7`
20: 08 80 B7 89 80 80 B0 21 00 88 81 90 92 B4 37 60         !      7`
30: 08 80 B7 89 80 80 B0 21 00 88 81 90 92 B4 37 60         !      7`
40: 08 80 B7 89 80 80 B0 21 00 88 81 90 92 B4 37 60         !      7`
50: 08 80 B7 89 80 80 B8 21 00 88 81 90 92 B8 3B 60         !      ;`
60: 08 80 B8 89 80 80 B8 21 00 88 81 90 92 B8 3B 60         !      ;`
70: 08 80 B8 89 80 80 B8 21 00 88 81 90 92 B8 3B 60         !      ;`
80: 08 80 B8 89 80 80 B8 21 00 88 81 90 92 B8 3B 60         !      ;`
90: 08 80 B8 89 80 80 B8 21 00 88 81 90 92 B8 3B 60         !      ;`
A0: 08 80 B8 89 80 80 B8 21 00 88 81 90 92 B8 3B 60         !      ;`
B0: 08 80 B8 89 80 80 B8 21 00 88 81 90 92 B8 3B 60         !      ;`
C0: 08 80 B8 89 80 80 B8 21 00 88 81 90 92 B8 3B 60         !      ;`
D0: 08 80 B8 89 80 80 B8 21 00 88 81 90 92 B8 3B 60         !      ;`
E0: 08 80 B8 89 80 80 B8 21 00 88 81 90 92 B8 3B 60         !      ;`
F0: 08 80 B8 89 80 80 B8 21 00 88 81 90 92 B8 3B 60         !      ;`

Device found at 0x5C
     0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  < visible char >
00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 C0 BD                  
10: 0F 1C 00 00 1B 6E 80 11 69 7A 70 00 77 26 1B A2       n  izp w&  
20: 00 00 00 00 00 00 00 00 00 48 2F 00 00 00 00 20           H/     
30: 00 00 AB A2 04 56 F5 4F 40 38 00 00 00 00 C0 00       V O@8      
40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00                  
50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00                  
60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00                  
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00                  
80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 C0 BD                  
90: 0F 1C 00 00 1B 6E 80 11 69 7A 70 00 77 26 1B A2       n  izp w&  
A0: 00 00 00 00 00 00 00 00 00 48 2F 00 00 00 00 20           H/     
B0: 00 00 AB A2 04 56 F5 4F 40 38 00 00 00 00 C0 00       V O@8      
C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00                  
D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00                  
E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00                  
F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00                  

END
 RTC-8564は16バイトごとに同じ値が返ってきています。たぶんアドレスのデコードを下位の4ビットだけやっているのだと思います。ちなみにRTCとして動いているので、データーの内容が途中で少し変わっています。一方のLPS331では128バイト毎に同じ値です。
 とりあえずこういうプログラムを準備しておけば、I2Cのデバイスでトラブルが起きた時の原因調査に便利ではないかと思います。

 なお、デバイスによってデーターを読むだけで状態が変わるレジスタを持っている場合があります。また、データーを読んだだけで予期せぬ動きをすることがあるかも知れません。このプログラムはそういう事情は全く無視しています。変な現象が起こるかも知れませんがご容赦下さい。
関連記事

コメントの投稿

管理者にだけ表示を許可する

カレンダー
09 | 2017/10 | 11
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31 - - - -
プロフィール

ラジオペンチ

Author:ラジオペンチ
電子工作を中心としたブログです。たまに近所(東京都稲城市)の話題など。60過ぎて視力や器用さの衰えを感じつつ日々挑戦!
コメントを入れる時にメールアドレスの記入は不要です。なお、非公開コメントは受け付けていません。

記事が気に入ったらクリックを!
最新記事
カテゴリ
最新コメント
リンク
FC2カウンター
検索フォーム
月別アーカイブ
RSSリンクの表示
QRコード
QRコード