Week 10 Reading Reflection

I  enjoyed both readings. The number of discussions and reading materials covering user interactions in our course so far is quite intriguing to me. Different thoughts on user interactions has also been very interesting. Is user interaction supposed to be simple or authentic?

Reflecting on Tom Igoe’s insights into interactive design, I am increasingly captivated by the potential for sensor-driven art to create immersive environments. For instance, envisioning a virtual landscape that responds not just to the location but also the pressure of a hand is exhilarating. Light interactions could simulate natural phenomena such as rustling leaves, while stronger interactions might alter weather or time settings, offering a vivid, multisensory experience. This technology could revolutionize educational environments by enabling museum visitors to interact with exhibits in ways that make learning intuitive and engaging. Similarly, in physical therapy, such technologies could provide exciting ways to engage patients and monitor their progress by gamifying therapeutic activities.

Igoe’s emphasis on the principle of “shutting up and listening” deeply resonates with me, highlighting the importance of observing how users interact with a design to identify improvement areas. This principle has been pivotal in my projects, particularly in video game development, where soliciting real-time feedback has been crucial. These interactions provide direct insights into the user experience, invaluable for refining game mechanics.

Moreover, his discussions on physical computing, where technologies like Floor Pads and interactive elements such as Scooby-Doo Paintings illustrate the seamless integration of user interaction and technology, have been enlightening. These technologies enhance traditional experiences like art viewing with modern technological interactions, suggesting new ways to engage audiences.

Igoe’s focus on the iterative nature of design through “user-testing” has reshaped my approach to interactive projects. This ongoing dialogue with users is not just a step in the process but a continuous part of the creative cycle, essential for refining and evolving a project. This perspective encourages me to remain open to feedback and committed to innovation, reinforcing the transformative impact of user-centered design and technology in expanding the boundaries of traditional media and interactive environments.

Week 10 Analog input & output

For this week’s assignment, I have implemented a small lighting system that interfaces both analog and digital sensors.

The task was to use at least one analog sensor and one digital sensor to control two LEDs differently—one in a digital fashion and the other in an analog fashion. For this, I used:

  1. Analog sensor: A photoresistor to sense ambient light levels.
  2. Digital sensor: A tactile button switch to change modes.
  3. LEDs: A standard LED and an RGB LED for digital and analog control, respectively.

I have used the tactile button and the photoresistor to control the RGB LED in two distinct modes: Night Mode and Party Mode.

  • Night Mode: The RGB LED’s behavior is influenced by the ambient light level detected by the photoresistor. When it’s dark, the RGB LED cycles through colors at a slower pace, providing a soothing nighttime light effect.
  •  Party Mode: Activated by pressing the tactile button, this mode turns on an additional LED indicator to show that Party Mode is active. In this mode, the RGB LED cycles through colors more quickly, creating a dynamic and festive atmosphere.

The tactile button toggles between these two modes, allowing the RGB LED to adapt its behavior based on the selected mode and the ambient light conditions.

 

The button debouncing was tricky for me. Button debouncing is basically  managing the button input to toggle between normal and party modes without accidental triggers.

int reading = digitalRead(A1);
if (reading != lastButtonState) {
  lastDebounceTime = millis(); // Reset the debouncing timer
}

if ((millis() - lastDebounceTime) > debounceDelay) {
  if (reading != buttonState) {
    buttonState = reading;
    if (buttonState == HIGH) {
      partyMode = !partyMode;
      digitalWrite(8, partyMode ? HIGH : LOW);
    }
  }
}
lastButtonState = reading;

Another challenging part was figuring out the color change minimally. I used bitwise operations for this.

if (!partyMode && sensorValue >= 400) {
  digitalWrite(10, LOW);
  digitalWrite(11, LOW);
  digitalWrite(12, LOW);
} else {
  int interval = partyMode ? partyInterval : normalInterval;
  if (millis() - lastChangeTime >= interval) {
    lastChangeTime = millis();
    rgbLedState = (rgbLedState + 1) % 8;

    // Determine which LEDs to turn on based on the current state
    digitalWrite(10, (rgbLedState & 0x01) ? HIGH : LOW); // Red
    digitalWrite(11, (rgbLedState & 0x02) ? HIGH : LOW); // Green
    digitalWrite(12, (rgbLedState & 0x04) ? HIGH : LOW); // Blue
  }
}

 

Week 9-Analog Input & Output

Concept

As part of the 9th Assignment of Intro to IM, we were tasked with the objective of reading input from at least one analog sensor, and at least one digital sensor (switch). This data would then be used to control at least two LEDs, one in a digital fashion and the other in an analog fashion, in some creative way.

The core idea of my project is to create an interactive light experience using a combination of analog and digital inputs to control an RGB LED in a creative and visually appealing manner. Initially, the RGB LED displays a steady red color, which gradually transitions through a spectrum of colors, creating a calming and dynamic visual effect. This smooth color transition continues indefinitely, creating a mesmerizing ambient display.

The interaction becomes more engaging with the introduction of a user-controlled digital button and a light sensor. The button, when pressed, shifts the mode of the LED from its continuous color transition to a responsive blinking state. In this state, the color of the LED’s blinking is determined by the ambient light level measured by the sensor. Specifically:

  • Below 300 units: The LED blinks in red, indicating low light conditions.
  • Between 300 and 900 units: The LED blinks in blue, corresponding to moderate light levels.
  • Above 900 units: The LED blinks in green, signifying high light intensity.

Implementation

Pictures of Circuit

With this, I produced the following circuit:

Demo Video

A demo video, in detail, can be seen here:

 

Difficulties & Improvements

While the concept of the color transition was straightforward, implementing it in Arduino presented significant challenges. Determining the correct method for transitioning from one color to another smoothly, without abrupt changes, was particularly tricky. This aspect of the project required careful tweaking of the code to ensure that the color shifts were visually pleasing.

void smoothColorTransition() {
  // Fade colors smoothly
  if (redValue > 0 && blueValue == 0) {
    redValue -= step;
    greenValue += step;
  }
  if (greenValue > 0 && redValue == 0) {
    greenValue -= step;
    blueValue += step;
  }
  if (blueValue > 0 && greenValue == 0) {
    blueValue -= step;
    redValue += step;
  }

Despite these challenges, I thoroughly enjoyed this part of the project. It was rewarding to see the seamless color transitions come to life. Looking ahead, I plan to expand this project by adding an additional LED and another button to enhance interactivity and complexity, making the experience even more engaging.

 

Reading Response – Making Interactive Art: Set the Stage, Then Shut Up and Listen

This idea of not over-explaining your interactive artworks really struck a chord with me. I’ve definitely been guilty of that in the past – spelling out too many specifics about what different elements “mean” and how people are “supposed” to interact with them. But as the author points out, doing that pretty much defeats the whole purpose. You’re just dictating how the audience should think and experience the piece, instead of leaving room for them to explore and interpret it themselves.

I can vividly remember one interactive installation I saw that fell into this trap. It looked really cool – these conductive surfaces that would trigger light patterns when you touched them. But then the description plaque gave you this long, explicit walkthrough of the precise sequence you “should” follow when engaging with it. It ended up feeling really prescriptive and took away from the sense of curiosity and spontaneous discovery that initially drew me to the work.

The author’s point about interactive art being the “start of a conversation” between the artist and viewer resonated so much. Rather than a static, finished product, it’s meant to be this open-ended exchange where the audience’s live participation and personal perspectives complete the experience. Kind of like a director setting up a premise and suggestions for the actors, but then letting them organically find their own emotional truths within that framework.

Moving forward, I really want to embrace that spirit of intentional ambiguity in my own interactive work. Instead of strictly defining roles and meanings, I should focus on crafting intriguing environments, suggestive arrangements of elements, and potential pathways to explore – but then step back and allow diverse interpretations to emerge organically through self-directed engagement. Creating prompts for personal dialogue rather than dictating conclusions. It’s a shift in mindset, but one I think will lead to much richer, more interactive experiences.

Reading Response – Physical Computing’s Greatest Hits (and misses)

This tour through the greatest hits (and misses) of physical computing projects was such a fun read!

One quote that particularly resonated with me was: “Sometimes when people learning about physical computing hear that a particular idea has been done before, they give up on it, because they think it’s not original. What’s great about the themes that follow here is that they allow a lot of room for originality.” As someone still finding my footing in creative disciplines, I can relate to that instinct to get discouraged if you feel like you’re just retreading old ground. But the author makes a compelling case for why revisiting familiar concepts is worthwhile – there’s an endless well of creative variations to explore.

Rather than dismissing these well-trod paths as clichés, the piece argues that putting your own spin on an established idea can make it feel totally fresh and novel. I was particularly struck by the examples under “Mechanical Pixels.” The artistic possibilities of combining precise kinetic movements with immersive audiovisuals seems endlessly fascinating. Dan Rozin’s mind-bending mechanical mirrors sound like they blur the boundaries between interactive art and raw mechanism in some delightfully bizarre ways.

At the same time, I’ll admit some of the Greatest Hits left me a bit puzzled. I’m still not 100% sure I grasp the emotional motivation behind things like “Remote Hugs” that aim to convey intimacy over a distance. Maybe I’m just a cynic, but I have a hard time imagining any unhuggable object truly capturing that warmth and connection.

The whole catalog is a humbling reminder of just how much creative ground has already been covered in this space – but also how unmapped the frontiers of invention still remain. I can only hope that I can someday create my own trail.

Colour-Changing Lamp

The challenge was to create something that blended analog and digital inputs to control a set of LEDs – one through an analog sensor and the other digitally.

The Concept:
I envisioned a vibrant desktop lamp that could cycle through a kaleidoscope of smoothly blending colours.

The Execution:
For the analog input, a potentiometer proved perfect – capable of outputting 1024 values just by twisting its knob. This enabled fluid color control.

An RGB LED became the centerpiece light source. Its red, green, and blue elements could blend into any hue based on the potentiometer’s analog output levels. A regular red LED served as the digital indicator, powering on/off with the slide switch.

I wired the potentiometer to an Arduino analog input and the slide switch to a digital input pin. The RGB LED trio connected to three PWM analog outputs for mixable color output, while the red LED patched into a separate digital pin.

The Code:
The Arduino continuously read the potentiometer’s smooth analog value via analogRead(). I then mapped this range across the full RGB spectrum, setting the three LED output levels to precisely blend the corresponding hue on the RGB model. This proved to be slightly beyond my scope and I used the help of online resources to accomplish this

For the digital side, it just checked the slide switch state – HIGH powered the separate red LED, while LOW turned it off.

// Define pin connections
int potPin = A0;           // Potentiometer at analog pin A0
int redPin = 9, greenPin = 10, bluePin = 11; // RGB LED pins
int switchPin = 2;         // Digital pin for the toggle switch
int ledPin = 13;           // Pin for the additional standard LED

void setup() {
  pinMode(redPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(bluePin, OUTPUT);
  pinMode(ledPin, OUTPUT);     // Set the additional LED pin as output
  pinMode(switchPin, INPUT_PULLUP); // Set the switch pin as input with pull-up
}

void loop() {
  int potValue = analogRead(potPin); // Read the potentiometer value
  int hueValue = map(potValue, 0, 1023, 240, 0); // Map pot value from blue to red hue values

  // Convert hue to RGB
  float r, g, b;
  hueToRGB(hueValue, r, g, b);

  // Write RGB values to LED pins
  analogWrite(redPin, r * 255);
  analogWrite(greenPin, g * 255);
  analogWrite(bluePin, b * 255);

  // Check the state of the switch
  if (digitalRead(switchPin) == LOW) {  // Switch is pressed (toggle switch connects to GND)
    digitalWrite(ledPin, HIGH);         // Turn on the additional LED
  } else {
    digitalWrite(ledPin, LOW);          // Turn off the additional LED
  }

  delay(10); // Short delay for stability
}

void hueToRGB(int hue, float &r, float &g, float &b) {
  int s = 1; // Saturation: 1 for full color
  int v = 1; // Value: 1 for max brightness
  float C = s * v;
  float X = C * (1 - fabs(fmod(hue / 60.0, 2) - 1));
  float m = v - C;
  float r1, g1, b1;

  if (hue >= 0 && hue < 60) {
    r1 = C, g1 = 0, b1 = X;  // Red to pinkish-red
  } else if (hue < 120) {
    r1 = X, g1 = 0, b1 = C;  // Pinkish-red to purple
  } else if (hue < 180) {
    r1 = 0, g1 = X, b1 = C;  // Purple to blue
  } else if (hue < 240) {
    r1 = 0, g1 = C, b1 = X;  // Lighter blue
  } else if (hue < 300) {
    r1 = X, g1 = C, b1 = 0;  // Skip greens
  } else {
    r1 = C, g1 = X, b1 = 0;  // Skip greens to yellow
  }
  r = (r1 + m);
  g = (g1 + m);
  b = (b1 + m);
}

Challenges:

My original vision was integrating this into a physical lamp with the RGB as the main light source. However, I struggled to find an easy way to run the component wires and extend the LEDs cleanly off the breadboard – a skill I’ll need to develop.

Future Improvements:
– Adding animation modes like pulsing, gradual color-cycling, and custom fading sequences between hues.
– Using light sensors to automatically adjust brightness based on ambient lighting.
– Exploring alternative RGB mapping patterns beyond the standard spectrum for unnatural, psychedelic hue blends.
– Integrating everything into a stylish 3D printed desktop lamp enclosure.

 

Reading Reflection – Week #10

I found the readings for today quite engaging in the sense that the first reading “Making Interactive Art: Set the Stage, Then Shut Up and Listen” offers vision for how interactivity should be executed by artists, and the second reading gives us widespread examples of such interactivity in the world of physical computing.

Firstly, I would like to address the points that resonated with me. I agree that exploring the interactive artwork by yourself is a better experience than being guided and directed along the way of that exploration. That could give audience a sense of emotional connection to the work, as the more modes and options of interaction there are, the more the artwork could “feel like home” for the individuals in the audience, hence leaving the audience and the artwork face-to-face is a great way of fostering emotional connection.

However, I do not agree with the distinction that the author makes between interactive artwork and other artwork. Many books, paintings are left for interpretation, which, I would argue, carries a sense of interactivity with the artwork, with the ideas, the perception of those ideas between audience members. So, I would not rush to call traditionally non-interactive artwork a “statement” or just an “expression”, as the author mentions. Vice versa, what we call interactive artwork can be understood solely as an expression in some cases, therefore the definition of “interactive artwork” is blurry and needs refinement in order to be categorized as needed to be left interpretation.

As a tangent to the last point, I, personally, do not appreciate the firm stances of guarding the intention of the author from audiences’ interpretation. I understand the value it can provide, as outlined in the beginning of this reflection, but I appreciate getting a chance for a glimpse of what was going on in the author’s mind while creating the artwork, as the process of creation could be as valuable as the creation itself, if not more.

Week 10 – Arduino: analog input & output

Concept 
I built a cool project using an ultrasonic sensor and an Arduino! It measures the distance to objects and tells me how far away they are using LEDs. If something is close, a red light blinks faster the closer it gets – like a warning. A green light turns on if it’s further away, so I know it’s safe. I can even start and stop the sensor with a button, which is pretty neat.

Video 

Components Required:
Arduino Uno (or any compatible board)
Ultrasonic Sensor (HC-SR04 or similar)
Red LED
Green LED
220-ohm resistors (2 pieces) & 10k-ohm resistor
Push button
Jumper wires
Breadboard

Schematic

Code

const int trigPin = 3;    //Trig
const int echoPin = 2;    //Echo
const int redLedPin = 13;  //RedLED
const int greenLedPin = 12; //GreenLED
const int buttonPin = 4;  //PushButton

int blinkInterval = 500; //BlinkInterval
bool projectRunning = false; //FlagToStart

void setup() {
  Serial.begin(9600);
  pinMode(trigPin, OUTPUT);  //SetUltrasonicSensor 
  pinMode(echoPin, INPUT);
  pinMode(redLedPin, OUTPUT);
  pinMode(greenLedPin, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP); //SetButton 
}

void loop() {
  if (digitalRead(buttonPin) == LOW) { 
    projectRunning = !projectRunning; //Toggle project state
  }

  if (projectRunning) {
    //Measure distance with ultrasonic sensor
    long duration = 0;
    long distance = 0;
    int retryCount = 0;
    const int maxRetries = 5; //Set a max number of retries
    while (duration == 0 && retryCount < maxRetries) {
      digitalWrite(trigPin, LOW);
      delayMicroseconds(2);
      digitalWrite(trigPin, HIGH);
      delayMicroseconds(10);
      digitalWrite(trigPin, LOW);
      duration = pulseIn(echoPin, HIGH);
      retryCount++;
    }
  
    if (duration != 0) {
      distance = duration * 0.034 / 2; //Convert to cm
    }
  
    //Print distance to Serial Monitor
    Serial.print("Distance: ");
    Serial.print(distance);
    Serial.println(" cm");
  
    //Control LED based on distance
    if (distance <= 50) { 
      digitalWrite(greenLedPin, LOW);  
      blinkInterval = map(distance, 0, 50, 100, 1000); 
      digitalWrite(redLedPin, HIGH);   
      delay(blinkInterval);
      digitalWrite(redLedPin, LOW);    
      delay(blinkInterval);             
    } else {
      digitalWrite(redLedPin, LOW);     
      digitalWrite(greenLedPin, HIGH);   
    } 
  } else {
    //Turn off both LEDs when the project is not running
    digitalWrite(redLedPin, LOW);
    digitalWrite(greenLedPin, LOW);
  }
}

Building this project was a real learning curve! Seeing the LEDs react to the distance measurements was super cool, but getting there wasn’t always smooth sailing. The sensor readings were a bit wonky at first, picking up on random noise and stuff. I had to get creative with the code to filter that out and make sure it was actually measuring the right things.

Reading Reflection: week 10

I’ve always been fascinated by the intersection of technology and art, so reading about these interactive projects really resonated with me. It’s incredible how specific themes, like theremins and video mirrors, keep popping up, proving that some ways of interacting are just inherently enjoyable. However, I realize that the true magic lies not in the technology itself but in the experience it creates.
Initially, I was drawn to the technical aspects of these projects: the sensors, the code, and the gadgets. But now I see them as tools, like a painter’s brush or a musician’s instrument. Technology is simply a means to an end, and the real focus should be on the interaction and the meaning it conveys.

One of my most important takeaways is the idea of “shutting up and listening.” As creators, it’s easy to fall into the trap of over-explaining our work, dictating how it should be interpreted. But that approach stifles the audience’s ability to explore and discover their own meaning. Instead, we should create experiences that invite participation, spark curiosity, and allow for diverse interpretations.

These readings have ignited my passion to explore interactive art more deeply. I want to create projects beyond mere novelty and offer meaningful experiences that evoke emotions and stimulate thought. I’m excited to experiment with different technologies and approaches, always considering the importance of observation and listening to understand how people interact with and interpret my work.

I believe that interactive art has the potential to bridge the gap between the creator and the audience, fostering a sense of connection and shared experience. By focusing on meaningful interaction and embracing the audience’s role in shaping the experience, we can create art that is not only engaging but also transformative.

Potentiometer Switch

I came up with the idea of this assignment while playing around with the potentiometer. It has a wide range of values it can provide and I wanted to utilize the potential of its variability and precision.

There are 4 LEDs – red, yellow, green and blue – that light up as the values generated by the variable resistor change. The potentiometer is the analog sensor here, but provides functionality of both an analog and a digital sensor. The purely digital sensor here is the green button.

The potentiometer values are supplied to the digital output pins and control the brightness of the LEDs. The value range of the potentiometer is also split into 4 equal segments, so that each LED only has a quarter of the full range of brightness it can take. The splitting also allows to switch the LED as the value changes, meaning for (0, 256] range of the potentiometer reading, one LED lights up with (0, 1/4] of its brightness range. Same logic applies to the other LEDs in a successive fashion.

The green button  (digital sensor) allows to change the sequence of LEDs that light up with certain values of the potentiometer. For instance, if initially the red LED has the lowest quarter of values, the switch sets that lowest range to the next LED in succession, which would be the yellow one, and every LED gets the position of the next one, hence in this example the red one would get the highest range of values and be the brightest if turned on. The video of how the system works is attached below.

The main code responsible for the button and the value switches is provided below. The relatively challenging part was figuring out a way to make the switch between what values which LED gets, and I ended up with an array structure for efficiency.

if (buttonState == HIGH){
    if (swapped == 0){
    switchState += 1;
    switchState = switchState % 4;
    }
    swapped = 1;
  }
  else{
    swapped = 0;
  }

  if (sensorValue > 0 && sensorValue <= 256){
    analogWrite(leds[switchState], sensorValue/4);
    digitalWrite(leds[(switchState+1)%4], LOW);
    digitalWrite(leds[(switchState+2)%4], LOW);
    digitalWrite(leds[(switchState+3)%4], LOW);
    //speed = 2000;
  }
  else if(sensorValue > 256 && sensorValue <= 512){
    digitalWrite(leds[switchState], LOW);
    analogWrite(leds[(switchState+1)%4], sensorValue/4);
    digitalWrite(leds[(switchState+2)%4], LOW);
    digitalWrite(leds[(switchState+3)%4], LOW);
    //speed = 1000;
  }
  else if(sensorValue > 512 && sensorValue <= 768){
    digitalWrite(leds[switchState], LOW);
    digitalWrite(leds[(switchState+1)%4], LOW);
    analogWrite(leds[(switchState+2)%4], sensorValue/4);
    digitalWrite(leds[(switchState+3)%4], LOW);
    //speed = 500;
  }
  else if(sensorValue > 768 && sensorValue <= 1023){
    digitalWrite(leds[switchState], LOW);
    digitalWrite(leds[(switchState+1)%4], LOW);
    digitalWrite(leds[(switchState+2)%4], LOW);
    analogWrite(leds[(switchState+3)%4], sensorValue/4);
    //speed = 250;
  }
  else{
    digitalWrite(red, LOW);
    digitalWrite(yellow, LOW);
    digitalWrite(green, LOW);
    digitalWrite(blue, LOW);
    //speed = 0;
  }

For improvements, I could add more variability into what the button does, possibly incorporate flickering rate for different potentiometer readings to make the transitions more clear. I also could optimize the code and make it more reusable so that when new functionality or LEDs are added, it does not take much code to incorporate.