User Testing

IMG_0901

Today I had a few people try my project without giving them any instructions, just to see how intuitive it actually is. Since the website isn’t fully finished yet, some parts were definitely confusing at first. People weren’t totally sure what the experience was supposed to be, and the lack of intro screens made it feel like something was missing.

But honestly, the four buttons in the p5 interface made a huge difference. Even without explanations, most people understood pretty quickly that each button does something to the robot. They started clicking around, testing what each one does, and exploring on their own. The mapping between the controls and the robot’s movement felt clear to them, which is a good sign.

Still, because the rest of the experience isn’t complete yet, they didn’t really understand why the robot was moving or what the larger goal of the project was supposed to be. This is where most of the confusion happened. I found myself needing to explain the story/context and what the robot is meant to represent , which means that once the website is finished, I need to make sure the narrative is communicated immediately and visually, without me talking.

Overall, the parts that are working really well right now are:

  • the p5 buttons

  • the immediate direct feedback

  • the fact that people naturally experimented

The parts that need improvement:

  • clearer intro

  • clearer purpose

  • smoother connection between the physical robot and the digital scenes

Once the full website and story screens are built, I think the experience will make a lot more sense for first-time users. For now, at least the controls are intuitive so that’s a good foundation to build on.

Week 12 – Documentation on Final Project

Finalized Concept: “The Snail’s Journey to School”

Project Summary
The Snail’s Journey to School is an interactive physical–digital storytelling installation.
The player controls a small snail robot navigating a handmade obstacle course, helping it reach “school.” As the player moves the snail using physical buttons, a connected p5.js sketch narrates the adventure, updates animations, and reacts to the snail’s progress in real time through serial communication with Arduino.

1. Finalized Detailed Concept

Physical World (Arduino + Snail Robot)

The snail robot sits on a small motorized base (the base will be the robot that can be built from Arduino Uno kit). The user controls the snail with three buttons:

  • FORWARD
  • LEFT
  • RIGHT

A “finish line” sensor (photoresistor or IR distance sensor) detects when the snail reaches the school.

The obstacle course includes:

  • A puddle (painted blue)
  • Small pebbles
  • A small cardboard ramp
  • A school gate with the sensor hidden inside

Digital World (p5.js Storytelling Screen)

The p5 screen visually tells the story through 4 scenes:

  1. Intro Scene
    “The snail is late for school! Guide it through the obstacle course.”
  2. Instructions Scene
    Shows button directions + images.
  3. Live Story Mode
    Reacts to every button press and displays animations such as:
  • “Snail moves forward!”
  • “Turning left…”
  • Little movement animations or sound effects.
  1. Ending Scene
    When the sensor triggers finish, p5 displays:
    “You made it! The snail is in class now!” with a cute animation.
  2. If the player doesn’t make it on time, which is 2.5 minutes, or fails to cross more than 1 obstacle the screen shows “oh no, you’re late to school!”

Project Interaction Loop (Final Version)

  1. Player presses physical button
  2. Arduino moves snail robot + sends message to p5
  3. p5 receives message and updates story animation
  4. Snail reaches sensor
  5. Arduino sends “finish” to p5 ->  p5 plays ending

Arduino Program Design

Week 11 – Final Project Prompt

My final project is an interactive installation titled “The Snail’s Journey to School.” The idea is inspired by the opening scenes of Monsters University, where a small character makes their way toward school. In my version, the user helps a robot snail travel through a physical obstacle course until it reaches its destination.

Arduino will control the physical movement of the robot snail using motors and buttons for directional input. It may also include an optional sensor, such as a photoresistor or distance sensor, to detect obstacles or the finish line. The snail robot and the obstacle course will be fabricated by me, either through 3D printing or hand-built materials.

p5.js will act as the narrative and feedback layer. It will display an introduction, instructions, and story elements that respond to the user’s physical interactions. As the user presses buttons to move the snail, Arduino will send messages to p5.js, which will update the visuals, play small animations or sounds, and react to progress in real time. When the snail reaches the “school” area, p5 will display the final scene.

The interaction loop centers on listening (reading the user’s button presses), thinking (moving the snail and sending corresponding data), and speaking (p5.js reacting immediately with feedback).

Week 11 – Reading Response

In Design Meets Disability, Graham Pullin challenges the way society frames disability by questioning why assistive devices are often treated as purely functional rather than expressive. He argues that design for disability should not be limited to medical necessity, it should also include aesthetics, identity, and personal preference. What stood out to me is how Pullin highlights the quiet power imbalance in design: mainstream objects like glasses or smartphones have endless variations and styles, while many assistive tools remain clinical and uniform. This difference reveals how disability is still seen as something to “fix” instead of a natural part of human diversity.

Pullin pushes the reader to consider that assistive devices could be opportunities for creativity rather than reminders of limitation. For example, he discusses the possibility of hearing aids becoming fashionable accessories instead of devices people feel pressured to hide. His argument reframes disability not as a deficit but as a design space full of potential innovation.

Overall, the reading invites designers to rethink their assumptions. Instead of designing for disabled people, Pullin encourages designing with them, treating disability as a source of insight and richness. The book ultimately suggests that inclusive design is not just ethical, it also expands the possibilities of design itself.

Week 11 – Production

Task 1: make something that uses only one sensor on Arduino and makes the ellipse in p5 move on the horizontal axis, in the middle of the screen, and nothing on arduino is controlled by p5.

Asma built a simple circuit using an Arduino and a 10kΩ potentiometer to control an on-screen ellipse in p5.js. She connected the potentiometer’s outer legs to 5V and GND and the middle leg to the analog pin A0, allowing it to act as a variable voltage divider. After uploading the Arduino code and checking the serial monitor, she could see how turning the knob changed the analog readings from 0 to 1023. This helped her understand how analog sensors translate physical movement into numerical data that can be visualized digitally.

Arduino code:

const int potPin = A0;

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

void loop() {
  int val = analogRead(potPin);   // 0..1023
  Serial.println(val);            
  delay(10);                     
}

P5.js codę:

// === Arduino + p5.js WebSerial (directional movement, fixed) ===
// Pot controls direction/speed by how its value changes. p5 does NOT control Arduino.

let port;
let reader;
let connectButton;
let isConnected = false;

let latestData = null; // last parsed int from serial (0..1023)
let prevData   = null; // previous sample to compute delta
let lineBuffer = '';   // accumulate serial chunks until '\n'

let posX = 0;          // ellipse position
let speed = 0;         // horizontal velocity

function setup() {
  createCanvas(windowWidth, windowHeight);
  background(240);
  textFont('monospace');

  connectButton = createButton('Connect to Arduino');
  connectButton.position(20, 20);
  connectButton.mousePressed(connectToSerial);

  // start centered; we'll keep it centered until first data arrives
  posX = width / 2;
}

async function connectToSerial() {
  try {
    // Request and open port
    port = await navigator.serial.requestPort();
    await port.open({ baudRate: 9600 });
    isConnected = true;
    console.log(' Port opened');

    // Create a text decoder stream and reader for clean line-by-line reads
    const textDecoder = new TextDecoderStream();
    const readableClosed = port.readable.pipeTo(textDecoder.writable);
    reader = textDecoder.readable.getReader();

    // Kick off read loop
    readSerialLines();
  } catch (err) {
    console.error(' Connection failed:', err);
    isConnected = false;
  }
}

async function readSerialLines() {
  try {
    while (true) {
      const { value, done } = await reader.read();
      if (done) break; // reader released
      if (!value) continue;

      // Accumulate and split by newline
      lineBuffer += value;
      let lines = lineBuffer.split(/\r?\n/);
      lineBuffer = lines.pop(); // save incomplete tail

      for (let line of lines) {
        line = line.trim();
        if (!line) continue;
        const v = parseInt(line, 10);
        if (!Number.isNaN(v)) {
          // Clamp to expected 10-bit range
          latestData = Math.min(Math.max(v, 0), 1023);
          // Initialize prevData on first valid sample
          if (prevData === null) prevData = latestData;
        }
      }
    }
  } catch (err) {
    console.error(' Read error:', err);
  } finally {
    try { reader && reader.releaseLock(); } catch {}
  }
}

function draw() {
  background(240);

  if (!isConnected) {
    fill(200, 0, 0);
    noStroke();
    textAlign(CENTER, CENTER);
    textSize(20);
    text("Click 'Connect to Arduino' to begin", width / 2, height / 2);
    return;
  }

  // If we haven't received any valid data yet, show waiting status
  if (latestData === null || prevData === null) {
    fill(0);
    textSize(16);
    textAlign(LEFT, TOP);
    text('Waiting for data...', 20, 60);
    // Keep ellipse centered until first data arrives
  } else {
    // Change in pot reading determines direction and speed bump
    const delta = latestData - prevData;

    // Deadband to ignore small noise
    const deadband = 4;
    if (delta > deadband) {
      speed = constrain(speed + 0.6, -12, 12); // turn right -> move right
    } else if (delta < -deadband) {
      speed = constrain(speed - 0.6, -12, 12); // turn left -> move left
    } else {
      // friction when knob still
      speed *= 0.90;
    }

    // Integrate position and clamp
    posX += speed;
    posX = constrain(posX, 0, width);

    // Update prev for next frame
    prevData = latestData;
  }

  // Draw ellipse at vertical center
  noStroke();
  fill(50, 100, 255);
  ellipse(posX, height / 2, 80, 80);

  // HUD
  fill(0);
  textSize(14);
  textAlign(LEFT, TOP);
  const shown = latestData === null ? '—' : latestData;
  text(⁠ Sensor: ${shown} ⁠, 20, 60);
  text(⁠ Speed:  ${nf(speed, 1, 2)} ⁠, 20, 80);
}

function windowResized() {
  resizeCanvas(windowWidth, windowHeight);
  // Keep position on-screen if you resize smaller
  posX = constrain(posX, 0, width);
}

Schematic:

 

Task 2: make something that controls the LED brightness from p5

Hajar created a simple schematic and circuit using one LED and one resistor connected to the Arduino. Since the main goal was to control the LED’s brightness through serial communication with p5.js, she kept the hardware minimal and focused more on the coding. She first tested the LED with a basic Arduino sketch to make sure everything worked, then created the schematic. Although the circuit was simple and familiar, it still showed her how even a basic setup can become interactive when combined with p5.js.

Arduino code:

const int ledPin = 10;  // LED connected to pin 10

void setup() {
  Serial.begin(9600);   // must match p5.js baud rate
  pinMode(ledPin, OUTPUT);
}

void loop() {
  if (Serial.available() > 0) {
    int brightness = Serial.read();      // read 0–255
    brightness = constrain(brightness, 0, 255);
    analogWrite(ledPin, brightness);     // control LED brightness
  }
}

P5.js codę:

Sketch:

Task 3: take the gravity wind example and make it so every time the ball bounces one led lights up and then turns off, and you can control the wind from one analog sensor

For this project, I combined both physical computing and digital simulation by connecting an Arduino circuit to a p5.js sketch. My setup included a potentiometer to control the wind force in the animation and an LED that lit up every time the falling ball hit the ground. I built a simple circuit using one LED, a resistor, and a 10kΩ potentiometer, and then connected it to my computer through serial communication. Even though the hardware was straightforward, the real challenge came from getting the Arduino and p5.js to communicate properly. I spent a lot of time testing the potentiometer readings, debugging the serial connection, and making sure the LED responded at the right moment in the animation.

P5.js code:

let velocity;
let gravity;
let position;
let acceleration;
let drag = 0.99;
let mass = 50;

let brightnessValue = 0; // Potentiometer value from Arduino (0–5)
let ballDropped = false;
let ledOn = false;

function setup() {
  createCanvas(640, 360);
  noFill();
  textSize(18);

  position = createVector(width / 2, 0);
  velocity = createVector(0, 0);
  acceleration = createVector(0, 0);
  gravity = createVector(0, 0.5 * mass);
}

function draw() {
  background(255);

  fill(0);
  if (!ballDropped) {
    text("Press D to drop the ball", 20, 30);
    text("Press Space Bar to select Serial Port", 20, 50);
    return;
  }

  if (serialActive) {
    text("Connected", 20, 30);
    text(`Potentiometer: ${brightnessValue}`, 20, 50);
  } else {
    text("Serial Port Not Connected", 20, 30);
  }

  // Gravity only (no wind)
  applyForce(gravity);

  // Update ball
  velocity.add(acceleration);
  velocity.mult(drag);
  position.add(velocity);
  acceleration.mult(0);

  // Draw ball
  ellipse(position.x, position.y, mass, mass);

  // Bounce
  if (position.y >= height - mass / 2) {
    velocity.y *= -0.9;
    position.y = height - mass / 2;

    // Tell Arduino: turn LED on briefly
    if (serialActive && !ledOn) {
      writeSerial("1,0\n");
      ledOn = true;
    }
  } else if (ledOn) {
    // Tell Arduino: turn LED off
    writeSerial("0,0\n");
    ledOn = false;
  }
}

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

// Serial setup and drop ball
function keyPressed() {
  if (key == " ") setUpSerial();
  if (key == "D" || key == "d") dropBall();
}

function dropBall() {
  position.set(width / 2, 0);
  velocity.set(0, 0);
  mass = 50;
  gravity = createVector(0, 0.5 * mass);
  ballDropped = true;
}

// Read data from Arduino
function readSerial(data) {
  if (data != null) {
    let fromArduino = split(trim(data), ",");
    if (fromArduino.length === 1) {
      brightnessValue = int(fromArduino[0]); // Potentiometer value
    }
  }
}

Arduino code:

int potPin = A5;   
int ledPin = 3;    

void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);

  analogWrite(ledPin, 255);
  delay(200);
  analogWrite(ledPin, 0);
}

void loop() {
  int raw = analogRead(potPin);

  int brightness = map(raw, 0, 1023, 0, 255);

  Serial.println(brightness);

  // Check for serial commands from p5
  if (Serial.available()) {
    String data = Serial.readStringUntil('\n');

    if (data == "1,0") {
      analogWrite(ledPin, brightness);  // flash with pot brightness
      delay(100);
      analogWrite(ledPin, 0);           // turn off after flash
    }
  }

  delay(30); 
}

Sketch:

Video:

IMG_9469

Week 10 – Reading Reflection

This piece, A Brief Rant on the Future of Interaction Design, really made me stop and think about how disconnected we’ve become from the physical world, even as our technology gets “smarter.” The author argues that our so-called “futuristic” devices are actually quite limited, everything has become a flat piece of glass we tap on, instead of something we truly interact with. He calls out this obsession with “pictures under glass” as lazy design — a downgrade from the richness of real, tactile experience.

What really stuck with me was his reminder of how incredible our hands are. They can sense texture, pressure, temperature, yet we now use them mainly to poke at screens. His comparison to trying to tie your shoes with numb fingers really drives it home. It’s not just that we’ve lost physical feedback, we’ve lost creativity and subtlety in how we use our bodies to understand the world.

But as much as I agree with him, I think his critique could use a bit more realism. There’s a reason touchscreens took over: they’re convenient, cheap, and universal. Designing physical, tactile, or responsive interfaces on a large scale would be expensive and hard to standardize. For example, the Apple Vision Pro tries to reintroduce gesture-based control, but even that feels awkward and unnatural for many people. It’s like we’ve already trained ourselves to think in 2D, to expect smooth glass, not texture or resistance.

Still, I think his rant is important because it challenges the direction of design thinking. It made me think about situations like education or online learning. imagine how much richer it would be if students could physically interact with virtual models or data instead of just scrolling and clicking. Or think of creative fields like art or architecture, where so much of the learning used to come from the feel of materials. Now, everything happens behind a screen.

So, while his rant might sound idealistic, it’s also a necessary wake-up call. It reminds us that innovation shouldn’t just mean “simpler” or “sleeker”, it should mean more human. The goal shouldn’t be to erase physicality for convenience, but to design technology that reconnects us to the world instead of flattening it.

Week 9 – Shadow and Light

Concept

For this project, I decided to make a small interactive game called Light & Shadow”. The concept is simple but fun: the yellow LED changes brightness depending on how much light the photoresistor (LDR) senses, and the blue LED only lights up when it’s dark and the button is pressed, basically “catching the shadow.” I liked that idea because it combines analog and digital inputs in a way that feels like a mini game.

The Process

The production process was mostly about setting up the circuit on the breadboard and figuring out how to connect everything correctly. Choosing the right resistors was harder than I expected,  sometimes the LEDs didn’t light up properly, and I had to try a few combinations before it worked. I also spent a lot of time drawing the schematic to make sense of the connections. I must have redrawn it several times to make it at least slightly understandable. Even now, I’m not 100% sure my plan is perfect, but it works!

Figure: the process of sketching the plan

The Finalized Sketch

The coding part was fun because it was simple enough to understand but still taught me a lot. I read the analog value from the photoresistor and mapped it to the brightness of the red LED, then used a simple if-statement to check the button and darkness to control the green LED. Seeing the LEDs react in real time to light and button presses made all the work feel rewarding.

int lightSensor = A0;
int buttonPin = 2;
int redLED = 9;
int greenLED = 8;

void setup() {
  pinMode(buttonPin, INPUT);
  pinMode(greenLED, OUTPUT);
  pinMode(redLED, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  int lightValue = analogRead(lightSensor);    // 0–1023
  int brightness = map(lightValue, 0, 1023, 255, 0); // dark = bright
  analogWrite(redLED, brightness);

  int buttonState = digitalRead(buttonPin);

  if (buttonState == HIGH && lightValue < 400) {
    digitalWrite(greenLED, HIGH);
  } else {
    digitalWrite(greenLED, LOW);
  }

  delay(100);
}

Reflection

Overall, this project was a great learning experience. I got hands-on practice with analog and digital inputs, using resistors correctly, and writing basic Arduino code. I also learned patience, both in wiring and drawing schematics. Even though some parts were frustrating or confusing, it felt really satisfying to see the LEDs respond the way I wanted. Next time, I’d probably try adding a buzzer or even a little LCD display to make it even more interactive.

The video demonstration

IMG_8850

Reading reflection

Reading Physical Computing’s Greatest Hits and Misses alongside Making Interactive Art: Set the Stage, Then Shut Up and Listen really made me rethink how we interact with technology in creative spaces. Both texts explore the tension between human intention and technological behavior, but they approach it from slightly different angles. The first one dives into successes and failures in physical computing projects, highlighting that even the best ideas can flop if the execution ignores user experience or the unpredictability of the real world. The second reading, on the other hand, emphasizes listening to the audience and letting interactions evolve naturally, rather than forcing a rigid narrative onto the art or installation.

The most interesting part for me was the recurring theme of “letting go.” In physical computing, there’s often a desire to control every aspect of a system, to make it work perfectly according to the designer’s vision. But as the readings show, interaction is messy. Sensors misfire, people behave unexpectedly, and sometimes the “mistakes” end up being the most engaging parts of the project. I appreciated the reminder that in interactive art, and in technology projects more broadly, failure isn’t always a failure, it’s data, feedback, and sometimes even the spark for something better.

One question that came to mind while reading was: How do we balance designing for reliability with designing for surprise and emergent behavior? Both readings suggest that embracing unpredictability can make projects more engaging, but too much unpredictability can frustrate users. My takeaway is that the key might be thoughtful scaffolding, providing enough structure so that the system is understandable and responsive, while leaving space for improvisation and interaction to shape the experience.

Overall, I found these readings both inspiring and a little humbling. They reminded me that creativity in physical computing isn’t just about technical skill, it’s about curiosity, flexibility, and, honestly, patience with both technology and people.

Week 8 – creative switch

For my project, I designed an Arduino switch using open-end wires that respond to the camera’s power state. I taped the wires to a digital camera so that when the camera is turned on, the wires disconnect and the LED light turns off, and when the camera is turned off, the wires reconnect and the light turns on. This created a simple but clever system where the camera itself acts as a physical trigger for the circuit. I really enjoyed experimenting with the setup, testing how small adjustments in the wire placement affected the light’s response. Since I’m passionate about photography, I wanted to combine my interest in cameras with my curiosity about electronics, and this project gave me a fun way to explore both creative and technical sides at the same time.

IMG_8468 (1) The video representation

week 8 – reading response

Reading Norman’s Emotion & Design and Her Code Got Humans on the Moon made me rethink what we usually praise in tech. Norman’s main idea that “attractive things work better” makes sense at first. If a product is enjoyable to use, we’re more likely to stick with it. But honestly, it feels a bit too neat. Just because something looks good doesn’t mean it works well. I’ve had plenty of apps or gadgets that are gorgeous but a pain to actually use. Norman makes a strong point about emotion shaping usability, but sometimes I feel designers lean on aesthetics as a crutch instead of solving real problems.

On the other hand, Her Code Got Humans on the Moon reminded me that behind every “perfect” design or software is a ton of human effort — in this case, women programmers whose work literally made moon landings possible. It’s wild how long their contributions were invisible. It makes me question why we hype technology itself while ignoring the people who make it run. The “heroic inventor” story Norman sometimes leans on in design discussions seems incomplete — we rarely celebrate the actual humans doing the work.

Putting these together, I think the readings challenge the usual tech narrative. Norman focuses on emotion and aesthetics, which are important, but Her Code highlights that real success comes from skill, persistence, and problem-solving. My takeaway? Great design isn’t just about looking or feeling good — it’s also about respecting and acknowledging the humans who make it work. Otherwise, we’re praising the wrong things and missing the bigger picture.