Arduino Uno R3 connected to an HC-SR04 ultrasonic sensor and SSD1306 I2C OLED display for a STEM DIY distance measurement project

親子 STEM DIY (第4課):用 Arduino OLED 顯示屏顯示超聲波測距結果|I²C 教學

完成上一課的 HC-SR04 超聲波測距實驗後,今次我們會再為專案加入一個 I²C OLED 顯示屏,讓 Arduino 直接在螢幕上顯示物件距離,不再需要每次打開電腦上的 Serial Monitor。

本課會使用 Arduino Uno R3、HC-SR04 超聲波感應器及 0.91 吋 SSD1306 OLED 顯示屏,製作一個簡單的距離顯示器。你會學習 I²C 通訊、OLED 程式庫安裝,以及如何將感應器讀數顯示在螢幕上。

本課學習重點

  • 認識 OLED 顯示屏及 I²C 通訊。
  • 學習將 OLED 顯示屏連接至 Arduino Uno R3。
  • 安裝及使用 Adafruit SSD1306 和 GFX 程式庫。
  • 將 HC-SR04 的測距結果顯示在 OLED 螢幕上。
  • 處理沒有收到有效回波的情況。

適合對象:Arduino 初學者、親子 STEM DIY、學生及 Maker
預計時間:約 30–45 分鐘(視乎經驗而定)
難度:入門至初階
前置課程:第 3 課 HC-SR04 超聲波測距教學

一、所需材料

  1. Arduino Uno R3 開發板:執行程式及連接各個模組。
  2. HC-SR04 超聲波感應器:測量感應器與物件之間的距離。
  3. 0.91 吋 I²C OLED 顯示屏(SSD1306、128 × 32):顯示測量距離。
  4. 麵包板及杜邦線:方便進行無焊接接線。
  5. USB 線及電腦:供電、上載程式及查看 Serial Monitor。

相關產品:

規格提示:本教學以 SSD1306、128 × 32 像素、I²C 介面的 0.91 吋 OLED 為基準。此款模組支援 3.3V–5V DC,常見 I²C 地址為 0x3C。其他 OLED 模組可能採用不同控制晶片、解像度或地址,請先核對實際產品規格。

二、甚麼是 OLED 顯示屏?

OLED 是 Organic Light-Emitting Diode(有機發光二極管)的縮寫。OLED 像素可以自行發光,不需要像傳統 LCD 一樣依靠背光,因此能在小巧的模組上顯示清晰文字及圖像。

在 Arduino DIY 專案中,OLED 常用來顯示感應器讀數、溫度、濕度、電池狀態、計時器及簡單選單。今次使用的 128 × 32 OLED,代表螢幕橫向有 128 個像素、縱向有 32 個像素,適合顯示距離數值及簡單提示。

三、甚麼是 I²C 通訊?

I²C(Inter-Integrated Circuit)是一種常用於微控制器與電子模組之間的通訊方式。一般四針 I²C OLED 會使用電源、地線,以及兩條訊號線:

OLED 接腳 功能 Arduino Uno R3
VCC 電源正極 5V(本教學所用模組支援 5V)
GND 電源地 GND
SDA 數據線 A4 / SDA
SCL 時鐘線 A5 / SCL

I²C 使用 SDA 傳送數據,並使用 SCL 提供時鐘訊號。由於顯示屏只需兩條主要數據線,因此可以節省 Arduino 的輸入輸出腳位。Arduino Uno R3 的 SDA 及 SCL 分別對應 A4 及 A5;如果開發板上有獨立標示 SDA、SCL 的接腳,也可以按照板上標示接駁。

接線注意:接線前先拔除 USB 電源;不要假設所有 OLED 都支援 5V;SDA 與 SCL 不可接反;OLED、HC-SR04 及 Arduino 必須共用 GND。

四、Arduino 接線方法

今課會保留上一課的 HC-SR04 接線,再額外連接 OLED 顯示屏。

1. HC-SR04 超聲波感應器

HC-SR04 腳位 Arduino Uno R3
VCC 5V
GND GND
Trig D9
Echo D10

2. OLED 顯示屏

OLED 接腳 Arduino Uno R3
VCC 5V
GND GND
SDA A4 / SDA
SCL A5 / SCL

Arduino Uno R3 與 HC-SR04 的實際接線照片。OLED 顯示效果可參考下方實測影片。

完成接線後,檢查 VCC、GND、SDA 及 SCL 是否正確,並確認沒有短路,才重新連接 USB 電源。

五、安裝 Arduino OLED 程式庫

本教學使用 Adafruit 提供的 SSD1306 及 GFX 程式庫,方便 Arduino 在 OLED 上顯示文字及圖形。

  1. 開啟 Arduino IDE。
  2. 在選單中開啟 Library Manager(程式庫管理員)。
  3. 搜尋 Adafruit SSD1306,並安裝。
  4. 搜尋 Adafruit GFX Library,並安裝。
  5. 如程式庫管理員提示需要安裝其他相依程式庫,請按提示完成安裝。

六、完整 Arduino 程式碼

以下程式會讀取 HC-SR04 的測量結果,再將距離顯示在 OLED 螢幕上。如果沒有收到有效回波,螢幕會顯示 No echo!。

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

const int trigPin = 9;
const int echoPin = 10;

const int screenWidth = 128;
const int screenHeight = 32;
const int oledReset = -1;
const int oledAddress = 0x3C;

Adafruit_SSD1306 display(
  screenWidth,
  screenHeight,
  &Wire,
  oledReset
);

void setup() {
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);

  Serial.begin(9600);

  if (!display.begin(
        SSD1306_SWITCHCAPVCC,
        oledAddress)) {
    Serial.println("OLED initialization failed!");
    while (true) {
      delay(100);
    }
  }

  display.clearDisplay();
  display.setTextColor(SSD1306_WHITE);
  display.setTextSize(1);

  display.setCursor(0, 0);
  display.println("Arduino Distance");

  display.setCursor(0, 16);
  display.println("Starting...");

  display.display();
  delay(1000);
}

void loop() {
  long duration;
  float distance;

  // Send the trigger pulse
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);

  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  // Wait up to 30,000 microseconds for an echo
  duration = pulseIn(echoPin, HIGH, 30000UL);

  display.clearDisplay();
  display.setTextColor(SSD1306_WHITE);
  display.setTextSize(1);

  display.setCursor(0, 0);
  display.println("Distance:");

  if (duration == 0) {
    display.setCursor(0, 16);
    display.println("No echo!");
    Serial.println("No echo - check sensor.");
  } else {
    distance = duration * 0.0343 / 2;

    display.setCursor(0, 16);
    display.print(distance, 1);
    display.println(" cm");

    Serial.print("Distance: ");
    Serial.print(distance, 1);
    Serial.println(" cm");
  }

  display.display();

  delay(200);
}

程式碼重點解說

1. 引入程式庫:Wire.h 負責 I²C 通訊;Adafruit_GFX.h 提供基本文字及圖形功能;Adafruit_SSD1306.h 用來控制 SSD1306 OLED。

2. 設定顯示屏尺寸及地址:本例使用 128 × 32 OLED,並設定 I²C 地址為 0x3C。如顯示屏沒有反應,應先確認實際地址及控制晶片。

3. 初始化 OLED:display.begin() 嘗試啟動顯示屏。如果初始化失敗,程式會在 Serial Monitor 顯示錯誤訊息並停止後續操作。

4. 讀取超聲波回波:pulseIn(echoPin, HIGH, 30000UL) 最多等待 30,000 微秒。若沒有收到有效回波,函式會回傳 0。

5. 計算距離:程式使用 duration * 0.0343 / 2 估算距離,單位為厘米。除以 2 是因為超聲波需要往返一次。

6. 更新畫面:setCursor() 設定文字位置,print() 輸出內容,而 display.display() 將緩衝區內容更新至 OLED。

七、實際測試及展示

完成接線、安裝程式庫及上載程式後,重新連接 Arduino USB 電源。OLED 應先顯示啟動畫面,然後開始顯示 HC-SR04 測量到的距離。

  1. 將一件平整物件放在 HC-SR04 前方。
  2. 觀察 OLED 上的距離數值。
  3. 慢慢將物件移近或移遠,留意數值是否隨之改變。
  4. 開啟 Serial Monitor,將鮑率設為 9600,對照序列輸出。
實際測試影片:OLED 讀數會隨物件移動而改變。影片中可看到約 23.0 cm、9.1 cm 及 3.5 cm 的不同讀數。

預期結果

測試情況 OLED 顯示
初始化期間 Arduino Distance / Starting...
收到有效回波 距離數值及 cm
沒有收到有效回波 No echo!

讀數可能與物件的實際距離略有差異。物件表面、反射角度、環境及感應器本身都會影響結果。

八、常見問題及排解方法

1. OLED 完全沒有顯示,怎麼辦?

先檢查 VCC 及 GND 是否正確、SDA 是否接至 A4 / SDA、SCL 是否接至 A5 / SCL,以及顯示屏是否支援目前的供電電壓。同時確認已安裝 Adafruit SSD1306 和 Adafruit GFX 程式庫。若仍然沒有顯示,可使用 I²C Scanner 程式檢查裝置地址。

2. OLED 初始化失敗,怎麼辦?

請確認顯示屏是否採用 SSD1306 控制晶片,以及程式中的解像度和 I²C 地址是否正確。並非所有 OLED 都使用相同控制晶片;其他型號可能需要不同的程式庫或初始化設定。

3. OLED 有顯示,但一直出現 No echo!,怎麼辦?

檢查 HC-SR04 的 VCC、GND、Trig 及 Echo 接線,並將平整物件放在感應器前方。物件過度傾斜或表面不適合反射超聲波,都可能令感應器收不到回波。

4. 為甚麼距離讀數會跳動?

超聲波讀數可能受到物件材質、角度、附近障礙物及環境溫度影響。可先固定感應器及使用平整物件測試;如想進一步改善穩定性,可學習多次取樣及平均值計算。

5. 可以使用其他尺寸的 OLED 嗎?

可以,但要確認顯示屏的控制晶片、通訊介面、解像度及電壓要求。更換不同型號後,可能需要調整程式中的螢幕尺寸、程式庫或顯示排版。

九、延伸 STEM DIY 挑戰

挑戰 A:加入距離警告
當物件進入指定距離範圍時,在 OLED 顯示 TOO CLOSE!,讓裝置除了顯示數值,亦能提供提示。

挑戰 B:加入 LED 指示燈
加入 LED 電路,讓 OLED 顯示實際距離,同時由 LED 顯示物件是否進入指定範圍。請為 LED 串聯合適的限流電阻。

挑戰 C:改善測量穩定性
連續測量數次並計算平均值,觀察是否能減少個別讀數波動。

挑戰 D:設計自己的顯示介面
在 OLED 加入標題、分隔線或簡單圖示,令畫面更容易閱讀。

十、總結

今課我們將 Arduino Uno R3、HC-SR04 超聲波感應器及 I²C OLED 顯示屏結合,完成一個可以直接顯示測距結果的電子裝置。透過這個專案,你學習了 I²C 通訊、OLED 初始化、程式庫使用,以及如何把感應器讀數顯示在螢幕上。

下一課將進一步介紹 SG90 伺服馬達,學習如何使用 Arduino 控制馬達角度,讓專案由「感應及顯示」進一步發展至「動作控制」。

正在尋找 Arduino 開發板、感應器、OLED 顯示屏或其他 STEM DIY 配件?歡迎瀏覽:

新昌電腦有限公司 Sun Cheong Computer Company Limited
深水埗鴨寮街 246 號地下

返回部落格