DEV Community

張旭豐
張旭豐

Posted on

讓房間會呼吸:Arduino 感應燈 DIY(350元,一個晚上)

從黑暗裡找回那一盞燈

阿哲房間的書桌下面,總是黑黑的。

筆電的USB hub疊在上面,三塊外接硬碟排成一排,還有一個永遠懶得整理的整線盒。每次蹲下去找線,都是一場盲人的探險。

他不是沒想過裝燈。IKEA的LED燈條要七百塊,還要鑽孔。他租房子,怕房東說話。

想要,很想,但代價太高。

這是阿哲最真實的處境。


商業場景:這盞燈可以出現在哪裡

場景 需求
博物館展品 靠近時展品照明自動亮起,延長壽命、節省電力
店面櫥窗 有人經過時觸發動態燈光,吸引目光
展覽攤位 參觀者靠近時裝置「醒來」,他們離開後「睡去」
互動裝置原型 快速驗證概念,不需要量產電路

DIY 的意義不是「便宜」,而是「可以快速驗證想法,然後決定要不要投入更多」。


技術方案比較:選哪個感測器

感測器 成本 適用場景 限制
PIR(紅外線) 30元 大範圍有人/無人偵測 無法測量距離,只能偵測移動
Ultrasonic(超聲波) 60元 距離觸發、判斷「有多近」 外觀需要開孔,噪音環境可能誤觸
ToF(光飛行時間) 180元 精準距離測量、互動展示 成本較高,小組件

選型建議:原型驗證用 Ultrasonic;正式部署、对外展示用 ToF 或PIR。

本文以 Ultrasonic 為例(CP值最高)。


350元,電商平台就能買齊

材料 規格 價格
Arduino Nano 兼容版 130元
超音波感測器 HC-SR04 60元
RGB LED 燈條 WS2812B(30顆燈) 120元
麵包板 + 杜邦線 必要的配角 40元
總計 350元有找

材料今天訂,明天到。硬體費用跟一杯手搖差不多。


原理:它怎麼「看」到你

超聲波感測器,運作原理跟蝙蝠一樣:

  1. 發射一道超聲波(頻率太高,人耳聽不見)
  2. 超聲波碰到腿,反射回來
  3. 計算來回時間,除以二,再除以聲速
  4. 距離小於80公分 → 燈亮;超過30秒沒動 → 燈暗
// 這一行是整個互動的核心
if (distance < 80) {
  fadeIn();  // 燈認識你了
} else if (idleTime > 30000) {
  fadeOut(); // 晚安
}
Enter fullscreen mode Exit fullscreen mode

就是這樣。沒有祕密,沒有奇蹟,就是一個感測器,一塊晶片,和一行 if。


為什麼這比 TeamLab 還要酷

TeamLab 的互動展覽,底層邏輯跟這盞燈是一樣的:

感測 → 判斷 → 反應

TeamLab 的牆面有紅外線感測器陣列,紀錄人體的精確位置。這個套件只有一組超聲波,紀錄一個大概的距離。

規模不同,原理完全相同。

阿哲做完了這個專案,再去看 TeamLab,會看到牆面背後的演算法。他不再是「觀眾」,而是「知道秘密的人」。


從開箱到完成,一個晚上夠了

  1. 露天拍賣搜尋「Arduino Nano HC-SR04 WS2812B 套件」
  2. 明天材料到貨
  3. 下載 Arduino IDE(免費)
  4. 把下面這段程式碼貼進去,按上傳
#include <Adafruit_NeoPixel.h>

#define PIN 6
#define NUM_PIXELS 30
#define TRIG_PIN 9
#define ECHO_PIN 10
#define TRIGGER_DISTANCE 80
#define OFF_DELAY 30000

Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_PIXELS, PIN, NEO_GRB + NEO_KHZ800);
unsigned long lastMotionTime = 0;
bool isOn = false;

void setup() {
  strip.begin();
  strip.show();
  pinMode(TRIG_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);
}

void loop() {
  long duration, cm;
  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);
  duration = pulseIn(ECHO_PIN, HIGH);
  cm = duration / 29 / 2;

  if (cm > 0 && cm < TRIGGER_DISTANCE) {
    lastMotionTime = millis();
    if (!isOn) fadeIn();
  }

  if (isOn && (millis() - lastMotionTime > OFF_DELAY)) {
    fadeOut();
  }
}

void fadeIn() {
  for (int i = 0; i <= 255; i += 5) {
    strip.setBrightness(i);
    for (int j = 0; j < NUM_PIXELS; j++) {
      strip.setPixelColor(j, strip.Color(255, 240, 200));
    }
    strip.show();
    delay(20);
  }
  isOn = true;
}

void fadeOut() {
  for (int i = 255; i >= 0; i -= 5) {
    strip.setBrightness(i);
    for (int j = 0; j < NUM_PIXELS; j++) {
      strip.setPixelColor(j, strip.Color(255, 240, 200));
    }
    strip.show();
    delay(20);
  }
  isOn = false;
}
Enter fullscreen mode Exit fullscreen mode

需要 Adafruit_NeoPixel 函式庫:Arduino IDE → 草稿碼 → 匯入程式庫 → 管理程式庫 → 搜尋「Adafruit NeoPixel」→ 安裝。


原型 vs 正式部署:差距在哪裡

維度 DIY 原型 正式部署
供電 USB 或行動電源 12V/24V 變壓器 + 熔絲保護
外壳 裸機或3D列印 防水外壳 + 隱藏式安裝
誤觸 可能因環境噪音觸發 需要校準阈值 + 延遲
維護 可以隨時調整 需要考慮維護便利性
穩定性 長時間可能當機 需要看門狗電路

如果你想把 DIY 原型變成可以對外展示的產品,還有幾個關卡要過。我可以幫你評估你的硬體架構,設計控制邏輯,並建立一個可以穩定運作的原型。


完成之後

阿哲蹲下去找線的時候,燈自己會亮。

不用找手機的手電筒,不用用膝蓋感覺鑰匙在哪裡。

那盞燈知道他什麼時候需要光。

這就是互動設計的終極目標:讓環境主動適應你,而不是你去適應環境。


如果你正在建置博物館互動展示、店面感應燈、或展覽裝置,我可以幫你:

  • 選擇適合的感測器(PIR / Ultrasonic / ToF)
  • 設計控制邏輯與狀態機
  • 建立穩定的原型

Contact me for a paid consultation or prototype build.

GitHub 上有完整程式碼:github.com/techerHF/motion-sensor-templates


概念句:用超聲波感測器讓燈認識阿哲,350元,一個晚上。

Top comments (0)