# 「黑盒子」 製作者:黃鈺晴、林柔劭 ### 設計理念 ![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 } ```