第12章 I²C 雙線通訊完整教學:Arduino Wire、位址掃描與 LCD1602 實作

發布日期: |更新日期:
文章主圖:第12章 I²C 雙線通訊完整教學:Arduino Wire、位址掃描與 LCD1602 實作

I²C(Inter-Integrated Circuit)是一種常見的同步序列匯流排,只需要 SDA 與 SCL 兩條訊號線,就能讓 Arduino 與多個感測器、顯示器或擴充晶片通訊。

本章將從 I²C 的基本原理、Arduino Uno 腳位、裝置位址與上拉電阻開始,接著實作 I²C Scanner 與 LCD1602 I²C 顯示器,建立後續使用 OLED、RTC、BMP280、MPU6050 等模組所需的基礎。

不同模組可能使用不同工作電壓與 I²C 位址。接線前應先確認模組規格,並避免將僅支援 3.3V 的裝置直接接到不相容的 5V 邏輯電位。

本章學習目標

  • 了解 I²C 的工作原理與匯流排概念。
  • 認識 SDA 與 SCL 的用途。
  • 了解 Arduino Uno 的 I²C 腳位。
  • 學會使用 Wire.h 函式庫。
  • 使用 I²C Scanner 找出模組位址。
  • 控制 LCD1602 I²C 顯示器。
  • 為 OLED、RTC、BMP280 等 I²C 模組建立通訊基礎。

什麼是 I²C?

I²C 是 Inter-Integrated Circuit 的縮寫,最初由 Philips Semiconductor 提出,後來由 NXP 延續發展。它是一種同步序列通訊匯流排,常用於同一塊電路板或短距離配線中的晶片與模組通訊。

I²C 最大的特色是只需要兩條訊號線,就能讓一個控制器與多個裝置共享同一組通訊線路。Arduino 專案中的 LCD1602 I²C、OLED SSD1306、RTC DS3231、BMP280、BME280、MPU6050、ADS1115、PCF8574、EEPROM、INA219 與 PCA9685 等模組,都常使用 I²C。

知識卡:I²C
項目 說明
全名 Inter-Integrated Circuit
中文常見名稱 積體電路間通訊
訊號線 SDA、SCL
通訊方式 同步序列通訊
Arduino 函式庫 Wire.h
Arduino Uno 腳位 SDA:A4、SCL:A5

為什麼 Arduino 專案常使用 I²C?

傳統平行介面的 LCD1602 通常需要 RS、E、D4、D5、D6、D7 等多條控制與資料線。當專案同時加入顯示器、感測器與時鐘模組時,Arduino 可用腳位很快就會不足。

改用 I²C 後,多個裝置可以共用 SDA 與 SCL。只要裝置位址不衝突,Arduino 就能透過位址選擇要通訊的模組,大幅節省腳位並簡化配線。

傳統 LCD1602 與 LCD1602 I²C 接法比較
比較項目 傳統 4-bit 平行介面 I²C 介面
主要訊號線數量 通常需要 6 條控制與資料線 只需要 SDA、SCL 兩條訊號線
Arduino 腳位占用 較多 較少
配線複雜度 較高 較低
多裝置擴充 需另外分配腳位 可共用同一條 I²C 匯流排

I²C 的兩條訊號線

SDA:序列資料線

SDA 是 Serial Data 的縮寫,用來傳送位址、資料與確認訊號。SDA 上的資料變化必須配合 SCL 時脈,通訊雙方才能正確判讀每一個位元。

SCL:序列時脈線

SCL 是 Serial Clock 的縮寫,由控制器提供時脈,使匯流排上的裝置依照相同節奏傳送與接收資料。

Arduino Uno 的 I²C 腳位

Arduino Uno 的 SDA 位於 A4,SCL 位於 A5。Uno R3 也在板子上另外提供標示為 SDA 與 SCL 的接腳,但電氣上仍與 A4、A5 相連。

同一條 I²C 匯流排上的所有裝置,通常需要共用 SDA、SCL 與 GND。各模組的 VCC 則必須依照模組規格連接 5V 或 3.3V。

Arduino Uno 與 I²C 模組基本接線
模組接腳 Arduino Uno 接腳 用途
VCC 依模組規格接 5V 或 3.3V 模組供電
GND GND 共用接地
SDA A4 或 SDA 序列資料
SCL A5 或 SCL 序列時脈

I²C 匯流排架構與裝置位址

I²C 採用控制器與受控裝置的匯流排架構。Arduino 在多數入門專案中扮演控制器,LCD、RTC、OLED、BMP280 或 MPU6050 等模組則是受控裝置。

每個 I²C 裝置都有位址。Arduino 傳送資料前,會先指定目標位址,再與對應裝置交換資料。常見 LCD1602 I²C 背板可能使用 0x27 或 0x3F,BMP280 常見位址則可能是 0x76 或 0x77,但實際位址仍應以模組規格或掃描結果為準。

使用 I²C Scanner 找出模組位址

當 LCD 沒有畫面,或感測器程式無法讀取資料時,位址設定錯誤是常見原因。I²C Scanner 會依序測試常用的 7-bit 位址範圍,並在 Serial Monitor 顯示有回應的裝置位址。

上傳程式前,先確認模組已正確供電、SDA 與 SCL 未接反,而且 Arduino 與模組已共用 GND。

#include <Wire.h>

void setup()
{
  Wire.begin();
  Serial.begin(9600);
  Serial.println("I2C Scanner");
}

void loop()
{
  byte error;

  for (byte address = 1; address < 127; address++)
  {
    Wire.beginTransmission(address);
    error = Wire.endTransmission();

    if (error == 0)
    {
      Serial.print("Found: 0x");

      if (address < 16)
      {
        Serial.print("0");
      }

      Serial.println(address, HEX);
    }
  }

  delay(5000);
}

預期掃描結果

開啟 Serial Monitor 並設定為 9600 baud。若模組位址是 0x27,預期會看到 Found: 0x27。若沒有找到任何位址,應先檢查供電、接地、SDA、SCL、模組電壓與接觸不良問題。

Wire.h 函式庫基礎

Arduino 的 I²C 程式通常需要先加入 Wire.h,並在 setup() 中呼叫 Wire.begin() 初始化 I²C。

#include <Wire.h>

void setup()
{
  Wire.begin();
}

void loop()
{
}
  • Wire.begin():初始化 I²C 通訊。
  • Wire.beginTransmission(address):開始對指定裝置位址傳送資料。
  • Wire.write():將資料放入傳送緩衝區。
  • Wire.endTransmission():結束傳送並取得通訊狀態。
  • Wire.requestFrom():向指定裝置要求資料。
  • Wire.available():確認接收緩衝區是否還有資料。
  • Wire.read():讀取接收到的一個位元組。

實作一:LCD1602 I²C 顯示文字

準備材料

  • Arduino Uno。
  • LCD1602 顯示器。
  • 相容的 I²C 轉接模組或已整合 I²C 背板的 LCD1602。
  • 杜邦線。

接線方式

LCD1602 I²C 與 Arduino Uno 接線表
LCD1602 I²C Arduino Uno
VCC 5V,仍應以模組規格為準
GND GND
SDA A4 或 SDA
SCL A5 或 SCL

顯示 Hello Arduino

下列範例使用常見的 LiquidCrystal_I2C 函式庫。不同函式庫的建構子或初始化函式可能不同,安裝前應確認函式庫文件與模組相容性。程式中的 0x27 必須改成 Scanner 實際找到的位址。

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 2);

void setup()
{
  lcd.init();
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("Hello Arduino");
}

void loop()
{
}

程式上傳後,LCD 第一行預期顯示 Hello Arduino。若背光亮起但沒有文字,可先調整 I²C 背板上的對比旋鈕,再確認位址與函式庫是否正確。

實作二:在 LCD 顯示 ADC 數值

此實作可搭配第 9 章的 analogRead()。將可變電阻中間腳接到 A0,另外兩腳接 5V 與 GND,再把讀到的 ADC 數值顯示在 LCD 第二行。

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 2);

void setup()
{
  lcd.init();
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("Analog Input");
}

void loop()
{
  int adcValue = analogRead(A0);

  lcd.setCursor(0, 1);
  lcd.print("ADC=");
  lcd.print(adcValue);
  lcd.print("    ");

  delay(200);
}

LCD 每 200 毫秒更新一次 A0 的 ADC 數值。程式在數值後補上空白,用來清除前一次顯示留下的多餘字元。

一條 I²C 匯流排可以連接多少模組?

I²C 可以讓多個裝置共用 SDA 與 SCL,例如同時連接 LCD、OLED、RTC、BMP280 與 MPU6050。能否正常共存,主要取決於裝置位址是否衝突、電壓是否相容、上拉電阻配置、線路長度、匯流排負載與供電品質。

若兩個模組使用相同且無法更改的位址,就不能直接在同一條 I²C 匯流排上獨立存取。可先查看模組是否提供位址選擇焊點,或使用 I²C 多工器等方式處理。

I²C 為什麼需要上拉電阻?

I²C 的 SDA 與 SCL 通常採用開漏極或開集極輸出。裝置主要負責把訊號線拉低,訊號線回到高電位則需要上拉電阻。

常見模組可能已內建約 4.7kΩ 的上拉電阻,因此單一模組短線測試通常不需要另外加裝。多個模組都內建上拉電阻時,等效阻值會下降;匯流排較長、模組較多或速度較高時,應依電壓、總電容與實際波形評估,不宜只憑固定阻值判斷。

I²C 通訊速度與配線限制

Arduino Wire 函式庫常以 100 kHz 標準模式運作,部分裝置也支援 400 kHz Fast Mode。是否能提高速度,必須同時確認控制器、所有受控裝置與配線條件。

速度越高,越需要縮短線材、降低雜訊、維持良好接地並正確配置上拉電阻。I²C 原本主要用於板級或短距離通訊,不適合直接當作長距離外部傳輸介面。

常見問題與故障排除

Scanner 找不到任何裝置

  1. 確認模組 VCC 與 GND 接線正確。
  2. 確認 Arduino 與模組共用 GND。
  3. 確認 SDA 接 A4 或 SDA,SCL 接 A5 或 SCL。
  4. 檢查 SDA 與 SCL 是否接反。
  5. 確認模組工作電壓與 Arduino 相容。
  6. 更換杜邦線或重新插拔,排除接觸不良。
  7. 確認程式已呼叫 Wire.begin()。
  8. 若模組允許更改位址,確認位址設定焊點或跳線狀態。

LCD 背光亮但沒有文字

  1. 使用 I²C Scanner 確認實際位址。
  2. 把程式中的 0x27 改成掃描結果。
  3. 調整 I²C 背板上的對比旋鈕。
  4. 確認 LCD 尺寸參數為 16 欄、2 列。
  5. 確認 LiquidCrystal_I2C 函式庫與範例程式相容。

多個模組接上後通訊不穩定

  1. 逐一接回模組,找出造成問題的裝置。
  2. 使用 Scanner 檢查是否有位址衝突。
  3. 縮短 SDA 與 SCL 線路,避免與馬達或高電流線路平行。
  4. 確認所有模組的邏輯電壓相容。
  5. 檢查多個模組內建上拉電阻造成的等效阻值是否過低。
  6. 先使用 100 kHz 測試,不要一開始就提高時脈。

本章實作練習

  1. 執行 I²C Scanner,記錄 LCD1602 I²C 模組的位址。
  2. 讓 LCD 第一行顯示 Hello Arduino。
  3. 將 analogRead(A0) 的 ADC 數值顯示在 LCD 第二行。
  4. 再接上一個 OLED、RTC 或感測器模組,重新掃描並記錄每個位址。
  5. 說明多個模組共用 SDA、SCL,卻能透過不同位址分別通訊的原因。

本章重點整理

  • I²C 是使用 SDA 與 SCL 的雙線同步序列匯流排。
  • Arduino Uno 的 SDA 是 A4,SCL 是 A5。
  • 多個 I²C 裝置可以共用同一組 SDA 與 SCL。
  • Arduino 透過裝置位址選擇通訊目標。
  • I²C Scanner 可以快速確認模組是否被偵測及其實際位址。
  • Wire.h 與 Wire.begin() 是 Arduino I²C 程式的基礎。
  • 穩定性除了位址之外,也受到工作電壓、上拉電阻、線路長度與匯流排速度影響。

下一章預告

第 13 章將介紹 SPI(Serial Peripheral Interface)高速序列通訊,包括 MOSI、MISO、SCK、SS 的用途、Arduino Uno 的 SPI 腳位,以及 SPI 與 I²C 的差異。

相關資源與文章匯出
下載 Arduino 入門基礎教材 下載 DOCX PDF/列印

← 回文章列表