Neon Sonic Echo (霓光聲波感應器) 提升居家生活品質設計的感應式霓虹療癒裝置
by linjustin96 in Circuits > LEDs
55 Views, 0 Favorites, 0 Comments
Neon Sonic Echo (霓光聲波感應器) 提升居家生活品質設計的感應式霓虹療癒裝置
這是一款專為提升居家生活品質設計的感應式霓虹療癒裝置。將手機這個現代人離不開的科技產品,轉化為療癒身心的核心。透過光影與聲音的視覺化同步,當你放下手機的那一刻,就是放鬆時刻的開始。在繁忙的一天過後,我們需要一個儀式來切換心情。透過感測,當你將手機靠近或放入底座,裝置會緩緩亮起柔和的霓虹光譜,它能將手機播放的舒緩音樂(如白噪音、冥想音樂、輕音樂),轉化為如同呼吸般起伏的燈光,營造出安穩、寧靜的居家氛圍。
Supplies
Downloads
電源系統
1. 電源系統 (Power Rail)
由於 LED 燈條在全亮時較耗電,請務必確認電源供應充足。
將 Arduino 的 5V 引腳連接到麵包板的正極軌。
將 Arduino 的 GND 引腳連接到麵包板的負極軌(地線)。
超音波感測器 (HC-SR04) — 負責手機偵測
2. 超音波感測器 (HC-SR04) — 負責手機偵測
VCC: 接麵包板 5V。
Trig: 接 Arduino D8。
Echo: 接 Arduino D9。
GND: 接麵包板 GND。
3. WS2812B LED 燈條 — 負責療癒光效
3. WS2812B LED 燈條 — 負責療癒光效
5V/VCC: 接麵包板 5V(若燈條顆數多,建議外接 5V 電源並與 Arduino 共地)。
DIN (Data In): 接 Arduino D2。
GND: 接麵包板 GND。
聲音感應模組 — 負責音樂同步
4. 聲音感應模組 — 負責音樂同步
VCC: 接麵包板 5V。
Out/Analog Output: 接 Arduino A0。
GND: 接麵包板 GND。
電位器 (Potentiometer) — 負責切換色系
5. 電位器 (Potentiometer) — 負責切換色系
側邊引腳 1: 接麵包板 5V。
中間引腳 (Wiper): 接 Arduino A1。
側邊引腳 2: 接麵包板 GND。
程式碼
ARDUINO 程式碼
#include <Adafruit_NeoPixel.h>
#define LED_PIN 2
#define NUM_LEDS 16
#define MIC_PIN A0
#define POT_PIN A1
#define TRIG_PIN 8 // 超音波發射
#define ECHO_PIN 9 // 超音波接收
Adafruit_NeoPixel strip(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);
const int sampleWindow = 50;
unsigned int sample;
void setup() {
strip.begin();
strip.setBrightness(150);
strip.show();
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
Serial.begin(9600);
}
void loop() {
// --- A. 超音波偵測距離 ---
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
long duration = pulseIn(ECHO_PIN, HIGH);
int distance = duration * 0.034 / 2; // 換算成公分
// --- B. 判斷開關門檻 (30公分內才啟動) ---
// 如果距離大於 30cm 或偵測不到 (0),就關燈
if (distance > 2 || distance <= 0) {
strip.clear();
strip.show();
Serial.print("OFF - Distance: "); Serial.println(distance);
delay(200); // 減少偵測頻率,節省效能
return; // 跳過後面的音樂與顏色運算
}
// --- C. 若有人靠近,執行原本的功能 ---
// 1. 讀取電位器 (切換色系)
int potValue = analogRead(POT_PIN);
// 2. 讀取聲音 (決定亮燈顆數)
unsigned long startMillis = millis();
unsigned int peakToPeak = 0;
unsigned int signalMax = 0;
unsigned int signalMin = 1024;
while (millis() - startMillis < sampleWindow) {
sample = analogRead(MIC_PIN);
if (sample < 1024) {
if (sample > signalMax) signalMax = sample;
else if (sample < signalMin) signalMin = sample;
}
}
peakToPeak = signalMax - signalMin;
int ledLevel = map(peakToPeak, 10, 110, 0, NUM_LEDS);
ledLevel = constrain(ledLevel, 0, NUM_LEDS);
// 3. 繪製燈光
for (int i = 0; i < NUM_LEDS; i++) {
if (i < ledLevel) {
uint32_t color;
if (potValue < 341) {
color = Wheel((i * 256 / NUM_LEDS) & 255); // 七彩
} else if (potValue < 682) {
color = strip.Color(map(i,0,15,0,255), map(i,0,15,0,255), map(i,0,15,255,0)); // 藍綠黃
} else {
color = strip.Color(255, 0, map(i,0,15,0,255)); // 紅紫
}
strip.setPixelColor(i, color);
} else {
strip.setPixelColor(i, 0);
}
}
strip.show();
// 除錯訊息
Serial.print("ON - Dist: "); Serial.print(distance);
Serial.print(" | Pot: "); Serial.println(potValue);
}
// 經典七彩顏色輪
uint32_t Wheel(byte pos) {
if(pos < 85) return strip.Color(255 - pos * 3, 0, pos * 3);
else if(pos < 170) { pos -= 85; return strip.Color(0, pos * 3, 255 - pos * 3); }
else { pos -= 170; return strip.Color(pos * 3, 255 - pos * 3, 0); }
}