Physical Computing

Prototyping interactive systems that respond to sound, movement, and human behavior.

Pulse Play 2025

This project explores the intersection of sound, light, and interactivity through a responsive lighting system built with a sound sensor, potentiometer, and a series of LEDs. I began by focusing on building a stable circuit that could reliably detect and react to sound input before experimenting with form and reflection.

Early tests involved observing how the LEDs responded to varying sound levels and light reflections. Using a small mirror and paper, I experimented with how light could be manipulated—an exploration that inspired my first prototype: a stage-like setup where mirrors reflected light across the surface, evoking the dynamic visual atmosphere of a concert.

To enhance interactivity, I integrated a potentiometer that allows users to adjust light behavior in real time, transforming them from passive viewers into “light DJs.” The system maps potentiometer input values (0–1023) into five lighting modes, while the sound sensor triggers illumination only within a 200-millisecond window after detecting audio input. When no sound is present, the system resets to darkness, creating a rhythmic, performance-based experience that visually translates sound into light.

Pulse Play Final Video

For our midterm we were tasked to create something that expands on our mini projects from earlier in the semester. My idea was Pulse Play a household product that translates auditory energy into a dynamic visual display. Designed for entertainment spaces such as small venues, home studios, or lounges it transforms sound into movement, allowing environments to “perform” alongside music, conversation, or ambient noise.

Code

const int soundPinDigital = 2;  
const int potPin = A1;          

const int led1 = 3;
const int led2 = 4;
const int led3 = 5;
const int led4 = 6;
const int led5 = 7;
const int led6 = 8;
const int led7 = 9;
const int led8 = 10;

int leds[] = {led1, led2, led3, led4, led5, led6, led7, led8};
int numLeds = 8;
int mode = 0;
int currentLED = 0;
unsigned long lastTrigger = 0;
unsigned long lastSoundTime = 0;

void setup() {
  pinMode(soundPinDigital, INPUT);
  
  for (int i = 0; i < numLeds; i++) {
    pinMode(leds[i], OUTPUT);
  }
  
  Serial.begin(9600);
}

void loop() {
  int digitalValue = digitalRead(soundPinDigital);
  bool soundDetected = (digitalValue == LOW);
  
  int potValue = analogRead(potPin);
  mode = map(potValue, 0, 1023, 0, 5);
  
  if (soundDetected) {
    lastSoundTime = millis();
  }
  
  bool showLights = (millis() - lastSoundTime < 200);
  
  Serial.print("Sound: ");
  Serial.print(soundDetected ? "YES" : "NO");
  Serial.print(" | Lights: ");
  Serial.print(showLights ? "ON" : "OFF");
  Serial.print(" | Mode: ");
  Serial.println(mode);
  
  if (!showLights) {
    allOff();
  } else {
    switch(mode) {
      case 0:
        allOn();
        break;
      case 1:
        waveChase();
        break;
      case 2:
        alternating();
        break;
      case 3:
        randomSparkle();
        break;
      case 4:
        buildUp();
        break;
    }
  }
  
  delay(20);
}

void allOff() {
  for (int i = 0; i < numLeds; i++) {
    digitalWrite(leds[i], LOW);
  }
}

void allOn() {
  for (int i = 0; i < numLeds; i++) {
    digitalWrite(leds[i], HIGH);
  }
}

// MODE 1
void waveChase() {
  if (millis() - lastTrigger > 70) {
    allOff();
    digitalWrite(leds[currentLED], HIGH);
    currentLED = (currentLED + 1) % numLeds;
    lastTrigger = millis();
  }
}

// MODE 2
void alternating() {
  static unsigned long lastSwitch = 0;
  static bool showOdd = true;
  
  if (millis() - lastSwitch > 100) {
    showOdd = !showOdd;
    lastSwitch = millis();
  }
  
  for (int i = 0; i < numLeds; i++) {
    if ((showOdd && i % 2 == 0) || (!showOdd && i % 2 == 1)) {
      digitalWrite(leds[i], HIGH);
    } else {
      digitalWrite(leds[i], LOW);
    }
  }
}

// MODE 3
void randomSparkle() {
  static unsigned long lastSparkle = 0;
  
  if (millis() - lastSparkle > 80) {
    allOff();
    int numToLight = random(3, 6);
    for (int i = 0; i < numToLight; i++) {
      digitalWrite(leds[random(0, numLeds)], HIGH);
    }
    lastSparkle = millis();
  }
}

// MODE 4
void buildUp() {
  static int level = 0;
  static unsigned long lastUpdate = 0;
  
  if (millis() - lastUpdate > 80) {
    level = (level + 1) % (numLeds + 1);
    lastUpdate = millis();
  }
  
  for (int i = 0; i < numLeds; i++) {
    if (i < level) {
      digitalWrite(leds[i], HIGH);
    } else {
      digitalWrite(leds[i], LOW);
    }
  }
}
Next
Next

Marketing and Branding