Production Week 8

I made a simple but really cool switch using foil sheets and a rolling marker. I connected two foil pieces to the two ends of my circuit, keeping them separated so the circuit stays open and the LED is off. Then I covered a small marker with foil and used it as the connector. When I blow the marker so that it rolls between the two foil sheets, it touches both sides, completes the circuit, and allows the 5V to pass through, causing the LED to light up. When the marker rolls away, the light turns off again.

It’s a fun and unusual way to switch an LED on and off just by blowing the marker in and out of the foil sheets.

Week 11 – Gravity, Bounce, and Wind

For this assignment, I worked with Youssab to connect p5.js and Arduino. We completed three exercises to practice sending data between the physical and digital worlds.

Part 1: One Sensor to p5.js

In this first exercise, we used a potentiometer on the Arduino. This controls the horizontal position of a circle on the computer screen. The Arduino reads the sensor value and sends it to p5.js. Then, p5.js moves the ball left or right based on that number.

Schematic

Arduino Code

void setup() {
  Serial.begin(9600);
}

void loop() {
  // Read analog value and send it as a line of text
  int sensorValue = analogRead(A0);
  Serial.println(sensorValue);
  delay(20); 
}

p5.js Code

let port;
let connectBtn;
let ballX = 0;
let sensorVal = 0;

function setup() {
  createCanvas(600, 400);
  background(50);

  port = createSerial();

  // Open the port automatically if used before
  let usedPorts = usedSerialPorts();
  if (usedPorts.length > 0) {
    port.open(usedPorts[0], 9600);
  }

  connectBtn = createButton('Connect to Arduino');
  connectBtn.position(10, 10);
  connectBtn.mousePressed(connectBtnClick);
}

function draw() {
  // Check if port is open
  if (port.available() > 0) {
    let data = port.readUntil("\n");
    
    if (data.length > 0) {
      // Update value
      sensorVal = Number(data.trim()); 
    }
  }

  background(256);
  
  // Map sensor val to canvas width
  ballX = map(sensorVal, 0, 1023, 25, width - 25);
  
  // Draw ball
  fill(0, 255, 100);
  noStroke();
  ellipse(ballX, height / 2, 50, 50);
}

function connectBtnClick() {
  if (!port.opened()) {
    port.open('Arduino', 9600);
  } else {
    port.close();
  }
}

Part 2: p5.js to LED Brightness

For the second part, we reversed the flow of data. We send information from p5.js to the Arduino. The ball on the screen represents a light bulb. If you drag the ball higher, the LED gets brighter. If you drag it lower, the LED dims.

Schematic

Arduino Code

C++

void setup() {
  Serial.begin(9600);
  pinMode(9, OUTPUT); //pmw pin
}

void loop() {
  if (Serial.available() > 0) {
    String input = Serial.readStringUntil('\n');
    int brightness = input.toInt();    // convert str to int
    brightness = constrain(brightness, 0, 255);    // just in case data is weird
    analogWrite(9, brightness);
  }
}

p5.js Code

JavaScript

let port;
let connectBtn;

// Ball variables
let ballX = 300;
let ballY = 200;
let ballSize = 50;
let isDragging = false; 

// Data variables
let brightness = 0;
let lastSent = -1; 

function setup() {
  createCanvas(600, 400);
  
  port = createSerial();
  
  let usedPorts = usedSerialPorts();
  if (usedPorts.length > 0) {
    port.open(usedPorts[0], 9600);
  }

  connectBtn = createButton('Connect to Arduino');
  connectBtn.position(10, 10);
  connectBtn.mousePressed(connectBtnClick);
}

function draw() {
  background(50);

  // ball logic
  if (isDragging) {
    ballX = mouseX;
    ballY = mouseY;
    
    // Keep ball inside canvas
    ballY = constrain(ballY, 0, height);
    ballX = constrain(ballX, 0, width);
  }

  // map brightness to y pos
  brightness = floor(map(ballY, 0, height, 255, 0));

  // send data
  if (port.opened() && brightness !== lastSent) {
    port.write(String(brightness) + "\n");
    lastSent = brightness;
  }
  //draw ball
  noStroke();
  fill(brightness, brightness, 0); 
  ellipse(ballX, ballY, ballSize);
  stroke(255);
  line(ballX, 0, ballX, ballY);

}

// --- MOUSE INTERACTION FUNCTIONS ---
function mousePressed() {
  // check if mouse is inside the ball
  let d = dist(mouseX, mouseY, ballX, ballY);
  if (d < ballSize / 2) {
    isDragging = true;
  }
}

function mouseReleased() {
  // stop dragging when mouse is let go
  isDragging = false;
}

function connectBtnClick() {
  if (!port.opened()) {
    port.open('Arduino', 9600);
  } else {
    port.close();
  }
}

Part 3: Gravity Wind and Bi-directional Communication

This final exercise combined everything. We used the gravity wind example code. We modified it to do two things.

First, we use a potentiometer to control the wind force. Second, when the ball bounces on the floor, the LED lights up.

This required some problem solving. I had to ignore very small bounces. Without that check, the LED would blink constantly when the ball rolled on the floor. I also added a visual indicator arrow to show the direction of the wind.

Schematic

Arduino Code

void setup() {
  Serial.begin(9600);
  pinMode(9, OUTPUT); // LED on Pin 9
}

void loop() {
  // read & send pot value
  int potValue = analogRead(A0);
  Serial.println(potValue);


  if (Serial.available() > 0) {
    char inChar = Serial.read();
    
    // check for blink command
    if (inChar == 'B') {
      digitalWrite(9, HIGH);
      delay(50); 
      digitalWrite(9, LOW);
    }
  }
  
  delay(15);
}

p5.js Code

let port;
let connectBtn;

let velocity;
let gravity;
let position;
let acceleration;
let wind;
let drag = 0.99;
let mass = 50;
let sensorVal = 512; 

function setup() {
  createCanvas(640, 360);
  noFill();
  
  // Physics Setup
  position = createVector(width/2, 0);
  velocity = createVector(0,0);
  acceleration = createVector(0,0);
  gravity = createVector(0, 0.5*mass);
  wind = createVector(0,0);

  // Serial Setup
  port = createSerial();
  let usedPorts = usedSerialPorts();
  if (usedPorts.length > 0) {
    port.open(usedPorts[0], 9600);
  }
  
  connectBtn = createButton('Connect to Arduino');
  connectBtn.position(10, 10);
  connectBtn.mousePressed(connectBtnClick);
}

function draw() {
  background(255);
  
  // read for wind
  if (port.available() > 0) {
    let data = port.readUntil("\n");
    if (data.length > 0) {
      sensorVal = Number(data.trim());
    }
  }
  
  // map wind
  let windX = map(sensorVal, 0, 1023, -0.8, 0.8);
  wind.set(windX, 0);

  // apply physics
  applyForce(wind);
  applyForce(gravity);
  velocity.add(acceleration);
  velocity.mult(drag);
  position.add(velocity);
  acceleration.mult(0);
  
  // draw
  fill(0);
  ellipse(position.x, position.y, mass, mass);
  drawWindIndicator(windX);

  // detect bounce
  if (position.y > height - mass/2) {
      velocity.y *= -0.9; 
      position.y = height - mass/2;
      
      // send blink command
      if (abs(velocity.y) > 1 && port.opened()) {
        port.write('B');
      }
  }
  
  // collision detection
  if (position.x > width - mass/2) {
    position.x = width - mass/2;
    velocity.x *= -0.9;
  } else if (position.x < mass/2) {
    position.x = mass/2;
    velocity.x *= -0.9;
  }
}

function applyForce(force){
  let f = p5.Vector.div(force, mass);
  acceleration.add(f);
}

function connectBtnClick() {
  if (!port.opened()) {
    port.open('Arduino', 9600);
  } else {
    port.close();
  }
}

// helper to visualize the wind
function drawWindIndicator(w) {
  push();
  translate(width/2, 50);
  fill(150);
  noStroke();
  text("Wind Force", -30, -20);
  stroke(0);
  strokeWeight(3);
  line(0, 0, w * 100, 0); 
  fill(255, 0, 0);
  noStroke();
  if (w > 0.05) triangle(w*100, 0, w*100-10, -5, w*100-10, 5); // Right Arrow
  if (w < -0.05) triangle(w*100, 0, w*100+10, -5, w*100+10, 5); // Left Arrow
  pop();
}

function keyPressed(){
  // reset ball
  if (key==' '){
    mass=random(15,80);
    position.y=-mass;
    position.x = width/2;
    velocity.mult(0);
  }
}

Video Demonstration

Week 11 – Post Response

This week, I read Design Meets Disability by Graham Pullin, and it really struck a chord with me. It made me think about a conversation I have with my parents constantly.

For years, my parents have tried to talk me into getting LASIK eye surgery. They see it as fixing a problem. But I have always refused. I don’t see my poor eyesight as a disability that needs to be erased. I see my glasses as a feature. They are part of who I am. They are part of my identity.

Pullin talks about this in the book. He uses eyewear as the perfect example of a medical device becoming a fashion statement. Nobody looks at glasses and thinks “medical equipment” anymore. We just think “style.” This is exactly how I feel. If I fixed my eyes, I would lose a part of my personality.

However, I did not agree with everything in the text. There was a point where the “Swiss Army Knife” approach—making one tool do many things—was critiqued as ugly or cluttered. I disagree. I think there is beauty in something that is highly functional and straightforward. Design does not always have to be minimal to be good. If a device solves a problem efficiently, that is good design.

The biggest takeaway for me is that we need to stop hiding. Too often, medical design tries to mimic skin tone or conceal the device. This is a mistake. When you try to hide a hearing aid or a wheelchair, you are telling the user that their condition is something to be ashamed of. It also limits creativity.

If we stop trying to hide, we can start designing.

Imagine if Nike designed a wheelchair. It wouldn’t look like a hospital chair. It would look fast, sporty, and bold. Imagine if Apple designed a hearing aid. It wouldn’t be “flesh-colored” plastic. It would be sleek, white, or metallic, and people might actually want to wear it.

We need to move toward a world where assistive technology does not apologize for existing. It should serve its function while prioritizing great design. Just like my glasses.

Week 10 – DJ

Project: The Arduino DJ Console

Assignment Description
For this assignment, we had to create a musical instrument. The requirements were to use at least one digital sensor (switch) and one analog sensor.

What We Made
We created a DJ console using an Arduino. This instrument allows for infinite possibilities based on the user. We used the following components:

  • Two Potentiometers (Analog Sensors): One knob adjusts the tone (pitch) of the note. The other knob adjusts the speed (duration) of the note.

  • One Button (Digital Sensor): This button acts as a mute switch to stop the sound.

  • Piezo Buzzer: This plays the sound.

Schematic

Here is the circuit diagram for our project. We connected the knobs to the analog pins (A0 and A5) and the button to a digital pin (13).

Code

We wrote code to read the sensors and play notes from a C Major scale. Here is the source code for the project:

C++

// Control a buzzer with two knobs and a button

// Define hardware pins
const int piezoPin = 9;
const int pitchPotPin = A0;
const int durationPotPin = A5;
const int buttonPin = 13;

// List of frequencies for C Major scale
int notes[] = {262, 294, 330, 349, 392, 440, 494, 523};

void setup() {
  // Start data connection to computer
  Serial.begin(9600);
  Serial.println("Instrument Ready! Note Stepping Enabled.");

  // Set pin modes
  pinMode(piezoPin, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);
}

void loop() {
  // Check if the button is pressed
  int buttonState = digitalRead(buttonPin);

  // Mute sound if button is held down
  if (buttonState == LOW) {
    noTone(piezoPin);
  } else {
    // Read values from both knobs
    int pitchValue = analogRead(pitchPotPin);
    int durationValue = analogRead(durationPotPin);

    // Convert pitch knob value to a note index from 0 to 7
    int noteIndex = map(pitchValue, 0, 1023, 0, 7);

    // Select the frequency from the list
    int frequency = notes[noteIndex];

    // Convert duration knob value to time in milliseconds
    int noteDuration = map(durationValue, 0, 1023, 50, 500);

    // Play the sound
    tone(piezoPin, frequency, noteDuration);

    // Show information on the screen
    Serial.print("Note Index: ");
    Serial.print(noteIndex);
    Serial.print(" | Frequency: ");
    Serial.print(frequency);
    Serial.print(" Hz | Duration: ");
    Serial.print(noteDuration);
    Serial.println(" ms");

    // Wait for the note to finish
    delay(noteDuration + 50);
  }
}

Video Demonstration

Check out the video below to see the instrument in action.

 

Here is my attempting Happy Birthday (Badly)

Week 10 – Post Response

Reading Bret Victor’s “A Brief Rant on the Future of Interaction Design” feels like a wake-up call. His critique of modern interfaces—what he calls “Pictures Under Glass”—is undeniable. We have taken the incredible dexterity of the human hand, capable of thousands of distinct movements, and reduced it to a single, numb motion: the swipe.

Victor argues that the future should be about “Dynamic Media”—screens that can physically morph, allowing us to feel buttons and textures. While I agree with his diagnosis of the problem (we are disconnected from the physical world), I disagree with his solution. I don’t think the future is a morphing screen.

In my opinion, Smart Glasses are the next big thing.

The End of the Swipe

Victor’s main gripe is that touchscreens blind our hands. We have to look at the screen to know where the buttons are because we can’t feel them.

Smart glasses solve this, but not by adding texture. They solve it by freeing our hands entirely. With the advanced hand-tracking and depth sensors we are seeing in emerging tech, the “swipe” becomes obsolete. Instead, we can return to the real-life gestures Victor mourns the loss of.

If I want to turn a dial, I can mime turning a dial in the air. If I want to grab an object, I just grab it. The interface isn’t trapped under a sheet of glass anymore; it is overlaid onto the real world. We can use our full range of motor skills to manipulate digital objects as if they were physical ones.

24/7 Access, Zero Friction

The other massive advantage of the Smart Glasses form factor is integration. Victor worries that interfaces are separating us from our environment. But if the interface is a pair of glasses that look like normal eyewear, the digital world becomes a seamless layer on top of the physical one.

We could have access to the digital world 24/7, completely unnoticeable to the people around us. No more looking down at a phone, hunching over, or disengaging from a conversation to check a notification. The technology recedes into the background, becoming a true extension of the senses rather than a “tool” you have to pick up and hold.

The Futility of Prediction

However, reading through Victor’s “Responses” page reminds me that we should be humble with our predictions.

Victor wrote his rant in 2011, convinced that the iPad was just a transitional phase like black-and-white photography. Yet, over a decade later, we are still swiping on glass.

When we look back at how people in the 1900s predicted the year 2000, they got almost everything wrong. They imagined flying firefighters and personal blimps, but they completely missed the internet, microchips, and AI. We tend to predict the future by exaggerating the present—Victor predicted better physical buttons because he liked physical tools. I am predicting smart glasses because I like visual overlays.

Ultimately, nobody knows what the “next big thing” actually is until it arrives. We can analyze and debate, but in the end, we just have to wait and see.

Week 9 – Simon Says

Description

For this assignment, I created a “Simon Says” style memory game. The goal of the game is to memorize a sequence of colors displayed on the main RGB LED and repeat the pattern back using four push buttons.

To fulfill the assignment requirements, I incorporated both digital and analog controls to affect the game’s behavior:

  1. Digital Inputs (Switches): Four push buttons act as the game controller. These are used to start the game and input the color sequence.

  2. Analog Input (Sensor): A Potentiometer is used as a difficulty selector. Before the game starts, reading the analog value of the potentiometer determines the speed of the flashes and the length of the sequence.

  3. Outputs:

    • RGB LED: Displays the randomized game sequence.

    • Feedback LEDs: Two separate LEDs (Green and Red) indicate if the player won or lost the round.

Schematic

Here is the hand-drawn wiring diagram for the circuit. It details the connections for the RGB LED (Pins 11-13), the Feedback LEDs (Pins 9-10), the Buttons (Pins 2-5), and the Potentiometer (Pin A1).

Logic & Interaction

The system waits for the Yellow button to be pressed to start. Once triggered, the Arduino reads the Potentiometer.

  • If the potentiometer is turned one way, the game is “Easy” (slower flashes, shorter sequence).

  • If turned the other way, the game becomes “Hard” (rapid flashes, longer sequence).

The Arduino then generates a random pattern displayed on the RGB LED. The player must press the buttons in the correct order. If successful, the distinct Green feedback LED flashes; if incorrect, the Red feedback LED flashes.

Gameplay Video

Code

Below is the Arduino code used for this project. 

// RGB LED Pins
const int RGB_RED_PIN = 13;
const int RGB_GREEN_PIN = 12;
const int RGB_BLUE_PIN = 11;

// Feedback LED Pins
const int FEEDBACK_RED_PIN = 9;
const int FEEDBACK_GREEN_PIN = 10;

// Button Pins
const int BUTTON_YELLOW_PIN = 2;
const int BUTTON_BLUE_PIN = 3;
const int BUTTON_GREEN_PIN = 4;
const int BUTTON_RED_PIN = 5;

// Potentiometer Pin
const int POT_PIN = A1;

// Game Settings
const int BASE_SEQUENCE_LENGTH = 3;
const int MAX_SEQUENCE_LENGTH = 12;
const int BASE_LIGHT_DISPLAY_TIME = 1000;
const int FAST_LIGHT_DISPLAY_TIME = 100;
const int PAUSE_BETWEEN_LIGHTS = 50;
const int FEEDBACK_BLINK_TIME = 200;
const int FEEDBACK_BLINK_COUNT = 3;

// Game State
int gameSequence[MAX_SEQUENCE_LENGTH];
int currentSequenceLength = BASE_SEQUENCE_LENGTH;
int currentDisplayTime = BASE_LIGHT_DISPLAY_TIME;

void setup() {
  // Initialize serial communication
  Serial.begin(9600);
  Serial.println("Simon Game Started!");

  // Configure LED pins
  pinMode(RGB_RED_PIN, OUTPUT);
  pinMode(RGB_GREEN_PIN, OUTPUT);
  pinMode(RGB_BLUE_PIN, OUTPUT);
  pinMode(FEEDBACK_RED_PIN, OUTPUT);
  pinMode(FEEDBACK_GREEN_PIN, OUTPUT);

  // Configure button pins
  pinMode(BUTTON_YELLOW_PIN, INPUT_PULLUP);
  pinMode(BUTTON_BLUE_PIN, INPUT_PULLUP);
  pinMode(BUTTON_GREEN_PIN, INPUT_PULLUP);
  pinMode(BUTTON_RED_PIN, INPUT_PULLUP);

  // Reset LEDs
  turnAllRGBOff();
  digitalWrite(FEEDBACK_RED_PIN, LOW);
  digitalWrite(FEEDBACK_GREEN_PIN, LOW);

  // Seed random generator
  randomSeed(analogRead(A0));
  
  Serial.println("Waiting for start...");
}

void loop() {
  // Wait for start button 
  while (digitalRead(BUTTON_YELLOW_PIN) == HIGH) {
    digitalWrite(FEEDBACK_RED_PIN, HIGH);
    digitalWrite(FEEDBACK_GREEN_PIN, LOW);
    delay(150);
    digitalWrite(FEEDBACK_RED_PIN, LOW);
    digitalWrite(FEEDBACK_GREEN_PIN, HIGH);
    delay(150);
    digitalWrite(FEEDBACK_GREEN_PIN, LOW);
    delay(100);
  }
  
  digitalWrite(FEEDBACK_RED_PIN, LOW);
  digitalWrite(FEEDBACK_GREEN_PIN, LOW);

  Serial.println("Game Starting...");
  delay(200);
  
  // Update difficulty based on potentiometer
  updateGamePace();
  
  // Generate and display sequence
  generateSequence();
  printSequence();
  displaySequence();

  // Process player input
  bool correct = getUserInput();

  // Provide result feedback
  if (correct) {
    Serial.println("Correct!");
    feedbackBlink(FEEDBACK_GREEN_PIN, FEEDBACK_BLINK_COUNT, FEEDBACK_BLINK_TIME);
  } else {
    Serial.println("Incorrect!");
    feedbackBlink(FEEDBACK_RED_PIN, FEEDBACK_BLINK_COUNT, FEEDBACK_BLINK_TIME);
  }
}

// Adjust sequence length and speed based on potentiometer value
void updateGamePace() {
  int potValue = analogRead(POT_PIN);

  currentSequenceLength = map(potValue, 0, 1023, BASE_SEQUENCE_LENGTH, MAX_SEQUENCE_LENGTH);
  currentSequenceLength = constrain(currentSequenceLength, BASE_SEQUENCE_LENGTH, MAX_SEQUENCE_LENGTH);

  currentDisplayTime = map(potValue, 0, 1023, BASE_LIGHT_DISPLAY_TIME, FAST_LIGHT_DISPLAY_TIME);
  currentDisplayTime = constrain(currentDisplayTime, FAST_LIGHT_DISPLAY_TIME, BASE_LIGHT_DISPLAY_TIME);
}

// Fill sequence array with random colors
void generateSequence() {
  for (int i = 0; i < currentSequenceLength; i++) {
    gameSequence[i] = random(4);
  }
}

// Output current sequence to serial monitor for debugging
void printSequence() {
  Serial.print("Sequence: [");
  for (int i = 0; i < currentSequenceLength; i++) {
    Serial.print(gameSequence[i]);
    if (i < currentSequenceLength - 1) Serial.print(", ");
  }
  Serial.println("]");
}

// Play back the sequence on the RGB LED
void displaySequence() {
  for (int i = 0; i < currentSequenceLength; i++) {
    switch (gameSequence[i]) {
      case 0: turnOnRGBRed(); break;
      case 1: turnOnRGBGreen(); break;
      case 2: turnOnRGBBlue(); break;
      case 3: turnOnRGBYellow(); break;
    }
    delay(currentDisplayTime);
    turnAllRGBOff();
    delay(PAUSE_BETWEEN_LIGHTS);
  }
}

// Capture player input and verify against sequence
bool getUserInput() {
  int inputCount = 0;

  while (inputCount < currentSequenceLength) {
    int pressedButton = readButtons();
    
    if (pressedButton != -1) {
      // Visual feedback for button press
      switch (pressedButton) {
        case 0: turnOnRGBRed(); break;
        case 1: turnOnRGBGreen(); break;
        case 2: turnOnRGBBlue(); break;
        case 3: turnOnRGBYellow(); break;
      }
      delay(100);
      turnAllRGBOff();
      delay(50);

      // Check against expected sequence
      if (pressedButton != gameSequence[inputCount]) {
        return false;
      }
      
      inputCount++;
      
      // Wait for button release
      while(digitalRead(BUTTON_RED_PIN) == LOW || digitalRead(BUTTON_GREEN_PIN) == LOW ||
            digitalRead(BUTTON_BLUE_PIN) == LOW || digitalRead(BUTTON_YELLOW_PIN) == LOW);
    }
  }
  return true;
}

// Return index of pressed button or -1 if none
int readButtons() {
  if (digitalRead(BUTTON_RED_PIN) == LOW) return 0;
  if (digitalRead(BUTTON_GREEN_PIN) == LOW) return 1;
  if (digitalRead(BUTTON_BLUE_PIN) == LOW) return 2;
  if (digitalRead(BUTTON_YELLOW_PIN) == LOW) return 3;
  return -1;
}

// Blink specified LED for feedback
void feedbackBlink(int pin, int count, int blinkTime) {
  for (int i = 0; i < count; i++) {
    digitalWrite(pin, HIGH);
    delay(blinkTime);
    digitalWrite(pin, LOW);
    delay(blinkTime);
  }
}

// --- RGB Control Helpers ---

void turnAllRGBOff() {
  digitalWrite(RGB_RED_PIN, LOW);
  digitalWrite(RGB_GREEN_PIN, LOW);
  digitalWrite(RGB_BLUE_PIN, LOW);
}

void turnOnRGBRed() {
  turnAllRGBOff();
  digitalWrite(RGB_RED_PIN, HIGH);
}

void turnOnRGBGreen() {
  turnAllRGBOff();
  digitalWrite(RGB_GREEN_PIN, HIGH);
}

void turnOnRGBBlue() {
  turnAllRGBOff();
  digitalWrite(RGB_BLUE_PIN, HIGH);
}

void turnOnRGBYellow() {
  turnAllRGBOff();
  digitalWrite(RGB_RED_PIN, HIGH);
  digitalWrite(RGB_GREEN_PIN, HIGH);
}

 

Week 9 – Post Response

Good Design Needs No Explanation

This week we read “Physical Computing’s Greatest Hits and Misses” and “Making Interactive Art: Set the Stage, Then Shut Up and Listen.” These readings made me think about how we interact with objects.

In my opinion, the main factor for a brilliant design is intuition. It should be unnoticeable. It should not require an instruction manual. I am a self-proclaimed kinesthetic learner. This means I learn by doing. I despise manuals. When I get something new, I like to jump in headfirst and discover how it works.

The reading on “Greatest Hits and Misses” talks about reliability and clarity. However, modern tech companies often ignore this. They prioritize simple, sleek designs to look futuristic. This often sacrifices intuitivity.

For example, you might have to double tap the back of a phone to take a screenshot. Or you have to triple tap to turn on a flash. These are hidden secrets, not clear controls.

I have a personal example of this. I used to go into the settings menu on my phone every time I wanted to turn on noise cancellation on my AirPods. Eventually, someone pointed out that I can just hold the stem of the AirPod to change the mode. I felt silly, but I shouldn’t have. The design gave me no clue that the feature existed.

Of course, there are exceptions. An airplane cockpit is very complex. It has hundreds of buttons. This affords complexity because knowledge is a prerequisite. You have to go to flight school to fly a plane.

But for everyday items or art, we should not need flight school.

This connects to the second reading, “Set the Stage, Then Shut Up and Listen.” This text argues that an artist should not stand next to their work and explain it.

If you let a user interact with your art without context, and they do it wrong, that is important data. It does not mean the user is stupid. It means the design is flawed or unintuitive.

As a designer, you have to set the stage. You have to give clues through the shape and feel of the object. If you have to write a manual for your art installation, you have failed to make a connection. Good interaction is about letting the user figure it out with their own hands.

Week 8 – Post Response

Design is More Than Function: Why Feeling Right Matters

When we think about technology, it’s easy to focus only on what it does. But good design isn’t just about function, it’s about how it feels. The readings “Emotion & Design: Attractive Things Work Better” and Her Code Got Humans on the Moon reminded me that emotion, perception, and clever design tricks shape how we interact with technology every day.

Take something as simple as a volume bar on your phone. On paper, 50% should be half the sound. But our ears don’t perceive sound linearly, they perceive it logarithmically. This means that a volume slider isn’t just a slider, it’s an emotional experience. Apple and Google realized this and adjusted the curves so that the volume feels smooth and natural to our ears. YouTube, by contrast, leaves most of the adjustment in the last 10%, making it feel unpredictable and frustrating.

Some designs don’t actually change the outcome but give the illusion of control. Elevators are a perfect example. About 80% of “close door” buttons don’t do anything, the door closes automatically, but the button makes users feel empowered. That illusion of control creates a better experience, even if it’s technically unnecessary. This is exactly the kind of trick designers use to shape our perception and emotions.

Another example from the transcript is the Nintendo Switch joycon mirrors. The solution was low-tech and simple: a small mirror to reflect the LED lights. It’s deceptively simple but brilliantly effective. It shows that design isn’t always about complexity, it’s about solving the human problem in a way that feels right.

Even everyday software hides these design decisions. Progress bars, icons, and animations are not just decorative, they are carefully crafted to keep users calm, informed, and engaged. Google tested 50 shades of blue to see which one users clicked most, and Apple uses subtle motion blur to make screens feel smoother. These small touches are invisible if done well, but they make a huge difference in the user experience.

Week 5 – Post Response

Computer vision works in a very different way from how people see. We read situations without thinking. We notice feelings, intent, and small details that are not written anywhere. A computer has none of this. It only receives a grid of values and waits for someone to tell it what to look for. Nothing has meaning until a developer builds rules or trains a model to reach a goal.

There are simple methods that can guide the system. Finding outlines helps the computer separate one shape from another. Tracking color ranges can point it toward a moving object. Contours make it easier to follow form. With the right setup and some training, the computer can get close to noticing what matters in a scene, even if it never truly understands it.

This matters a lot in interactive art. Vision gives the work a way to notice the audience and respond. A camera can capture movement, distance, and presence at the same time, which makes it one of the strongest sensors an artist can use. At the same time, people take in art through many senses. We see, listen, and feel. Computer vision tries to narrow that gap by giving machines a way to observe instead of just wait. This opens new creative space, but it also raises questions about how much the artwork should watch and how that changes the experience for the viewer.

Week 3 – Post Response

Rethinking Interactivity

After reading Chapter 1 of The Art of Interactive Design by Chris Crawford, I started to see how we often talk about interactivity as if it is all or nothing. You either have it or you do not. In my opinion, it is not that simple. There are levels to it.

Crawford draws a clear line between reaction and interaction. He says that a reactive system only answers a user action with a single output. An interactive system listens, responds, and listens again. It becomes a loop between the user and the system. I agree with this idea, but I still think even simple reactions sit on the same scale, only at the very bottom.

A fridge light turning on when the door opens is a good example. It changes based on what the user does, so it is not completely passive. Still, it does not take in new information after that first moment. There is no ongoing exchange. It is interactive in a very low way.

What separates the two is the direction of the flow. A reactive system goes from input to output and then stops. An interactive system keeps the conversation going. It listens to the user, gives feedback, and then listens again. The more complex the loop becomes, the higher the interactivity feels.

Thinking of interactivity as a spectrum makes design more interesting. It helps us see why some systems feel alive while others feel flat. It also shows that even simple actions can be part of a larger idea when we look at them in context.