• Skip to primary navigation
  • Skip to main content
  • Skip to primary sidebar

Ken's Documentation Blog

  • Home
  • Interaction Lab
  • Communication Lab
  • VR/AR Fundamentals
  • NIME
  • Toy Design and Prototyping
  • Make Believe
  • Remade in China
  • The Cultivated City
  • Interactive Fashion

Interaction Lab

Interaction Lab Final Blog Post

December 21, 2020 by Ken Wu Leave a Comment

A. Molecular Soccer – Ken Wu and Alan Chao – Professor Eric Parren

 

(Video: World Finals of Molecular Soccer) 

B. Conception and Design

The concept of this project was to make a game that was competitive, but simple and could be played by people of all ages. We aimed for this project to be fun for children where there was interaction and struggle when playing the game itself. We looked at how simple interfaces in the Gameboy were playable and enjoyable as well as took inspiration from how this simple the design was. The simplicity of such design influenced me to design the game in such a way that was intuitive for children. We thought about how the game should be played to make the game more fun and entertaining for individuals to give them difficulty and a different experience which led to us to want to create a pulley system for playing the game, however, the ER lacked the material leading to us not being able to trial this out. Buttons were the last option for consideration, but the option we had to go with. As the game is played with hands rather than fingers, the button size was important which is what we focused on to create greater user experience. In the user testing session, we received feedback about the projection of our game, however, we ultimately decided to use an external screen due to the terrible outcome of projection on 3dimensional buttons. I think that this kind of feedback was valuable in trialing the extent that our design could function upon. 

C. Fabrication and Production

For fabrication and production, a very crucial part was for the processing to work without much delay. Alan was in charge of the processing debugging to get the wanted result due to his expertise. This process in the fabrication and production process can be seen in his reflection for the work that he put it on it. A very important part was linking his processing with the final design. We were successful with designing the board interface to represent the interface as well as making the product refined through sanding all the edges and the board to create wonderful user experience. 

 

(Figure 1: Interface and Board Parallel)

 

(Figure 2: Sanding)

(Figure 3: Blowing dust off wood for smooth crisp texture)

Of course, this design wasn’t without small failures with the design. At first, the intended design was a closed box, however, that did not take into consideration the button framework or the hole for the USB to computer. Therefore, I amended the design on Rhino after having laser cut the pieces to see if there was any way to save it. This overlooked aspect led to the open box design.

 

(Figure 4: Previous design with the border on the edges)

(Figure 5.1: Modeling)

(Figure 5.2: Changed design to accommodate item size and USB hole)

As we decided on an open box design where people can see through the hole, it was important for the wires to be tidy. We then cut wires to be small rather than using jumper wires to make it a clean circuit.

(Figure 6: Short wires for the circuit)

One thing previously mentioned was the button that we would use for playing. On user testing day, we borrowed buttons from the ER which were terrible for our game as they were small and had a lot of limitations in terms of user experience. Therefore, we bought huge buttons which made the experience more friendly. 

 

(Figure 7: Terrible buttons)

 

(Figure 8: Good buttons)

Essentially, those were all the components that were actually decided in our project where the end product was clean easy and applicable. 

 

(Figure 9: Clean user experience)

D. Conclusions

Our project’s intended goal morphed from having a bit of education input within it to being fully for entertainment. This was a good change as the connection between education and entertainment for our game wasn’t very clear and beneficial. This project was super successful in entertainment though where many of the responses to our project were highly positive and the game had a lot of people into it where they kind of had an addiction to it after playing it for a bit of time. For one, Alan and I were both addicted to this game and actually spent hours playing together in multiple sessions to understand how user experience could be built better. This aligns with my definition of interaction as the actions of someone affect the actions of the other in a continuous sequence. Our game is never-ending in interaction. The focus of the player doesn’t end after pressing one button as they have to continuously focus on playing the game. We would improve our project by retrying the projected interface with pulley system to make this more advanced. This would need more time as it was our initial plan but the engineering of the pulley system was too advanced for my advanced beginner 3dmodeling skills. I think that I learned a lot from my setbacks and failures, particularly in the aspect of realizing the best solution. Our solution couldn’t be fulfilled due to a lack of skill and experience in designing mechanical features which is something I hope to learn and become advanced upon to realize more interactive mechanical designs before integrating it with the digital. I think that my biggest takeaway from the project produced is that there are multiple solutions and sometimes basic solutions aren’t always bad for the project. In fact, it may make the game easier to play. Of course, why should anyone care? I personally believe that people should care about people’s failures, insights, and thoughts as they may drive you from making the same mistakes and being stalled at one point. If one can understand the difficulty of realizing a solution, they should also realize how they can understand how to mitigate the difficulty through learning. Only when people learn can they create the future. 

E. Technical Documentation

General Processing Sketch

import processing.sound.*;
SoundFile file;
SoundFile win;
//SoundFile blob;
import processing.serial.*;

String myString = null;
Serial myPort;


int NUM_OF_VALUES = 10;   /** YOU MUST CHANGE THIS ACCORDING TO YOUR PROJECT **/
int[] sensorValues; 

PImage soccer;
Ball ball;
PVector loc;
PVector gravity = new PVector(0, 10);

boolean playState = true;
int count = 0;
int left_score = 0;
int right_score = 0;

float[][] trails = new float[100][2];

Player[] players = new Player[10];
String goalSide;
PFont arcade;
int winningHue;

void setup() {
  fullScreen();
  arcade = createFont("ArcadeClassic", 32);
  //size(1200, 675);
  setupSerial();
  loc = new PVector(width/2,height/2);
  //fullScreen();
  //pixelDensity(2);
  ball = new Ball(loc);
  rectMode(CORNERS);
  win = new SoundFile(this, "win.wav");
  //blob = new SoundFile(this, "blob.wav");
  file = new SoundFile(this, "378355__13gpanska-lakota-jan__bouncing-football-ball-off-the-ground.wav");
  players[0] = new Player(new PVector(310, height/2 - 117.5), 1);
  players[1] = new Player(new PVector(310, height/2 + 117.5), 1);
  players[2] = new Player(new PVector(550, height/2 - 280), 1);
  players[3] = new Player(new PVector(550, height/2 + 280), 1);
  players[4] = new Player(new PVector(width/2 + 200, height/2), 1);
  
  players[5] = new Player(new PVector(width-310, height/2 - 117.5), 2);
  players[6] = new Player(new PVector(width-310, height/2 + 117.5), 2);
  players[7] = new Player(new PVector(width - 550, height/2 - 280), 2);
  players[8] = new Player(new PVector(width-550, height/2 + 280), 2);
  players[9] = new Player(new PVector(width/2-200, height/2), 2);
}

void draw() {
  background(240);
  updateSerial();
  println(frameRate);
  //printArray(sensorValues);
  push();
  //textFont(arcade);
  fill(255, 0,0, 40);
  textSize(800);
  textAlign(CENTER);
  text(left_score, width/2 - 350, height - 200);
  fill(0, 0, 255, 40);
  text(right_score, width/2 + 350, height - 200);
  pop();
  drawCourt();
  for (int i = 0; i < players.length; i++) {
    players[i].run();
  }
  if (playState){

  //println(mouseX, ",", mouseY);


  //println(frameRate);
  gravity.y = 20*noise(frameCount) - 10;
  ball.applyForce(gravity);
  int head = frameCount%100;
  trails[head][0] = ball.location.x;
  trails[head][1] = ball.location.y;
  push();
  colorMode(HSB);
  for (int i = 0; i < trails.length; i++) {
    float dia;
    if (i >= head) {
      dia = 0.3*(head - i);
    }else{
      dia = 0.3*(head - (i+100));
    }
    fill(30, 200, 255, 80);
    circle(trails[i][0], trails[i][1], dia);
  }
  pop();
  ball.run();
  
  if (ball.location.x <= ball.size/2 + 133 ||  ball.location.x >= width - ball.size/2 - 133) {
    ball.velocity.x *= -1;
    file.play();
    ball.hue += random(200);
    if (ball.location.x < 133) {
      ball.location.x = ball.size/2 + 20;
    }else if (ball.location.x > width - 133) {
      ball.location.x = width - ball.size/2 - 20;
    }
      if (ball.location.y > height/2 - 200 && ball.location.y < height/2 + 200 && ball.location.x < width/2) {
    right_score += 1;
    goalSide = "Blue";
    playState = false;
    //ball.velocity.mult(0);
    push();
    fill(255,0,0);
    rect(0, height/2 - 200, 133, height/2 + 200);
    pop();
  }
  if (ball.location.y > height/2 - 200 && ball.location.y < height/2 + 200 && ball.location.x > width/2) {
    //ball.velocity.mult(0);
    left_score += 1;
    goalSide = "Red";
    playState = false;
    push();
    fill(255,0,0);
    rect(width-133, height/2 - 200, width, height/2 + 200);
    pop();
  }
  }
  if (ball.location.y <= ball.size/2 + 5 ||  ball.location.y >= height - ball.size/2 -5) {
    ball.velocity.y *= -1;
    file.play();
    ball.hue += random(200);
    if (ball.location.y < 5) {
      ball.location.y = ball.size/2 + 20;
    }else if (ball.location.y > height - 5) {
      ball.location.y = height - ball.size/2 - 20;
    }
  }
  

  
  //println(keyPressed);
  for (int i = 0; i < players.length; i++) {
    //players[i].run();
    players[i].bounce(ball);
    //if (i != 9) {
    //  players[i].reactSize(i == Character.getNumericValue(key) - 1 && keyPressed);
    //}else{
    //  players[i].reactSize(0 == Character.getNumericValue(key) && keyPressed);
    //}
    players[i].reactSize(parseBoolean(sensorValues[i]));
    
    
  }
  }
  else{
    if (!win.isPlaying()){
      win.play();
    }
    
    count += 1;
    push();
    colorMode(HSB);
    winningHue += round(10*noise(frameCount));
    winningHue %= 360;
    fill(winningHue, 150, 230);

    textFont(arcade);
    textAlign(CENTER);
    textSize(200);
    text(goalSide + " Scores", width/2, height/2 + 50*noise(frameCount*0.1) - 25);
    //println(count);
    pop();
    if (count > 180) {
      playState = true;
      win.stop();
      count = 0;
      ball.location.x = width/2;
      ball.location.y = height/2;
      //ball.velocity.mult(0);
      //ball.velocity.y = random(-1,1);
    }
  }
}


void drawCourt () {
  pushStyle();
  stroke(120);
  noFill();
  strokeWeight(3);
  
  line(133, 5, 133, height - 5);
  line(width - 133, 5, width - 133, height - 5);
  line(133, 5, width -133, 5);
  line(133, height-5, width -133, height-5);
  strokeWeight(1);
  //rect(2, 382, 30, 468);
  
  rect(133, height/2 - 200, 94, height/2 + 200);
  rect(133, height/2 - 350, 215, height/2 + 350);
  
  //rect(width-2, 382, width-30, 468);
  rect(width-133, height/2 - 200, width-94, height/2 + 200);
  rect(width-133, height/2 - 350, width-215, height/2 + 350);
  ellipse(width/2, height/2, 200, 200);
  line(width/2, 5, width/2, height-5);
  push();
  stroke(0, 200, 200);
  strokeWeight(5);
  line(133, height/2 - 200, 133, height/2 + 200);
  line(width - 133, height/2 - 200, width-133, height/2 + 200);
  pop();
  popStyle();
}



void setupSerial() {
  printArray(Serial.list());
  myPort = new Serial(this, Serial.list()[ 3 ], 9600);
  // WARNING!
  // You will definitely get an error here.
  // Change the PORT_INDEX to 0 and try running it again.
  // And then, check the list of the ports,
  // find the port "/dev/cu.usbmodem----" or "/dev/tty.usbmodem----" 
  // and replace PORT_INDEX above with the index number of the port.

  myPort.clear();
  // Throw out the first reading,
  // in case we started reading in the middle of a string from the sender.
  myString = myPort.readStringUntil( 10 );  // 10 = '\n'  Linefeed in ASCII
  myString = null;
  
  sensorValues = new int[NUM_OF_VALUES];
}



void updateSerial() {
  while (myPort.available() > 0) {
    myString = myPort.readStringUntil( 10 ); // 10 = '\n'  Linefeed in ASCII
    if (myString != null) {
      String[] serialInArray = split(trim(myString), ",");
      if (serialInArray.length == NUM_OF_VALUES) {
        for (int i=0; i<serialInArray.length; i++) {
          sensorValues[i] = int(serialInArray[i]);
        }
      }
    }
  }
}

Sketch of Ball

 

class Ball {
  PVector location;
  PVector velocity;
  PVector acceleration;
  float size;
  float mass = 30;
  int hue;

  Ball(PVector l) {
    acceleration = new PVector(0,0);
    velocity = new PVector(random(10),random(-2,0));
    //velocity = new PVector(0,0);
    location = l.get();
    size = 30;
    hue = 0;
  }

  void run() {
    update();
    display();
  }

  void applyForce(PVector force) {
    PVector f = force.get();
    f.div(mass);   
    acceleration.add(f);
  }

  // Method to update location
  void update() {
    velocity.add(acceleration);
    location.add(velocity);
    acceleration.mult(0);
    velocity.limit(16);
    velocity.mult(0.998);
    //lifespan -= 2.0;
  }

  // Method to display
  void display() {
    push();
    stroke(0);
    strokeWeight(2);
    
    //noStroke();
    colorMode(HSB);
    fill(hue % 360, 200 , 255);
    ellipse(location.x,location.y,size,size);
    pop();
  }
  
  void setSize(float value) {
    size = value;
  }

  // Is the particle still useful?
  //boolean isDead() {
  //  if (lifespan < 0.0) {
  //    return true;
  //  } else {
  //    return false;
  //  }
  //}
}

class Player extends Ball {
  int side;
  float originalSize;
  Player(PVector l, int s) {
    super(l);
    this.setSize(130);
    originalSize = size;
    side = s;
    velocity = new PVector(0,0);
  }
  
  void display() {

    noStroke();
    if (side == 1) {
      fill(200, 0, 0, size * 1.1);
    }
    else if (side == 2) {
      fill(0, 0, 200, size* 1.1);
    }

    ellipse(location.x,location.y,size,size);

    if (size > 160) {
          push();
      for (int i = 0; i < 20; i++) {
      float d = map(i, 0, 20, 0, size);
      float op = map(d, 0, size, 80, 0);
      stroke(255, op);
      strokeWeight(20);
      noFill();
      circle(location.x,location.y,d);
      }
          pop();
    }

  }
  
  boolean checkPos(Ball other) {
    float dist = this.location.dist(other.location);
    if (dist <= (size + other.size)/2 + 2) {
      return true;
    }else{
      return false;
    }
  }
  
  void reactSize(boolean triggerState) {
    if (triggerState){

      //println("yes");
      //float rate = sensorValues[i] - pSensorValues[i];
      //rate = map(rate, 0, 1023, 30, 100);
      //if (!blob.isPlaying() || frameCount % 30 == 0){
      //  blob.play();
      //}
      size += 40;

    if (size > 300) {
        size = 300;
      }
    }
    else if (size > originalSize){
       size = lerp(size, originalSize, 0.03);
    }
  } 
  
  void bounce(Ball other) {
    if (this.checkPos(other)) {
      file.play();
      other.hue += random(200);
      PVector force = new PVector(other.location.x - location.x, other.location.y - location.y);
      float dist = this.location.dist(other.location);
      dist = dist / 2;
      force.normalize();
      force.mult((other.velocity.mag()+1) * dist);
      //force.mult(dist*100);
      other.applyForce(force);
    }
  }
}

Arduino Sketch

// IMA NYU Shanghai
// Interaction Lab
// For sending multiple values from Arduino to Processing

int sensors[10];

void setup() {
  Serial.begin(9600);
  for (int i=2; i < 12; i++) {
  pinMode(i, INPUT);  
  }
}

void loop() {
  for (int i=2; i < 12; i++) {
    sensors[i] = digitalRead(i);
    Serial.print(sensors[i]);
    if(i != 11) {
      Serial.print(",");
      }
    
  }

  // keep this format
//  Serial.print(sensor1);
//  Serial.print(",");  // put comma between sensor values
//  Serial.print(sensor2);
//  Serial.print(",");
//  Serial.print(sensor3);
    Serial.println(); // add linefeed after sending the last sensor value

  // too fast communication might cause some latency in Processing
  // this delay resolves the issue.
  delay(100);
}

 

Filed Under: Interaction Lab

Recitation: User Testing

December 11, 2020 by Ken Wu Leave a Comment

Step 1

For the critique of a project, I went to the project by Duorfan and Kiki where they created an interaction game for solving recycling where the background gradually became more green as people recycled. This stresses the environmental value of recycling.  I thought that this project was interesting in the sense that people had to identify the object and move the trashcan to catch it as an interaction rather than simply using the mouse to press the trashcan. Moreover, this interaction is similar to the real world’s interaction of recycling which was very clever. While conceptually it was very good, there were design flaws with the project where I provided feedback. They will be listed as follows:

  1. There is no time that is provided for the player to see what the object they are recycling is. It was highly difficult to recycle without Duorfan telling me what the object was. To fix this, I recommended that they have the graphic of the object static for 2 seconds before starting the game so that players could identify the object.  
  2. Another flaw was the distance sensor which was a big nuisance to use as the sensitivity was lacking and that the box didn’t slide well on the board. I recommended that they make a slider for the board or add wheels to the box so that it was easier to play the game. Moreover, more variety could be used in the product. 

Step 2

According to the people that participated in the user test, the intuitiveness of our project was the most successful, however, as our project didn’t have the buttons created so that they align with the position of the game during user testing, the user experience was lackluster. People wanted to play our game, but couldn’t play it comfortably as there was a lack of alignment with the game. I agree with this as I struggled to play and only controlled 2 circles rather than the 5 that I could control. There was also feedback on the interface that this should be played on. There was a recommendation to borrow a projector. We agree but  we couldn’t access one as they were all borrowed from the ER already. Other than that, we didn’t really incorporate any feedback from others. This is due to the planned design of the project previously thought out where the rendering designs and 3d modeling were already created to limit the necessity of changing anything or having anything be incorrectly made. 

Filed Under: Interaction Lab

Recitation 9: Media Controller

December 3, 2020 by Ken Wu Leave a Comment

For this recitation, I focused on making a parallel pattern with a light sensor and the brightness of a photo. The light sensor composes of the Arduino part while the brightness of the photo is from Processing. This parallel seemed like a natural process and is similar to what happens to the computer screen or phone screen that auto detect brightness and change itself accordingly which was what I aimed to mirror. Essentially, this is similar to how the brightness of a camera or the iso can be modified to be dimmed or brightened according to the brightness of the external background. 

 

Processing Code:


// IMA NYU Shanghai
// Interaction Lab
// For receiving multiple values from Arduino to Processing

/*
 * Based on the readStringUntil() example by Tom Igoe
 * https://processing.org/reference/libraries/serial/Serial_readStringUntil_.html
 */

import processing.serial.*;

String myString = null;  //string will take the Arudino values , but according to ASICC code
Serial myPort;


int NUM_OF_VALUES = 1;   /** YOU MUST CHANGE THIS ACCORDING TO YOUR PROJECT **/
int[] sensorValues;      /** this array stores values from Arduino **/

PImage photo;

void setup() {
  background(0);
  size(1500, 1500);
  photo = loadImage("HELP.png");
   setupSerial();
}


void draw() {
  updateSerial();
  //printArray(sensorValues);

  // use the values like this!
  // sensorValues[0] 
 tint(map (sensorValues[0], 0, 1023, 0, 255)); 
  image(photo, 0, 0);

} 



void setupSerial() {
  printArray(Serial.list());
  myPort = new Serial(this, Serial.list()[2], 9600);
  // WARNING!
  // You will definitely get an error here.
  // Change the PORT_INDEX to 0 and try running it again.
  // And then, check the list of the ports,
  // find the port "/dev/cu.usbmodem----" or "/dev/tty.usbmodem----" 
  // and replace PORT_INDEX above with the index number of the port.

  myPort.clear();
  // Throw out the first reading,
  // in case we started reading in the middle of a string from the sender.
  myString = myPort.readStringUntil( 10 );  // 10 = '\n'  Linefeed in ASCII
  myString = null;

  sensorValues = new int[NUM_OF_VALUES];
}



void updateSerial() {
  while (myPort.available() > 0) {
    myString = myPort.readStringUntil( 10 ); // 10 = '\n'  Linefeed in ASCII
    if (myString != null) {
      String[] serialInArray = split(trim(myString), ",");
      if (serialInArray.length == NUM_OF_VALUES) {
        for (int i=0; i<serialInArray.length; i++) {
          sensorValues[i] = int(serialInArray[i]);
        }
      }
    }
  }
}

Arduino Code:

// IMA NYU Shanghai
// Interaction Lab
// For sending multiple values from Arduino to Processing


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

void loop() {
  int sensor = analogRead(A0);

  // keep this format
  Serial.print(sensor);
  Serial.println(); // add linefeed after sending the last sensor value

  // too fast communication might cause some latency in Processing
  // this delay resolves the issue.
  delay(100);
}

Filed Under: Interaction Lab

Recitation 8: Serial Communication

November 26, 2020 by Ken Wu Leave a Comment

For recitation 8, the focus was on serial communication where there were tasks to create Arduino to processing serial communication and processing to Arduino serial communication. 

Exercise 1

For exercise 1, the task was to create an etch a sketch. This wasn’t too difficult as potentiometers sent serial communication to processing to draw lines. One potentiometer controlled the x of the processing and the other controlled the y coordinate. A video will be attached to show this learning. 

 

Processing Code

// IMA NYU Shanghai
// Interaction Lab
// For receiving multiple values from Arduino to Processing

/*
 * Based on the readStringUntil() example by Tom Igoe
 * https://processing.org/reference/libraries/serial/Serial_readStringUntil_.html
 */

import processing.serial.*;

String myString = null;
Serial myPort;
float x, y;//current
float m, n;//previous


int NUM_OF_VALUES = 2;   /** YOU MUST CHANGE THIS ACCORDING TO YOUR PROJECT **/
int[] sensorValues;      /** this array stores values from Arduino **/

void setup() {
  size(500, 500);
  background(0);
  setupSerial();
  m = 0;
  n = 0;
}


void draw() {
  updateSerial();
  printArray(sensorValues);
  float x = map(sensorValues[0], 0, 1023, 0, width);
  float y = map (sensorValues[1], 0, 1023, 0, height);
  fill(255);
  stroke(255);
  strokeWeight(5);
  line(m, n, x, y);

  //update previous 
  m = x; 
  n = y;
  //stroke(5);
  //frameRate(1);
  //   line (0,0, x, y);

  //}
  //  if (sensorValues[1]==1){

  //    background (0);
  //    fill(255);
  //  circle (50,50,50);
  //}

  // use the values like this!
  // sensorValues[0] 

  // add your code

  //
}



void setupSerial() {
  printArray(Serial.list());
  myPort = new Serial(this, Serial.list()[ 2 ], 9600);
  // WARNING!
  // You will definitely get an error here.
  // Change the PORT_INDEX to 0 and try running it again.
  // And then, check the list of the ports,
  // find the port "/dev/cu.usbmodem----" or "/dev/tty.usbmodem----" 
  // and replace PORT_INDEX above with the index number of the port.

  myPort.clear();
  // Throw out the first reading,
  // in case we started reading in the middle of a string from the sender.
  myString = myPort.readStringUntil( 10 );  // 10 = '\n'  Linefeed in ASCII
  myString = null;

  sensorValues = new int[NUM_OF_VALUES];
}



void updateSerial() {
  while (myPort.available() > 0) {
    myString = myPort.readStringUntil( 10 ); // 10 = '\n'  Linefeed in ASCII
    if (myString != null) {
      String[] serialInArray = split(trim(myString), ",");
      if (serialInArray.length == NUM_OF_VALUES) {
        for (int i=0; i<serialInArray.length; i++) {
          sensorValues[i] = int(serialInArray[i]);
        }
      }
    }
  }
}

Arduino Code
// IMA NYU Shanghai
// Interaction Lab
// For sending multiple values from Arduino to Processing
void setup() {
 Serial.begin(9600);
}
void loop() {
 int potentiometer1 = analogRead(A0);
 int potentiometer2 = analogRead(A1);
 // keep this format
 Serial.print(potentiometer1);
 Serial.print(",");  // put comma between sensor values
 Serial.print(potentiometer2);
 Serial.println(); // add linefeed after sending the last sensor value
 // too fast communication might cause some latency in Processing
 // this delay resolves the issue.
 delay(100);
}

Exercise 2
For exercise 2, I focused on making the buzzer's frequency react to the coordinates of the x-coordinate of the trackpad. 
This helped make it more focused and interactive where a video will be attached. 
 

// IMA NYU Shanghai
// Interaction Lab


/**
 * This example is to send multiple values from Processing to Arduino.
 * You can find the arduino example file in the same folder which works with this Processing file.
 * Please note that the echoSerialData function asks Arduino to send the data saved in the values array
 * to check if it is receiving the correct bytes.
 **/


import processing.serial.*;

int NUM_OF_VALUES = 2;  /** YOU MUST CHANGE THIS ACCORDING TO YOUR PROJECT **/


Serial myPort;
String myString;

// This is the array of values you might want to send to Arduino.
int values[] = new int[NUM_OF_VALUES];

void setup() {
  size(500, 500);
  background(0);
  printArray(Serial.list());
  myPort = new Serial(this, Serial.list()[ 2 ], 9600);
  // check the list of the ports,
  // find the port "/dev/cu.usbmodem----" or "/dev/tty.usbmodem----" 
  // and replace PORT_INDEX above with the index of the port

  myPort.clear();
  // Throw out the first reading,
  // in case we started reading in the middle of a string from the sender.
  myString = myPort.readStringUntil( 10 );  // 10 = '\n'  Linefeed in ASCII
  myString = null;
}


void draw() {
  background(0);

  // changes the values
  //for (int i=0; i<values.length; i++) {
  values[0]= mouseX;//
  values[1] = mouseY;




  // sends the values to Arduino.
  sendSerialData();

  // This causess the communication to become slow and unstable.
  // You might want to comment this out when everything is ready.
  // The parameter 200 is the frequency of echoing. 
  // The higher this number, the slower the program will be
  // but the higher this number, the more stable it will be.
  echoSerialData(20);
}

void sendSerialData() {
  String data = "";
  for (int i=0; i<values.length; i++) {
    data += values[i];
    //if i is less than the index number of the last element in the values array
    if (i < values.length-1) {
      data += ","; // add splitter character "," between each values element
    } 
    //if it is the last element in the values array
    else {
      data += "n"; // add the end of data character "n"
    }
  }
  //write to Arduino
  myPort.write(data);
}


void echoSerialData(int frequency) {
  //write character 'e' at the given frequency
  //to request Arduino to send back the values array
  if (frameCount % frequency == 0) myPort.write('e');

  String incomingBytes = "";
  while (myPort.available() > 0) {
    //add on all the characters received from the Arduino to the incomingBytes string
    incomingBytes += char(myPort.read());
  }
  //print what Arduino sent back to Processing
  print( incomingBytes );
}

Arduino Code

// IMA NYU Shanghai
// Interaction Lab


/**
  This example is to send multiple values from Processing to Arduino.
  You can find the Processing example file in the same folder which works with this Arduino file.
  Please note that the echo case (when char c is 'e' in the getSerialData function below)
  checks if Arduino is receiving the correct bytes from the Processing sketch
  by sending the values array back to the Processing sketch.
 **/

#define NUM_OF_VALUES 3    /** YOU MUST CHANGE THIS ACCORDING TO YOUR PROJECT **/


/** DO NOT REMOVE THESE **/
int tempValue = 0;
int valueIndex = 0;
float x;
float y;
/* This is the array of values storing the data from Processing. */
int values[NUM_OF_VALUES];


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

void loop() {
  getSerialData();
  x = map(values[0], 0, 500, 2000, 5000);
  y = map(values[1], 0, 500, 100, 200);
  tone(8, x, y);

}


//recieve serial data from Processing
void getSerialData() {
  if (Serial.available()) {
    char c = Serial.read();
    //switch - case checks the value of the variable in the switch function
    //in this case, the char c, then runs one of the cases that fit the value of the variable
    //for more information, visit the reference page: https://www.arduino.cc/en/Reference/SwitchCase
    switch (c) {
      //if the char c from Processing is a number between 0 and 9
      case '0'...'9':
        //save the value of char c to tempValue
        //but simultaneously rearrange the existing values saved in tempValue
        //for the digits received through char c to remain coherent
        //if this does not make sense and would like to know more, send an email to me!
        tempValue = tempValue * 10 + c - '0';
        break;
      //if the char c from Processing is a comma
      //indicating that the following values of char c is for the next element in the values array
      case ',':
        values[valueIndex] = tempValue;
        //reset tempValue value
        tempValue = 0;
        //increment valuesIndex by 1
        valueIndex++;
        break;
      //if the char c from Processing is character 'n'
      //which signals that it is the end of data
      case 'n':
        //save the tempValue
        //this will b the last element in the values array
        values[valueIndex] = tempValue;
        //reset tempValue and valueIndex values
        //to clear out the values array for the next round of readings from Processing
        tempValue = 0;
        valueIndex = 0;
        break;
      //if the char c from Processing is character 'e'
      //it is signalling for the Arduino to send Processing the elements saved in the values array
      //this case is triggered and processed by the echoSerialData function in the Processing sketch
      case 'e': // to echo
        for (int i = 0; i < NUM_OF_VALUES; i++) {
          Serial.print(values[i]);
          if (i < NUM_OF_VALUES - 1) {
            Serial.print(',');
          }
          else {
            Serial.println();
          }
        }
        break;

Additional Homework

The additional homework for this week revolved around using boolean true and boolean false to create the stars appearance and disappearance. I struggled at first to understand how boolean would be used as I made it flicker when I pressed the button, however after asking a fellow to assist me in understanding how the drawing works, I was able to figure it out to be boolean. A video will be attached as well as a photo of the circuit. 

 

Processing Code :

// IMA NYU Shanghai
// Interaction Lab
// For receiving multiple values from Arduino to Processing

/*
 * Based on the readStringUntil() example by Tom Igoe
 * https://processing.org/reference/libraries/serial/Serial_readStringUntil_.html
 */

import processing.serial.*;

String myString = null;
Serial myPort;


int NUM_OF_VALUES = 2;   /** YOU MUST CHANGE THIS ACCORDING TO YOUR PROJECT **/
int[] sensorValues;      /** this array stores values from Arduino **/
int h=0;
int k=0;
boolean b = false;
boolean c=false;

void setup() {
  size(600, 600);
  background(0);
  setupSerial();
}


void draw() {
  updateSerial();
  printArray(sensorValues);
  background (0);
  if (sensorValues[0]==1 &&sensorValues[0]!=h) {
    b=!b;
  }
  if (sensorValues[1]==1 &&sensorValues[1]!=k) {
    c=!c;
  }
  if (b) {
    star(100, 100, 80, 100, 40);
  }
  if (c) {
    star(250, 300, 30, 70, 5);
  }
  h=sensorValues[0];
  k=sensorValues[1];
}


void setupSerial() {
  printArray(Serial.list());
  myPort = new Serial(this, Serial.list()[2], 9600);
  // WARNING!
  // You will definitely get an error here.
  // Change the PORT_INDEX to 0 and try running it again.
  // And then, check the list of the ports,
  // find the port "/dev/cu.usbmodem----" or "/dev/tty.usbmodem----" 
  // and replace PORT_INDEX above with the index number of the port.

  myPort.clear();
  // Throw out the first reading,
  // in case we started reading in the middle of a string from the sender.
  myString = myPort.readStringUntil( 10 );  // 10 = '\n'  Linefeed in ASCII
  myString = null;

  sensorValues = new int[NUM_OF_VALUES];
}

void star(float x, float y, float radius1, float radius2, int npoints) {
  float angle = TWO_PI / npoints;
  float halfAngle = angle/2.0;
  beginShape();
  for (float a = 0; a < TWO_PI; a += angle) {
    float sx = x + cos(a) * radius2;
    float sy = y + sin(a) * radius2;
    vertex(sx, sy);
    sx = x + cos(a+halfAngle) * radius1;
    sy = y + sin(a+halfAngle) * radius1;
    vertex(sx, sy);
  }
  endShape(CLOSE);
}

void updateSerial() {
  while (myPort.available() > 0) {
    myString = myPort.readStringUntil( 10 ); // 10 = '\n'  Linefeed in ASCII
    if (myString != null) {
      String[] serialInArray = split(trim(myString), ",");
      if (serialInArray.length == NUM_OF_VALUES) {
        for (int i=0; i<serialInArray.length; i++) {
          sensorValues[i] = int(serialInArray[i]);
        }
      }
    }
  }
}

Arduino code: 

// IMA NYU Shanghai
// Interaction Lab
// For sending multiple values from Arduino to Processing


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

void loop() {
  int button1 = digitalRead(7);
  int button2 = digitalRead(8);

  // keep this format
  Serial.print(button1);
  Serial.print(",");  // put comma between sensor values
  Serial.print(button2);
  Serial.println(); // add linefeed after sending the last sensor value

  // too fast communication might cause some latency in Processing
  // this delay resolves the issue.
  delay(100);
}

 

Filed Under: Interaction Lab

Final Project Essay

November 25, 2020 by Ken Wu Leave a Comment

For the Final Project, we changed the initial 6 ideas we had to this final project due to information received from the instructor and classmates. In particular, what influenced us was the suggestion to move away from buttons and sliders where we reviewed all our existing ideas and thought about how this component could be removed. In addition, we also focused on trying to make the works original as there was a comment that the sand table idea didn’t add many original components to it. The final project information will then be provided below. 

A. Molecular Soccer

B. I found inspiration from the Gameboy for this project where controls of the console were simple but could alternate the dimensionality of the game. When I was young, I’ve also played soccer on a Gameboy before thus this project also is derived from past experience of playing soccer. Our project focuses on the specific purpose of entertainment for young children as well as ingraining technical scientific principle of expansion and heat upon them. We’d like to address simple education through entertainment to young children to allow them to actually use a product that would help them learn. This is due to children’s interests in leisure rather than learning. We’d also like to include subtle graphics that show scientific models of expansion to children to expose them to knowledge at an early age as a byproduct of playing this game in hopes that they understand such knowledge easily. 

C. Our project will be a projection of a game similar to soccer, but simplified to simple circles to represent the players. The circles will expand and compress based on the distance of the hand above or below them which is important to note as the “soccer ball” reflects on the circle based on the angle of impact. In total, there will be 14 circles with 7 circles that are controlled by each user. This project will first have the mechanics of processing work out in which the circular ball reflects when it hits another ball as well as how it will count points when it enters the goal which will be completed by December 1. Afterwards, we will try to implement the ultrasonic sensors to test the serial connection between Arduino and processing on December 2. When both of these steps have been perfectly completed, the design of the game box will be 3D modeled in Rhinoceros before having the pieces laser cut and attached to each other on December 3 and perfected so that it can be user tested on December 4. 

Steps that will be taken to empathize with the target audience would be to account for arm span so that they can properly experience the game device without stretching and covering the projection. Moreover, as this device is conceptually targeted to children we would like to make it simpler for them to control where the ultrasonic sensor will have lower distance settings in which the circle will expand. Other than the above, the aesthetics may appear more childish in the sense that there may be engraved drawings. 

D. From the preparatory research and readings, I was most impacted by the definition of interaction that was studied between them. In particular, Edmonds’ dynamic-passive interaction and dynamic-interactive interaction stood out to me most which inspires this proposal. It can be seen in my project that it is dynamic-interactive as the movement of the virtual ball changes how the players move within the game. Moreover, this also is inline with my definition of interaction which is that an action leads to a reaction that leads to another action from the source. This should be reciprocal where both sources should contribute in the interactive manner. It can be seen in this idea that the action of a ball moving leads to reactions of the individual which lead to continuous movements of the ball in the direction that’s reflected. 

I think that this project is unique in the sense that a lot of the control components are simplified so that only the size of the ball can affect movement, direction, and etc. We then take the existing sport of soccer and implement it to this game to create a new experience of playing soccer which is different from modern day video game consoles. We think that this is significant as it provides opportunities to strengthen the kinetic skills of individuals as an entertaining game to them. It can also provide a basis to them on how cells expand when heating as the circle will turn red. This project could be a non-digital screen based game which is rare in society as everything is technology based, especially gaming consoles. Subsequent projects could build upon this idea of simple controls to address the child audience in a healthy manner that doesn’t include digital gaming on a screen. While the value of this project would not be especially high in terms of educational worth, it can provide joy which can arguably be worth it for many parents in our society as well as entertainment worth. 

Filed Under: Interaction Lab

Final Project Project Proposal

November 19, 2020 by Ken Wu Leave a Comment

Sand Art Table

This table concept takes inspiration from the Sisyphus Table that I researched outside of the projects from the last blog. It essentially is a clear table with sand and a metal ball inside of it that creates kinetic designs. I want to evolve this design to be manual and interactive for people to entertain themselves with where I would include the addition of a joystick that controls the movement of the ball on the sand to create certain patterns. Along with this, there will be a projector that projects different colors to create a more immersive table that creates different moods. 

This product aims to redefine the aesthetics of a table to be dynamic through creating a device that amends the patterns of the table for people of all ages. For children, this will be a device that initiates their creativity as a entertainment object while for teenagers, students, and the working class, this can be a product that reduces stress during their daily activities as it has been proven that art reduces stress. Being for a vast audience, the purpose of the product isn’t to provide the entertaining, stress-relieving features that it offers, rather, it is to be a product that has the potential of providing these services when there is a need so the users can also use this as a normal table for completing their daily tasks. 

Arduino Educational Board Game

This idea takes inspiration from both the Gameboy and Monopoly where it is a board game that revolves around a device for educational purposes when playing a game. The board game is based on movement according to whether or not a question on a card is answered correctly. The questions are based on the Arduino programming language where it may ask questions such as function notations of void setup or details such as whether or not a circuit is correct. This was influenced by Monopoly for the game movement and the device is based on the old Gameboy to display the answers to the question through input of numbers. 

This product aims to provide an educational experience of Arduino to young children and aspiring computer engineers that want to learn how the logic of computers work. In providing an educational experience through a board game that young children would like to play, it would like to assist the development of the next generation of talents in the STEM studies. In teaching these talents to basic STEM fundamentals through a game, the aim is to ingrain such knowledge into them so that they can apply it to Arduino later. 

Musical Table 

This concept is based upon the Gameboy but used on a different surface being the table. It essentially is a variety of buttons and levers on a table surface which serve as an instrument that can be played. Each button has a different pitch on the table which they can play and pitch can be determined by other buttons of the interface. 

This product children aspiring to learn instruments and is meant to improve their music interests. When children go to school, they normally go back home to do homework where they would use a desk. This product is meant to provide inspiration for children to develop musical interests on the table that they write homework in which may also serve them entertainment purposes. 

 

Filed Under: Interaction Lab

Recitation 7: Functions and Arrays

November 19, 2020 by Ken Wu Leave a Comment

For this recitation, there was an emphasis on using arrays to create a function in which we were tasked to create a drawing of an object. For this, I created a hourglass like design using triangles and a square. It would look like the photo below where the sketch video will also be attached. 

 

The code to this drawing is the following:

int instances=100;
float[] move = new float[100];
float [] xPos= new float [instances];
float [] yPos= new float[instances];
color [] cL=new color[instances];

void shapeX (float x, float y, color c) {
  fill (c);
  circle (x, y, 20);
  fill (c/2);
  rectMode (CENTER);
  square (x, y, 30);
  fill (c/4);
  triangle (x-15, y+10, x, y-5, x+15, y+10);
  fill (c/8);
  triangle (x-15, y-10, x, y+5, x+15, y-10);
}
void setup() {
  size (600, 600);
  background (0);
  for (int i=0; i<instances; i++) {
    xPos[i]=(random(0, 600));
    yPos[i]=(random(0, 600));
    cL[i]=color (random(0, 255), random (0, 255), random (0, 255));
    move[i]=(random(5));
  }
  noStroke();
}
void draw() {
  background (0);
  for (int i=0; i<instances; i++) {
    shapeX (xPos[i], yPos[i], cL[i]); 
    if ((xPos[i] + move[i] > 600)||(xPos[i] + move[i] < 0)) {
      move[i]=-move[i];
    }
    xPos[i] = xPos[i]+move[i];
  }
}

Afterwards, there was the additional homework with the responsive graphic to the mouse point where a video of the graphic will be attached as well as the code. For the code, I struggled with it a lot and went to the study session to understand how it works and what to do. 

 

int col=25, row=25;
int totalNumber=col*row;
int padding=140;
int defaultSize=10;
float[]xPositionsOriginal = new float [totalNumber];
float[]yPositionsOriginal = new float [totalNumber];


float[]xPositions = new float [totalNumber];
float[]yPositions = new float [totalNumber];

float[]sizeFactors = new float [totalNumber];

float lerpFactors=0.5;

void setup() {
  size(800, 800);
  for (int i=0; i<col; i++) {
    for (int j=0; j<row; j++) {
      int index=j+i*row;
      xPositionsOriginal[index]=map(i, 0, col-1, padding, width-padding);
      yPositionsOriginal[index]=map(j, 0, col-1, padding, height-padding);

      xPositions[index]=xPositionsOriginal[index];
      yPositions[index]=yPositionsOriginal[index];
      sizeFactors[index]=1.0;
    }
  }
}
void draw() {
  background(255);
  for (int i=0; i<totalNumber; i++) {
    float offset=dist(mouseX, mouseY, xPositionsOriginal[i], yPositionsOriginal[i]);
    offset=max(offset, 0.001);
    float newX=xPositionsOriginal[i]-(25/offset)*(mouseX-xPositionsOriginal[i]);
    float newY=yPositionsOriginal[i]-(25/offset)*(mouseY-yPositionsOriginal[i]);


    xPositions[i]=lerp(xPositions[i], newX, lerpFactors);
    yPositions[i]=lerp(yPositions[i], newY, lerpFactors);

    sizeFactors[i]=100/offset;
    sizeFactors[i]=max(sizeFactors[i], 0.4);
    sizeFactors[i]=min(sizeFactors[i], 2);
    fill(0);
    circle(xPositions[i], yPositions[i], sizeFactors[i]*defaultSize);
  }
}

For question 1, the difference between having the loop and set up and draw is essentially whether the sketch will be a continuous animation or if the sketch will be static. When the loop is in setup, there will be no repetition of the sketch which only allows it to be a static image. When the loop is in draw, it will repeat the animation and the functions of the code per frame which would make it animating if the frame has such properties. For question 2, I believe that arrays are beneficial to processing codes as it makes the code more efficient and makes the code easier to control. Essentially, it stores data of information within a set of data which can easily be accessed by the user at their will. This then can be applied to sets of data for names of objects, functions such as color, size, and etc, and more. It also condenses the information allowing it to be tidy so that information can be easily accessed and used to create the wanted sketch. I might use this in my project by combining information of a certain project within my text. For example, if I make a board game, I may include variables of text that should appear in an array so that the projector can display the necessary text.

Filed Under: Interaction Lab

Recitation 6: Processing Animation

November 12, 2020 by Ken Wu Leave a Comment

This week, the recitation’s focus was on creating animation on processing in which it should be incorporated to the text and interactive with the keyboard or mouse. From this prompt, I created an animation that was based on random circle designs that could be incorporated via the coded keys of up, down, left, right, and an “eraser” with the mouse. 

From this I think it was very interesting to incorporate both the mouse and keyboard into an interactive processing code. The code itself allowed for it. Moreover, I think that the colors itself allowed for interesting compositions where the random colors could be edited to create more harmonic pieces. I, however, like adding neutral colors to the red and blue dots I could input. I think that the frameRate function was particularly interesting in this piece as it allowed for me to control the rate at which ellipses were added where the standard frame rate was too high, but my edited frameRate was perfect.

I will now input videos of using this and the code. 

 

 

float y=10;
float x=10;
float z=255;
void setup() {
  size (1000, 1000);
  background(125);
  noStroke();
  frameRate(8);
}
void draw () {
  frameRate(8);
  for (int i=0; i<25; i++) {
    println(i);
    if (keyPressed && key==CODED) {
      if (keyCode==DOWN) {
        fill (y, y*0.3, y*0.1);
        y++;
        ellipse (random(0, 1000), random(0, 1000), random (25, 50), random(25, 50));
      }
    }
    if (keyPressed && key==CODED) {
      if (keyCode==UP) {
        fill (x*0.1, x*0.3, x);
        x++;
        ellipse (random(0, 1000), random(0, 1000), random (25, 50), random(25, 50));
      }
    }
    if (keyPressed && key==CODED) {
      if (keyCode==LEFT) {
        fill (x, x, x);
        x++;
        ellipse (random(0, 1000), random(0, 1000), random (25, 50), random(25, 50));
      }
    }
    if (keyPressed && key==CODED) {
      if (keyCode==RIGHT) {
        fill (z, z, z);
        z--;
        ellipse (random(0, 1000), random(0, 1000), random (25, 50), random(25, 50));
      }
    }
    if (mousePressed ==true) {
      fill (125);
      frameRate(60);
      circle (mouseX, mouseY, 75);
    }
  }
}

As for the circle homework, I made it so that I could move it with the up, down, left, and right. 

I will include the code and video of the processing below. 

 

int x = 50;
//x refers to radius
int s = 2;
// increments for shrinking and expanding
int w = 0;
//int for width
int h = 0;
//int for height
void setup() {
  size(600, 600);
  background(360);
  colorMode(HSB);
}
void draw() {
  background(255);
  stroke(x-50, 360, 360);
  strokeWeight(15);
  circle(w+width/2, h+height/2, x);
  if (x > 200 || x < 50) {
    s = -s;
  }
  x = x + s;
  if (keyPressed&&key==CODED) {
    if (keyCode == UP) {
      h--;
    } 
    if (keyCode == DOWN) {
      h++;
    }
    if (keyCode == LEFT) {
      w--;
    }
    if (keyCode == RIGHT) {
      w++;
    }
  }
}

Filed Under: Interaction Lab

Final Project: Preparatory Research and Analysis Blog by Ken Wu

November 12, 2020 by Ken Wu Leave a Comment

Having read the Ernest Edmonds’ Art, Interaction, and Engagement which discussed the different categories of interaction for devices and aspect of interaction, I researched two interactive projects I found interesting being the Monopoly Ultimate Banking Board Game and the Nintendo Game Boy which are from different time periods.

I selected Monopoly Ultimate Banking Board Game as it is a rendition of the old Monopoly Board Game which was a successful board game that appealed to a large audience. This particular rendition has a device that users use throughout the game to keep track of the money of each player, owner of each building, level of the buildings, fines that each player is to take, and bonuses that players receive. It can fulfill the functions of switching property or increasing the level of properties through using a card on the device. Because it has such functions, it makes the experience easier for players as they can focus on the board rather than having to consistently keep track of the levels of the building. I think that because this rendition makes user experience easier, it is successful as their isn’t much that the user has to memorize or think about when playing. I think that this example of a project will inform my work through the criteria of making the experience simpler for the user to deal with. My project will aim to limit the user having to personally keep track of past interaction and moves if that is not my intention. Moreover, this may also inform my project if I decide to create an interactive board game where my digital device should make the board game easier to play not harder. Furthermore, this will also inform my project’s layout if I do a board game where it should have a beginning and end with rules that should make sense for users to interact with. 

I also selected the Nintendo Game Boy which is a old device used for handheld games. I chose this because the technology at this time was limited but still reached out to the audience at the time. This sort of marketability is something I found interesting and wanted to investigate. This is somewhat similar to what I could create for my final project which may be limited for proper presentation as a professional project. Another reason why I chose this project was because I was interested in using a digital interface and controls as my main interaction object in my final project where the Game Boy could inform decisions that I make regarding the design of the project. This is because people are used to such control systems where any difference may misinform their intuition on using a device. I think that this device is successful in that it can import different games to be played and is not restricted to one. This success is what also informs me to create dynamic nature for my product so that it is not limited to one form. For example, the Legend of Zelda can be played on this but so can Pong. Difference of user experience in one device is something that I want to also apply to my interactive device where different experiences can be felt. For example, if I were to create a board game, I may provide two different game boards or two variations of cards that can provide a different experience when playing. 

Game-Boy-FL.jpg

From my previous definition of interaction, it is where an action leads to a reaction that leads to another action from the source. This should be reciprocal where both sources should contribute in the interactive manner. This is also similar to my interaction featured in my midterm exam where the action of a doorbell leads to the reaction of the user and the interaction of the two from the reaction of the user. I think that a successful interaction should also provide a sense of freshness and uniqueness to the experience that should be simplified but interactive which is based from the research I just completed on the two projects. I think that there should be interaction like the dynamic-passive interaction or dynamic-interactive interaction stated by Edmonds which I think is the best form of interactivity. This is because there’s constant changes that occur that are predictable yet still provides a sense of freshness and uniqueness. 

Works Cited

“Monopoly.” Amazon, www.amazon.com/Monopoly-Ultimate-Banking-Board-Game/dp/B01ALHAMTK.

“Nintendo Game Boy.” Wikipedia, en.wikipedia.org/wiki/Game_Boy#/media/File:Game-Boy-FL.jpg.

 

 

Filed Under: Interaction Lab

Midterm Project Individual Reflection by Ken Wu

November 3, 2020 by Ken Wu Leave a Comment

Doorbell for the Deaf by Ken Wu and Cherie Tan, Instructor: Eric Parren

When working on this midterm project, I was influenced by my group project in three ways being user-friendliness, practicality, and purpose. For my group project, it was a helmet that transferred memories and data of an individual to a robot where they could continue to live through the body of a robot. This group project’s purpose was to warn about the implications of cryogenics and the longing for preservation of one’s life for the future as it was performative in nature. When the prompt changed to creating something functional, I considered the impracticality of the memory helmet and wanted to create something that could be used in the real world via the function. Due to this, the purpose of my product was constructed to be something that could be used by people everyday in their life. Our product for the helmet also lacked in being user-friendly as it required more components that weren’t intuitive. From this experience, I wanted to create something that was usable and intuitive to people where it should build upon existing products that are intuitive with a special purpose. 

As our group project was a one time interaction, it lacked economic practicality in the sense that it could not be used more times. Due to this, my understanding and aim of creating interaction is that it must be continuous rather than a one-and-done feature. From this, I think that my definition of interaction has evolved to include the property where input and output should be continuous and not be limited to single usage. Moreover, there should also be an action that is caused as a result of the input and output of a product.

In our project, we created a doorbell for deaf people. My initial inspiration for the specific audience of deaf people is my great-grandmother who has difficulty hearing where one of my childhood memories is being locked out of the house and being unable to contact her and let her open the door. Knowing that deaf people or hearing-impaired individuals lack the ability to hear, we wanted to create signals to them that would let them be alerted from a doorbell. In the market, there are already existing products such as lights to create signals to deaf people. We thought that it would be more practical if the product had to do with the sensation of “touch” or “feel”. We then thought of the notification system to be an input of a doorbell to the output of a vibration that could be felt on the user. This would solve the purpose of notifying the individuals and it built upon preexisting products of watches and doorbells which made the product easier to understand and more user-friendly. As doorbells only have one switch, it becomes intuition to press on it to alert another individual hence the interaction is already systematically engrained in ourselves. Watches or bracelets are also common objects in human life where wearing such a product would not require humans to learn how to use such a product. Using these two existing products, we combined them to create a product for a specialized purpose which is to alert deaf people of visitors. This is mutually beneficial as the individual seeking to approach the deaf person can alert them to let them know that there is someone at the door while it is also beneficial for the deaf person to know when guests arrive.

For the designing of the project, I was in charge of creating it where I wanted it to be minimalistic, clean, and easily understood without users being confused. This meant simplicity for the designing of the doorbell and simplicity in the bracelet. Knowing that Arduino circuits take up space due to the Arduino, battery, breadboard and etc, I tried to hide the inessential objects that would confuse the user so I enclosed it in a box. When designing the box, I measured out every single component within the box so that it represented the height, width, and depth clearly and avoided the box from being too small or too big. This was then 3-d modeled to provide a basic idea of how it would look like. Below are photos of the 3d modeling process.

Firstly, I began with creating a model for the Arduino, power, and breadboard. This was created in different layers and colors that represented the product which allowed me to render later to decide materials. 

 

This was further developed by moving the components and creating a box with a button to represent the doorbell. The individual pieces for cutting would again be created using Rhino and Adobe Illustrator for Laser cutting. 

When creating the bracelet, I wanted to make it wearable where it should be flexible enough for different users to be able to wear it. The design isn’t closed to allow for users to easily wear it. After creating the bracelet, I put it side by side to the boxes that supplied the power for important components to know the size that this product would be (other than the prototypes made with cardboard which will be described later).

When deciding the material that the box should be I experimented with rendering to test out certain colors of the box and whether or not I wanted it to be opaque or transparent. I enjoyed the transparent look of the box which looked more authentic and beautiful as compared to an opaque color masking everything else so I decided to use clear acrylic for the boxes. As for the wristband, I wanted the material to be more flexible to allow for users to wear it the way they like. Being fully designed, I imagined the products to look something like the renderings below. 

For the production section, it was actually complementary to the designing and conception process. When we thought of our product, we already thought of the object of output hence our product revolved around two commonly seen objects. During the user testing session, Cherie was in a recitation before me so she would user test first. I had no class during that time so I also attended. At the time of the session, our product didn’t have a prototype bracelet made yet which confused individuals as to what the product would look like. I received some of this feedback in her session and made the changes during lunch time by creating a prototype that simulated what it would look like in the future. When this was shown, it started to make more sense to the individuals user testing where they would know that they should wear it to receive the output. As our bracelet was huge during user testing, we made changes to the size for the design of the 3d-printed object. 

Honestly, the adaptations made were adjusted when we were cutting the parts of the box and printing the bracelet. There weren’t many design flaws due to 3d modeling before printing and cutting, but the only issue was the size of the bracelet and it not being the result that we wanted. At first the printed bracelet was oversized and hard which was the opposite of what we wanted so I talked to Andy about printing in plastic that could be more flexible for our purposes. I changed the dimensions of the circumference of the wristband as well. Below are the bracelets where the before is seen on the left and after is on the right. 

Our project aligns with the definition of interaction proposed as our input and output aren’t limited to single usage and it creates an action to be taken from the user as a result of the output vibration. While it causes an action to be taken, the action is more so limited which might not allow for interaction to occur on a higher degree, but I think that this is the most practical solution that could be taken and applied. The audience interacted with it according to our planned input output system as the design of the product is simple in nature. We removed anything that could mislead users such as having more buttons, lights, and etc. There were some issues with the transmission process from the transmitter most likely due to the direction that antennas were in, but it overall performed the intended function for the intended purpose. While the range and functionality weren’t the best or showed the product’s potential to the highest degree, it was still a product that showed the applicability to the real world. 

I would improve this product’s transmitter and receiver by buying better products so that it is more stable. The current version of our product lacks the potential that could actually be used in the world right now. The components aren’t made small enough. In the ideal situation, the vibrator, battery, and receiver of the watch should all fit within the square component of the bracelet in a lightweight manner, but due to lack of skill and technology, that isn’t possible at this stage. I think that from this experience of creating a product, I became more aware of the design capabilities with an Arduino in terms of form and more aware of the process of refining a product to be exactly what is wanted. Moreover, I developed more skills in conceptualizing the product and imagining the looks beforehand. 

To conclude, the design process is a long struggle where issues are brought about by lack of skill, consideration, or technology. To fully develop a product to the maximum potential, there must be careful planning beforehand for what IS to be created and what CAN be created. If the planning of IS and CAN is not synonymous, the product fails to achieve the maximum potential which may not be well if presenting to investors of the product. Moreover, for the product, there should be a clear purpose so that one can truly contribute something meaningful to society. In my conversations with Andy during the brainstorming and conceptualizing process, he continually asked me what is the concept and why am I creating this product. He challenged me to think of the design concept beforehand and research products like the one I imagined. Having rejected a couple of my design ideas, I became more aware of the importance of concept in design and the originality of concept where design is not for the sake of creating a project. It is the creation of a concept. 

Below will be a video of how the product works, poster to the audience, and the code.

 

//Transmitter

#include <VirtualWire.h>

//Grove - 315(433) RF link kit Demo v1.0
//by :http://www.seeedstudio.com/
//connect the sent module to D2 to use
#include <VirtualWire.h>

int RF_TX_PIN = 2;
const int buttonPin = 3;
int buttonState = 0;


void setup()
{
  vw_set_tx_pin(RF_TX_PIN); // Setup transmit pin
  vw_setup(2000); // Transmission speed in bits per second.

  pinMode(buttonPin, INPUT);

}

void loop()
{

  buttonState = digitalRead(buttonPin);

  if (buttonState) {


    const char *msg = "hello";
    vw_send((uint8_t *)msg, strlen(msg));  // Send 'hello' every 400ms.
    delay(400);
  }


}




//Receiver

//Grove - 315(433) RF link kit Demo v1.0
//by :http://www.seeedstudio.com/
//connect the receive module to D2 to use ..
#include <VirtualWire.h>

int RF_RX_PIN = 2;
int v=9;


void setup()
{
  Serial.begin(9600);
  Serial.println("setup");
  pinMode(9 ,OUTPUT );
  vw_set_rx_pin(RF_RX_PIN);  // Setup receive pin.
  vw_setup(2000); // Transmission speed in bits per second.
  vw_rx_start(); // Start the PLL receiver.
}

void loop()
{
  uint8_t buf[VW_MAX_MESSAGE_LEN];
  uint8_t buflen = VW_MAX_MESSAGE_LEN;
  if (vw_get_message(buf, &buflen)) // non-blocking I/O
  {
    int i;
    // Message with a good checksum received, dump HEX
    Serial.print("Got: ");
    for (i = 0; i < buflen; ++i)
    {
      Serial.print(buf[i], HEX);
      Serial.print(" ");
      //Serial.print(buf[i]);
    }
    Serial.println("");
  }

  vibrate();
}

    //vibrate
    void vibrate(){
       digitalWrite(v, HIGH);
        delay(2000);
        //turn transistor ON
        digitalWrite(v, LOW);
        delay(500);
        digitalWrite(v, HIGH);
        delay(1000);
        //turn transistor ON
        digitalWrite(v, LOW);
        delay(500);
        //turn transistor OFF
        digitalWrite(v, HIGH);
        delay(1000);
        //turn transistor ON
        digitalWrite(v, LOW);
        delay(500);
      }

Filed Under: Interaction Lab

  • Page 1
  • Page 2
  • Go to Next Page »

Primary Sidebar

Copyright © 2025 · News Pro on Genesis Framework · WordPress · Log in