Skip to main content
< All Topics
Print

【顯示】狀態燈使用 | ws2812b

簡介


想像你的機器人擁有一雙「會說話的眼睛」。WS2812B 全彩 LED 就像是機器人的表情符號,能透過色彩傳達即時訊息:藍燈閃爍代表正在尋找連線、紅燈恆亮發出危險警示、綠燈則象徵任務完成。這款「狀態燈」類別將複雜的色彩原理簡化為直覺的指令,讓開發者能輕鬆為作品加入如呼吸燈般的生命感,或是打造如同儀表板般的直觀視覺回饋,提升使用者互動的溫度與專業感。

在嵌入式系統開發中,單純的序列埠輸出(Serial Monitor)難以在離線狀態下提供資訊。dual2s 函式庫提供的 stateLED 類別,專為控制 WS2812B(NeoPixel) 可定址全彩 LED 而設計。它不僅支援基礎的 RGB 調色,更預設了常用的顏色列舉(Enum),讓開發者能以極簡的程式碼實現多變的視覺回饋。

硬體規格與配置

  • 控制腳位:GPIO 2 (DUAL2S_HW::WSLED)
  • 預設燈數:dual2s 常規版為 2 顆;mini 版則為 1 顆。
  • 擴充性:支援串接更多 WS2812B 燈珠,僅需於建構子中修改 NUM_LEDS 數值。

核心功能亮點

  1. 直覺的顏色列舉 (Color Enum): 不需記憶複雜的 RGB 數值,直接呼叫 stateLED::REDstateLED::BLUEstateLED::YELLOW 即可定義狀態,大幅提高程式碼的可讀性。
  2. 層次化的控制介面
    • 進階控制fillColor()setColor() 適合快速建立系統狀態燈。
    • 基礎控制fill()setPixel() 提供 0-255 的 RGB 細緻調色,滿足美工設計需求。
  3. 動態亮度管理: 內建 setBrightness() 函式,除了能節省功耗與保護視力外,還能配合迴圈輕鬆實作出「呼吸燈」或「漸暗」等高品質的視覺特效。
  4. 低資源佔用: 基於 Adafruit NeoPixel 底層最佳化,在 ESP32 上執行效率極高,不會干擾機器人的馬達控制或感測器讀取等高優先權任務。

快速入門建議

  • 初始化:在 setup() 中務必執行 myLED.begin(),否則 LED 將無法反應。
  • 安全性:WS2812B 在全亮(白色)時耗電較大,若串接大量 LED 時請注意電源供應是否充足。

dual2s控制器與環境


AI學伴


互動(1):基於函數庫 – dual2s

互動(2):基於範例程式

👉 你也可以在dual2s函數庫(./example/basic)中找到此範例程式。

/*=====================================================================================
yesio.net / 2026.03.12 / by nick
# Filename:01_stateLED.ino
# Function:WS2812b全採LED(statusLED類別)使用範例
  Test Code of dual2S's stateLED CLASS for ws2812b.
# dual2s:Buzzer Pin G2 & number 2. You can extend ws2812b number in G2.
# dual2s mini:Buzzer Pin G2 & number 1. You can extend ws2812b number in G2.
# Toolchain & Libs:ESP32 Arduino Core v3.3.5 (ESP-IDF v5.1), dual2s, Adafruit_NeoPixel.h
======================================================================================*/
#include <dual2s.h>

// 定義硬體腳位與 LED 數量
#define NUM_LEDS 2

// 宣告 stateLED 物件
// dual2s G2控制 ws2812b, DUAL2S_HW::WSLED
// 參數1:控制腳位, 參數2:燈數
stateLED myLED(DUAL2S_HW::WSLED, NUM_LEDS);

void setup() {
  Serial.begin(115200);
  Serial.println("=== stateLED WS2812B 測試開始 ===");

  // 1. 初始化 LED (必須呼叫)
  myLED.begin();
}

void loop() {
  Serial.println("\n--- 測試 1:進階控制 (fillColor 一鍵全亮 Enum 顏色) ---");
  myLED.fillColor(stateLED::BLUE);   delay(1000); // 全亮藍光 (代表連線)
  myLED.fillColor(stateLED::YELLOW); delay(1000); // 全亮黃光 (代表警告)
  myLED.fillColor(stateLED::RED);    delay(1000); // 全亮紅光 (代表攻擊)

  Serial.println("--- 測試 2:進階控制 (setColor 單顆控制 Enum 顏色) ---");
  myLED.clear(); // 先清除畫面
  
  // 讓第 0 顆 (左邊) 亮綠色,第 1 顆 (右邊) 亮紫色
  myLED.setColor(0, stateLED::GREEN);
  delay(500);
  myLED.setColor(1, stateLED::PURPLE);
  delay(1500);

  Serial.println("--- 測試 3:基礎控制 (setPixel 自訂 RGB 單顆顏色) ---");
  myLED.clear();
  // 自訂特殊的粉紅色 (R:255, G:20, B:147) 給第 0 顆
  myLED.setPixel(0, 255, 20, 147);
  // 自訂特殊的湖水綠 (R:32, G:178, B:170) 給第 1 顆
  myLED.setPixel(1, 32, 178, 170);
  delay(2000);

  Serial.println("--- 測試 4:基礎控制 (fill 自訂 RGB 全亮) ---");
  // 全亮自訂的暖白色 (R:255, G:200, B:100)
  myLED.fill(255, 200, 100);
  delay(1000);

  Serial.println("--- 測試 5:動態亮度調整 (setBrightness) ---");
  // 測試呼吸燈效果 (由亮變暗)
  Serial.println("--- 測試 5-1:由亮變暗 ---");
  for (int b = 255; b > 5; b -= 5) {
    myLED.setBrightness(b); // 動態改變亮度
    delay(100);
  }
  // 測試呼吸燈效果 (由暗變亮)
  Serial.println("--- 測試 5-2:由暗變亮 ---");
  for (int b = 5; b <= 255; b += 5) {
    myLED.setBrightness(b);
    delay(100);
  }
  delay(1000);

  Serial.println("--- 測試 6:清除畫面 (clear) ---");
  myLED.clear(); // 關閉所有燈光
  delay(2000); // 停頓 2 秒後,重新開始新一輪測試
}
Table of Contents