Assignment 11: Preliminary Concept for Final Project

I want to create a mini pet cat experience! The idea is to build a physical figure of a cat and have it connect to a p5.js sketch which shows the cat’s current mood. Users can pet the cat, and using some sensor (pressure sensor? or flex sensor?), the arduino will send this reading to p5.js and displays the cat’s mood on the screen.

Another way I could implement the cat is if I have it illustrated in p5.js. This way, users can also play yarn with the cat and watch the cat on the screen move to the user’s hand movements (perhaps tracked by an ultrasonic sensor).

This third way of implementation is I think on the harder side to implement, but I could try making a physical figure of a cat and use wheels so that it is able to move. Perhaps I could make the user control this movement using an ultrasonic sensor as well.

Reading Reflection 11: Design Meets Disability

As someone who has been wearing glasses for almost all her life, I never considered it as an assistive device (even though it is, since I would be blind without them). It really just proves how the use of eyewear has become so normalized, and somehow capitalized into this fashion wear. I’m all for it honestly, I love when people get creative with self expression and using a variety of glasses is one of the ways people do so. I think the same can be said about contact lenses. They are technically an assistive device too, yet it is also commonly used to enhance one’s look; another form of self expression.

I really appreciate the comment on simplicity; it reminds me of the saying “less is more.” Sometimes it’s so easy to go overboard with features and always wanting to improve or update a work in progress, but it only ends up messy and overwhelming to work with. So this was a great reminder to keep it simple, because not everything that has extensive features are always considered good; as long as it does what it’s intended to do, I think that’s a success. And sometimes if we focus too much on adding features, we tend to lose track of the original intention, so it’s definitely better to keep it simple and try to not lose sight of what’s intended.

Assignment #9: Serial Communication [in team with Ryan]

Exercise 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.

p5 code:

let position;
let mass = 50;
let potValue = 0; 
function setup() {
  createCanvas(640, 360);
  noFill();
  // Initialize position of the ellipse
  position = createVector(width / 2, height / 2);
}
function draw() {
  background(255);
  // Map potentiometer value to horizontal position
  position.x = map(potValue, 0, 1023, 0, width);
  // Keep the ellipse in the middle 
  ellipse(position.x, height / 2, mass, mass);
}
function keyPressed(){
   if (key == " ") { //set up serial
     setUpSerial();
   } 
}
function readSerial(value) {
  potValue = int(value); // Parse the potentiometer value
}

Arduino:

void setup() {
  Serial.begin(9600); // Start serial communication 
}
void loop() {
  int potValue = analogRead(A0); // Read the potentiometer value 
  Serial.println(potValue);     // Send the value to p5.js
  delay(10);                    
}

Exercise 2.

Make something that controls the LED brightness from p5.

p5 code:

function setup() {
  createCanvas(400, 400);
}
function draw() {
  background(225);
  // brightness based on cursor's x position
  let brightness = map(mouseX, 0, width, 0, 255);
  brightness = constrain(brightness, 0, 255); // Ensure brightness stays within range
  // Send brightness value to Arduino if serial is active
  if (serialActive) {
    writeSerial(`${brightness}\n`); 
  }
}
function keyPressed(){
   if (key == " ") { //set up serial
     setUpSerial();
   } 
}
function readSerial(value) {
  potValue = int(value); // Parse the potentiometer value
}

Arduino:

int ledPin = 9; 
int brightness = 0; 
void setup() {
  Serial.begin(9600); // Start serial communication
  pinMode(ledPin, OUTPUT); //LED pin as output
}
void loop() {
  if (Serial.available() > 0) {
    // Read the incoming brightness value
    brightness = Serial.parseInt();
    brightness = constrain(brightness, 0, 255);
    // Set the LED brightness
    analogWrite(ledPin, brightness);
  }
}

Exercise 3.

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.

p5 code:

let velocity;
let gravity;
let position;
let acceleration;
let wind;
let drag = 0.99;
let mass = 50;
let potValue = 0; // potentiometer value
let serialConnected = false; 
let onGround = false; // whether ball is on the ground
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);
}
function draw() {
  background(255);
  if (!serialConnected) {
    textAlign(CENTER, CENTER);
    fill(0);
    text("Press 'Space' key on the keyboard", width / 2, height / 2);
    return;
  }
  applyForce(wind);
  applyForce(gravity);
  velocity.add(acceleration);
  velocity.mult(drag);
  position.add(velocity);
  acceleration.mult(0);
  
// check for bounce on the x axis
  if (position.x > width - mass / 2) {
    if(!onGround){
    position.x = width - mass / 2; 
    velocity.x *= -0.9;
    }
  }
    else if (position.x < mass / 2) {
      position.x = mass / 2; 
    velocity.x *= -0.9;
    }
  
  // check for bounce on the y axis
if (position.y > height - mass / 2) {
  velocity.y *= -0.9; 
  position.y = height - mass / 2; 
  if (!onGround) {
    sendBounceSignal(); 
    onGround = true; 
  }
} else {
  onGround = false; 
}
  wind.x = map(potValue, 0, 1023, -1, 1); 
  ellipse(position.x, position.y, mass, mass);
  // boundaries on x axis
  if (position.x > width - mass / 2 || position.x < mass / 2) {
    velocity.x *= -0.9; 
  }
}
function applyForce(force) {
  let f = p5.Vector.div(force, mass);
  acceleration.add(f);
}
// bouncing signal to Arduino
function sendBounceSignal() {
  if (serialActive) {
    let sendToArduino = "1\n"; 
    writeSerial(sendToArduino);
  }
}
// receive data from Arduino
function readSerial(data) {
    potValue = int(trim(data)); 
}
// initialize serial connection
function keyPressed() {
  if (key == ' ') {
    mass = random(10,100);
    setUpSerial(); 
    serialConnected = true; 
  }
}
function serialOpened() {
  serialActive = true; 
}

Arduino:

const int potPin = A0; 
const int ledPin = 13; 
int potValue = 0; 
bool ledState;     
void setup() {
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
}
void loop() {
  // read the potentiometer value
  potValue = analogRead(potPin);
  // send potentiometer value to p5
  Serial.println(potValue);
  // check for data from p5
  if (Serial.available() > 0) {
    char received = Serial.read(); 
    if (received == '1' && !ledState) {
      // turn on the LED 
      digitalWrite(ledPin, HIGH);
      ledState = true;
      delay(100); 
      // turn off the LED
      digitalWrite(ledPin, LOW);  
    }
    else if (received != '1'){
      ledState = false;
    }
  }
  delay(50); 
}

Video demonstration:

Final Project Concept

After reading the chapter from Graham Pullin’s book Design Meets Disability and thinking about my personal experiences related to this topic, I decided work on an unconventional model of eyeglasses. My final project will be a synthesis on an interactive artwork and an assistive device, inviting audience to think about the stigma around certain types of products for disabled people.

Drawing inspiration from Meta Ray Ban smart glasses,  I want to combine audio with visuals by adding small speakers to the ends of the temples, so that the user can hear the sound clearly only when they wear the product. In terms of visuals, I want to use camera mode in p5.js to detect the eye area of the user, with the help of glasses designed in a specific way to facilitate this. I will be modelling the glasses myself using Rhino and then printing them on 3D printer in order to create a precise structure that would fit desired electronic components. The speakers will be connected to Arduino, which in its turn will be connected to p5.js sketch using serial communication. Depending on the gazing sequences of the user, the visuals on the screen will be changing, depicting eyes of changing sizes. For user’s eye-tracking WebGazer.js library will be used.

From my individual experience and observations, one of the key reasons why people feel awkward about wearing glasses is because of the way they distort the size of their eyes depending on the prescription, hence altering the familiar look of the face. Such minor things are often invisible to strangers, but people wearing glasses can become extremely conscious about this. By providing an exaggerated illustration of such distortion, I wish to draw attention to the way people with disabilities perceive themselves.

Week #11 – Final Project Preliminary

Concept

I have been thinking long on my final idea project and for now I stopped on idea of utilizing my midterm project and adding Arduino circuits to it.

Here is my previous Midterm project

The reason I decided to pursue my Friends Game House project was because I felt there is still room for its improvement in terms of interactivity. For example, I feel like the interfaces for the Ross, Joey, Monica characters can be designed more interestingly with greater room for unusual interactions. Therefore, I thought of transferring these interactions from software to real life. Currently, my focus stays on transferring important details from the Friends series into smaller things that I can build myself or recreate with elements that we learned to use in Arduino.
For example, in Phoebe interface, there is interaction with the user, where he has to press certain keys to voice specific lines of the songs. I think this can be transformed to the buttons on Arduino, especially bigger buttons that I saw in many final projects of previous students.

Here are some ideas that I’ve been noting to myself about the ways I can implement Arduino to the project:

  • Joey’s interface – there was an idea initially that “Joey doesn’t share food”, so I could transfer it to Arduino, by making red LEDs go bright, when somebody is touching the plate with the food.
  • Potentiometer to adjust the volume of the song on Phoebe’s screen or overall if the Friends theme song is implemented on the background.
  • Using motors recreate the scene with umbrellas, so they could spin while the user is playing
    This may contain: a group of people standing next to each other with umbrellas in front of them

Assignment 9 – Serial Communication

Task 1

Prompt: 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 decided to approach all the tasks following Christmas style.

P5 Code:
let positionX = 0; 
function setup() {
  createCanvas(600, 600);
  noFill();
}
function draw() {
  background("#bb010b");
  stroke("#ffcf00");
  // maping the values from light sensor to the width of the canvas
  ellipse(map(positionX, 0, 1023, 0, width), height / 2, 100, 100);
  if (!serialActive) {
  // the initial screen of p5, when it is not connected to arduino, this helps to start serial communication
    background("#2d661b");
    stroke("#white");
    textSize(50);
    text("Press Space Bar to select Serial Port", 20, 30, width - 30, 200);
  }
}
function keyPressed() {
  // starting serial communication when space bar is pressed
  if (key == " ") setUpSerial(); 
}
function readSerial(data) {
  if (data != null)
    // ensuring there is actual data, then storing it in a variable
    positionX = int(data);
}
Arduino Code
int lightPin = A0;

void setup() {
Serial.begin(9600);
pinMode(lightPin, INPUT);
}

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

Task 2

Prompt: Make something that controls the LED brightness from p5

For this assignment, we decided to control LED brightness using 4 circles/buttons on p5 interface. By pressing different circles, you increased the brightness of LED.

P5 Code 
let LEDbrightness = 0; 
function setup() {
  createCanvas(600, 600);
  background('#2d661b');
  stroke ('#white');
  noFill();
}
function draw() {
  
  if (serialActive){  
  
  //circles-buttons
  circle (150, height/2, 50);
  circle (250, height/2, 50);
  circle (350, height/2, 50);
  circle (450, height/2, 50);
  
  // to understand whether user pressed specific circles, we used distance function. the LED brightness had 4 variations
  if (dist (mouseX, mouseY, 150, height/2) <= 50){
    LEDbrightness = 60;
  }
  if (dist(mouseX, mouseY, 250, height/2)<=50){
    LEDbrightness = 120;
  }
  if (dist(mouseX, mouseY, 350, height/2)<=50){
    LEDbrightness = 180;
  }
  if (dist(mouseX, mouseY, 450, height/2)<=50){
    LEDbrightness = 255;
  }
    }
  
  if (!serialActive) {
    // to understand if serial communication is happening
    textSize(50);
    text ("Press Space Bar to select Serial Port", 20, 30, width-30, 200);
    }
  }
function keyPressed() {
    if (key == " ")
      // starting the serial connection using space bar press
        setUpSerial(); 
}
function readSerial(data) {
  //sending data to arduino
    writeSerial(LEDbrightness);
}

 

Arduino Code
void setup() {
Serial.begin(9600);
pinMode(5, OUTPUT);
}

void loop() {
analogWrite(5, Serial.parseInt());
Serial.println();
}

IMG_9258

Task 3

Prompt: 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.

We decided to use light sensor as analog sensor, which controlled the wind on p5 that affected movement of ball.

P5 Code
let position, velocity, acceleration, gravity, wind;
let drag = 0.99,
  mass = 50,
  hasBounced = 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);
  textSize(18);
}
function draw() {
  background(255);
  if (!serialActive) {
    background("#2d661b");
    fill("white");
    text("Press F to select Serial Port", 20, 30, width - 30, 200);
  } else {
    applyForce(wind);
    applyForce(gravity);
    velocity.add(acceleration);
    velocity.mult(drag);
    position.add(velocity);
    acceleration.mult(0);
    if (hasBounced) {
      fill("red");
    } else {
      fill("white");
    }
    ellipse(position.x, position.y, mass, mass);
    if (position.y > height - mass / 2) {
      velocity.y *= -0.9; // dampening
      position.y = height - mass / 2;
      if (!hasBounced && abs(velocity.y) > 1) {
        hasBounced = true;
        setTimeout(() => (hasBounced = false), 100);
      }
    }
  }
}
function applyForce(force) {
  let f = p5.Vector.div(force, mass);
  acceleration.add(f);
}
function keyPressed() {
  if (key == " ") {
    mass = 20;
    position.set(width / 2, -mass);
    velocity.mult(0);
    gravity.y = 0.5 * mass;
    wind.mult(0);
  } else if (key == "f") {
    setUpSerial();
  }
}
function readSerial(data) {
  if (data != null) {
    let value = int(trim(data)); 
    wind.x = map(value, 0, 1023, -1, 1);
    let bounceState = 0;
    if (hasBounced) {
      bounceState = 1;
    }
    writeSerial(bounceState + "\n");
  }
}

 

Arduino Code
const int ledPin = 5;
const int lightPin = A0;
void setup() {
    Serial.begin(9600);
    pinMode(ledPin, OUTPUT);
    pinMode(lightPin, INPUT);
    while (Serial.available() <= 0) {
        Serial.println("0"); 
;    }
}
void loop() {
    while (Serial.available()) {
        int ledState = Serial.parseInt(); 
        
        if (Serial.read() == '\n') {
            digitalWrite(ledPin, ledState);
            Serial.println(analogRead(lightPin));
        }
    }
}

 

IMG_9260

Assignment 9 – Serial Communication

Exercise 1.

p5 code:

let position;
let mass = 50;
let potValue = 0; 


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

  // Initialize position of the ellipse
  position = createVector(width / 2, height / 2);

}

function draw() {
  background(255);

  // Map potentiometer value to horizontal position
  position.x = map(potValue, 0, 1023, 0, width);

  // Keep the ellipse in the middle 
  ellipse(position.x, height / 2, mass, mass);
}

function keyPressed(){
   if (key == " ") { //set up serial
     setUpSerial();
   } 
}

function readSerial(value) {
  potValue = int(value); // Parse the potentiometer value
}

Arduino Code:

void setup() {
  Serial.begin(9600); // Start serial communication 
}

void loop() {
  int potValue = analogRead(A0); // Read the potentiometer value 
  Serial.println(potValue);     // Send the value to p5.js
  delay(10);                    
}

Exercise 2.

p5 code:

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

function draw() {
  background(225);

  // brightness based on cursor's x position
  let brightness = map(mouseX, 0, width, 0, 255);
  brightness = constrain(brightness, 0, 255); // Ensure brightness stays within range

  // Send brightness value to Arduino if serial is active
  if (serialActive) {
    writeSerial(`${brightness}\n`); 
  }
}

function keyPressed(){
   if (key == " ") { //set up serial
     setUpSerial();
   } 
}

function readSerial(value) {
  potValue = int(value); // Parse the potentiometer value
}

Arduino Code:

int ledPin = 9; 
int brightness = 0; 

void setup() {
  Serial.begin(9600); // Start serial communication
  pinMode(ledPin, OUTPUT); //LED pin as output
}

void loop() {
  if (Serial.available() > 0) {
    // Read the incoming brightness value
    brightness = Serial.parseInt();
    brightness = constrain(brightness, 0, 255);

    // Set the LED brightness
    analogWrite(ledPin, brightness);
  }
}

Exercise 3.

p5 code:

let velocity;
let gravity;
let position;
let acceleration;
let wind;
let drag = 0.99;
let mass = 50;
let potValue = 0; // potentiometer value
let serialConnected = false; 
let onGround = false; // whether ball is on the ground

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);
}

function draw() {
  background(255);
  if (!serialConnected) {
    textAlign(CENTER, CENTER);
    fill(0);
    text("Press 'Space' key on the keyboard", width / 2, height / 2);
    return;
  }

  applyForce(wind);
  applyForce(gravity);
  velocity.add(acceleration);
  velocity.mult(drag);
  position.add(velocity);
  acceleration.mult(0);
  
// check for bounce on the x axis
  if (position.x > width - mass / 2) {
    if(!onGround){
    position.x = width - mass / 2; 
    velocity.x *= -0.9;
    }
  }
    else if (position.x < mass / 2) {
      position.x = mass / 2; 
    velocity.x *= -0.9;
    }
  
  // check for bounce on the y axis
if (position.y > height - mass / 2) {
  velocity.y *= -0.9; 
  position.y = height - mass / 2; 
  if (!onGround) {
    sendBounceSignal(); 
    onGround = true; 
  }
} else {
  onGround = false; 
}

  wind.x = map(potValue, 0, 1023, -1, 1); 
  ellipse(position.x, position.y, mass, mass);

  // boundaries on x axis
  if (position.x > width - mass / 2 || position.x < mass / 2) {
    velocity.x *= -0.9; 
  }
}

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

// bouncing signal to Arduino
function sendBounceSignal() {
  if (serialActive) {
    let sendToArduino = "1\n"; 
    writeSerial(sendToArduino);
  }
}

// receive data from Arduino
function readSerial(data) {
    potValue = int(trim(data)); 
}

// initialize serial connection
function keyPressed() {
  if (key == ' ') {
    mass = random(10,100);
    setUpSerial(); 
    serialConnected = true; 
  }
}

function serialOpened() {
  serialActive = true; 
}

Arduino code:

const int potPin = A0; 
const int ledPin = 13; 
int potValue = 0; 
bool ledState;     

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

void loop() {
  // read the potentiometer value
  potValue = analogRead(potPin);

  // send potentiometer value to p5
  Serial.println(potValue);

  // check for data from p5
  if (Serial.available() > 0) {
    char received = Serial.read(); 

    if (received == '1' && !ledState) {
      // turn on the LED 
      digitalWrite(ledPin, HIGH);
      ledState = true;
      delay(100); 
      // turn off the LED
      digitalWrite(ledPin, LOW);  
    }
    else if (received != '1'){
      ledState = false;
    }
  }
  delay(50); 
}

Video demonstration:

 

 

Week 11 Exercises

Exercise 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.

The location of the x of ellipse is being altered by the potentiometer.

The value from the potentiometer is mapped between 0 and 640, the width of the canvas.

Utilizing a Potentiometer, the ellipse moves along the horizontal axis, while also changing colors by making changes to the B value of fill.

Arduino code

P5 code:

let ellipseX = 0; //x value of ellipse to be changed by potentiometer
let B =0;

function setup() {
  createCanvas(640, 480);
  ellipseMode(CENTER);
}

function draw() {
  clear();
  background(0)
  fill(255,0,B);
  ellipse(ellipseX, height/2, 50, 50);


  if (!serialActive) {
    text("Press Space Bar to select Serial Port", 20, 30);
  } else {
    text("Connected", 20, 30);  
    // Print the current values
    text('ellipseX = ' + str(ellipseX), 20, 50);
  }
}

function keyPressed() {
  if (key == " ") {
   
    setUpSerial(); //establish serial communication
  }
}

function readSerial(data) {  
  if (data) {    //run only if data is received
    data = data.trim(); // Remove any whitespace
    if (!isNaN(data)) { //check whether data is a number or not
      //debug: console.log("Received:", data);
      ellipseX = int(data);
    }
  }

Exercise 2:

Make something that controls the LED brightness from p5.

A slider is created and data from it is sent to the arduino. Based on the input from the p5 sketch, the LED’s brightness is adjusted accordingly.

Arduino code

P5 code:

let slider;
let brightness = 0;
function setup() {
  createCanvas(400, 400);
  // Create a brightness slider
  slider = createSlider(0, 255, 128);
  slider.position(width/2, height/2);
  slider.style('width', '100px');
}
function draw() {
  background(255);
  if (!serialActive) {
    textAlign(CENTER)
    text("Press Space Bar to select Serial Port", width/2, height/3);
  } else {
    text("Connected", width/2, height/3);
  }
  brightness = slider.value();
}
function keyPressed() {
  if (key == " ") {
    // important to have in order to start the serial connection!!
    setUpSerial();
  }
}
function readSerial(data) {
  console.log(data);
    let dataToSend = brightness + ", \n";
    writeSerial(dataToSend);  
}

Exercise 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.

Using a potentiometer mapped from -2 to 2, when the potentiometer is towards the left, the wind blows towards the left, and vice versa. The LED lights up every time the ball touches the bottom edge of the canvas.

A serial signal is sent to arduino everytime the ball touches the bottom of the canvas, resulting in the led to light up on the arduino. The potentiometer’s value will be reflected in the direction that the wind is blowing on the ball. I also added two walls on the right and left sides of the canvas, to prevent the wind from blowing the ball outside of the canvas.

Arduino code

P5 code:

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

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);
}

function draw() {
  background(255);
  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(serialActive){
      writeSerial("bounced\n");
    }
    }
  // Check for collisions with the left wall
  if (position.x < mass / 2) {
    velocity.x =0; // Reverse horizontal velocity (bounce)
    position.x = mass / 2; // Correct position
  }

  // Check for collisions with the right wall
  if (position.x > width - mass / 2) {
    velocity.x =0; // Reverse horizontal velocity (bounce)
    position.x = width - mass / 2; // Correct position
  }
}

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 == " ") {
    // important to have in order to start the serial connection!!
    setUpSerial();
  }
  if (keyCode==DOWN_ARROW){
    //mass=random(15,80);
    position.y=-mass;
    velocity.mult(0);
  }
}


function readSerial(data){
  
  if (data != null){
    wind.x=int(data);
    console.log("working");

  }
}

 

Reading Reflection – Week #11

Design Meets Disability

While reading the chapter from Graham Pullin’s book, I caught myself thinking about a recent case from my friend’s life – she is a student at Tandon, working on a project in collaboration with Langone Hospital. The theme of the project is development of products for accessible environment, specifically a belt that allows people with blindness to orient in space. My friend’s immediate suggestion was to move the sensors from the belt to hands, e.g. to gloves, so that calculation of the distance to objects was more precise – makes sense, right? However, her idea was met with criticism from the professor – she forgot about that very discretion.

Our goal is to make sure that their limitation not only does not interfere with their lives, but also remains absolutely unnoticeable” – although I do understand the point of my friend’s professor, I would formulate this objective differently. From my understanding, discretion is not simply about hiding the product, but rather about its seamless integration into one’s life. Balancing both engineering and design aspects in one person’s mind is extremely complicated, since the “perfect” solutions in both categories of tasks can be mutually exclusive.

As a person who wears glasses and contacts, used to wear braces and orthopaedic insoles, I have been concerned with the image of such products since I was a child – when I was five, I refused to wear Birkenstock sandals because I was convinced that they were ugly, even though they were prescribed to me by a doctor. That fear of looking stupid and funny is relatable to many people, so I believe that there is a huge room for improvement in the field of design for disability.

Week 11 Assignment

EXERCISE 01: ARDUINO TO P5 COMMUNICATION

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.

P5 code: https://editor.p5js.org/lj2369/full/dO1bxX9t_

let ellipseX = 0; //x value of ellipse to be changed by potentiometer
let B =0;

function setup() {
  createCanvas(640, 480);
  ellipseMode(CENTER);
}

function draw() {
  clear();
  background(0)
  fill(255,0,B);
  ellipse(ellipseX, height/2, 50, 50);


  if (!serialActive) {
    text("Press Space Bar to select Serial Port", 20, 30);
  } else {
    text("Connected", 20, 30);  
    // Print the current values
    text('ellipseX = ' + str(ellipseX), 20, 50);
  }
}

function keyPressed() {
  if (key == " ") {
   
    setUpSerial(); //establish serial communication
  }
}

function readSerial(data) {  
  if (data) {    //run only if data is received
    data = data.trim(); // Remove any whitespace
    if (!isNaN(data)) { //check whether data is a number or not
      //debug: console.log("Received:", data);
      ellipseX = int(data);
    }
  }
}

the location of the x of ellipse is being altered by the potentiometer

Arduino ide: https://github.com/lonussss/Intro-to-IM/blob/main/week11exercise1.ino 

 

int sensor = A0; 

void setup() {

  Serial.begin(9600);


 
}

void loop() {
      int sensorValue= analogRead(sensor);
      int mappedValue = map(sensorValue,0,1023,0,640); //mapped value to size of canvas
      Serial.println(mappedValue); //send value to p5.js
  }

The value from the potentiometer is mapped between 0 and 640, the width of the canvas.

Utilizing a Potentiometer, the ellipse moves along the horizontal axis, while also changing colors by making changes to the B value of fill.

 

Demonstration:

IMG_3526

 

EXERCISE 02: P5 TO ARDUINO COMMUNICATION

Make something that controls the LED brightness from p5.

P5 slider to control LED brightness

P5: https://editor.p5js.org/tinganyang/sketches/oFcyYfJaa

let slider;
let brightness = 0;
function setup() {
  createCanvas(400, 400);
  // Create a brightness slider
  slider = createSlider(0, 255, 128);
  slider.position(width/2, height/2);
  slider.style('width', '100px');
}
function draw() {
  background(255);
  if (!serialActive) {
    textAlign(CENTER)
    text("Press Space Bar to select Serial Port", width/2, height/3);
  } else {
    text("Connected", width/2, height/3);
  }
  brightness = slider.value();
}
function keyPressed() {
  if (key == " ") {
    // important to have in order to start the serial connection!!
    setUpSerial();
  }
}
function readSerial(data) {
  console.log(data);
    let dataToSend = brightness + ", \n";
    writeSerial(dataToSend);  
}

A slider is created and data from it is sent to the arduino.

Arduino: https://github.com/Ting-AnYang/Intro-to-IM/blob/ebd695cde4ece4858599434e4cc13a205d2b5aef/Week11%20Exercise%202.ino

const int ledPin = 9;  
void setup() {
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
}
void loop() {
  Serial.println("sensor");
  if (Serial.available() > 0) {
    int brightness = Serial.parseInt();
    brightness = constrain(brightness, 0, 255);
    analogWrite(ledPin, brightness);
  }
}

Based on the input from the p5 sketch, the LED’s brightness is adjusted accordingly.

Demonstration:

IMG_8413

EXERCISE 03: BI-DIRECTIONAL COMMUNICATION

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

 

Using a potentiometer mapped from -2 to 2, when the potentiometer is towards the left, the wind blows towards the left, and vice versa. The LED lights up every time the ball touches the bottom edge of the canvas.

P5: https://editor.p5js.org/lj2369/full/EbBBWKl0S

function draw() {
  background(255);
  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(serialActive){
      writeSerial("bounced\n");
    }
    }
  // Check for collisions with the left wall
  if (position.x < mass / 2) {
    velocity.x =0; // Reverse horizontal velocity (bounce)
    position.x = mass / 2; // Correct position
  }

  // Check for collisions with the right wall
  if (position.x > width - mass / 2) {
    velocity.x =0; // Reverse horizontal velocity (bounce)
    position.x = width - mass / 2; // Correct position
  }
}

f

function readSerial(data){
  
  if (data != null){
    wind.x=int(data);
    console.log("working");

  }
}

A serial signal is sent to arduino everytime the ball touches the bottom of the canvas, resulting in the led to light up on the arduino. The potentiometer’s value will be reflected in the direction that the wind is blowing on the ball. I also added two walls on the right and left sides of the canvas, to prevent the wind from blowing the ball outside of the canvas.

Arudino: https://github.com/lonussss/Intro-to-IM/blob/main/week11exercise3.ino 

 

int ledPin = 8;       // Pin connected to the LED
int sensorPin = A0;   // Pin connected to the analog sensor
String inputString = "";  // String to accumulate incoming serial data
bool stringComplete = false; // Flag to check if a full command is received

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

void loop() {
  

  while(Serial.available()){
    String bounced = Serial.readStringUntil('\n');  //read serial string until new line
    if(bounced == "bounced"){
      flashLED();
    }
  int sensorValue = analogRead(sensorPin); // Read the analog sensor value
  int mappedValue = map(sensorValue, 0, 1023, -3 ,3);  // Map the sensor value to a range (-3 to 3)
  Serial.println(mappedValue); // Send the mapped value to p5.js
  }

  

}

void flashLED() {
  digitalWrite(ledPin, HIGH); // Turn LED on
  delay(100);                 // Keep LED on for 100 ms
  digitalWrite(ledPin, LOW);  // Turn LED off
}

There’s a function called flashLED which flashes the led 100ms whenever the ball touches the bottom of the canvas. The potentiometer is mapped between -3, and 3. The input will be reflected on the wind in p5.

Demonstration:

IMG_3537