上一篇文章提到了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秒,方便使用者紀錄,
掃完之後會顯示總共找到幾個裝置。
程式執行時的照片:
開機時顯示
掃描到裝置時顯示位址:
掃描結束後顯示找到幾個裝置: