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 11: Production

Group Member: Aditi

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.

We used a potentiometer as the analog sensor on Arduino to move the ellipse on the horizontal axis.

p5js code:

// Serial port object
let port;

// Latest sensor value
let sensorVal = 0;

function setup() {
  createCanvas(400, 300);
  background(220);

  // Create the serial connection object
  port = createSerial();

  // If a port was used before, auto-reconnect
  let used = usedSerialPorts();
  if (used.length > 0) {
    port.open(used[0], 9600);
  }
}

function draw() {
  background(220);

  // Read one line of text until newline "\n"
  let str = port.readUntil("\n");

  // Make sure we actually received something
  if (str.length > 0) {

    // Convert the string into an integer
    let val = int(str.trim());

    // Map sensor value (0–1023) to screen X position (0–400)
    let x = map(val, 0, 1023, 0, width);

    // Draw a circle at mapped position
    ellipse(x, height / 2, 40, 40);

  } else {

    // If empty data is received, print it for debugging
    console.log("Empty:", str);
  }
}

Arduino code:

const int sensor=A2;
int sensorValue;
void setup() {
  // put your setup code here, to run once:
  pinMode(sensor,INPUT);
  Serial.begin(9600);
  Serial.println(0); // send a starting message
}

void loop() {
  // put your main code here, to run repeatedly:
  sensorValue=analogRead(sensor);
  delay(60);
  Serial.println(sensorValue);  
}

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

We decided to control the LED’s brightness through four buttons on p5js.

p5js code:

let port;
let brightnessToSend = 0;
const baudrate = 9600;

function setup() {
  createCanvas(400, 400);

  // Create the serial port
  port = createSerial();

  // connect automatically if used before
  let usedPorts = usedSerialPorts();
  if (usedPorts.length > 0) {
    port.open(usedPorts[0], baudrate);
  } else {
    connectBtn = createButton("Connect to Serial");
    connectBtn.position(10, 10);
    connectBtn.mousePressed(() => port.open(baudrate));
  }
}

function draw() {
  background(30);

  drawStarButton(80, 150, 40, 20, 5, 64);
  drawStarButton(160, 150, 40, 20, 5, 128);
  drawStarButton(240, 150, 40, 20, 5, 192);
  drawStarButton(320, 150, 40, 20, 5, 255);

  fill(255);
  textAlign(CENTER);
  text("Current brightness: " + brightnessToSend, width / 2, 280);
}

function mousePressed() {
  if (!port.opened()) return; // p5.webserial function to check if open

  let stars = [
    { x: 80,  brightness: 64  },
    { x: 160, brightness: 128 },
    { x: 240, brightness: 192 },
    { x: 320, brightness: 255 }
  ];

  for (let s of stars) {
    if (dist(mouseX, mouseY, s.x, 150) < 30) {
      brightnessToSend = s.brightness;

      // Send brightness (0–255)
      port.write(brightnessToSend);
    }
  }
}

function drawStarButton(x, y, radius1, radius2, points, brightness) {
  let angle = TWO_PI / points;
  let halfAngle = angle / 2;

  if (brightnessToSend === brightness) fill(255, 200, 0);
  else fill(255);

  push();
  translate(x, y);
  beginShape();
  for (let a = 0; a < TWO_PI; a += angle) {
    vertex(cos(a) * radius1, sin(a) * radius1);
    vertex(cos(a + halfAngle) * radius2, sin(a + halfAngle) * radius2);
  }
  
  endShape(CLOSE);
  pop();
}

Arduino code:

int ledPin = 9;

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

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

Video:

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.

p5js code:

let velocity;        // velocity vector of the ball
let gravity;         // gravity force vector
let position;        // position of the ball
let acceleration;    // accumulated acceleration each frame
let wind;            // wind force vector
let drag = 0.99;     // drag factor to slow down velocity a bit
let mass = 50;       // "mass" of the ball, also used as its size
let port;            // serial port object for Arduino ↔ p5 communication
let button;          // button to trigger serial connection popup
let open=false;      // flag to track if we've tried to open the port

function setup() {
  createCanvas(640, 360);
  noFill();
  position = createVector(width/2, 0);   // start ball at top center
  velocity = createVector(0,0);          // start with no movement
  acceleration = createVector(0,0);      // acceleration accumulates forces
  gravity = createVector(0, 0.5*mass);   // gravity pulls ball downward
  wind = createVector(0,0);              // wind starts with no force
  port = createSerial(); //port is an object that will be used to send message and receeieve message from arudnio
 
  //createbutton creates button in p5js with quote
  button=createButton("Connect to Arduino");
  button.position(width/2,height/2); //where you want your button to be
  button.mousePressed(openArduino); 
}

function openArduino(){
  if(!port.opened()){ //to check if the port is opened or not we use function opened
    port.open(9600) // we open the port for communication with 9600 frequency
   
    button.remove() // once arudino is opended we removed the button to connect to ardunio
   
    open=true; //just a variable to check if we opended the port or not
  } 
}

function draw() {
  if(port.opened()){             // run main logic only if serial port is open
  background(255);               // clear canvas every frame
  applyForce(wind);              // apply wind force first
  applyForce(gravity);           // then apply gravity force
  velocity.add(acceleration);    // a → v
  velocity.mult(drag);           // apply drag to slowly reduce velocity
  position.add(velocity);        // v → position
  acceleration.mult(0);          // reset acceleration so next frame starts fresh
  ellipse(position.x,position.y,mass,mass);  // draw the ball
 
  }

  // collision + LED control are outside the port.opened() block,
  // so they always run based on current position
  if (position.y > height-mass/2) {     
      velocity.y *= -0.9;         // A little dampening when hitting the bottom (bounce)
      position.y = height-mass/2; // keep ball from sinking below the "floor"
      port.write("1\n")           // send "1" to Arduino → turn LED ON
    }
    else {
      port.write("0\n")    // otherwise send "0" → turn LED OFF
    }
    potvalue=port.readUntil("\n");  // read a line from Arduino (pot value as text)
    // console.log(potvalue);
 
    if(potvalue>514){      // simple threshold: above midpoint = wind to the right
      wind.x=1
    }
    else{                  // below midpoint = wind to the left
      wind.x=-1
    } 
}

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

function keyPressed(){
  if (keyCode==LEFT_ARROW){
    wind.x=-1;              // keyboard override: push ball left
  }
  if (keyCode==RIGHT_ARROW){
    wind.x=1;               // keyboard override: push ball right
  }
  if (key==' '){
    mass=random(15,80);     // randomize mass (and drawn size)
    position.y=-mass;       // reset ball above the top so it falls back down
    velocity.mult(0);       // clear velocity so it restarts clean
  }
}

Arduino code:

int greenLight=7;
int sensor=A0;
void setup() {
  // put your setup code here, to run once:
  pinMode(greenLight,OUTPUT);
  pinMode(sensor,INPUT);
  Serial.begin(9600);
  digitalWrite(greenLight,0);
}

void loop() {
  // put our main code here, to run repeatedly:
  // Serial.print("0");
 
  int value= analogRead(sensor);
  Serial.print(value);
  Serial.print("\n");

  while(Serial.available()>0){ //avaiable checks if there is any message in inbox of ardino
    String a=Serial.readStringUntil('\n');
    a.trim();
    if(a=="1"){
       digitalWrite(greenLight,1);
    }
    else{
      digitalWrite(greenLight,0);
    }   
  }
}

Video:

Week 11 reading response

This text suffers from a fundamental contradiction that undermines its own arguments: while championing simplicity and challenging universal design, it romanticises elite consumer products that are themselves inaccessible to many disabled users. The iPod worship is weird, celebrating a device with no tactile feedback beyond a smooth wheel and minimal physical controls as some paragon of inclusive thinking. The author gestures at Peter and Steve’s differing preferences but never interrogates why someone like Tyler would need to feel “self-confident” using a phone in public, treating internalised ableism as personal taste rather than a design failure. The golden prosthetic hand and Aimee Mullins’s carved wooden legs are presented as liberating alternatives to discretion, yet these bespoke art objects are available only to those with money, barely a decent vision of disability design.

The tension between “fashion meets discretion” reveals the author’s shallow engagement with power dynamics in disability. Dismissing pink plastic hearing aids as shameful while celebrating expensive designer eyewear ignores that frames cost hundreds of pounds, discretion through flesh-coloured plastic may be the only affordable option for many users. The suggestion that “fashion designers should be involved as a matter of course” treats aesthetics as a universal good without acknowledging that high design often increases cost and decreases repairability.

The “flying submarine” metaphor encapsulates the text’s elitism, better to have multiple specialised and beautifully designed products than one versatile compromise. This definitely works if you can afford a wardrobe of prosthetics or a collection of single purpose devices, but it’s design thinking for the wealthy masquerading as liberation. The text never acknowledges that universal design emerged precisely because disabled people couldn’t access or afford specialised alternatives.

Shahram Chaudhry – Week 11 – Production

Task 1

I used a flex sensor to control the horizontal movement of the circle on the screen. When the sensor is bent, the circle moves horizontally. 

P5JS Code:

let port;
let sensorValue = 0;

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

function draw() {
  background(240);
  let str = port.readUntil("\n");
  if (str.length > 0) {
    sensorValue = int(str);
  }
  let x = map(sensorValue, 430, 500, 0, width);
  fill(100, 150, 255);
  ellipse(x, height / 2, 50, 50);
  fill(0);
  text("Sensor: " + sensorValue, 10, height - 20);
}

function mousePressed() {
  if (!port.opened()) {
    port.open("Arduino", 9600);
  }
}

Arduino Code:

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

void loop() {
  int sensorValue = analogRead(A0);  
  Serial.println(sensorValue);       
  delay(20);                         
}

Schematic:

Video

 

Task 2:

Moving the mouse left or right on the screen changes how bright the LED connected to the Arduino glows. As we move the mouse toward the left, the LED gets dimmer, and as we move it to the right, it gets brighter.

P5js Code:

let port;

function setup() {
  createCanvas(600, 600);
  port = createSerial();

  let usedPorts = usedSerialPorts();
  if (usedPorts.length > 0) {
    port.open(usedPorts[0], 9600);
  }
}

function draw() {
  background(220);
  if (port.opened()) {
    let brightness = map(mouseX, 0, width, 0, 255);
    port.write(int(brightness) + "\n");
    textSize(50);
    text("Brightness: " + int(brightness), 50 , height - 20);
  } else {
    text("Click to connect", 10, height - 20);
  }
} 
function mousePressed() {
  if (!port.opened()) {
    port.open("Arduino", 9600);  
  }
}

Arduino Code:

int brightness = 0; 
int input = 0; 
void setup() { 
  Serial.begin(9600); 
  pinMode(9, OUTPUT); 
} 
void loop() { 
  if (Serial.available() > 0) { 
    input = Serial.parseInt(); 
    brightness = map(input, 0, 1023, 0, 255); 
    analogWrite(9, brightness); 
  } 
}
Schematic

Video

 

 

Task 3:

I modified the gravity wind example so that an LED lights up briefly each time the ball hits the ground and bounces back. The wind that pushes the ball left or right is controlled by the potentiometer.

P5js Code: 

let port;
let sensorValue = 0;
let velocity;
let gravity;
let position;
let acceleration;
let wind;
let drag = 0.99;
let mass = 50;
let onGroundLastFrame = false;

function setup() {
  createCanvas(640, 360);
  noFill();
  port = createSerial();
  let usedPorts = usedSerialPorts();
  if (usedPorts.length > 0){
    port.open(usedPorts[0], 9600);
  }
  position = createVector(width/2, 0);
  velocity = createVector(0,0); 
  acceleration = createVector(0,0);
  gravity = createVector(0, 0.5*mass);
  wind = createVector(0,0);
}

function draw() {
  background(255);
  let incoming = port.readUntil("\n");
  if (incoming.length > 0) {
    sensorValue = int(incoming);  
  }
  wind.x = map(sensorValue, 0, 1023, -1, 1);

  applyForce(wind);
  applyForce(gravity);
  velocity.add(acceleration);
  velocity.mult(drag);
  position.add(velocity);
  acceleration.mult(0);
  ellipse(position.x,position.y,mass,mass);
  
  let onGroundNow = (position.y > height - mass / 2);

  if (onGroundNow && !onGroundLastFrame) {
    port.write("1\n"); // bounce, flash led
  } else {
    port.write("0\n");
  }
  if (onGroundNow) {
    velocity.y *= -0.9;
    position.y = height - mass / 2;
  }
  onGroundLastFrame = onGroundNow;
}

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 mousePressed() {
  if (!port.opened()) {
    port.open("Arduino", 9600);
  }
}

Arduino Code:

int ledPin = 2;

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

void loop() {
  int sensor = analogRead(A0);
  Serial.println(sensor);
  if (Serial.available() > 0) {
    int bouncesig = Serial.parseInt();
    if (bouncesig == 1) {
      digitalWrite(ledPin, HIGH);
      delay(50);
      digitalWrite(ledPin, LOW);
    }
  }
  delay(10); 
}

Schematic

 

Video

 

 

Week 11: Reading Response

Design Meets Disability

I never really thought about disability and design in the same breath until reading Design Meets Disability. But the more I read, the more I realized something: design isn’t just about making things pretty or functional. It’s about shaping identity, dignity, and belonging. And disability, instead of limiting design, has actually pushed it forward in powerful ways.

One of the first images that stayed with me was the Eames leg splint. It surprised me that something meant for wartime medical emergencies became a milestone in modern furniture design. It made me rethink how innovation often begins in uncomfortable or overlooked places. It reminded me that creativity isn’t always glamorous, sometimes it grows out of necessity, pain, or urgency. And yet, from that, something beautiful emerges.

I never really thought about disability and design in the same breath until reading Design Meets Disability. But the more I read, the more I realized something: design isn’t just about making things pretty or functional. It’s about shaping identity, dignity, and belonging. And disability, instead of limiting design, has actually pushed it forward in powerful ways.

One of the first images that stayed with me was the Eames leg splint. It surprised me that something meant for wartime medical emergencies became a milestone in modern furniture design. It made me rethink how innovation often begins in uncomfortable or overlooked places. It reminded me that creativity isn’t always glamorous sometimes it grows out of necessity, pain, or urgency. And yet, from that, something beautiful emerges.

Week 11: Exercise

1st Exercise

p5js:

// Serial port object
let port;

// Latest sensor value
let sensorVal = 0;

function setup() {
  createCanvas(400, 300);
  background(220);

  // Create the serial connection object
  port = createSerial();

  // If a port was used before, auto-reconnect
  let used = usedSerialPorts();
  if (used.length > 0) {
    port.open(used[0], 9600);
  }
}

function draw() {
  background(220);

  // Read one line of text until newline "\n"
  let str = port.readUntil("\n");

  // Make sure we actually received something
  if (str.length > 0) {

    // Convert the string into an integer
    let val = int(str.trim());

    // Map sensor value (0–1023) to screen X position (0–400)
    let x = map(val, 0, 1023, 0, width);

    // Draw a circle at mapped position
    ellipse(x, height / 2, 40, 40);

  } else {

    // If empty data is received, print it for debugging
    console.log("Empty:", str);
  }
}

Arduino  Code:

const int sensor=A2;
int sensorValue;
void setup() {
  // put your setup code here, to run once:
  pinMode(sensor,INPUT);
  Serial.begin(9600);
  // while (Serial.available() <= 0) {
  
    Serial.println(0); // send a starting message
   
  
}



void loop() {
  // put your main code here, to run repeatedly:
sensorValue=analogRead(sensor);
delay(60);
Serial.println(sensorValue);
  
  
}



2nd exercise: 

p5js

int ledPin = 9;

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

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

P5JS CODE:
let port;
let brightnessToSend = 0;
const baudrate = 9600;

function setup() {
  createCanvas(400, 400);

  // Create the serial port
  port = createSerial();

  // connect automatically if used before
  let usedPorts = usedSerialPorts();
  if (usedPorts.length > 0) {
    port.open(usedPorts[0], baudrate);
  } else {
    connectBtn = createButton("Connect to Serial");
    connectBtn.position(10, 10);
    connectBtn.mousePressed(() => port.open(baudrate));
  }
}

function draw() {
  background(30);

  drawStarButton(80, 150, 40, 20, 5, 64);
  drawStarButton(160, 150, 40, 20, 5, 128);
  drawStarButton(240, 150, 40, 20, 5, 192);
  drawStarButton(320, 150, 40, 20, 5, 255);

  fill(255);
  textAlign(CENTER);
  text("Current brightness: " + brightnessToSend, width / 2, 280);
}

function mousePressed() {
  if (!port.opened()) return; // p5.webserial function to check if open

  let stars = [
    { x: 80,  brightness: 64  },
    { x: 160, brightness: 128 },
    { x: 240, brightness: 192 },
    { x: 320, brightness: 255 }
  ];

  for (let s of stars) {
    if (dist(mouseX, mouseY, s.x, 150) < 30) {
      brightnessToSend = s.brightness;

      // Send brightness (0–255)
      port.write(brightnessToSend);
    }
  }
}

function drawStarButton(x, y, radius1, radius2, points, brightness) {
  let angle = TWO_PI / points;
  let halfAngle = angle / 2;

  if (brightnessToSend === brightness) fill(255, 200, 0);
  else fill(255);

  push();
  translate(x, y);
  beginShape();
  for (let a = 0; a < TWO_PI; a += angle) {
    vertex(cos(a) * radius1, sin(a) * radius1);
    vertex(cos(a + halfAngle) * radius2, sin(a + halfAngle) * radius2);
  }
 
  endShape(CLOSE);
  pop();
}

Arduino:

// const int ledPin = 5;
// const int lightPin = A0;
// const int a=0;

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

//     while (Serial.available() <= 0) {
//         Serial.println(0);
// ;    }
// }

// void loop() {
//   int a=Serial.read();
//   Serial.print("message print ");
//   Serial.print(a);
//   digitalWrite(ledPin, a);
 
    // while (Serial.available()) {
    //     int ledState = Serial.parseInt();
       
    //     if (Serial.read() == '\n') {
    //         digitalWrite(ledPin, ledState);
    //         Serial.println(analogRead(lightPin));
    //     }
    // }
// }

int led = 5;
void setup() {
  Serial.begin(9600); // initialize serial communications
}
 
void loop() {
  if (Serial.available()) {
    int ballState = Serial.parseInt(); // reads full number like 0 or 1
    if (ballState == 1) {
      digitalWrite(led, HIGH); // ball on ground
    } else {
      digitalWrite(led, LOW); // ball in air or default
    }
  }
  // read the input pin:
  int potentiometer = analogRead(A1);                  
  //
 
  //remap the pot value to 0-400:
  int mappedPotValue = map(potentiometer, 0, 1023, 0, 900);
  // print the value to the serial port.
  Serial.println(mappedPotValue);
  // slight delay to stabilize the ADC:
  delay(1);                                            
 
  // Delay so we only send 10 times per second and don't
  // flood the serial connection leading to missed characters on the receiving side
  delay(100);
}

video:

3rd exercise:

p5js

let velocity;        // velocity vector of the ball
let gravity;         // gravity force vector
let position;        // position of the ball
let acceleration;    // accumulated acceleration each frame
let wind;            // wind force vector
let drag = 0.99;     // drag factor to slow down velocity a bit
let mass = 50;       // "mass" of the ball, also used as its size
let port;            // serial port object for Arduino ↔ p5 communication
let button;          // button to trigger serial connection popup
let open=false;      // flag to track if we've tried to open the port

function setup() {
  createCanvas(640, 360);
  noFill();
  position = createVector(width/2, 0);   // start ball at top center
  velocity = createVector(0,0);          // start with no movement
  acceleration = createVector(0,0);      // acceleration accumulates forces
  gravity = createVector(0, 0.5*mass);   // gravity pulls ball downward
  wind = createVector(0,0);              // wind starts with no force
  port = createSerial(); //port is an object that will be used to send message and receeieve message from arudnio
 
  //createbutton creates button in p5js with quote ma lekyeko kura aayera
  button=createButton("Connect to Arduino");
  button.position(width/2,height/2); //where you want your button to be
  button.mousePressed(openArduino); //mousePressed bhayo yo button ma bhanye kun function open garne  pass garne ani it opens "openArduino" wala function
 
}

function openArduino(){
  if(!port.opened()){ //to check if the port is opened or not we use function opened
    port.open(9600) // we open the port for communication with 9600 frequency
   
    button.remove() // once arudino is opended we removed the button to connect to ardunio
   
    open=true; //just a variable to check if we opended the port or not
  }
 
}

function draw() {
  if(port.opened()){             // run main logic only if serial port is open
  background(255);               // clear canvas every frame
  applyForce(wind);              // apply wind force first
  applyForce(gravity);           // then apply gravity force
  velocity.add(acceleration);    // a → v
  velocity.mult(drag);           // apply drag to slowly reduce velocity
  position.add(velocity);        // v → position
  acceleration.mult(0);          // reset acceleration so next frame starts fresh
  ellipse(position.x,position.y,mass,mass);  // draw the ball
 
  }
  // collision + LED control are outside the port.opened() block,
  // so they always run based on current position
  if (position.y > height-mass/2) {
     
      velocity.y *= -0.9;  // A little dampening when hitting the bottom (bounce)
      position.y = height-mass/2; // keep ball from sinking below the "floor"
      port.write("1\n")    // send "1" to Arduino → turn LED ON
    }
    else{
      port.write("0\n")    // otherwise send "0" → turn LED OFF
    }
    potvalue=port.readUntil("\n");  // read a line from Arduino (pot value as text)
    // console.log(potvalue);
 
    if(potvalue>514){      // simple threshold: above midpoint = wind to the right
      wind.x=1
    }
    else{                  // below midpoint = wind to the left
      wind.x=-1
    }
 
 
 
 
}

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

function keyPressed(){
  if (keyCode==LEFT_ARROW){
    wind.x=-1;              // keyboard override: push ball left
  }
  if (keyCode==RIGHT_ARROW){
    wind.x=1;               // keyboard override: push ball right
  }
  if (key==' '){
    mass=random(15,80);     // randomize mass (and drawn size)
    position.y=-mass;       // reset ball above the top so it falls back down
    velocity.mult(0);       // clear velocity so it restarts clean
  }
}
int greenLight=7;
int sensor=A0;
void setup() {
  // put your setup code here, to run once:
  pinMode(greenLight,OUTPUT);
  pinMode(sensor,INPUT);
  Serial.begin(9600);
  digitalWrite(greenLight,0);

}

void loop() {
  // put our main code here, to run repeatedly:
  // Serial.print("0");
 
  int value= analogRead(sensor);
  Serial.print(value);
  Serial.print("\n");

  while(Serial.available()>0){ //avaiable checks if there is any message in inbox of ardino
    String a=Serial.readStringUntil('\n');
    a.trim();
    if(a=="1"){ //if we receive 1 then the light turns on else turn off
       digitalWrite(greenLight,1);
    }
    else{
      digitalWrite(greenLight,0);
    }
   
   
  }
 

 

 

}

video link: Google Drive

Shahram Chaudhry – Week 11 – Reading Response

This reading challenged my assumptions about the relationship between disability and design. I’ve always seen assistive technologies as specialized tools adapted from mainstream innovations, but the suggestion that disability itself can inspire new directions in design was a refreshing and thought-provoking shift. It reframes disability not as a limitation but as a perspective, a source of insight that can benefit everyone. This reversal of influence invites us to see people with disabilities not only as users but also as collaborators in the design process.

One idea I found interesting was the coexistence of two design ideologies: one rooted in problem-solving and respecting constraints, and another that playfully challenges them. This balance resonates with many everyday experiences. Take elevators, for instance. Originally intended to solve mobility issues, they’ve become an expected convenience in buildings of all kinds. They represent an engineering mindset that respects accessibility constraints, yet their widespread use has also changed how we think about them. Elevators are now also aesthetic spaces. Designers often include mirrors, polished metal, ambient lighting, or even music, not because they help with accessibility, but because they enhance the experience.

The reading also discusses how the push for discretion in assistive devices, like smaller hearing aids, can ironically reinforce stigma. Trying to hide disability implies shame or abnormality, which is counterproductive. 

The example of glasses was especially meaningful to me. I’ve seen firsthand how they function both as corrective devices and as fashion statements. Growing up, my siblings and parents all wore glasses, and I actually used to wear non prescription glasses as an accessory, but now that I actually have poor sight, I don’t like wearing glasses. I guess it’s human nature to want the freedom to choose, especially when it comes to fashion, which is all about personal expression. Now that I have to wear glasses out of necessity rather than choice, it feels different. I don’t like that the decision has been taken out of my hands.

The reading opened up broader conversations about involving fashion designers and aesthetic thinking in assistive technology. Why shouldn’t prosthetics be beautiful? Why not design hearing aids that are meant to be seen, not hidden?

Also I agree with the idea that we must be cautious about making technology overly complex in the name of accessibility, sometimes simplicity serves a broader audience better. I liked the example of the iPod. Its tactile minimalist interface made it accessible to more users, including those with visual impairments. I think if I had owned an iPod back when it was still popular, I would have really enjoyed the experience, especially because I’m quite indecisive. Having the order of songs chosen for me would’ve taken away the pressure of deciding what to play next, making listening feel more effortless and enjoyable.

Week 11 – Reading Reflection

One of the most interesting points Pullin makes in his book is the idea that lots of design standards around disability is to cover it up rather than embrace it or emphasize it. There is always a strong push towards “normalcy” in the design world. His example of how glasses went from medical necessities to a fashion item; I believe most people may acknowledge someone wears glasses out of necessity but we also subtly know that the style of glasses they wear is also an expression of themselves. I imagine as prosthetics become more advanced and fine-tuned, humans will find a way to embrace these tools as more than just their functions but also introduce an expressive layer to them. An easy example of how that might look is if someone needs a prosthetic arm, they might want a prosthetic arm that resembles their favorite prosthetic-using character in fiction (like Edward Elric, Luke Skywalker, or even Guts). This agency and idea of co-design can empower non-able-bodied folks.

Pullin actually mentions that prosthetic arms are much more intimate than prosthetic legs; arms inherently serve more than their function, and it’s not just about nails, veins, or perceived texture. If it’s trying to resemble a fleshy human arm, it creates a serious sense of disappointment and is often off-putting. Pullin mentions the best approach here is often to NOT hide the fact that the arm is artificial and instead emphasize it while giving the functions of a fleshy arm. This was all really interesting to me, especially his example of how certain clients of Monestier would hate the feeling when the hand would initially fool new acquaintances until they had their moments of realization.

As I read this article, I thought about how prosthetics in fiction are often romanticized. A sick metal arm that can turn into a cannon or extend out to become a grapple hook are often framed as “upgrades” but I imagine not having complete dexterity and fleshiness creates quite a sense of void that most fiction rarely explores. I thought of this as a connection to last week’s reading on a “Brief Rant on the Future of Interaction Design”, which I also thought was very insightful. There must be an inherent, strong emotional gap on prosthetic function and feeling, and I think our portrayals of disabled characters in media could use some more commentary on losing their sense of touch.

Final Project Preliminary Idea – Week 11

A (Disney) Tangled Experience

Concept Overview

For my final project, I wanted to extend the assignment that I did all the way back in Week 3, Make a Wish. It was based on one of my favorite Disney films, Tangled, and I thought it would be interesting to extend it into a physically interactive system. Here is the sketch from Week 3:

For this project, I want users to “send out a wish” using Tangled-style wish lanterns. Before they can enter their wish, they must complete a short challenge. The challenge is a physical reaction-time game: four lanterns (each with an LED inside) are paired with four corresponding push buttons. The lanterns light up randomly at a fast pace, and the user must quickly press the button for the lantern that lights up, essentially “whacking” it. Their successful hits are tracked and displayed in p5, with a similar sketch as the one above as the background.

Once the user reaches 5 successful hits, a text box appears in the p5 interface where they can type their wish. That wish is then displayed on an Arduino screen, all the lanterns light up together, and the Tangled music plays to complete the experience. After this, the p5 screen gives the user an option to restart the experience all over again.

Projected Required Materials

  • Arduino and consumables that come with it
  • 4 large push buttons
  • 4 3-D printed lanterns big enough to fit small breadboard with yellow LEDs
  • Arduino screen and speakers
  • Cardboard and Paint

Week 11 – Reading Reflection

Pullin’s argument challenges the lazy division between design as aesthetic indulgence and disability as pure function. He dismantles the notion that assistive devices must be invisible or “normalized,” suggesting instead that disability could (and should) be a space for expressive, creative design. That was a refreshing perspective. The hearing aid, the wheelchair, the prosthetic are cultural objects that communicate identity (not just medical equipment).

Yet, what I appreciate most in Pullin’s framing is how he exposes the moral vanity of “inclusive design.” The impulse to hide difference in the name of inclusion often erases individuality altogether. Still, I wonder whether his optimism about designers embracing disability aesthetics underestimates the market’s conservatism; we live in a world where even fashion struggles to tolerate imperfection. The essay makes me question whether good design serves comfort or visibility, and whether true accessibility might require celebrating discomfort, making difference not something to be hidden, but worn, literally, in style.