week 10 reading

Wow — that was one hell of a ride. And honestly? I’m totally with the author.

This “Brief Rant” is one of those pieces that sneaks up on you — starts with what feels like a critique of tech hype, and then swerves into something deeper, richer, and honestly kind of inspiring. Like, it’s not just about interface design — it’s a call to remember we have bodies. Hands. Nerves. A whole kinesthetic intelligence we’re just not using when we swipe on glass all day.

I really liked how it re-centered the conversation around human capabilities. We always hear “design for human needs,” and sure, that’s important — but what about what we can do? Our bodies have evolved for interaction in a 3D world, not for dragging pixels around on glass rectangles.

The “Pictures Under Glass” metaphor hit hard. It made me think about how normalized numbness has become in tech. The flat, frictionless world of apps and interfaces is convenient, sure — but it’s also dulling. Tactile, responsive interaction? That’s not a luxury. That’s how we’re wired to engage.

And don’t even get me started on the sandwich example — I’ve never thought so deeply about lunch prep. But now? Every time I slice bread, I’ll be thinking “Is this more interactive than the entire iOS interface?” (Spoiler: yes.)

Also, the author’s tone? Perfect balance between fed-up tech veteran and hopeful visionary. No fake optimism, no over-promising. Just: “Here’s what sucks. Here’s why it matters. Let’s not settle.”

It left me feeling two things at once:

  1. Frustrated with how low the bar is for what we call “innovation.”

  2. Excited about the possibilities we haven’t tapped into yet — haptics, tangible interfaces, maybe even something entirely new.

Anyway, this wasn’t just a critique of screens. It was a reminder that vision matters, and that choosing better futures — not just shinier ones — is on us.

week 10 musical instrument

Concept

We were thinking a lot about what kind of instrument we want to make and wanted to stray away from the classic, well known ones like guitar and piano and drums and we decided to recreate an instrument many haven’t probably heard of, called Otomatone.

The instrument work by the user pressing the upper longer part of the instrument in different positions and pressing the “mouth” on both sides so it opens. The instrument than creates a sound and makes it look like the character is singing.

Our design

To recreate this we decided to use light resistors as the upper part of the body. The resistors would detect when the user puts their hand over them and create a sound. But the sound wouldn’t be heard until the user pressed on the “cheeks” of the character which had force resistors to detect the force of the press.

Here is the photo of the board and the photoresistors. We also added a button which, if held, will give the sound some vibration while playing. The final design of our Otomatone instrument looks like this:

Code higlight

The code for this instrument wasn’t that complicated. The hardest part was finding the values for all the notes but we used the help of the internet for that.

// Multi-note LDR1
if (ldrVal1 < 500 && duration > 10) {
if (totalPressure < 256) {
activeNote = 440; // A4
} else if (totalPressure < 512) {
activeNote = 523; // C5
} else if (totalPressure < 768) {
activeNote = 659; // E5
} else {
activeNote = 784; // G5
}
Serial.print("LDR1 note: "); Serial.println(activeNote);
}

 

This is the code for one of the light resistors which as you can see combines the value of the resistor with the total pressure of the force sensors detected and gives us a tone based on those calculations. The code for other light resistors is similar and not too complicated to understand.

Challenges and future improvement

The biggest challenge for this project was, surprisingly, getting the buzzer inside the “mouth” of the instrument. Getting 2 holes in the back of the “head” of the instrument  was very hard, and even though we tried to do it with our hands it prove impossible to do without a drill which in the end, after many attempts, broke the inside of the ball enough for a jumper cable to pass. The idea was to stick the breadboard to the back of the head and in that way recreate the original instrument and also not have the alligator clips inside the mouth, rather have the buzzers nodes sticking out through the holes. Due to the time constraint this sadly wasn’t possible, but I hope in the future we will be able to add it. As for the future improvements I would like to clean up the wires a bit and add a breadboard to the back of the head. Overall we are happy with the final result and we had a lot of fun working on this project and we also learned a lot!

week 11- reading

Reading this made me think about how design for people with disabilities is often overlooked or treated differently from regular products. I was surprised to learn that something as useful as a leg splint could also be inspiring in its design. It showed me that design doesn’t have to be boring just because it’s made for a medical use. I also liked how the author talked about fashion and disability. Glasses are a good example of how something can help people see better but still be stylish and accepted by everyone. The book made me reflect on how design can be both helpful and creative, and how we need more balance between solving problems and exploring new ideas in design especially in the disability world.

Week 11 – Final Project Proposal

Concept
My project will be inspired those old music boxes with spinning ballerinas. Ideally, my project would feature a spinning ballerina or just a figurine, LED’s that would synchronize with the music, and an aesthetic, coded background that adjusts to the mood and rhythm of the music. It would have multiple song options, and based on the song picked the ballerina, LED’s, and screen would change and be synchronized to the tempo and mood of the song.

Implementation

The p5.js component of the project will generate a visual background on a screen that reacts to the mood and rhythm of the music. As the music plays, the background will shift in real-time, creating patterns or abstract shapes that match the mood of the track. For example, more upbeat, energetic songs could produce fast-moving, bright, dynamic visuals, while softer or slower melodies might evoke slower, more tranquil visuals. p5 will also be in charge of the user interaction, the user will be able to  interact with the system through buttons on the screen, where they can select which songs to play.

Arduino on the other hand will serve as the main controller for the mechanical and physical elements of the installation. It will control the motor for the ballerina’s spin and manage the LED lights, ensuring that both respond appropriately to the music.

Week 11 – Reading Response

Design Meets Disability

This reading made me reconsider how I think about design in the context of disability. The leg splint designed by Charles and Ray Eames specifically really stood out to me, because it was initially created to help injured soldiers, but ended up influencing furniture that became iconic. Its actually fascinating how something made for a medical purpose could also be seen as beautiful and timeless. This really challenges the idea that medical or assistive products don’t need to look good, and that their purpose somehow makes good design less important. This made me think about how we often overlook the innovation that can come from designing for smaller, more specific needs, and how that innovation can influence much broader areas. What stayed with me most was the idea of tension between problem-solving and creative exploration in design. The author describes how the Eameses worked within two different approaches, so one that focused on solving practical issues, and another that played with form and possibility. That mix led to some of their most important work. It made me wonder why design for disability today is still so dominated by clinical or technical thinking. Where is the space for imagination and experimentation? This feels like a missed opportunity, and I think if more designers brought in artistic and playful approaches, we might see tools and products that are not only more effective but also more meaningful and engaging for the people using them.

Week 11 – Reading Response

Design Meets Disability

When reading about how eyewear went from medical necessity to iconic fashion accessories, I thought about how headphones could go down that route as well. Hearing aids are designed to be small and discrete, which can even hinder their abilities. However, nowadays in popular fashion, big chunky headphones are worn as part of the outfit. For example, people purchase overpriced AirPod Maxes despite better quality noise-cancelling choices out there for cheaper. However, Maxes are a symbol of status and have a clean slick look to them that help complete the outward appearance someone’s trying to uphold. Ear jewelry is a huge part of the fashion industry and part of everyday accessorizing for some people, but at the same time, hearing aids are shameful. If accessibility and fashion designers could work together to create something people with hearing impairments can be proud of , it’d be like the difference between consuming bitter medicine versus gummy vitamins.

I really liked reading about Hugh Herr with prosthetic legs that do more than legs can do. They actually help him perform acts in climbing that able-bodied people cannot. Perhaps prosthetics shouldn’t aim to replicate limbs but to achieve beyond what’s possible. There’s so much more freedom to create and add; prosthetic limbs shouldn’t fit inside a box to replicate what society deems as normal. This ties back to the idea of designing “invisible” and discrete products, implying an underlying shame attached to them and having a disability. However, confidence stems from being proud of oneself. If these products inherently disregard its user/wearer, that’s hard to achieve. Having more interface designers in this field could alleviate such problems.

Week 11 – Serial Communication

Features:

P5 sketch:

Arduino Code:

// Inputs:
// - A0 - sensor connected as voltage divider (e.g. potentiometer or light sensor)
// - A1 - sensor connected as voltage divider 
//
// Outputs:
// - 2 - LED
// - 5 - LED

int leftLedPin = 2;
int rightLedPin = 5; // analog

void setup() {
  // Start serial communication so we can send data
  // over the USB connection to our p5js sketch
  Serial.begin(9600);

  // We'll use the builtin LED as a status output.
  // We can't use the serial monitor since the serial connection is
  // used to communicate to p5js and only one application on the computer
  // can use a serial port at once.
  pinMode(LED_BUILTIN, OUTPUT);

  // Outputs on these pins
  pinMode(leftLedPin, OUTPUT);
  pinMode(rightLedPin, OUTPUT);

  // Blink them so we can check the wiring
  digitalWrite(leftLedPin, HIGH);
  digitalWrite(rightLedPin, HIGH);
  delay(200);
  digitalWrite(leftLedPin, LOW);
  digitalWrite(rightLedPin, LOW);

  // start the handshake
  while (Serial.available() <= 0) {
    digitalWrite(LED_BUILTIN, HIGH); // on/blink while waiting for serial data
    Serial.println("0,0"); // send a starting message
    delay(300);            // wait 1/3 second
    digitalWrite(LED_BUILTIN, LOW);
    delay(50);
  }
}

void loop() {
  // wait for data from p5 before doing something
  while (Serial.available()) {
    digitalWrite(LED_BUILTIN, HIGH); // led on while receiving data

    int left = Serial.parseInt();
    int right = Serial.parseInt();
    if (Serial.read() == '\n') {
      digitalWrite(leftLedPin, left);
      analogWrite(rightLedPin, right);
      int sensor = analogRead(A0);
      delay(5);
      int sensor2 = analogRead(A1);
      delay(5);
      Serial.print(sensor);
      Serial.print(',');
      Serial.println(sensor2);
    }
  }
  digitalWrite(LED_BUILTIN, LOW);
}

 

Final Project IDEA

Final project idea:

  • Create something similar to tamagachi – 3D print casing – spherical with a space for an LCD screen
  • LCD Screen will emote emotions – happy, sad, angry, barf
  • You can feed the vivagachi via p5 – this will in turn make it happy in the physical world – also play sounds from computer
  • If you feed it too much – it will make a barf face
  • https://www.thingiverse.com/thing:6455210
  • How it works:
    • P5 will be in charge of all the code, it’ll just send arduino all the expressions. For example, [1,2,3,4] – each represents a diff emotion
      • 1 – happy – after being fed
      • 2 – sad – after being hit 
      • 3 – scared (light sensor for darkness)
      • 4 – full/barf
      • 5 – neutral
    • Can also have a sensor ..? – if it’s too dark it’ll make a scared face
    • Servo motor – control arms/hands – when happy, arms swing back and forth
    • Colors! – use neopixels – depending on the emotional transition – so each emotion has a color associated with it – depending on the transition, it’ll lerp one color to another. 1 to 2 – yellow to blue, for example
    • Force sensor on its hand..?if you hold it it’ll be happy, but if you press too hard, it’ll be sad (threshold)
    • Tilt sensor – if it’s upside down, say it’s dizzy

week 11- Homework

Task 1:

We made it so that the program shows a circle on the screen that moves left and right when u rotate the potentiometer. The Arduino sends values to p5, and p5 reads those values through the serial port. As the potentiometer is rotated, the circle moves across the canvas to match its position. Theres also a button in the sketch that lets you connect to the Arduino manually.

p5.js code:

let serialPort;         // connection to the arduino
let connectButton;      // button to connect to arduino
let serialSpeed = 9600; // speed of communication between p5 and arduino
let xCircle = 300;      // starting x position of circle

function setup() {
  createCanvas(300, 300);
  background(245);

  serialPort = createSerial();

  let previous = usedSerialPorts();
  if (previous.length > 0) {
    serialPort.open(previous[0], serialSpeed);
  }

  connectButton = createButton("Connect Arduino"); // connect button
  connectButton.mousePressed(() => serialPort.open(serialSpeed)); // when clicked, connect
}

function draw() {
  let data = serialPort.readUntil("\n");  // reads the data from arduino

  if (data.length > 0) {       // if data received
    let sensorValue = int(data); // convert it to a number
    xCircle = sensorValue;       // use it to update the circles x position
  }

  background(245);
  fill(255, 80, 100);
  noStroke();
  ellipse(xCircle, height/2, 35); // draw circle at new position
}

Arduino code:

void setup() {
  Serial.begin(9600); // initialize serial communications
}
 
void loop() {
  // read the input pin:
  int potentiometer = analogRead(A1);                  
  // remap the pot value to 0-300:
  int mappedPotValue = map(potentiometer, 0, 1023, 0, 300); 
  Serial.println(mappedPotValue);
  // slight delay to stabilize the ADC:
  delay(1);                                            
  delay(100);
}

Task 2:

When the Arduino receives the letter ‘H’, it turns the LED on. When it receives the letter ‘L’, it turns the LED off. This lets you control the LED p5 by pressing the “Turn ON” or “Turn OFF” buttons.

p5.js code:

let serialPort;
let connectButton;
let serialSpeed = 9600;

function setup() {
  createCanvas(300, 200);
  background(240);

  serialPort = createSerial(); // create serial port connection

  let prev = usedSerialPorts(); // check if theres a previously used port
  if (prev.length > 0) {
    serialPort.open(prev[0], serialSpeed);
  }

  connectButton = createButton("Connect Arduino");
  connectButton.position(10, 10); // button position
  connectButton.mousePressed(() => serialPort.open(serialSpeed)); // open port when button clicked

  let onBtn = createButton("Turn ON"); // button to turn the LED on
  onBtn.position(10, 50); // position of ON button
  onBtn.mousePressed(() => serialPort.write('H')); // Send 'H' to arduino when pressed

  let offBtn = createButton("Turn OFF"); // button to turn the LED off
  offBtn.position(90, 50); // position of OFF button
  offBtn.mousePressed(() => serialPort.write('L')); // send 'L' to arduino when pressed
}

function draw() {
}

Arduino code:

void setup() {
  pinMode(9, OUTPUT);        // LED on pin 9
  Serial.begin(9600);        // start serial communication
}

void loop() {
  if (Serial.available()) {
    char c = Serial.read();

    if (c == 'H') {
      digitalWrite(9, HIGH); // turn LED on
    }
    else if (c == 'L') {
      digitalWrite(9, LOW);  // turn LED off
    }
  }
}

Task 3:

We used serialPort to read the sensor value and mapped it to wind force. To light up the LED only once per bounce, we added a boolean flag (ledTriggered). When the ball hits the ground, it sends a signal like ‘H’ to the Arduino to turn on the LED and ‘L’ to turn it off.

p5.js code:

let velocity;
let gravity;
let position;
let acceleration;
let wind;
let drag = 0.99;
let mass = 50;
let serial;
let connectBtn;
let ledTriggered = false;

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

  // setup serial connection
  serial = createSerial();
  let previous = usedSerialPorts();
  if (previous.length > 0) {
    serial.open(previous[0], 9600);
  }

  connectBtn = createButton("Connect to Arduino");
  connectBtn.position(10, height + 10); // button position
  connectBtn.mousePressed(() => serial.open(9600));
}

function draw() {
  background(255);
  // check if we received any data
  let sensorData = serial.readUntil("\n");

  if (sensorData.length > 0) {
  // convert string to an integer after trimming spaces or newline

    let analogVal = int(sensorData.trim());
    let windForce = map(analogVal, 0, 1023, -1, 1);
    wind.x = windForce; // horizontal wind force
  }

  applyForce(wind);
  applyForce(gravity);
  velocity.add(acceleration);
  velocity.mult(drag);
  position.add(velocity);
  acceleration.mult(0);
  ellipse(position.x, position.y, mass, mass);
  if (position.y > height - mass / 2) {
    velocity.y *= -0.9; // A little dampening when hitting the bottom
    position.y = height - mass / 2;

    if (!ledTriggered) {
      serial.write("1\n");   // trigger arduino LED
      ledTriggered = true;
    }
  } else {
    ledTriggered = false;
  }
}

function applyForce(force) {
  // Newton's 2nd law: F = M * A
  // or A = F / M
  let f = p5.Vector.div(force, mass);
  acceleration.add(f);
}

function keyPressed() {
  if (key === ' ') {
    mass = random(15, 80);
    position.y = -mass;
    velocity.mult(0);
  }
}

Arduino code:

int ledPin = 5;

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

void loop() {
  // send sensor value to p5.js
  int sensor = analogRead(A1);
  Serial.println(sensor);
  delay(100);

  // check for '1' from p5 to trigger LED
  if (Serial.available()) {
    char c = Serial.read();
    if (c == '1') {
      digitalWrite(ledPin, HIGH);
      delay(100);
      digitalWrite(ledPin, LOW);
    }
  }
}

Video:

Midterm Project – Oracle Lady

Oracle Cards – Midterm Project Report

Oracle Cards is an interactive web-based application I developed, inspired by the mystical allure of tarot and oracle card readings. For this project, I utilized the p5.js library to create a visually engaging and user-friendly experience that allows users to select a category and receive either advice or a reflection question. My goal was to craft an accessible and contemplative digital experience, drawing from my interest in mindfulness and self-reflection. This project leverages p5.js for rendering graphics, handling user input, and incorporating audio to enhance immersion.

About

Gameplay Instructions:
To play Oracle Cards, click the game link above to open the application in a new window. Ensure your browser supports p5.js and that you have a stable internet connection for loading assets (images and audio). The game is controlled entirely via mouse clicks, making it intuitive and accessible. Upon loading, you’ll see a welcome screen with a background image and category buttons. Click a category to proceed, then choose between receiving advice or a reflection question. The result is displayed on a card, accompanied by ambient music you can control with on-screen buttons. All images (e.g., backgrounds, cards) were sourced from royalty-free libraries, and the music tracks are licensed for non-commercial use. I do not claim ownership of these assets but have customized their integration to suit the game’s aesthetic.

How the Game Works

Oracle Cards simulates a digital card-reading experience, drawing inspiration from oracle decks used for introspection and guidance. The game progresses through three states:

  1. Start: Users select a category (“Yourself,” “Friends & Family,” or “Transcendence”).

  2. Choose Type: Users pick between “Advice” or a “Reflection Question.”

  3. Result: A randomly selected response is displayed on a card, based on the chosen category and type.

The game uses a desk-themed interface with a lady in the background (inspired by a fortune-teller aesthetic) to create an immersive atmosphere. Users can control background music via play/pause, next, and previous buttons, enhancing the reflective mood. The sequence of events is as follows:

  • The game loads with a welcome screen and category buttons.

  • Clicking a category transitions to the choice screen, displaying a card with two options.

  • Selecting a choice reveals the result on a card, with a prompt to restart by clicking anywhere.

The design emphasizes simplicity and emotional resonance, encouraging users to pause and reflect.

Game Controls

The controls are straightforward:

  • Mouse Click: Click on category buttons (e.g., “Yourself”) to select a category, choice buttons (e.g., “Advice”) to pick a type, or anywhere on the result screen to restart.

  • Music Controls: Click the previous, play/pause, or next buttons in the top-right corner to manage background music.

This minimal input method ensures accessibility for users of all skill levels.

Proud Moment

I’m particularly proud of implementing the state management system using p5.js, which seamlessly transitions between the start, chooseType, and result states without glitches. Debugging the button click detection was challenging, especially ensuring accurate hitboxes for the buttons, but I resolved this by carefully calculating their positions relative to the canvas. Additionally, integrating audio functionality with p5.js’s loadSound and managing playback states (play/pause, next/previous) was a significant achievement. The randomization of responses, tailored to each category and choice, adds replayability and depth, which I fine-tuned to ensure a balanced and meaningful user experience.

The Code

Reusability and p5.js

The code is designed with modularity in mind, separating concerns like state management, rendering, and user input. Key p5.js functions (preload, setup, draw) are organized to handle asset loading, canvas initialization, and continuous rendering efficiently. For example, the drawButtons function is reusable for rendering both category and choice buttons:

function drawButtons(options, yStart) {
  for (let i = 0; i < options.length; i++) {
    let x = width / 2;
    let y = yStart + i * 50;
    fill(200, 100, 100); // Button color (red)
    rect(x - 100, y - 20, 200, 40, 10); // Draw button with rounded corners
    fill(255); // White text
    textAlign(CENTER, CENTER);
    text(options[i], x, y); // Display button label
  }
}

This function is called in both the start and chooseType states, reducing code duplication. The preload function ensures all images and sounds are loaded before rendering, with error handling via callbacks:

deskLadyImage = loadImage('assets/desk_lady.png', 
  () => console.log("Desk lady image loaded successfully"), 
  (err) => console.error("Failed to load desk lady image:", err)
);

Object-Oriented Code

While the project primarily uses functional programming, the responses object is structured hierarchically to store advice and reflection questions for each category, enabling easy access and randomization:

let responses = {
  "Yourself": {
    "Advice": [
      "Take a deep breath and trust yourself.",
      // ... other advice
    ],
    "Reflection Question": [
      "What is one thing you truly love about yourself?",
      // ... other questions
    ]
  },
  // ... other categories
};

The mousePressed function handles state transitions and music controls, using conditional logic to detect clicks within button boundaries:

if (gameState === "start") {
  for (let i = 0; i < categories.length; i++) {
    if (mouseX > width / 2 - 100 && mouseX < width / 2 + 100 &&
        mouseY > height / 2 + 150 + i * 50 - 20 && mouseY < height / 2 + 150 + i * 50 + 20) {
      selectedCategory = categories[i];
      gameState = "chooseType";
    }
  }
}

This modular approach ensures the code is maintainable and extensible.

Training the Model

No machine learning models were used in this project, as the focus was on user interaction and randomization within p5.js. However, the randomization logic for responses mimics a lightweight decision model. I curated the responses object by researching mindfulness and self-help literature, ensuring each piece of advice or question is concise yet impactful. The random function in p5.js was used to select responses, tested extensively to confirm uniform distribution across options.

Areas of Improvement

I’m delighted with Oracle Cards as a reflective and engaging experience that aligns with my vision of digital mindfulness. However, there are opportunities for enhancement:

  • Additional Features: I’d like to add animations for card transitions and a settings menu to adjust music volume or toggle visuals (e.g., enabling/disabling the crystal ball image).

  • Visual Polish: Incorporating hover effects for buttons and more varied card designs could elevate the aesthetic.

  • Content Expansion: Adding more categories or allowing users to input custom questions would increase replayability.

  • Accessibility: Implementing keyboard controls alongside mouse clicks would make the game more inclusive.

As for the game logic, I plan to explore subtle physics-based animations (e.g., card flipping) using p5.js to enhance interactivity.

Conclusion

Overall, I’m proud of Oracle Cards and how it blends creativity, technical skill, and emotional resonance. It’s a meaningful step in my journey with interactive design, and I look forward to refining it further to share its calming experience with others.

Below is the Game: