# 「黑盒子」
製作者:黃鈺晴、林柔劭
### 設計理念
![image](https://hackmd.io/_uploads/SyGOx4d46.png)
偏向藝術裝置的創作,黑色盒子像是育幼著某種生命體的遺跡聖物,內部脈動的視覺變化會隨著觀眾的某些移動觸發改變。
雖然意義虛玄,型態原始,在未來「生命體」會持續被進化改良。
### 具體功能造型
在最初我們的構思較為單純,
盒子內部有燈條,外接超音波感測器測距。
利用當互動者與盒子的距離發生變化,讓盒子內部的燈條產生不同變化(如速度與一色)的發光行為。
現階段我們想讓盒子的表現更為豐富,並且在測試過後決定將燈條從主角移至配角。
於是開始著手研究如何加入其他感測器和輸出裝置,使盒子產生更多動態與聲音。
### 材料質地
外殼使用材料基本上使用現成的物品組合。例如鐵籃、玻璃紙、鋁箔紙等。
### 機構電路與程式
這邊給的會是第一版的功能,後續的優化還在趕工當中。
使用FastLED的函式庫以及ChatGPT的大力相挺,模擬出當距離變化使多段燈條產生變化的畫面。~~(其實在如何讓多段LED燈條在同一個控制板上發光卡了很久😢)~~
![image](https://hackmd.io/_uploads/H1Wpi-zU6.png)
材料:(有些沒有在這張圖中出現因為模擬器貌似沒有提供)
- 電池(電源用)
- 330 歐姆電阻
- 電容器1000 微F
- 超音波模組HC-SR04
- Arduino UNO
- 燈條 WS2812
- 麵包板
```
#include <FastLED.h>
#define NUM_LEDS_PER_STRIP 18
#define NUM_STRIPS 6
#define TRIGGER_PIN 7
#define ECHO_PIN 6
#define TRIG_DISTANCE 30 // detection distance in centimeters
int dataPins[NUM_STRIPS] = {8, 9, 10, 11, 12, 13}; // Example pins, adjust as needed
CRGB leds[NUM_STRIPS * NUM_LEDS_PER_STRIP];
void setup() {
Serial.begin(9600);
// Initialize LED strips
FastLED.addLeds<WS2812, 8, GRB>(&leds[0], NUM_LEDS_PER_STRIP);
FastLED.addLeds<WS2812, 9, GRB>(&leds[NUM_LEDS_PER_STRIP], NUM_LEDS_PER_STRIP);
FastLED.addLeds<WS2812, 10, GRB>(&leds[2 * NUM_LEDS_PER_STRIP], NUM_LEDS_PER_STRIP);
FastLED.addLeds<WS2812, 11, GRB>(&leds[3 * NUM_LEDS_PER_STRIP], NUM_LEDS_PER_STRIP);
FastLED.addLeds<WS2812, 12, GRB>(&leds[4 * NUM_LEDS_PER_STRIP], NUM_LEDS_PER_STRIP);
FastLED.addLeds<WS2812, 13, GRB>(&leds[5 * NUM_LEDS_PER_STRIP], NUM_LEDS_PER_STRIP);
pinMode(TRIGGER_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
}
void loop() {
// Get distance from ultrasonic sensor
int distance = getDistance();
// Choose LED behavior based on distance
if (distance < TRIG_DISTANCE) {
angstyVibe(); //當觀看者非常靠近時LED會開始隨機閃爍給出一個躁動的畫面
}
else if (distance >= TRIG_DISTANCE && distance < 70) {
fasterPulse(); //當觀看者靠近時LED顏色的移動會越來越快
}
else {
normalBehavior(); //在遠處時光線會規律的漸變顏色
}
}
int getDistance() {
// Function to get distance from ultrasonic sensor
digitalWrite(TRIGGER_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIGGER_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIGGER_PIN, LOW);
return pulseIn(ECHO_PIN, HIGH) * 0.034 / 2; // Convert pulse duration to centimeters
}
void normalBehavior() {
// Function for normal LED behavior
// Implement the light pattern for regular shining and pulsing
static uint8_t paletteIndex = 0;
CRGBPalette16 purplePalette = CRGBPalette16(
CRGB::Magenta,
CRGB::DarkViolet,
CRGB::Black,
CRGB::Black,
CRGB::Magenta,
CRGB::Magenta,
CRGB::Linen,
CRGB::Linen,
CRGB::Magenta,
CRGB::Magenta,
CRGB::Black,
CRGB::Black,
CRGB::DarkViolet,
CRGB::DarkViolet,
CRGB::Linen,
CRGB::Linen);
//adjust the palette
//gradual change speed & speed change too
for (int i = 0; i < NUM_STRIPS; i++) {
fill_palette(&(leds[i * NUM_LEDS_PER_STRIP]), NUM_LEDS_PER_STRIP, paletteIndex + i * 10, 255 / NUM_LEDS_PER_STRIP, purplePalette, 255, LINEARBLEND);
}
EVERY_N_MILLISECONDS(10) {
paletteIndex--;
}
FastLED.show();
delay(100); // Adjust the delay as needed
}
void fasterPulse() {
// Function for faster pulsing LED behavior
// Implement the light pattern for faster pulsing
static uint8_t paletteIndex = 0;
CRGBPalette16 purplePalette = CRGBPalette16(
CRGB::Magenta,
CRGB::DarkViolet,
CRGB::Black,
CRGB::Black,
CRGB::Magenta,
CRGB::Magenta,
CRGB::Linen,
CRGB::Linen,
CRGB::Magenta,
CRGB::Magenta,
CRGB::Black,
CRGB::Black,
CRGB::DarkViolet,
CRGB::DarkViolet,
CRGB::Linen,
CRGB::Linen);
//adjust the palette
for (int i = 0; i < NUM_STRIPS; i++) {
fill_palette(&(leds[i * NUM_LEDS_PER_STRIP]), NUM_LEDS_PER_STRIP, paletteIndex + i * 10, 255 / NUM_LEDS_PER_STRIP, purplePalette, 255, LINEARBLEND);
}
EVERY_N_MILLISECONDS(0.0001) {
paletteIndex--;
}
FastLED.show();
delay(10); // Adjust the delay as needed
}
void angstyVibe() {
// Function for angsty vibe LED behavior
// Implement the light pattern for random lighting
// 當
for (int i = 0; i < NUM_STRIPS; i++) {
int numLights = random(1, NUM_LEDS_PER_STRIP); // Random number of lights to turn on
for (int j = 0; j < numLights; j++) {
int randomIndex = random(NUM_LEDS_PER_STRIP); // Random index for each light
leds[i * NUM_LEDS_PER_STRIP + randomIndex] = CRGB::Beige; // Set the color to red
}
}
FastLED.show();
delay(10); // Adjust the delay as needed
fill_solid(leds, NUM_STRIPS * NUM_LEDS_PER_STRIP, CRGB::Black); // Turn off all lights for the next iteration
//further adjustment: fewer lights, more colors
}
```