DEV Community

張旭豐
張旭豐

Posted on

互動裝置模組推薦:先問「人在什麼情境」,再選硬體

互動裝置模組推薦:先問「人在什麼情境」,再選硬體

你在淘寶看到十幾種 Arduino 模組套裝,價格從 200 元到 2000 元都有。客服說「這個套裝包含 30 種感測器,適合各種專題」。你下了單,收到快遞打開一看。

HC-SR04 超聲波、KY-037 聲音感測、PIR 紅外線、SW-420 震動開關、光敏電阻、濕度感測器,每種一片,全都沒有說明書。堆在桌上看起來很專業,但拿出來卻不知道從哪開始。

這不是你的問題。這是幾乎每個接觸互動裝置的人都會遇到的問題:拿到一堆模組,卻不知道它們各自服務什麼場景。

Three Arduino module setups: ultrasonic distance sensing, PIR motion detection, and pressure-sensitive input with IPO diagram on paper

互動裝置只有三件事:感知、判斷、動作

所有互動裝置的底層邏輯都可以用 IPO 模型解釋。

Input,輸入。裝置感知發生了什麼,例如有人靠近、溫度改變、被碰觸。

Process,處理。控制器讀取訊號,判斷這代表什麼。

Output,輸出。根據判斷結果,執行動作,例如發光、發聲、轉動、改變狀態。

買模組之前,先問自己一個問題:我的裝置要讓使用者在什麼情境下體驗什麼。答案決定了你需要什麼 Input 模組、什麼 Output 模組,以及兩者如何搭配。

情境一:人靠近,裝置有反應

人在哪裡:超聲波 vs PIR

超聲波感測(HC-SR04)

測量距離,範圍約 2cm 到 400cm。適合放在桌面或牆上,當人靠近到一定距離時觸發。

典型情境:桌上有一個小夜燈,當手靠近到 15cm 以內,燈光漸亮。手離開後燈光漸暗。

HC-SR04 的問題在於干擾。塑膠障礙物會造成誤讀,太靠近牆角也會有反射問題。如果感測範圍不需要那麼精確,可以把閾值設寬一點,例如「30cm 以內」而不是「精確的 20cm」。

// 超聲波距離感測基本模式
// 用途:當障礙物進入感測範圍時點亮 LED

// 超聲波模組接線
// VCC → 5V, GND → GND
// Trig → Pin 9, Echo → Pin 10

const int TRIG_PIN = 9;
const int ECHO_PIN = 10;
const int LED_PIN = 13;

void setup() {
  Serial.begin(9600);
  pinMode(TRIG_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);
  pinMode(LED_PIN, OUTPUT);
}

void loop() {
  // 發送超聲波脈衝
  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);

  // 讀取回波時間,單位微秒
  long duration = pulseIn(ECHO_PIN, HIGH, 60000);

  if (duration > 0) {
    // 計算距離:duration × 音速 / 2
    int distance = duration * 0.034 / 2;
    Serial.println(distance);

    // 距離門檻:30cm 以內就點亮 LED
    if (distance < 30 && distance > 2) {
      digitalWrite(LED_PIN, HIGH);
    } else {
      digitalWrite(LED_PIN, LOW);
    }
  }
  delay(100);
}
Enter fullscreen mode Exit fullscreen mode

調整方式:修改 distance < 30 的數值,數字越大感測範圍越寬。光線不好的環境用 HC-SR04 比紅外線更穩定。

Cozy room scene with Arduino ultrasonic sensor and LED responding to approaching hand

PIR 紅外線感測(HC-SR501)

偵測人體發射的紅外線熱源,範圍約 3 到 7 公尺,視角約 120 度。適合天花板安裝或大型空間。

典型情境:展場入口處有一個互動裝置,當參觀者走到距離 2 公尺內,裝置從休眠狀態醒來,開始展示動畫。

PIR 的問題是多個干擾源。冷氣出風口、日光直射、快速移動的窗簾,都會造成誤觸發。解決方式:用軟體過濾,連續偵測到訊號才觸發,而不是單次訊號就動作。

// PIR 紅外線感測加延遲消抖
// 用途:過濾快速變化的訊號,確認真的有人才動作

const int PIR_PIN = 7;
const int LED_PIN = 13;

int motion_count = 0;
const int TRIGGER_THRESHOLD = 3;  // 連續 3 次偵測到才觸發

void setup() {
  Serial.begin(9600);
  pinMode(PIR_PIN, INPUT);
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, LOW);
}

void loop() {
  int pir_state = digitalRead(PIR_PIN);

  if (pir_state == HIGH) {
    motion_count++;
    Serial.print("Motion detected: ");
    Serial.println(motion_count);

    if (motion_count >= TRIGGER_THRESHOLD) {
      // 確認有人,點亮 LED
      digitalWrite(LED_PIN, HIGH);
      Serial.println("Confirmed: person present");
    }
  } else {
    motion_count = 0;
    digitalWrite(LED_PIN, LOW);
  }

  delay(200);
}
Enter fullscreen mode Exit fullscreen mode

調整方式:如果環境有很多干擾,提高 TRIGGER_THRESHOLD。如果反應太慢,需要站著等 3 次偵測,降低數值。PIR 本身有可變電阻可以調整靈敏度和延遲時間,但那是固定參數,軟體過濾更彈性。

FSR 壓力感測(FSR-400 系列)

偵測按壓力度,適用近距離接觸。典型情境:展示台上有三個圓形按鈕,每個按下去代表不同的輸出模式。按「紅」切換成紅光,按「綠」切換成綠光。

FSR 不是開關,是類比輸入,可以偵測按壓的輕重。適合需要漸層回饋的設計,例如按越用力,馬達轉越快。

FSR 不是開關,是類比輸入,可以偵測按壓的輕重。適合需要漸層回饋的設計。以下是 FSR 搭配無源蜂鳴器的程式碼,輕按發出低音,重按發出高音。

// FSR 壓力感測基本模式
// 用途:按壓力度控制音調高低

const int FSR_PIN = A0;
const int BUZZER_PIN = 3;

void setup() {
  Serial.begin(9600);
  pinMode(BUZZER_PIN, OUTPUT);
}

void loop() {
  int pressure = analogRead(FSR_PIN);

  if (pressure > 50) {
    // 力度映射到頻率:50-1023 映射到 200-800 Hz
    int freq = map(pressure, 50, 1023, 200, 800);
    tone(BUZZER_PIN, freq, 100);
  }
  delay(50);
}
Enter fullscreen mode Exit fullscreen mode

調整方式:修改 map(pressure, 50, 1023, 200, 800) 的範圍參數,改變力度和音調的對應關係。如果想要更靈敏的設定,把 50 降低。

情境二:環境改變,裝置自動反應

環境感測:溫度、濕度、氣體

DHT22 溫濕度感測器

測量環境溫度和相對濕度,適合室內展示或小型環境監控。

典型情境:微型植物觀察箱內有兩個感測器。DHT22 測量溫度和濕度,當溫度超過 30°C,風扇自動開啟散熱。低於 18°C,加熱墊開始升溫。

DHT22 比 DHT11 精度高,但價格也貴約三倍。如果只是做「高於某溫度就觸發」的閾值判斷,DHT11 就夠用。

// DHT22 溫濕度感測加閾值觸發
// 用途:環境監控加簡單邏輯

#include <DHT.h>
#define DHTPIN 8
#define DHTTYPE DHT22

DHT dht(DHTPIN, DHTTYPE);
const int FAN_PIN = 6;
const int HEATER_PIN = 5;

void setup() {
  Serial.begin(9600);
  dht.begin();
  pinMode(FAN_PIN, OUTPUT);
  pinMode(HEATER_PIN, OUTPUT);
}

void loop() {
  // 讀取需要 2 毫秒以上
  float temp = dht.readTemperature();
  float hum = dht.readHumidity();

  if (!isnan(temp) && !isnan(hum)) {
    Serial.print("Temp: ");
    Serial.print(temp);
    Serial.print(" C, Humidity: ");
    Serial.print(hum);
    Serial.println(" %");

    // 溫度閾值控制
    if (temp > 30) {
      digitalWrite(FAN_PIN, HIGH);
      digitalWrite(HEATER_PIN, LOW);
    } else if (temp < 18) {
      digitalWrite(FAN_PIN, LOW);
      digitalWrite(HEATER_PIN, HIGH);
    } else {
      digitalWrite(FAN_PIN, LOW);
      digitalWrite(HEATER_PIN, LOW);
    }
  }
  delay(2000);
}
Enter fullscreen mode Exit fullscreen mode

調整方式:修改 30 和 18 這兩個閾值,適用不同的植物或物品保存需求。

Plant terrarium with DHT22 temperature/humidity sensor and MQ-2 gas sensor connected to Arduino, with fan running

MQ-2 氣體感測器

偵測 LPG、丙烷、沼氣、煙霧。適合有火源、燃料或封閉空間的互動裝置。

典型情境:展示區域擺放一個燃料博物館的小型情境模型。MQ-2 監測展示櫃內的氣體濃度,超過安全閾值時,警報燈亮起並發出聲響。

MQ 系列需要預熱。通電後等 1 到 2 分鐘,否則讀數不穩定。剛啟動時不要急著讀取感測值。

情境三:裝置給出可見、可聽的回饋

輸出模組:視覺、聽覺、動作

Dark staircase at night with warm white LED trail effect controlled by Arduino and PIR sensor, with buzzer nearby

WS2812B 可程式化 RGB LED(NeoPixel)

不需要 PWM 頻率設定,單一訊號線就可以控制整條燈帶或矩陣。顏色、亮度、動畫效果全部可程式化。

典型情境:樓梯扶手互動牆。每一級階梯嵌有一顆 WS2812B LED。當人走樓梯時,LED 從底部往頂部依序亮起暖白光,就像路燈隨腳步點亮的感覺。

// WS2812B 基本彩虹動畫
// 用途:視覺回饋,適用於樓梯、牆面、互動展示

#include <Adafruit_NeoPixel.h>
#define LED_PIN    6
#define LED_COUNT 12

Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  strip.begin();
  strip.show();  // 初始關閉所有 LED
}

void loop() {
  rainbowCycle(20);  // 20 毫秒延遲等於慢速彩虹
}

// 彩虹環移動動畫
void rainbowCycle(uint8_t wait) {
  static uint16_t firstPixelHue = 0;

  for (int i = 0; i < strip.numPixels(); i++) {
    uint32_t pixelHue = firstPixelHue + (i * 65536L / strip.numPixels());
    strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue)));
  }
  strip.show();
  delay(wait);
  firstPixelHue += 256;
}
Enter fullscreen mode Exit fullscreen mode

無源蜂鳴器 vs 有源蜂鳴器

如果需要聲音回饋,選有源蜂鳴器(內建震盪電路,給電就響)。選無源蜂鳴器(需要 PWM 訊號),可以發出不同音調。

典型情境:按壓力感測按鈕時,發出不同的確認音。輕按「嗶」,重按「嗶嗶」。無源蜂鳴器才能做到這個差異。

// 無源蜂鳴器發出不同音調
// 用途:按壓力大小給出不同音調確認

const int BUZZER_PIN = 3;
const int FSR_PIN = A0;

void setup() {
  pinMode(BUZZER_PIN, OUTPUT);
}

void loop() {
  int pressure = analogRead(FSR_PIN);

  if (pressure > 50) {
    int freq = map(pressure, 50, 1023, 200, 800);
    tone(BUZZER_PIN, freq, 100);  // 頻率根據按壓力度變化
  }
  delay(50);
}
Enter fullscreen mode Exit fullscreen mode

SG90 微型舵機

旋轉角度可控,適合需要動作輸出的互動裝置,例如指針、閥門、小的機械臂。

典型情境:桌面有一個顯示「今天心情指數」的小型指針儀表。當環境噪音越大,指針向右偏轉。安靜時,指針回到中央。

注意:舵機啟動時會有瞬間電流,如果供電不足(USB 直接供電),可能造成 Arduino 自動重啟。大型舵機建議外接電源。

SG90 是力道可控的旋轉輸出,適合指針和小型機械動作。以下是 SG90 搭配聲音感測(以環境噪音大小控制舵機角度)的範例。

// SG90 微型舵機基本模式
// 用途:根據類比輸入控制舵機角度

#include <Servo.h>
#define SERVO_PIN 9
#define SENSOR_PIN A0

Servo myservo;

void setup() {
  Serial.begin(9600);
  myservo.attach(SERVO_PIN);
}

void loop() {
  int sensorVal = analogRead(SENSOR_PIN);
  // 將感測器讀數映射到舵機角度(0-180度)
  int angle = map(sensorVal, 0, 1023, 0, 180);

  myservo.write(angle);
  Serial.print("Sensor: ");
  Serial.print(sensorVal);
  Serial.print(" -> Angle: ");
  Serial.println(angle);

  delay(100);
}
Enter fullscreen mode Exit fullscreen mode

調整方式:修改 map(analogVal, 0, 1023, 0, 180) 的最大值,改變舵機的旋轉範圍。如果舵機抖動,降低電壓或增加延遲。

模組選擇的核心思維:先情境,後規格

看完這三個情境,你會發現一件事。模組本身沒有最好或最厲害,只有這個情境適合不適合。

選擇超聲波(HC-SR04):當你需要測量精確距離,在一定範圍內偵測障礙物,例如桌面互動、機器人避障。

選擇 PIR(HC-SR501):當你需要偵測人體存在與否,覆蓋範圍大於 1 公尺,例如展場感應、自動化照明。

選擇 FSR(FSR-400):當你需要接觸式偵測,按壓力大小作為輸入變數,例如按鈕墊、踏墊、力度控制。

選擇 DHT22:當你需要環境溫濕度數據作為觸發條件,例如植物箱、儲存櫃、數據記錄器。

選擇 WS2812B:當你需要漂亮的視覺效果、動畫、多色控制,例如牆面裝置、樓梯感應、氛圍燈。

選擇無源蜂鳴器:當你需要不同音調回饋、簡單的語音提示。

選擇 SG90:當你需要機械動作輸出,但力量要求不大(拉力小於 1.5kg/cm)。

如果你想購買本文提到的模組,這裡是相關的 Amazon 搜尋連結:

Affiliate disclosure: As an Amazon Associate, I earn from qualifying purchases.

HC-SR04 超聲波感測器 — 測量距離,適合桌面互動

HC-SR501 PIR 紅外線感測器 — 人體紅外線偵測,適合展場和大型空間

FSR-400 壓力感測器 — 按壓力偵測,適合近距離接觸互動

DHT22 溫濕度感測器 — 環境監控,適合植物箱和數據記錄

WS2812B 可程式化 RGB LED 燈帶 — 視覺回饋,適合氛圍燈和牆面裝置

SG90 微型舵機 — 機械動作輸出,適合指針和小型機械臂

從選模組到完成原型:中間缺的那一步

這篇文章告訴你什麼情境選什麼模組,但從模組到一個真正的互動裝置,中間還有好幾步。

訊號處理的邏輯。Threshold 設多少,要不要加消抖。

Output 和 Input 的搭配方式。超聲波距離變化,LED 漸亮還是漸層閃爍。

供電設計。USB 供電穩定嗎,要不要外接電源。

如果你有明確的互動情境,想要有人陪你走過從想做到做出來這段路,我可以幫你。

一對一互動裝置原型顧問。從情境分析、模組選擇、電路連接、程式邏輯到完整作品,全程陪跑。

Fiverr: Arduino Interactive Prototype Generation

Affiliate disclosure: As an Amazon Associate, I earn from qualifying purchases.

Top comments (0)