上一篇文章提到了I2C bus好處之一就是可以多個裝置共用匯流排,

但這會產生一個問題,究竟我的I2C bus上有多少裝置?裝置的address

又在哪裡?

所以在Arduino上有人寫了一個 I2C scanner程式,可以讓你執行後

知道匯流排上有多少個裝置,然後所使用的address又是多少。

底下是本程式,可直接複製貼上使用沒有問題:

// I2C Scanner
// Written by Nick Gammon
// Date: 20th April 2011
#include <Wire.h>
void setup() { 
    Serial.begin (9600); // Leonardo: wait for serial port to connect 
    while (!Serial) { } 
    Serial.println (); 
    Serial.println ("I2C scanner. Scanning ..."); 
    byte count = 0; 
    Wire.begin(); 
    for (byte i = 8; i < 120; i++) { 
        Wire.beginTransmission (i); 
        if (Wire.endTransmission () == 0) { 
          Serial.print ("Found address: "); 
          Serial.print (i, DEC); 
          Serial.print (" (0x"); 
          Serial.print (i, HEX); 
          Serial.println (")"); 
          count++; 
          delay (1); // maybe unneeded? 
        } // end of good response 
    } // end of for loop 
    Serial.println ("Done."); 
    Serial.print ("Found "); 
    Serial.print (count, DEC); 
    Serial.println (" device(s).");
} // end of setup
void loop() {}

 

注意:原本程式上的serial port速度是115200,我這裡配合arduino原始設定

改成9600。這個速度只要能跟系統互相配合即可,可自行修改。

程式會輸出到序列埠監控視窗,可依照下圖開啟序列埠視窗,圖中的COM port需依照

你的系統去選擇,此COM位址並非固定,而是插上arduino後由視窗系統自動分配:

 

編譯完成後上傳到系統,將會得到如下結果:

 

這裡就顯示了掃描的結果,所以I2C模組本身預設的位址就是0x27,

這部份不管是賣模組的廠商或是網路搜尋到的文章中都顯得混亂,

如果你買的模組在A0 A1 A3都跟我上一篇文章中一樣是開路的話,

那就是0x27這個位址沒錯。

調整過A0-3之後也可以用此程式找出新的位址在哪裡,可以配合程式修改。

如果未來系統上也加入了別的I2C裝置,同樣可利用此程式找出新裝置的位址,

很實用的工具程式。

 

更新:

底下是我修改的scanner程式,將輸出由com port轉到LCD:

/*
本程式將I2C掃描結果輸出到I2C 1602A LCD上
作者:Lu yaku
日期:2018.04.17
 */
#include <Wire.h>
#include <LiquidCrystal_I2C.h>  

// 初始化 I2C 1602A LCD,I2C預設地址為0x27
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

void setup() { 

  lcd.begin(16, 2);
// LCD背光閃爍三次
  for(int i = 0; i < 3; i++) {
    lcd.backlight();    // 開啟背光
    delay(250);
    lcd.noBacklight();  // 關閉背光
    delay(250);
  }
  lcd.backlight();
    delay(250);
   lcd.setCursor(0, 0); // 設定游標位置在第一行行首 
   lcd.print("I2C scanner.");
   lcd.setCursor(0, 1); // 設定游標位置在第二行行首 
   lcd.print("Scanning ...");
   delay(1500);
    byte count = 0; 
    Wire.begin(); 
/*
I2C bus為7位元定址空間並保留前後各8個位址(共16個)不可使用,
所以掃描程式從位址8掃描到120即可 
 */
    for (byte i = 8; i < 120; i++) { 
        Wire.beginTransmission (i); 
        if (Wire.endTransmission () == 0) { 
    lcd.clear();
    lcd.setCursor(0, 0); 
    lcd.print ("Found address:"); 
    lcd.setCursor(0, 1); 
    lcd.print (i, DEC); 
    lcd.print (" (0x"); 
    lcd.print (i,HEX); 
    lcd.print (")"); 
    count++; 
    delay (5000); //找到I2C設備就顯示位址5秒
    
        } // end of good response 
    } // end of for loop 

lcd.clear();
    lcd.setCursor(0, 0); 
    lcd.print ("Done."); 
    delay (1500);
lcd.setCursor(0, 1);   
    lcd.print ("Found "); 
    lcd.print (count, DEC); 
    lcd.print ("device(s).");

} // end of setup
void loop() {}
 

因為LCD能顯示的內容跟com port不一樣,所以在輸出上有稍做修改,

每次找到新的I2C device就顯示I2C位置5秒,方便使用者紀錄,

掃完之後會顯示總共找到幾個裝置。

 

程式執行時的照片:

開機時顯示

 

掃描到裝置時顯示位址:

 

掃描結束後顯示找到幾個裝置:

 

創作者介紹
創作者 呂阿谷 的頭像
呂阿谷

呂阿谷的部落格

呂阿谷 發表在 痞客邦 留言(0) 人氣()