Final Project Documentation: Hide Nowhere

Date: 17 December 2018

Instructor: Eric&Young

Partner: Yanru Zhu

 

Hide Nowhere

( which indicates that there is no possibility to win this game)

 

CONCEPTION AND DESIGN:

For our project, we focus on personal information and aim to create an interactive game to stress the ubiquitous surveillance around people, and to remind people of the importance of protecting their privacy.

For the game part, before we actually started our project, we first explained our idea to friends and IMA fellows to ask for their opinions. Based on their suggestions, we improved our plan at the first beginning. We did the UI design to provide the players a better experience. During the process, we invited friends to try the game. And given their confusion on the game, we added the instruction page before the game start, and further clarified it after the presentation. Moreover, we offer a specific background story for the game and asked the players to first input their preferred name, so that we can use it to name the person in the game as if it is the player whose information is leaked. It only increases the engagement, but also shows our goal of the game—to emphasize the importance of personal privacy and call for people’s attention of its protection.

We changed our plan of Arduino part several times. Initially, we intended to use the leap motion, and control the person in the game through the movement of the hand. Then, we were suggested to use the webcam and control by detecting a certain color. Finally, we planned to create a three-floor apartment and displays the different outcomes in the game. Specifically, there is a person hanging by a string, each time player loses the game, the length of the string will increase and lead the person to a different floor, which indicates the increased surveillance level. We also printed several cameras and set the last floor as a room full of cameras, which is connected to a part of our goal—to stress the ubiquitous surveillance around people. And overall, we believe the vivid scene can reinforce the player’s attention to the leak of personal information.

 

FABRICATION AND PRODUCTION:

We spent most of the time on Arduino part, and to meet our original plan, we tried servo motor but failed to make it stop for a while, then begin to work. Then, we tried motor, but it moved so quickly, which is hard for us to calculate its time. Three hours before the presentation, we compromised and changed the plan to light the LED on each floor. However, this change makes the whole hardware part easily ignored. There are many improvements we made after the user test. For example, we changed the color of the person in the game part, so players can recognize it. And we beatified the hardware part. And in the IMA show, people suggested us to separate the control of the speed and direction by using one more microphone. I think this will enable one more player to participate in this game, and add more fun.

 

CONCLUSIONS:

For our project, we focus on personal information and aim to create an interactive game to stress the ubiquitous surveillance around people, and to remind people of the importance of protecting their privacy. It encourages players to engage with their voice. Through this interesting input, players can interact with the computer, which quite matches my understanding of interaction—a meaningful exchange of information between two and more objects which includes input, output, and process three parts. But for the hardware part, the LED just interact with the computer by receiving the signal and releasing the light. It does not interact with people, which made it easily be ignored. The value I learned is to insistence and always prepare plan BCD… Try as many ways as I can to achieve the effect, and prepare plan BCD in case the original plan does not work.

I really love the concept of our project and believe our project create an interesting way to remind people of this issue. We focus on the information privacy issue and it is really important and deserves everyone’s attention. To stress the issue, we offer the specific situation (the unknown phone call due to the leak of the phone number, the profile in a strange dating website due to the leak of general personal information…). Moreover, the ending that no one can win this game further emphasize that in this information era, it is impossible for people to perfectly avoid the leak, all they can do is only pay extra attention and decrease its possibility.

Special thanks to my partner Yanru, all the IMA professors and fellows. Thank for your generous help and suggestions. I had so much fun with you in IMA, on the 8th floor. This course really lit up my semester.

Thank you. 

 

#Appendix 1:The design of the game and Arduino part

 

#Appendix 2: Photos of the user testing

//Processing
//Part 1
float a =  2*PI;
float b =  0;
float x = 0.001 ; //speed
float n = 0.05; //arc kuandu
boolean death = false;

float[] colors = new float[width*height];

int deathTime = 0;

int conditionb = 1;
int conditionc = 1;

int startTimeA, startTimeB, startTimeC;
int endTimeA, endTimeB, endTimeC;
float timeA, timeB, timeC;
float totalTime;

int timeCondA =1;
int timeCondB =1;
int timeCondC =1;

int ranTimeCon = 1;
int ranTime1, ranTime2;

boolean gameStart = false;

PImage beginP;
PImage endP;
PImage gameSS;
PImage player;
PImage notice1;
PImage notice2;
PImage insp1;
PImage insp2;
PImage insp3;

boolean clockwise = true;
int directionTimer = 0;
float directionFlipTime = random(500, 2000);

boolean ins1 = true;
boolean ins2 = true;
boolean ins3 = true;

// sound part
import processing.sound.*;

//noiseLevel = 100;  
int env = 40;

AudioIn input;
Amplitude amp;
 
float volume = 0;
float prevVolume = 0;
float basicV = 0;

float ballXX = 800;
float ballYY = 400;

int hdfw = 200;//huodongbanjin

float s = PI;

boolean ballClockWise = true;


//textbox
import controlP5.*;
ControlP5 cp5;
String saved = "";

PFont f;


//send data
// This code sends one value from Processing to Arduino 
import processing.serial.*;
Serial myPort;
int valueFromArduino;


void setup() {
  //size(1500, 1200); 
  //pixelDensity(displayDensity());
  fullScreen();
//  size(1920,1080);
  //size(1440, 900);
  ellipseMode(CENTER);
  //frameRate(240);
  rectMode(CENTER);
  textAlign(CENTER);
  beginP = loadImage("hidenowhere.png");
  f = createFont("Helvetica neue", 25);
  endP = loadImage("ending.png");
  gameSS = loadImage("gameSS.png");
  player = loadImage("player.png");
  notice1 = loadImage("notice1.png");
  notice2 = loadImage("notice2.png");
  insp1 = loadImage("ins1.png");
  insp2 = loadImage("ins2.png");
  insp3 = loadImage("ins3.png");
  //sound part
  input = new AudioIn(this, 0);
  input.start();
  amp = new Amplitude(this);
  amp.input(input);
  basicV = amp.analyze()*100+env;

  //textbox
  cp5 = new ControlP5(this);
  cp5.addTextfield("PlayerName").setPosition(761, 528).setSize(300, 60).setAutoClear(false);
  cp5.addBang("Start").setPosition(761, 633).setSize(300, 60);
  //send data
  printArray(Serial.list());
  myPort = new Serial(this, Serial.list()[3], 9600);
}

void draw() {
  //println(mouseX, mouseY);
  //sound
  volume = amp.analyze()*100 - basicV;
  if (volume>0) {
    println(volume);
  }

  if (gameStart == false) {
    image(beginP, 0, 0);
  } else {
    if (deathTime == 0) {
      if (ins1) {
        image(insp1, 0, 0); 
        if (keyPressed) {
          if (key == 'a' || key == 'A') {
            ins1 = false;
          }
        }
      }
      if ((ins1 ==false) &&(ins2 == true) ) {
        image(insp2, 0, 0);
        if (keyPressed) {
          if (key == 's' || key == 'S') {
            ins2 = false;
          }
        }
      }
      if ((ins1 ==false) &&(ins2 == false) &&(ins3 == true)) {
        image(insp3, 0, 0);
        if (keyPressed) {
          if (key == 'd' || key == 'D') {
            ins3 = false;
          }
        }
      }


      if ((ins1 ==false) &&(ins2 == false) &&(ins3 == false)) {
        //Start Counting
        image(gameSS, 0, 0);

        if (timeCondA == 1) {
          startTimeA = millis();
          timeCondA = 2;
        }

        if (timeCondA == 2) {    

          cycle();
          if (death == true) {
            background(70);
            deathTime = 1;
            directionTimer = millis();
            s=PI;
            a =  2*PI;
            b =  0;
            x = 0.001 ; //speed
            n = 0.05; //arc kuandu
            endTimeA = millis();
            timeA = (endTimeA - startTimeA);
            image(notice1, 0, 0);
            myPort.write('1');
          }
          //blinking
          int elapsedTimeA = abs(startTimeA - millis());
          if (elapsedTimeA < 1000) {
            if (elapsedTimeA % 200 < 100) {
              ballXX = hdfw*cos(s)+width/2;
              ballYY = hdfw*sin(s)+height/2;
              fill(255, 80, 80);
              imageMode(CENTER);
              image(player, ballXX, ballYY);
              imageMode(CORNER);
            }
            s = PI;
            a = 0;
          }
        }
      }
    }

    // the second round
    if (deathTime == 1) {
      if (conditionb == 1) {
        death = false;
        noStroke();
        fill(220, 220, 220);
        ellipse(1327, 429, 50, 50);
        if (mouseButton == LEFT&&dist(1327, 429, mouseX, mouseY)<71) {
          background(70);
          conditionb = 2;
        }
      }

      if (conditionb == 2) {
        if (timeCondB == 1) {
          startTimeB = millis(); 
          timeCondB = 2;
        }
        if (timeCondB == 2) {
          cycle();
          if (death == true) {
            background(70);
            deathTime = 2;
            //death=false;
            directionTimer = millis();
            s=PI;
            a =  2*PI;
            b =  0;
            x = 0.001 ; //speed
            n = 0.05; //arc kuandu
            endTimeB = millis();
            timeB = endTimeB - startTimeB;
            myPort.write('2');
          }
          //blinking
          int elapsedTimeB = abs(startTimeB - millis());
          if (elapsedTimeB < 1000) {
            if (elapsedTimeB % 200 < 100) {
              ballXX = hdfw*cos(s)+width/2;
              ballYY = hdfw*sin(s)+height/2;
              imageMode(CENTER);
              image(player, ballXX, ballYY);
              imageMode(CORNER);
            }
            s = PI;
            a = 0;
          }
        }
      }
    }



    //the third round
    if (deathTime == 2) {
      if (conditionc == 1) {
        background(70);
        image(notice2, 0, 0);
        fill(0);
        textFont(f);
        text(saved, 1010, 279);
        death = false;
        if (mouseButton == LEFT&&dist(1298, 727, mouseX, mouseY)<30) {
          background(70);
          conditionc = 2;
        }
      }
      if (conditionc == 2) {
        if (timeCondC == 1) {
          startTimeC = millis(); 
          timeCondC = 2;
          s=PI;
        }
        if (timeCondC == 2) {
          cycle();
          if (death == true) {
            deathTime = 3;
            background(70);
            endTimeC = millis();
            timeC = endTimeC - startTimeC;
            myPort.write('3');
          }
          //blinking
          int elapsedTimeC = abs(startTimeC - millis());
          if (elapsedTimeC < 1000) {
            if (elapsedTimeC % 200 < 100) {
              ballXX = hdfw*cos(s)+width/2;
              ballYY = hdfw*sin(s)+height/2;
              imageMode(CENTER);
              image(player, ballXX, ballYY);
              imageMode(CORNER);
            }
            s = PI;
            a = 0;
          }
        }
      }
    }

    //final display
    if (deathTime == 3) {
      image(endP, 0, 0);
      totalTime = timeA+timeB+timeC;
      textSize(20);
      fill(0);
      textFont(f);
      text(saved, 755, 340);
      textSize(50);
      fill(255);
      text(totalTime/1000, 662, 640);
    }
  }

  fill(255);
}


void keyPressed() {
  if (key == 32) {
    ballClockWise = !ballClockWise;
  }
}

void Start() {
  saved = cp5.get(Textfield.class, "PlayerName").getText();
  cp5.dispose();
  gameStart = true;
}

//Part 2
void cycle() {
  image(gameSS, 0, 0);
  textFont(f);
  textSize(25);
  if (deathTime == 0) {
    text("You've survived "+(millis()-startTimeA)/1000+" Seconds", 0.85*width, 0.05*height);
  }
  if (deathTime == 1) {
    text("You've survived "+(millis()-startTimeB+timeA)/1000+" Seconds", 0.85*width, 0.05*height);
  }
  if (deathTime == 2) {
    text("You've survived "+(millis()-startTimeC+timeA+timeB)/1000+" Seconds", 0.85*width, 0.05*height);
  }
  //ray
  fill(150, 0, 0, 90); 

  //game difficulty will rising

  if (deathTime == 0) {
    moveOn();
    shapeAndDetect();
    player();
  }



  if (deathTime == 1) {
    if (millis() - directionTimer > directionFlipTime) {
      if (random(1) < 0.5) {
        clockwise = true;
      } else {
        clockwise = false;
      }
      directionTimer = millis();
      directionFlipTime = random(500, 2000);
    }

    //toTurn = int(random(10));
    if (clockwise) {
      moveOn();
      shapeAndDetect();
      player();
    } else {
      turnBack();
      shapeAndDetect();
      player();
    }
  }





  if (deathTime == 2) {
    if (millis() - directionTimer > directionFlipTime) {
      if (random(1) < 0.5) {
        clockwise = true;
      } else {
        clockwise = false;
      }
      directionTimer = millis();
      directionFlipTime = random(200, 2000);
    }

    //toTurn = int(random(10));
    if (clockwise) {
      moveOn();
      shapeAndDetect();
      player();
    } else {
      turnBack();
      shapeAndDetect();
      player();
    }
  }
}
//Part 3


// the player
void player() {
  //sound
  prevVolume = volume;
  volume = amp.analyze()*200 - basicV;
  if (volume>0) {
    if (ballClockWise  == true) {

      s = s+0.001*volume*PI;
      ballXX = hdfw*cos(s)+width/2;
      ballYY = hdfw*sin(s)+height/2;
      fill(255, 80, 80);
      ellipse(ballXX, ballYY, 50, 50);
      imageMode(CENTER);
      image(player, ballXX, ballYY);
      imageMode(CORNER);
    } else {

      s = s-0.001*volume*PI;
      ballXX = hdfw*cos(s)+width/2;
      ballYY = hdfw*sin(s)+height/2;
      fill(80, 80, 80);
      ellipse(ballXX, ballYY, 50, 50);
      imageMode(CENTER);
      image(player, ballXX, ballYY);
      imageMode(CORNER);
    }
  }
}




void fasterAndLarger() {
  int moveOrNot = int(random(3));
  if (moveOrNot != 0) {
    //faster/slower!!!!!!
    float fate = int(random(5));
    if (fate == 1) {
      x = x + 0.00003;
      n = n + 0.0005;
    }
    if (fate == 2) {
      x = x + 0.00006;
      n = n + 0.001;
    }
    if (fate == 3) {
      x = x + 0.00009;
      n = n + 0.0015;
    }
    if (fate == 4) {
      x = x - 0.00006;
      n = n - 0.001;
    }
    if (fate == 5) {
      x = x - 0.00009;
      n = n - 0.0001;
    }
    if (fate == 0) {
      x = x - 0.00003;
      n = n - 0.0005;
    }
  }
}


void turnBack() {
  a = a - x*PI;
  b = a - n*PI;
}

void moveOn() {
  a = a + x*PI;
  b = a + n*PI;
}


void shapeAndDetect() {

  float rrr = 2.5*width;
  float line1X = (rrr) * cos(a);
  float line1Y = (rrr) * sin(a);

  float line2X = (rrr) * cos(b);
  float line2Y = (rrr) * sin(b);

  beginShape();
  vertex(width/2, height/2);
  vertex(line1X, line1Y);
  vertex(line2X, line2Y);
  endShape(CLOSE);

  if (circleLineIntersect(width/2, height/2, line1X, line1Y, ballXX, ballYY, 25) == true) {
    death = true;
  }
  if (circleLineIntersect(width/2, height/2, line2X, line2Y, ballXX, ballYY, 25) == true) {
    death = true;
  }
  fasterAndLarger();
}




// Code adapted from Paul Bourke:
// http://local.wasp.uwa.edu.au/~pbourke/geometry/sphereline/raysphere.c
boolean circleLineIntersect(float x1, float y1, float x2, float y2, float cx, float cy, float cr ) {
  float dx = x2 - x1;
  float dy = y2 - y1;
  float a = dx * dx + dy * dy;
  float b = 2 * (dx * (x1 - cx) + dy * (y1 - cy));
  float c = cx * cx + cy * cy;
  c += x1 * x1 + y1 * y1;
  c -= 2 * (cx * x1 + cy * y1);
  c -= cr * cr;
  float bb4ac = b * b - 4 * a * c;

  //println(bb4ac);

  if (bb4ac < 0) {  // Not intersecting
    return false;
  } else {

    float mu = (-b + sqrt( b*b - 4*a*c )) / (2*a);
    float ix1 = x1 + mu*(dx);
    float iy1 = y1 + mu*(dy);
    mu = (-b - sqrt(b*b - 4*a*c )) / (2*a);
    float ix2 = x1 + mu*(dx);
    float iy2 = y1 + mu*(dy);

    // The intersection points
    //ellipse(ix1, iy1, 10, 10);
    //ellipse(ix2, iy2, 10, 10);

    float testX;
    float testY;
    // Figure out which point is closer to the circle
    if (dist(x1, y1, cx, cy) < dist(x2, y2, cx, cy)) {
      testX = x2;
      testY = y2;
    } else {
      testX = x1;
      testY = y1;
    }

    if (dist(testX, testY, ix1, iy1) < dist(x1, y1, x2, y2) || dist(testX, testY, ix2, iy2) < dist(x1, y1, x2, y2)) {
      return true;
    } else {
      return false;
    }
  }
}
//Arduino
// IMA NYU Shanghai
// Interaction Lab
// This code receives one value from Processing to Arduino
//
////char valueFromProcessing = '1';
char valueFromProcessing;

void setup() {
  Serial.begin(9600);
  pinMode(13, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(11, OUTPUT);   
}


void loop() {
  //   to receive a value from Processing
  while (Serial.available()) {
    valueFromProcessing = Serial.read();
  }

  if (valueFromProcessing == '1') {

    digitalWrite(12, HIGH);
    digitalWrite(11, LOW);
    digitalWrite(13, LOW);
  }

  if (valueFromProcessing == '2') {

    digitalWrite(11, HIGH);
    digitalWrite(12, LOW);
    digitalWrite(13, LOW);
  }
  if (valueFromProcessing == '3') {


    digitalWrite(13, HIGH);
    digitalWrite(11, LOW);
    digitalWrite(12, LOW);
  }

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

}

Recitation 10: Make a Media Controller

Date: 5 December 2018

Instructor: Eric&Young

 

Goal: To create a Processing sketch that controls media (images or video) by manipulating that media’s attributes using a physical controller made with Arduino.

During the recitation, I used the potentiometer to control the color of the shadow of  Shanghai in Processing. (It exists on my computer a long time ago. And I have no idea about its sources.)

Reflection

The reading Computer Vision for Artist and Designers introduces how the computer vision system helps the art and the design more interactive and provides plenty of examples. With the help of the computer vision system, art can be more interesting and enjoyable. Thanks to this reading, I gained the idea of how to design the hardware part of our final project, which my partner and I had struggled for a long time. Not to passively receiving the input and responding with simple figures anymore, I intend to make the hardware part more active and can display the outcomes of the game. It may sound abstract now, but everything will be clear next week.

//Arduino

int Pot = A1;

void setup() {
  Serial.begin(9600);
}
void loop() {
  int valOne = analogRead(Pot);
  Serial.write (valOne);
  delay(10);
}

//Processing

import processing.serial.*;
Serial myPort;
int valueFromArduino;
PImage img;

void setup() {
  size(600, 716);
  img = loadImage("SH.jpg");
  colorMode(HSB, 100);
  printArray(Serial.list());
  myPort = new Serial(this, Serial.list()[ 3 ], 9600);
}

void draw() {
  image(img, 0, 0, width, height);
  tint(valueFromArduino, 120, 255, 150);
  image(img, 200, 0);
  
    while ( myPort.available() > 0) {
    valueFromArduino = myPort.read();
  }
  println(valueFromArduino);
}

Recitation 9: Serial Communication

Date: November 21, 2018

Instructor: Eric & Young

 

This recitation is quite useful. Although I concentrated on the lecture, I still had difficulties to achieve these two process after class. During this recitation, I gained more hands-on experiences and finally knew how to transfer the information between Arduino and Processing.  I finished the first exercise quickly and spent more of my time on the second one.

 

The video for the first exercise:

draw-exer1

 

The picture for the second exercise:

 

 

//exercise 1
//arduino


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

void loop() {
  int sensor1 = analogRead(A0);
  int sensor2 = analogRead(A1);
  //int sensor3 = analogRead(A2);

  // keep this format
  Serial.print(sensor1);
  Serial.print(",");  // put comma between sensor values
  Serial.print(sensor2);
  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 1
//processing
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 **/

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

void draw() {
  updateSerial();
float posX=map(sensorValues[0],0,1023,0,500);
float posY=map(sensorValues[1],0,1023,0,500);
noStroke();
fill(255);
ellipse(posX,posY,30,30);
print(posX);
print(",");
print(posY);
println();
}



void setupSerial() {
  printArray(Serial.list());
  myPort = new Serial(this, Serial.list()[3], 9600);

  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]);
       }
      }
    }
  }
  
}
//exercise 2
//arduino

char valueFromProcessing;
void setup() {
  Serial.begin(9600);
  pinMode(7, OUTPUT);

}

void loop() {
   while (Serial.available()) {
    valueFromProcessing = Serial.read();
  }
  
  if (valueFromProcessing == 'H') {
     // turn off tone function for pin 8:
  noTone(8);
  // play a note on pin 6 for 200 ms:
  tone(7, 440, 200);
  delay(10);
  } if (valueFromProcessing == 'L') {
     // turn off tone function for pin 6:
  noTone(6);
  // play a note on pin 7 for 500 ms:
  tone(7, 494, 500);
  delay(10);
  }if (valueFromProcessing == 'P') {
     // turn off tone function for pin 7:
  noTone(7);
  // play a note on pin 8 for 300 ms:
  tone(7, 523, 300);
  delay(10);
    // something esle
  }
  // too fast communication might cause some latency in Processing
  // this delay resolves the issue.
  delay(10);
  
  // turn off tone function for pin 8:
//  noTone(8);
//  // play a note on pin 6 for 200 ms:
//  tone(7, 440, 200);
//  delay(200);
//
//  // turn off tone function for pin 6:
//  noTone(6);
//  // play a note on pin 7 for 500 ms:
//  tone(7, 494, 500);
//  delay(500);

//  // turn off tone function for pin 7:
//  noTone(7);
//  // play a note on pin 8 for 300 ms:
//  tone(7, 523, 300);
//  delay(300);
}

//exercise 2
//processing

import processing.serial.*;

Serial myPort;
int valueFromArduino;


void setup() {
  size(500, 500);
  background(0);

  printArray(Serial.list());
  // this prints out the list of all available serial ports on your computer.
  
  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.
}


void draw() {
  // to send a value to the Arduino
  if (pmouseX<width/3) {

    myPort.write('H');
  }   if (pmouseX<width/2 &&  pmouseX>width/3) {
    myPort.write('L');
   
  }  if (pmouseX>width/2){
    myPort.write('P');
  
}
}

Final Project Proposal: Hide Nowhere

  • Date: November 16, 2018
  • Instructor: Eric & Young

Hide Nowhere

 

  • Project Statement of Purpose 

It’s a best of times when people enjoy convenient lives thanks to the rapid improvement of technology. It’s a worst of times when people live with no privacy due to the rapid improvement of technology and even a small data can expose them to the public. This contradictoriness is what we want to convey through our project. Namely, we want to create an interactive game to show the contradictoriness of the technology, to stress the ubiquitous surveillance around people, and to remind people of the importance of protecting their privacy.

 

  • Project Plan

We intend to create an interactive game with Arduino, Processing and leap motion. We create the “Shanghai Tower” in the processing to stand for the achievement of the technology, and it will produce the ray to detect people, which stands for the ubiquitous surveillance. The player should control the little men to escape all the surveillance with certain gestures which can be detected by the leap motion.

There is no way to win the game since as the time goes by, the scale of surveillance will increase to cover all the map, which stands for the ubiquitous surveillance. And it is also the reason why the project is named “Hide Nowhere”.

 

Our weekly plan is:

week 12: Processing background building + Game Code

week 13: Game Code + Arduino leap motion

week 14: Arduino servo motor + adjustment

 

  • Context and Significance *

The project that inspired me is called Soul link which is an Arduino Marionette controlled by Leap Motion. This project changes the way of participation. Instead of controlling by pressing the key, it requires people to move their fingers, which provides a better engagement with the player.

As for my definition of interaction, I believe interaction is a meaningful exchange of information between two and more objects which includes input, output, and process three parts. So, my project first should include three parts. People’s gesture is the input, and the movement of the little man in the game can be the output. And it includes the information change between the people and the machine. Besides these mandatory parts, my project has a significant meaning, which is to show the contradictoriness of the technology, to stress the ubiquitous surveillance around people, and to remind people the importance of protecting their privacy. I think our idea is creative, the game is engaging, and the meaning we want to express is thought-provoking.

 

 

 

 

 

Recitation 8: Final Project Process

Instructor: Eric&Young

Date: November 8, 2018

 

In my previous blog post, my interpretation of interaction was influenced by the reading materials and I wrote: “interaction includes input, process, and output, and is a process that two or more objects affect one another.” My two projects were designed based on this interpretation.  My first group project is iCloud, where the input is various such as the environmental indexes, the figure of the people, etc. And after a series of process, iClous can change its size and shape or display some indexes of the environment to deliver some output. These data help iCloud to better interact with people, environment and other iCloud to offer a better experience for its users.

Based on the initial definition and your experience developing and executing your midterm project, how has your definition of interaction evolved? Be as specific as possible.

Although the interaction of iCloud quite matches my definition, it doesn’t require enough direct interactions to give the users a sense that they are “playing with” this equipment. So, I made some improvements in my midterm project Glowide. Based on the previous definition,  the input is the distance between the object and sensor, after a series of process, Glowdie can change its color to show the output. Moreover, it involves many interactions with people. The input requires the people to do some gestures or put on the hood, which encourages people to engage with the project.

The two projects I choose are The Flow of Qi and Cloud (CAITLIND R.C. BROWN & WAYNE GARRETT).

The Flow of Qi lines up with my definition. It takes the users’ depth and length of the breath as input and displays the calligraphy as output. The whole process is that people create the calligraphy through their breath. In this project, every participant matters. Every participant, every input they give will directly affect the final calligraphy. It’s quite fantastic and interactive.

However, in the other project Cloud, although it still includes the input (people’s movements like plugging), and output (light on/off), it requires more people to engage and a single movement doesn’t affect the whole project much, which is not as similar as my definition

As for my definition of interaction, I would say it is not my initial definition as more. Namely, it is not a single combination of input and output, but a meaningful information-process. So, my new definition of interaction will be interaction is a meaningful exchange of information between two and more objects which includes input, output, and process three parts.

Recitation 7: Processing Animation

Date: 6 November 2018

Instructor: Eric&Young

 

Introduction

Goal: To create an interactive animation in Processing.

 

Recitation:

I redrew my previous image for this recitation with the new method ( beginShape() and endShape()) and realized it is extremely inconvenient to draw irregular shapes in Processing. Especially when I tended to fill the irregular shape with the lines and points, the only way I come up with is to use the for loop, and I need to call more than fifteen for loops. The same effect can be achieved easily in either PS or Ai.

[Left: Previous , Right: Re-did]

 

As for the animation, I want to
  • Change the background color when the arbitrary key is pressed
  • Hide/Show the image with certain keys

Problem:

I made the first effect easily and it looks as if the background is blinking if the key is pressed for a long time.

However, when it comes to the second effect, a problem occurs.

I wanted to cover the previous image by adding an extra image on it. But when I pressed the key, the new sqaure did not show up as I expected. Instead, it blinks as the first effect.

 

 

With the help of Young, I realized it is because I worte code of the sqaure in the keyPress function, and it is teperorary. So, I removed these squares into draw part and made it.

 

Homework:

Step 1:

 

Step 2:

Final version:

void setup() {

  size(600, 600);
  background(255);
}

void draw() {

  fill(#235F9D);
  stroke(255);
  rect(210, 15, 180, 180);//2-1
  rect(405, 15, 180, 180);//3-1
  rect(15, 210, 180, 180);//2-3
  rect(15, 405, 180, 180);//1-3
  rect(405, 210, 180, 180);//3-2
  rect(210, 405, 180, 180);//2-3
  //bule ones

  if (keyPressed) {
    fill(random(0, 255), random(0, 255), random(0, 255));
  }
  //stroke(255);
  rect(15, 15, 180, 180);
  //blue
  fill(#DE7B2F);
  noStroke();
  beginShape();
  vertex(15, 105);
  vertex(28, 105);
  vertex(39, 97);
  vertex(42, 105);
  vertex(65, 90);
  vertex(72, 95);
  vertex(82, 80);
  vertex(95, 70);
  vertex(107, 80);
  vertex(112, 72);
  vertex(118, 79);
  vertex(195, 60);
  vertex(195, 195);
  vertex(15, 195);
  endShape(CLOSE);
  noStroke();
  //1-1
  //strokeWeight(5);
  stroke(#DE7B2F);
  fill(#DE7B2F, 150);
  beginShape();
  vertex(15, 300);
  vertex(28, 300);
  vertex(39, 292);
  vertex(42, 285+15);
  vertex(65, 270+15);
  vertex(72, 290);
  vertex(82, 275);
  vertex(95, 265);
  vertex(107, 275);
  vertex(112, 267);
  vertex(118, 274);
  vertex(195, 255);
  vertex(195, 390);
  vertex(15, 390);
  endShape(CLOSE);
  noStroke();
  //1-2
  stroke(#DE7B2F);
  fill(#DE7B2F, 80);
  beginShape();
  vertex(15, 495);
  vertex(28, 495);
  vertex(39, 484);
  vertex(42, 285+210);
  vertex(65, 270+210);
  vertex(72, 290+195);
  vertex(82, 275+195);
  vertex(95, 265+195);
  vertex(107, 275+195);
  vertex(112, 267+195);
  vertex(118, 274+195);
  vertex(195, 255+195);
  vertex(195, 390+195);
  vertex(15, 390+195);
  endShape(CLOSE);
  noStroke();
  //1-3
  stroke(#DE7B2F);
  beginShape();
  vertex(210, 60);
  vertex(230, 60);
  vertex(250, 55);
  vertex(270, 59);
  vertex(300, 42);
  vertex(310, 35);
  vertex(319, 38);
  vertex(325, 38);
  vertex(335, 72);
  vertex(370, 120);
  vertex(378, 135);
  vertex(390, 135);
  vertex(390, 195);
  vertex(210, 195);
  vertex(210, 60);
  endShape();
  ////2-1

  fill(#235F9D);
  if (keyPressed) {
    fill(random(0, 255), random(0, 255), random(0, 255));
  }
  stroke(255);
  rect(210, 210, 180, 180);
  fill(#DE7B2F);
  noStroke();
  beginShape();
  vertex(210, 255);
  vertex(230, 255);
  vertex(250, 250);
  vertex(270, 254);
  vertex(300, 237);
  vertex(310, 230);
  vertex(319, 233);
  vertex(325, 233);
  vertex(335, 267);
  vertex(370, 315);
  vertex(378, 330);
  vertex(390, 330);
  vertex(390, 390);
  vertex(210, 390);
  endShape(CLOSE);
  ////2-2
  fill(#DE7B2F, 150);
  stroke(#DE7B2F);
  beginShape();
  vertex(210, 255+195);
  vertex(230, 255+195);
  vertex(250, 250+195);
  vertex(270, 254+195);
  vertex(300, 237+195);
  vertex(310, 230+195);
  vertex(319, 233+195);
  vertex(325, 233+195);
  vertex(335, 267+195);
  vertex(370, 315+195);
  vertex(378, 330+195);
  vertex(390, 330+195);
  vertex(390, 390+195);
  vertex(210, 390+195);
  endShape(CLOSE);
  //2-3
  stroke(#DE7B2F);
  fill(#DE7B2F, 150);
  beginShape();
  vertex(405, 135);
  vertex(480, 129);
  vertex(500, 155);
  vertex(520, 150);
  vertex(535, 160);
  vertex(585, 162);
  ;
  vertex(585, 195);
  vertex(405, 195);
  endShape(CLOSE);
  //3-1stroke(#DE7B2F);
  fill(#DE7B2F, 80);
  beginShape();
  vertex(405, 135+195);
  vertex(480, 129+195);
  vertex(500, 155+195);
  vertex(520, 150+195);
  vertex(535, 160+195);
  vertex(585, 162+195);
  vertex(585, 195+195);
  vertex(405, 195+195);
  endShape(CLOSE);
  //3-1

  fill(#235F9D);
  if (keyPressed) {
    fill(random(0, 255), random(0, 255), random(0, 255));
  }
  stroke(255);
  rect(405, 405, 180, 180);
  fill(#DE7B2F);
  noStroke();
  beginShape();
  vertex(405, 525);
  vertex(480, 519);
  vertex(500, 545);
  vertex(520, 540);
  vertex(535, 550);
  vertex(585, 552);
  ;
  vertex(585, 585);
  vertex(405, 585);
  endShape(CLOSE);
  //3-3

  if (a == true) {
    fill(255);
    rect(210, 15, 200, 200);
    rect(15, 405, 200, 200);
    rect(405, 210, 200, 200);//2-3
  }
  if (b==true){
    fill(255);
    rect(405, 15, 200, 200);
    rect(15, 210, 200, 200);
    rect(210, 405, 200, 200);//3-2
  }
  if (c==true){
    fill(255);
    rect(210, 15, 200, 200);
    rect(15, 405, 200, 200);
    rect(405, 15, 200, 200);
    rect(15, 210, 200, 200);
    rect(405, 210, 200, 200);
    rect(210, 405, 200, 200);
  }
}

boolean a = false;
boolean b = false;
boolean c = false;

void keyPressed() {
  
  if (key == 'a' || key == 'A') {
    a = true;
  } 
  else if (key == 'q' || key == 'Q') {
    a = false;
  } 
  else if (key == 's' || key == 'S') {
    b = true;
  } 
  else if (key == 'w' || key == 'W') {
    b =false;
  } 
  else if (key == 'd' || key == 'D') {
    c = true;
  } 
  else if (key == 'e' || key == 'E') {
    c = false; 
}
}

Midterm Project: Glowdie

Date: 30 October 2018

Instructor: Eric&Young

Partner: Eden Wu

 

Project Name: Glowdie (which is the combination of the Glowing and Hoodie)

 

Project Statement of Purpose:

Protect the sharing bike bikers when they driving in the dark by making them recognized. 

Sharing bike is nowadays everywhere in China and greatly changes people’s ways of transportation. However, the absence of the lighting equipment fails to guarantee people’s safety when they bike in the dark since, in most of the cases in China, there are few bikeways so that the bikers have to share the road with the drivers.

Given the costly operating costs and implementation difficulty, it’s hard to add light equipment to sharing bikes. So, we intend to improve from the user’s side. After researching, we found a special arm signature for the bikers, they will raise their arm when turning the bike. Besides improving bikers’ safety, we also want our product to be easy-to-use, portable and low-cost. Inspired by the Neon and Tron suit, we decided to design a glowing hoodie that can make people easily-recognized when riding in the dark. That glowing hoodie is our Glowdie. It detects biker’s arm movement as input to control the LED arrow on each side and show the direction the bike will turn to.

 

Inspirations:

1. Reading: The Art of Interactive Design, written by Crawford.

In this book, Crawford interprets interactivity as “a cyclic process in which two actors alternately listen, think, and speak.”, which enlightens me a lot. When explaining my understanding of interaction, I always take it as my reference. And there is no doubt it also influences the interaction of our project Glowdie, where we intend to achieve a constant interactive process. It is not a one-time exchange of input and output, but a constant exchange, a nice “conversation”.

2.Reading:  A Brief Rant on The Future of Interaction Design

This reading inspires me to not only focus on improving the function of the project but also take the users’ experiences into consideration. Considering users’ experiences, we intend to design a project that is useful, easy-to-use and portable.

3. The object in real life: The Light Board

Light board is widely used in the lives since it is easy to catch eyes and even hard to ignore in the dark environment. Its conspicuousness inspires us to design something glowing so that drivers can notice the bikers and avoid the traffic accident.

4. Movie: Tron

We want our project to be easy-to-use and portable, and the suit the characters in Tron wears caught our attention. It fulfills the easy-to-use requirement since people all know how to wear a hoodie. As for the portability, their suit seems to be light and can be folded into a smaller one so that people will be free from the bother of its weight.

5. Research: the special gesture when turning the bike.

After researching, we found a special arm signature for the bikers, they will raise their arm to show their direction when turning the bike.

 

 

Project Description

DEMO ⬆️

Our initial goal is to design a useful, user-friendly project to improve people’s lives. And the first thing occurs to us is to design a glowing hoodie for people who guide the traffic on the street. However, after careful examination, we found the gestures these people use are really complicated and cannot be efficiently be recognized by the basic sensor we learned so far. Then, based on our original goal, we turned to other potential users. The sharing bikes caught our attention. Inspired by these bikes, and based our research on gestures of bikers, Gowdie comes out.

The tilt switch sensors on both sleeves detect biker’s arm movement as input to control the LED arrow on each side and show the direction the bike will turn to. And for the distance sensor which is on the back neck, takes charge of switching the color modes according to the changing distance. Namely, when people take off the hood, the color of the LED is blue, while when they take on the hood, both the color and the glowing patterns will change with the movement.

 

>>Hardware:

  • Arduino board * 1
  • Bread board * 1
  • 12V power input
  • 5050 RGB LED belt * 1
  • Tilt switch sensor * 2
  • Transistor* 3
  • 220Ω resistor * 3
  • Infrared Range Sensor*1
  • Wires * n

>>Software:  Code is attached at the end of the post.

 

Project Significance

The problem we want to solve is the absence of light equipment on sharing bikes. When it comes to driving in the dark, we find the most popular solution for the normal bikes is to add extra lighting equipment on either the handlebars or the wheels. However, given the costly operating costs and implementation difficulty, this solution can hardly be applied to sharing bikes.

So, our project Glowdie becomes a good choice for these bikers. Due to its conspicuousness, Glowdie can provide a safer driving environment with bikers and it is also a user-friendly product. It is easy-to-use, portable and low-cost.

Besides its basic use, Glowdie is also a good choice for entertainment. We specially design a color model. Specifically, in this model, besides the on and off, the color and pattern will change as well with the movement. This model breaks the limitation of its use and allows it to be used in more situations such as clubbing.

[Demo of color mode ⬇️]

 

Project Design & Production

For the lighting equipment, our initial choice was the LEDs. So, we bought 1000 LEDs from Taobao and decided to connect them together with two wires. We even designed a small connector and printed it with 3D printer so that we can fix the LEDs on the wires. After communicating with Leon, he recommended the LED light belt to us. The LEDs are already fixed on the belt, so it is much more convenient and it even allows us to change the color and create the glowing patterns, which contributes to our color mode.

For the switch of the light, our initial choice was the distance sensor. We intended to control the light according to the change of distance. However, we happened to find the tilt switch sensor when we were checking the component list of kits. We realized this tilt switch sensor can achieve the same goal with a simple circuit. It is more a switch than a sensor and will turn on when itis placed horizontally. So, we changed the distance sensor to the tilt switch sensor.

 

For the distance sensor, we put it on the back neck. It takes charge of switching the color modes according to the changing distance. Namely, when people take off the hood, the color of the LED is blue, while when they take on the hood, both the color and the glowing patterns will change with the movement. By adding this sensor and relating it to the hood, we intend to create a sense of ceremony.

 

We also designed a poster for our Glowdie with AI for a marketing purpose. We want to keep the style of our project constant, so we use the same elements to make our PPT for the presentation.

Before the User Testing, a small part of the arrow was dead due to the unstable soldering. And in the User Testing Session, we found our circuit was not stable, which, besides the soldering problem, was also because the wire we used was the combination of many short wires and a larger part of them are naked. Thus, after the session, we changed the combined wire to a completed longer one. Meanwhile, we searched on Taobao and found a special light belt connector which frees us from soldering. With help of these magical components, our circuit becomes more stable.

Also, we gained many useful suggestions during the User Testing Session. For ones which require much time and a great change, we collected them in the notebook and will take them into consideration in our next project (such as changing the original sensor to the accelerometer). For ones can be changed immediately, we carefully weighed up and took some of them such as to fix the circuit with the hot-melt glue rather than the tape.

Conclusions

I think our project is successful. It is not only useful— It fulfills our original goal that is to keep biker’s safety, but also enjoyable— People enjoy playing with this hoodie especially under the color Mode. During the user test, we are so glad to see people try on our hoodie and wave their arms to experience the change of the light. The most exciting thing is that a boy told us he came especially for trying on our hoodie and asked us to take the video for him. We also uploaded our demo onto Douyin(抖音). Besides likes, we receive many interesting comments like “the best dressing choice for clubbing.”, “I found my motivation for exercise” and “this hoodie helps you to be the most shining star on the street.” We really appreciate these comments and from which, we realize how magic and important the interaction is since even a simple interaction can improve people’s life.

It’s hard to make an idea come true. We spent almost a whole week on our midterm project and it was a week filled with disagreements and disappointments. We held different ideas and both of us were hard to be persuaded. We failed after tried, and tired after failed. However, it was also a week of enlightenment, encouragement, and achievement. We found a way to combine our idea together, and it turned out to be better. After many failures, we finally found out the bug hiding in our code and learned how to exam the circus with a single wire.  Thus, for me, the greatest achievement is not our project, but the cooperation and a better understanding of what we learned in class. [[takeaway]]

More specifically for the takeaways,

  • Brainstorming with others before starting. (THANKS LEON!!)
  • Draw the circus/diagram first.
  • The complexity of the circuit, and processing to transplant it to the product.
  • Soldering Skills.
  • Carefully search on TAOBAO.
  • The difference between the transistors.

For further improvement,

  • Adjust it with different situations, like in different seasons.
  • Add a sound system and a sensor which can sketch cars behind and detect its distance with the user. If the distance between the user and the car is less than a certain value, Glowdie will produce both the light and sound to warn its user.

 

Thank you.

 

 

/******** start code ********/
/*
 *  created   2013-07-29
 *  by    lisper (leyapin@gmail.com)
 *  function  test GP2Y0A41SK0F
 *
 */

//connect gp2d120x to A1
#define pin A1
#define RED_LED 9
#define BLUE_LED 10
#define GREEN_LED 11
//
int brightness = 255;

//
void setup () {
        Serial.begin (9600);
        pinMode(pin, INPUT);
        pinMode(GREEN_LED, OUTPUT);
        pinMode(RED_LED, OUTPUT);
        pinMode(BLUE_LED, OUTPUT);
}

void loop () {
        uint16_t value = analogRead (pin);
        double distance = get_IR (value); //Convert the analog voltage to the distance
        //Serial.println (value);                 //Print the data to the arduino serial monitor
        Serial.print (distance);
        Serial.println (" cm");
        Serial.println ();
        delay (50);//Delay 0.5s


        if(distance < 20) {
          digitalWrite(RED_LED, LOW);   // turn the LED on (HIGH is the voltage level)
          digitalWrite(GREEN_LED, LOW);
          digitalWrite(BLUE_LED, HIGH);
          delay(0);                       // wait for a second
//          digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
//          delay(1000);                       // wait for a second
        } else {
          digitalWrite(RED_LED, HIGH);
          digitalWrite(GREEN_LED, LOW);
          digitalWrite(BLUE_LED, LOW);
          delay(200);
          digitalWrite(RED_LED, LOW);
          digitalWrite(GREEN_LED, HIGH);
          digitalWrite(BLUE_LED, LOW);
          delay(200);
          digitalWrite(RED_LED, LOW);
          digitalWrite(GREEN_LED, LOW);
          digitalWrite(BLUE_LED, HIGH);
          delay(200);
          digitalWrite(RED_LED, HIGH);
          digitalWrite(GREEN_LED, LOW);
          digitalWrite(BLUE_LED, HIGH);
          delay(200);
          digitalWrite(RED_LED, LOW);
          digitalWrite(GREEN_LED, HIGH);
          digitalWrite(BLUE_LED, HIGH);
          delay(200);
          digitalWrite(RED_LED, HIGH);
          digitalWrite(GREEN_LED, HIGH);
          digitalWrite(BLUE_LED, LOW);
          delay(200);
        }
}

//return distance (cm)
double get_IR (uint16_t value) {
        if (value < 16)  value = 16;
        return 2076.0 / (value - 11.0);
}

/******** end code ********/

Recitation 6:Processing Basics

Date: 26 October 2018

Instructor: Eric&Young

 

Introduction

  • Goal:  Draw an image in Processing based off of an image that inspires you.

 

Step 1: Choose an image to be your motif

I chose this image  Interchangeables Orange Blue by Vera Molnar and Sainte Victories as my reference. Honestly, I picked several backups, but I gave them all away when I saw this one. I know immediately it is the one I want to draw since it reflects my recent life. The frame looks like a window. And outside the window, the constant shape reminds me of the shapes of economics graphs, which I read every day as an economics student. The original shape in three lines are the same, but they have the different highlight. From the left to right as if the slow process of examing and scanning the graphs.

 

Step 2: Draw your image in Processing

The biggest problem I met is to make the frame lines equally wide. I tried various ways and finally made it.

First, I drew nine squares and used the stroke() function to draw boarder around them. However, some lines are not as wide as others.

Then, I tried to draw lines separately but they were still not equal.

Finally, I drew nine narrower squares and filled the background with white and finally made it.

Second problem came as how to draw shapes with points. At first, I intended to draw the square first and fill them with points (repeatedly copy and paste the code). After reading the reference page, I found an efficient way — for loop.

The final version is attached below.

 

Conclusion

At first, I want to draw the same as the motif. However, I don’t know how to draw the irregular edge (The way I came up with is to draw with the line() function. I tried but failed to close the shape). So, I changed them to other diagrams.

I think Processing could be useful if people want to draw regular and repeated patterns. The computer can execute the order immediately and accurately. Personally, instead of drawing, the whole process is more a math problem. I spent much time determining the position and change the shapes by changing the values. And when it comes to the irregular shapes, it becomes much harder (which is also because probably because I know few about Processing). However, in PS or AI, I can easily draw what I want quickly.

 

 i

 

size(600,600);
background(255);
//fill(255);
//troke(255);
//rect(0, 0, 600, 600);
fill(#235F9D);
stroke(255);
rect(15, 15, 180, 180);
rect(210, 15, 180, 180);
rect(405, 15, 180, 180);
rect(15, 210, 180, 180);
rect(15, 405, 180, 180);
rect(210, 210, 180, 180);
rect(405, 210, 180, 180);
rect(210, 405, 180, 180);
rect(405, 405, 180, 180);
strokeWeight(3);
line(15,585,50,520);
line(50,520,58,530);
line(58,530,82,465);
line(82,465,97,540);
line(97,540,120,425);
line(120,425,130,455);
line(130,455,195,405);
//beginShape();
strokeWeight(1);
stroke(#DE7B2F);
for (int i = 230; i < 270; i = i+2) {
  for (int j =150; j < 195; j = j+2) {
    point(i, j);
  }
}
for (int i = 275; i < 315; i = i+2) {
  for (int j =65; j < 195; j = j+2) {
    point(i, j);
  }
}
for (int i = 320; i < 360; i = i+2) {
  for (int j =100; j < 195; j = j+2) {
    point(i, j);
  }
}
fill(#DE7B2F);
arc(495, 300, 145, 145, 0, PI+2*QUARTER_PI, PIE);

Recitation 5: Visual Communication

Date: 16 October 2018

Instructor: Eric&Young

 

Step 1: Make a 3D model

I built the iCloud in Tinkercad with many spheres.

Step 2: Edit the 3D model in Illustrator

I dragged the screenshot into the illustrator, got its trace with the pen, and slightly changed its shape (made it flatter).

To make it look like a cloud, I painted it.

Step 3: Design the advertisement

As for the posters, at first, I tried to display the comparison with the iCloud and the traditional umbrella through their portability. Then, an interesting idea suddenly occurred. Why not make it more fun? The motivation for designing the iCloud actually came from an animation I watched called 月刊少女野崎くん. The characters in that animation met problems in using the umbrella due to their huge height difference (the problems can be found in my poster).

So, I designed a poster telling a story that the male character realized their problem on the umbrella, but he failed to come up with a good solution.  So, he turned to his friend, a racoon cat for help. Then, he got iCloud from his friend, yeah. Again, a happy ending. Although I do love this idea, the sad part is the way to construct the story makes it kind of messy. Maybe I should try to display the story vertically rather than horizontally.

Recitation 5: Drawing Machine

Date: 6 October 2018

Instructor: Eric&Young

Partner: Daisy Chen

 

Introduction

  • Goal: To create drawing machines by using an H-bridge to control stepper motors attached to mechanical arms.
  • Components:

 For Steps 1 and 2

  • 1 * 42STH33-0404AC stepper motor
  • 1 * SN754410NE ic chip
  • 1 * power jack
  • 1 * 12 VDC power supply
  • 1 * Arduino kit and its contents

For Step 3

  • 2 * Laser-cut short arms
  • 2 * Laser-cut long arms
  • 1* Laser-cut motor holder
  • 2 * 3D printed motor coupling
  • 5 * Paper Fasteners
  • 1 * Pen that fits the laser-cut mechanisms
  • Paper

Step 1: Build the circuit

Code: Arduino>File>Examples>Stepper>stepper_oneRevolution

Diagram:

Circuit:

An interesting thing I found is that comparing what we build previously, everyone paid extra attention to this circuit. They all kept their breath, carefully read the diagram and built the circuit step by step for the sake of protecting their computer. Thanks to the explicit diagram, I built the circuit efficiently.

 

Step 2: Control rotation with a potentiometer

Code: Arduino>File>Examples>Stepper>MotorKnob

Because the motor used is a step one, some values in the previous program should be changed to adopt it. At first, I forgot the use of map and felt a loss. However, I quickly googled and made it.

The code changed is listed at the end of this documentation.

 

Step 3: Build a Drawing Machine!

We found hard to draw some regular shapes, so we started to create our abstract painting. We really enjoyed it. Another thing we found it that the fasteners we used it quite special. It is different from what we previously used which has the thread on and requires tools to fix it. These special ones are more safe and user-friendly. They can be bent with hands.

 

Question 1:

I would be interested in building a machine that can draw and design the materiel automatically on the computer according to the verbal instruction is received. It is like an advanced Siri, who can not only find something you need but also creates what you want through the sensor that can convert the sound to the electric signal.

For the draw, people can just give instructions like “draw a circle”, “color the circle in red”. And the machine will draw automatically. For the design, people can first tell what information the design should contain, and decide a basic style and purpose of the design such as colorful, used for advertising among the teenagers. Through the sensor that can convert the sound to the electric signal, and after a series of complexed process, the machine can recognize people’s demand. And based on tons of examples in the database, it can create several samples for people to choose.

I believe such the machine will first improve people’s work efficiency since it allows people to do multi-works at the same time. What’s more, it will enable everyone to be a designer and experience the process of art creation. I think everyone is a great artist and should enjoy the artistic creation. Somehow, not everyone has the chance to experience this process probably because of the limitation of their own drawing skills. They are too shy to try. Or even if they try, their poor skills fail to convey their ideas. However, with the help of the technology, through this machine, they can enjoy the art. It pushes people from the technical side to the idea side. It requires the professional designers to polish the creativity of their design rather than their technique of the design.

 

Question 2:

I will definitely choose Arduino. Besides being an art installation, Arduino itself is also the incubator of other art installations. Different from other installations, Arduino is not an end, but a start and from which, I see infinite possibilities. It reminds me of an old saying that “It is better to teach people to fish than to teach people to fish.”I think Arduino is teaching people how to “fish”. Similar to the machine I want to build, it provides the people without any background knowledge with a friendly platform, encouraging them to engage in invention and enjoy the process of thinking and creation.

As for its actuators, according to my previous experience, the board is open to various actuators. It really depends on what effect or function the designers want to achieve.

/Circuit For Step2&3
/*
 * MotorKnob
 *
 * A stepper motor follows the turns of a potentiometer
 * (or other sensor) on analog input 0.
 */

#include <Stepper.h>

// change this to the number of steps on your motor
#define STEPS 100

// create an instance of the stepper class, specifying
// the number of steps of the motor and the pins it's
// attached to
Stepper stepper(STEPS, 8, 9, 10, 11);

// the previous reading from the analog input
int previous = 0;

void setup() {
  // set the speed of the motor to 30 RPMs
  stepper.setSpeed(30);
}

void loop() {
  // get the sensor value
  int val = map(analogRead(0), 0, 1023, 0, 200);

  // move a number of steps equal to the change in the
  // sensor reading
  stepper.step(val - previous);

  // remember the previous value of the sensor
  previous = val;
}