Categories
Interaction Lab

Recitation 9: Sound in Processing

Exercise One

I tried to use the play(); function to play the music at first. But I found it doesn’t work. The music isn’t played when I pressed the keyboard. In addition, when I change the code, I can’t let it stop.  Then I asked the learning assistant for help and I changed it to “playSound1=!playSound1” In that case, it can stop when I press the button twice. 

 

Code

import processing.sound.*;
Boolean playSound1 = true;
Boolean playSound2 = true;
SoundFile sound1;
SoundFile sound2;

void setup() {
  size(640, 480);
  background(0);
  sound1 = new SoundFile(this, "plunkysynthloop.wav");
  sound2 = new SoundFile(this, "monsterwobbleloop.wav");
}

void draw() {
}

void keyPressed() {
  if (key == 'd') {
    playSound1=!playSound1;
  }
  if (playSound1==false) {
    sound1.loop();
    noStroke();
    fill(255,222,0);
    circle(200,250,100);
  } else {
    sound1.stop();
    noStroke();
    fill(150);
    circle(200, 250, 100);
  }
  if (key == 'j') {
    playSound2=!playSound2;
  }
  if (playSound2==false) {
    sound2.loop();
    fill(147,224,255);
    circle(400, 250, 100);
  } else {
    sound2.stop();
    fill(150);
    circle(400, 250, 100);
  }
}

Exercise Two

I can feel the vibration motor working when I put my hands on it but I can’t show it is jumping with the music even I put a light string on it. But it works. 

import processing.serial.*;
import processing.sound.*;
SoundFile sound;

int NUM_OF_VALUES_FROM_PROCESSING = 3;  /** YOU MUST CHANGE THIS ACCORDING TO YOUR PROJECT **/
float processing_values[] = new float[NUM_OF_VALUES_FROM_PROCESSING]; /** this array stores values you might want to send to Arduino **/

Serial myPort;
String myString;

Amplitude analysis;

void setup() {
  size(500, 500);
  background(0);
  setupSerial();
  sound = new SoundFile(this, "Lost On The Freeway.mp3");
  sound.play();
  analysis = new Amplitude(this);
  analysis.input(sound);
}

void draw() {
  
 println(analysis.analyze());
  background(0);
  
  // analyze the audio for its volume level
  float volume = analysis.analyze();
  // map the volume value to a useful scale
  float diameter = map(volume, 0, 1, 0, width);
  // draw a circle based on the microphone amplitude (volume)
  circle(width/2, height/2,diameter ); 


  sendSerialData();

}

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;

}

void sendSerialData() {
  String data = "";
  for (int i=0; i<processing_values.length; i++) {
    data += processing_values[i];
    //if i is less than the index number of the last element in the values array
    if (i < processing_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 linefeed "\n"
    }
    
  }
  //write to Arduino
  myPort.write(data);
  print(data); // this prints to the console the values going to arduino 
  
}

Homework

There are little faces changing with the music. The size of their faces changes with the volume of the music.

 

Code

import processing.sound.*;
AudioIn microphone;
Amplitude analysis;

void setup(){
    size(500, 480);
  // create the AudioIn object and select the mic as the input stream
  microphone = new AudioIn(this, 0);
  // start the mic input without routing it to the speakers
  microphone.start();
  // create the Amplitude analysis object
  analysis = new Amplitude(this);
  // use the microphone as the input for the analysis
  analysis.input(microphone);
}   

void draw(){
background(0);
  println(analysis.analyze());
 
  float volume = analysis.analyze();
 
  float diameter = map(volume, 0, 1, 0, width);
  // draw a circle based on the microphone amplitude (volume)


   fill(255,113,113,90);
  circle(320,240,diameter);
  fill(255);
  circle(310,240,10);
  circle(330,240,10);
  
  stroke(255);
  line(310,240,330,240);
  
  fill(147,224,255,90);
  circle(400,400,diameter);
  fill(255);
  circle(390,400,10);
  circle(410,400,10);
  
   stroke(255);
  line(390,400,410,400);
  
  fill(255,222,0,90);
  circle(200,200,diameter);
  fill(255);
  circle(190,200,10);
  circle(210,200,10);
   stroke(255);
  line(190,200,210,200);
  
  fill(131,175,155,90);
  circle(100,300,diameter);
  fill(255);
  circle(90,300,10);
  circle(110,300,10);
   stroke(255);
  line(90,300,110,300);
  
  fill(227,160,93,90);
  circle(80,50,diameter);
  fill(255);
  circle(70,50,10);
  circle(90,50,10);
  stroke(255);
  line(70,50,90,50);
  
  fill(255,238,210,90);
  circle(400,50,diameter);
  fill(255);
  circle(390,50,10);
  circle(410,50,10);
  stroke(255);
  line(390,50,410,50);

}

 

 

Categories
Interaction Lab

Final Project Essay

Food except 🐑

Younian and I decided to cooperate to finish the final project together. This project is based on current situation of Shanghai and aims at people who are locked down in Shanghai and worried about their food. We would like to make a game world that people can fetch the food they want, such as cakes and bubble tea and through an unrealistic way like “天上掉馅饼”( a saying in China that means getting something without hard work. It can be translated directly as ” pies falling down from the sky”)

This project will let players use fork to hunt food that falling from the sky.  People have 20 points that represents LIFE at the beginning of the game and the game has a  time limit of 140 seconds for one round.  LIFE increases when people get food and decreases when the fork touches sheep.( Since sheep is “羊yáng” in Chinese and its pronunciation is the same as 阳, which means positive)  We decided to let the microphone input the beginning of the game. The player shout out “FOOD” to let the food start falling. And then the player can use soft rubber toys to control the character to move left and right. These two toys are connected with pressure sensors so that people can release pressure by squeezing the toys. We decided to finish the first draft of code before May 1 and revise it before May 7. During the week of May 2, we will finish the physical part of the project.

This proposal contains variability that I have argued in the research part. People don’t know where and how fast the food is falling and they need to move the character to get food. The interaction is uncertain. In addition, people can easily step in to the role and try to explore the points of each food and the speed of them. This process is immersive just like the project Connected Worlds I have researched. People can have a interaction with the project without instructions from the designers or experts. 

 

 

Categories
Interaction Lab

Recitation 8: Serial Communication

Exercise 1: Make a Processing Etch-A-Sketch

code:

Arduino

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


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

void loop() {
  // to send values to Processing assign the values you want to send
  //this is an example
  int sensor1 = analogRead(A0);
  int sensor2 = analogRead(A1);
//  int sensor3 = analogRead(A2);

  // send the values keeping 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);

  // end of example sending values
}

Processing

// 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.*;


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

String myString = null;
Serial myPort;

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

void draw() {
  background(229,187,129);
  getSerialData();
  printArray(sensorValues);
  noStroke();
  fill(161,23,21);

 float val1 = sensorValues[0];
 float val2 = sensorValues[1];
 circle(val1, val2, 100);
}

void setupSerial() {
  //printArray(Serial.list());
  myPort = new Serial(this, Serial.list()[ 1 ], 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_FROM_ARDUINO];
}

void getSerialData() {
  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_FROM_ARDUINO) {
        for (int i=0; i<serialInArray.length; i++) {
          sensorValues[i] = int(serialInArray[i]);
        }
      }
    }
  }
}

I didn’t get into trouble when I let the ball move. But when I change it into a line, the problem of background happened again. I didn’t find this problem and tried to modify other elements. Finally, I found that I need to delete the background() in the void draw to let the line appear on the screen.

code

Processing

// 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.*;


int NUM_OF_VALUES_FROM_ARDUINO = 2;   /** YOU MUST CHANGE THIS ACCORDING TO YOUR PROJECT **/
int sensorValues[]; /** this array stores values from Arduino **/
String myString = null;
Serial myPort;
float x = random (width);
float y = random (height);

void setup() {
  size(500, 500);
  setupSerial();
   background(229,187,129);
}

void draw() {
 
  getSerialData();
  printArray(sensorValues);
  
 float lx = map ( sensorValues[0],0,1023,0,500);
 float ly = map ( sensorValues[1],0,1023,0,500);
 stroke(161,23,21);
 strokeWeight(3);
 line (lx,ly, x, y);
 
 x = lx;
 y = ly;
 
 
}

void setupSerial() {
  //printArray(Serial.list());
  myPort = new Serial(this, Serial.list()[ 1 ], 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_FROM_ARDUINO];
}

void getSerialData() {
  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_FROM_ARDUINO) {
        for (int i=0; i<serialInArray.length; i++) {
          sensorValues[i] = int(serialInArray[i]);
        }
      }
    }
  }
}

Exercise 2

 

Code

Arduino

#include <Servo.h>
#define NUM_OF_VALUES_FROM_PROCESSING 3    /** YOU MUST CHANGE THIS ACCORDING TO YOUR PROJECT **/

Servo myservo; 

/** DO NOT REMOVE THESE **/
int tempValue = 0;
int valueIndex = 0;

/* This is the array of values storing the data from Processing. */
int processing_values[NUM_OF_VALUES_FROM_PROCESSING];


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

  myservo.attach(9);
}

void loop() {
  getSerialData();
  
     if (processing_values[0] == 1){
      myservo.write(180);
      delay(100);
     }else{
      myservo.write(0);
    }
}

//receive serial data from Processing
void getSerialData() {
  while (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 ',':
        processing_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
        processing_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;
    }
  }
}

Processing

import processing.serial.*;
int NUM_OF_VALUES_FROM_PROCESSING = 1;  
int processing_values[] = new int[NUM_OF_VALUES_FROM_PROCESSING]; 
Serial myPort;
String myString;

float x;
float speedX;
float s;

void setup() {
  fullScreen();


  background(0);
  speedX = 5 ;
  
  setupSerial();
}
void draw() {
  background(147,224,255);
  noStroke();
  fill(255,66,93);
  circle (x, 350, 100);
  x= x+speedX;
  if (x > width || x < 0) {
    speedX = -speedX;
  }
   if (x > width) {// hit the left wall
    processing_values[0] = 1;
  } else  {
    processing_values[0] = 0;
}
  sendSerialData();
}
void setupSerial() {
  printArray(Serial.list());
  myPort = new Serial(this, Serial.list()[1], 9600);
  myPort.clear();
  myString = myPort.readStringUntil( 10 );  // 10 = '\n'  Linefeed in ASCII
  myString = null;
}
void sendSerialData() {
  String data = "";
  for (int i=0; i<processing_values.length; i++) {
    data += processing_values[i];
   
    if (i < processing_values.length-1) {
      data += ","; // add splitter character "," between each values element
    }
    else {
      data += "\n"; // add the end of data character linefeed "\n"
    }
  }
  myPort.write(data);
  print(data); // this prints to the console the values going to arduin0
}

When I made the Processing code, I found my motor didn’t move and only the bouncing ball worked. In addition, the number in the console of Processing is always 0. I asked Professor Godoy for help and she solved the coding problem by changing the “if (x > width-s/2)” into “if (x > width)” so that it represents 1 when the ball touches the side of the screen. And we also found I connect the circuit in the wrong way and it stopped the motor. (The right order is brown is ground, red is 5V and orange is special pin)

Homework

Code 

Arduino

// IMA NYU Shanghai
// Interaction Lab
// For sending multiple values from Arduino to Processing
int button1 = 4;
int button2 = 8;

int count1;
int count2;

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

void loop() {
  if (digitalRead(button1) == HIGH){
    count1 = count1 +1;
  }
    if (digitalRead(button2) == HIGH){
    count2 = count2 +1;
  }
  Serial.print(count1);
  Serial.print(",");  // put comma between sensor values
  Serial.print(count2);
  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);

  // end of example sending values
}

Processing

// 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.*;


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

String myString = null;
Serial myPort;

void setup() {
  size(600, 600);

  setupSerial();
  
}

void draw() {
    background(0);
  getSerialData();
  printArray(sensorValues);
 if (sensorValues[0] % 2 == 1) {
    pushMatrix();
    translate(width*0.3, height*0.3);
    rotate(frameCount / 200.0);
    star(0, 0, 30, 70, 5);
    popMatrix();
  }
  if (sensorValues[1] % 2 == 1) {
    pushMatrix();
    translate(width*0.7, height*0.7);
    rotate(frameCount / 200.0);
    star(0, 0, 80, 100, 40);
    popMatrix();
  }

}

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 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_FROM_ARDUINO];
}

void getSerialData() {
  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_FROM_ARDUINO) {
        for (int i=0; i<serialInArray.length; i++) {
          sensorValues[i] = int(serialInArray[i]);
        }
      }
    }
  }
}

At first, I write this Arduino code.

// Interaction Lab
// For sending multiple values from Arduino to Processing
int button1 = 4;
int button2 = 8;


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

void loop() {
  // to send values to Processing assign the values you want to send
  //this is an example
  int sensor1 = digitalRead(4);
  int sensor2 = digitalRead(8);
  Serial.print(sensor1);
  Serial.print(",");  // put comma between sensor values
  Serial.print(sensor2);
//  Serial.print(",");  // put comma between sensor values
//  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);

  // end of example sending values
}

 And I found only when I press the button, the star appears. The requirement is “when you press button 1 once, star 1 will appear on the canvas, and when you press button 1 once again, star 1 will disappear.”

So I decided to use count to solve this problem and when the number of pressing times is odd, the stars appear and the number is even, the stars disappear. 

I research that sound can work as input and generate creative outputs. Music can draw be shown on the screen and let it become more visible.

Here is the example I have found. https://processing.org/tutorials/sound/#example-5-6-audio-analysis

 

/**
 * Processing Sound Library, Example 5
 *
 * This sketch shows how to use the FFT class to analyze a stream
 * of sound. Change the number of bands to get more spectral bands
 * (at the expense of more coarse-grained time resolution of the spectrum).
 *
 * Load this example with included sound files from the Processing Editor:
 * Examples > Libraries > Sound > Analysis > FFTSpectrum
 */

import processing.sound.*;

// Declare the sound source and FFT analyzer variables
SoundFile sample;
FFT fft;

// Define how many FFT bands to use (this needs to be a power of two)
int bands = 128;

// Define a smoothing factor which determines how much the spectrums of consecutive
// points in time should be combined to create a smoother visualisation of the spectrum.
// A smoothing factor of 1.0 means no smoothing (only the data from the newest analysis
// is rendered), decrease the factor down towards 0.0 to have the visualisation update
// more slowly, which is easier on the eye.
float smoothingFactor = 0.2;

// Create a vector to store the smoothed spectrum data in
float[] sum = new float[bands];

// Variables for drawing the spectrum:
// Declare a scaling factor for adjusting the height of the rectangles
int scale = 5;
// Declare a drawing variable for calculating the width of the
float barWidth;

public void setup() {
  size(640, 360);
  background(255);

  // Calculate the width of the rects depending on how many bands we have
  barWidth = width/float(bands);

  // Load and play a soundfile and loop it.
  sample = new SoundFile(this, "beat.aiff");
  sample.loop();

  // Create the FFT analyzer and connect the playing soundfile to it.
  fft = new FFT(this, bands);
  fft.input(sample);
}

public void draw() {
  // Set background color, noStroke and fill color
  background(125, 255, 125);
  fill(255, 0, 150);
  noStroke();

  // Perform the analysis
  fft.analyze();

  for (int i = 0; i < bands; i++) {
    // Smooth the FFT spectrum data by smoothing factor
    sum[i] += (fft.spectrum[i] - sum[i]) * smoothingFactor;

    // Draw the rectangles, adjust their height using the scale factor
    rect(i*barWidth, height, barWidth, -sum[i]*height*scale);
  }
}

 

 

 

 

 

 

 

 

 

Categories
Interaction Lab

Final Projects: Three ideas

  1. Treasure Searching 

Players act as explorers and use a shovel to find buried treasure. In this project, I would use the Motion Detection functions to trace the movement of the shovel. There are several rounds in the game that require players to find both the treasure and the key. The shovel will be smaller and smaller and so is the treasure. This game can let people locked in their homes have more exercise and enjoy the fun of treasure hunting. 

2. Melody Matching 

In this game, participants need to first listen to the music from the player and use the stick to choose the correct button with the same melody and in the same order. (The music may consist of several pieces of melody) Motion Detection functions may be used or people can use two variable resistors to change the position of the stick. This game also will have several rounds and the music will be longer. It can practice players’ memorization.

3. Food Hunting

In this game, people will use two variable resistors to control the hunter. They need to go through a maze and keep away from the guards that move in a certain way to get the food. It represents the difficulty of buying food nowadays and I would like to show this phenomenon in a more interesting way. 

 

 

 

Categories
Interaction Lab

Final Project–Preparatory Research and Analysis

Interactive Projects Research

  1. An Auto-Multiscopic Projector Array for Interactive Digital Humans

      In this interactive project, the participant can interact with other people through interaction with equipment. Such interactions are both synchronous and asynchronous. The sense of transcending time and space adds fun to the equipment. In addition, people don’t need to wear external devices, which lowers the boundary of interaction and increases people’s sense of participation. It informs me that I need to think more about the interaction rather than feedback when I design my final project. And the interaction between users is also meaningful, maybe it is necessary to keep past users’ data. I also learned that keeping interaction requirements to a minimum to let more people get involved is also important.

2. Connected Worlds – Interactive ecosystem for NYSCI by Design I/O 

This interactive project uses bright colors and original designs of creatures to build interactive ecosystems. I was attracted by the setting of the hall and I also noticed that there is no instruction in the stadium. It gives the audience freedom of exploring the equipment by themselves and have their own experience. Moreover, exploring how to interact with the equipment is also a part of the interaction, which adds fun to the project. It informs me that I need to let my final project interact with the users rather than I told them how to interact with or use it. Maybe fewer instructions will be better.

What contributes to a successful interactive experience

Before I actually take this course, my definition of interaction was “a process of communication between two participators (both objects and people are all right) ” Moreover, it emphasizes the loop of effective listening, thinking, and feedback”. In other words, a successful interactive experience needs two or more participants and they need to have a complete conversation that includes the process of sending a message to receiving a response. 

Now based on the interactive projects I have made and found and the reading Art, Interaction and Engagement, I would like to explain more about the elements that contribute to a successful interactive experience. 

I think the first element is variability. When people get the same or similar feedback, they quickly get tired of interacting. Different kinds of feedback are necessary for people to continue interacting. In other words, a successful interactive experience is uncertain. Just as Edmonds has explained “It will depend on the history of interactions with the work. In this case, either the artist from time to time updates the specification of the art object or a software agent that is learning from the experiences of interaction automatically modifies the specification.” (3). Variability is the key to adding fun to the interactive equipment.

Another element is immersion. It implies the users need to have a conversation with the project by themselves. As the project Connected Worlds has shown, a successful interacting experience doesn’t need instructions from the designers or experts. Exploring during the process of interaction makes the experience even more impressive. 

   

 

Categories
Interaction Lab

Recitation 7: Functions and Arrays

Part 1: Grid Pattern

I wanted to create a more complex shape by combining different shapes. 

Here is the code:

void setup() { 
size(800, 800);
}
void draw() {  
noStroke();
background(132,192,194);
for (int i = -5; i < 70; i++){
  for (int j = -5; j < 70; j++){
  drawPicture (i*80,j*80,100,100);
    }
  }
}
void drawPicture (float u, float v, float s, float c){  
fill(132,192,194);
circle(u+60,v+60,s-20);

fill(252,222,180);
circle(u+60,v+60,s-60);

fill(132,192,194);
circle(u+60,v+60,s-70);

stroke(252,222,180);
strokeWeight(5);
line(u+88,v+88,u+32,v+32);
}

Part 2: moving shapes

Then I aimed to make these shapes move. I thought of the bubbles as the water boils and I decided to let these shapes move up and down.

Here is the code:

int n = 100;
float[] x = new float[n];
float[] y = new float[n];
float[] stepY = new float[n];
float speed = 2;
color[] c = new color[n];

void setup() { 
size(800, 800);
background(132,192,194);
for (int i=0; i< n; i++) {
    x[i] = random(width);
    y[i] = random(height);
    stepY[i] = random(-16, 16);
    c[i] = color(random(100,150), random(170,220), random(175,225));
}
}
void draw() {  
noStroke();
background(132,192,194);

   for (int i=0; i< n; i++) {
    drawPicture(x[i], y[i], 100, c[i]);
    y[i]= y[i]+stepY[i];
    if (y[i]<0 || y[i]>width) {
      stepY[i] = -stepY[i];
    }
  }
}
void drawPicture (float u, float v, float s, color c){  
fill(c);
circle(u+60,v+60,s-20);

fill(252,222,180);
circle(u+60,v+60,s-60);

fill(132,192,194);
circle(u+60,v+60,s-70);

stroke(252,222,180);
strokeWeight(5);
line(u+88,v+88,u+32,v+32);
}

Questions:

Q1: In the reading “Art, Interaction and Engagement” by Ernest Edmonds, he identifies four situations in an interactive artwork: ‘Static’, ‘Dynamic-Passive’, ‘Dynamic-Interactive’ and ‘Dynamic-Interactive(Varying)’. From the exercise you did today which situations you identify in every part you executed? Explain.

  In part one, the situation “static” happens since the shapes are still, and “There is no interaction between the two that can be observed by someone else, although the viewer may be experiencing personal psychological or emotional reactions.” (2) The computer will show the picture according to my code and I can’t change it without modifying the code just like people can’t touch the paintings in art galleries. So I think part one can be defined as “static”.

  In part two, the situation “Dynamic-Passive” happens since “The artist specifies the internal mechanism and any changes that take place are entirely predictable.” (3) The bubbles move up and down according to the code. In other words, it follows internal mechanisms.

Q2: What is the benefit of using arrays? How might you use arrays in a potential project? 

  Using arrays can make the code more simple and it is easier for people to modify the code since they only need to change one data and all relative things change. I think I will use arrays when there are a large number similar things or a lot of things follow the same order in the project. 

 

  

Categories
Interaction Lab

Recitation 6: Animating an Interactive Poster

I decided to use what I have learned in class to do this project and I got the idea of using red, yellow, and blue because of project B for Bauhaus Poster.  At first, I didn’t choose a light color background and I found it is a little bit insipid so I added different backgrounds for the letters and change the background to black. I found the trail of the bouncing balls left on the background and I solved this problem by changing the place of the background()   

 

Here is the code.

 

int x;
int y;
int p;
int q;
int a;
int b;


int speedX = 4;
int speedY = 4;
int speedP = 3;
int speedQ = 3;
int speedA = 5;
int speedB = 5;


PFont myFont;
void setup(){
  
  size(1024, 768);
  x = int (random (0, width));
  y = int (random (0, height));
  p = int (random (0, width));
  q = int (random (0, height));
  a = int (random (0, width));
  b = int (random (0, height));
  
  
  println(x);
  println(y);
  println(p);
  println(q);
  println(a);
  println(b);
 
 
  
}

void draw(){
  
 background(0,0,0);

 fill(255,0,0);
 rect(100,150, 200,100);
 
 fill(255,200,15);
 rect(50,350,630,60);
 
 fill(15,150,255);
 rect(90,450,170,60);
 
 fill(255,0,0);
 rect(130,550, 270,60);
 
 fill(255,200,15);
 rect(170,650,240,60);
  
  drawface();
  x = x+speedX;
  y = y+speedY;
  p = p+speedP;
  q = q+speedQ;
  a = a+speedA;
  b = b+speedB;
  
  if(x> width || x<0){
    speedX = - speedX;
  }
  if(y> height ||y<0){
    speedY = - speedY;
  }
  if(p> width || p<0){
    speedP = - speedP;
  }
  if(q> height ||q<0){
    speedQ = - speedQ;
  }
  if(a> width || a<0){
    speedA = - speedA;
  }
  if(b> height ||b<0){
    speedB = - speedB;
  }


  
}

void drawface() {
  
  
circle(x,y,200);
  fill(15,150,255);
  noStroke();
  strokeWeight(5);
  ellipse(x,y,200,200);
  
  
  fill(255, 255, 255);
  noStroke();
  circle(x-50, y, 10);
  circle(x+50, y, 10);
  circle(x, y, 20);
   
  
  circle(p,q,200);
  fill(255,0,0);
  noStroke();
  strokeWeight(5);
  ellipse(p,q,200,200);
  
  fill(255, 255, 255);
  noStroke();
  circle(p-50, q, 10);
  circle(p+50, q, 10);
  circle(p, q, 20);
  
  circle(a,b,200);
  fill(255,200,15);
  noStroke();
  strokeWeight(5);
  ellipse(a,b,200,200);
  
  fill(255,255,255);
  noStroke();
  circle(a-50, b, 10);
  circle(a+50, b, 10);
  circle(a, b, 20);
  myFont = createFont("Georgia",32);
  textFont(myFont);
  
  textSize(42);
  fill(255);
  text("Spring 22 End-Of-Semester Show",50,400);
  fill(255);
  text("8th floor",90,500);
  fill(255);
  text("Friday May 13",130,600);
  fill(255);
  text("6pm to 8pm",170,700);
  
  textSize(150);
  fill(255);
  text("IMA",100,200); 
   
}

Homework:  Make it Interactive

I want to make the project more interesting and I thought of scraping wax painting. I turned all the letters to black and let the mouse control three dots to move. At first, I remain the face of the previous project but I found it is too messy so I decided to delete it. 

(scraping wax painting)

Here is the code.

 

int x;
int y;
int p;
int q;
int a;
int b;

int r= 0;

int speedX = 4;
int speedY = 4;
int speedP = 3;
int speedQ = 3;
int speedA = 5;
int speedB = 5;


PFont myFont;
void setup(){
  background(0,0,0);
  size(1024, 768);
  x = int (random (0, width));
  y = int (random (0, height));
  p = int (random (0, width));
  q = int (random (0, height));
  a = int (random (0, width));
  b = int (random (0, height));
  
  
  println(x);
  println(y);
  println(p);
  println(q);
  println(a);
  println(b);
}

void draw(){
  drawface(mouseX,mouseY,1);
  drawface(mouseX,mouseY,1);
  drawface(mouseX,mouseY,1);
  if (keyPressed == true){
    r= r+1;
  }else{
    r=0;
  }
  
  x = x+speedX;
  y = y+speedY;
  p = p+speedP;
  q = q+speedQ;
  a = a+speedA;
  b = b+speedB;  
}

void drawface(float i, float j, float size) {
  fill(15,150,255);
  noStroke();
  strokeWeight(5);
  ellipse(i+28,j+28,30,30);
  fill(255,0,0);
  noStroke();
  strokeWeight(5);
  ellipse(i,j,30,30);
  fill(255,200,15);
  noStroke();
  strokeWeight(5);
  ellipse(i+28,j-28,30,30);
  

  myFont = createFont("Georgia",32);
  textFont(myFont);
  
  textSize(42);
  fill(0);
  text("Spring 22 End-Of-Semester Show",50,400);
  fill(0);
  text("8th floor",90,500);
  fill(0);
  text("Friday May 13",130,600);
  fill(0);
  text("6pm to 8pm",170,700);
  
  textSize(150);
  fill(0);
  text("IMA",100,200); 
   
}

 

 

Categories
Interaction Lab

Midterm Project Individual Reflection

Project Title: Career Express

Ran Xu (Charlotte) 

Instructor Name: Prof. Marcela Godoy

Context and Significance:

 The previous group project reminds me of using the material around and my ability to make full use of the material improved because of that. In addition, my understanding of the interaction: a process in which each participant in turn listens, thinks, and speaks can be shown in the process of the project. When a player wins, his sense of time is adjusted to the normal sense of time; in other words, it is an input and listening process. The player’s clock thinks about how to adjust accordingly after receiving the signal of winning or losing (winners tend to have the correct time, while losers have the same sense of time) is the thinking part. The corresponding adjustment of time sense given by the clock at the end (presented in the speed of pointer rotation) is the speaking part or the output part.  

We are inspired by a Bilibili short video (here is the link) and it is a short drama on a “career auction”. Near the ending of the video, a woman shout out “8000” but the host ignores her. So we intended to make a project to raise people’s awareness, especially men’s awareness of gender inequality in workplaces.

In order to make our project more scientific, we search for relative information from UNDP (here is the link) and use accurate data for our labels.

Conception and Design

  For the first part of the game, two players try their best to press the button as fast as they can and the serial monitor shows the times that they have pressed them. When one of the players first reaches 10 presses, the LED that represents him/ her lights up and the buzzer plays the melody. At first, we want to put this speed game on top of the equipment and use the cardboard as support. But we find that the competition is very fierce and the cardboard may break during the game. So we decided to put the breadboard aside. And we also want to change the design of the buttons and let them can be held in people’s hands. But we find the connection between wires and buttons is weak and we didn’t find appropriate material to make the connection stronger. In that case, we put the button on the breadboard.

For the second part of the game, the interaction part is people using the clip to stick the labels. Although it is manual, there is an interaction between the equipment and the player since he needs to use the clip manually and the label gives him relative feedback. (showing the content of notes) 

 

Fabrication and Production   

I think the most significant part of making the physical equipment.  Since at first, both Younian and I want to make combine the speed game and the UFO catcher together and put them in one piece of equipment. And in the original version, we have two players in the second round. I tried several ways to realize that target.

I forgot to take the picture of the finished first version. But I Cut two holes in the cardboard to hold the clips, then put the breadboard in the middle. But I found it’s not stable and the space for the clips are too small for players to control, so I just quit this idea.

(the original version design)

This is the second version of the equipment and at that time we supposed we can let the button be held in players’ hands. But after the user test, we found it is hard for us to realize that the second round only needs one player, so I also quit this idea. (We want to use the fruit button at first, but because of lockdown, we can’t buy apples immediately and the fruit we own is too juicy)

At last, I change the design and use a longer stick to make the clip hang on the hole. In addition, I move the light on the breadboard to the cardboard to make the result of the game clearer. Since the edge of my turntable is not connected with the equipment, poking down labels may break the turntable and the motor. So I try a different way from Younian’s and I use the clip to stick the label.

For the part of the concept, we also made changes. The original design of this project is to let women and men find their “true selves” and talks about gender labeling.  After talking with Professor Godoy, we realized that our target audience is too big and we need to focus on a specific topic. She also advised us to find some relative information such as data to make the design of labels more visual and scientific. So we changed the topic to “Career Express” and search for relative academic resources to support our project.

Younian and I find the relative code in the previous classes and recitations. Younian modify these codes to make them fit our project and I also made some modifications to the code such as the music. During this process, Professor Godoy helps us a lot with debugging. And after we made the physical equipment, we started to make the poster. We cooperate to write the content of the poster. Younian made the 3D model and I draw the 2D sketches. Then Younian combine everything together and made the amazing poster.  At last, we shoot the video and I did the editing part to make the final video.

Our Poster

Our Code 

int buzzerPin = 8;
int button1 = 10;
int button2 = 11;
int led1 = 3;
int led2 = 2;
int goal = 10;
int buttonState1 = LOW;
int previousState1 = LOW;
int buttonState2 = LOW;
int previousState2 = LOW;
int counter1 = 0;
int counter2 = 0;
boolean winner1 = false;
boolean winner2 = false;
long time = 0;
long debounce = 200;
boolean stage2 = false; // this is going to be a boolean variable that we will make true when we want to go to the second stage
void setup() {
  Serial.begin(9600);
  pinMode(buzzerPin, OUTPUT);
  pinMode(button1, INPUT);
  pinMode(button2, INPUT);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  Serial.println("****ROUND 1: Once the monitor shows 【GO!!!!!!!!!!!!!!!!】, press the button as fast as you can. The one that first reaches 10 presses will win the game and can go into the 2nd round.");
  Serial.println("ROUND 2: Use the stick to poke down the label in the hole. And the game will end when you get the label with 【TRUE-SELF】 on it.****");
  delay(5000);
  Serial.println("READY");
   playBeep();
  delay(1000);
  Serial.println("SET");
 playBeep();
 playBeep();
  delay(1500);
    Serial.println("GO!!!!!!!!!!!!!!!!");
playBeep();
playBeep();
playBeep();
}
void playBeep() {
  playFreq(100, 200);
}
void playFreq(double freqHz, int durationMs) {
  //Calculate the period in microseconds
  int periodMicro = int((1 / freqHz) * 1000000);
  int halfPeriod = periodMicro / 2;
  //store start time
  long startTime = millis();
  //(millis() - startTime) is elapsed play time
  while ((millis() - startTime) < durationMs) {
    digitalWrite(buzzerPin, HIGH);
    delayMicroseconds(halfPeriod);
    digitalWrite(buzzerPin, LOW);
    delayMicroseconds(halfPeriod);
  }
} 
void loop() {
  buttonState1 = digitalRead(button1);
  buttonState2 = digitalRead(button2);
  if (counter1 < goal && winner2 == false) {
    if (buttonState1 != previousState1 && millis() - time > debounce) {
      if (buttonState1 == HIGH) {
        counter1++;
        Serial.print("player MALE: ");
        Serial.println(counter1);
        time = millis();
      }
    }
    previousState1 = buttonState1;
    if (counter1 == goal && winner2 == false) {
      winner1 = true;
      digitalWrite(led2, HIGH);
      Serial.println("PLAYER MALE WINS");
      playMelody();
    }
  }
  if (counter2 < goal && winner1 == false) {
    if (buttonState2 != previousState2 && millis() - time > debounce) {
      if (buttonState2 == HIGH) {
        counter2++;
        Serial.print("player FEMALE: ");
        Serial.println(counter2);
        time = millis();
      }
    }
    previousState2 = buttonState2;
    if (counter2 == goal && winner2 == false) {
      winner2 = true;
      digitalWrite(led2, HIGH);
      Serial.println("PLAYER MALE WINS");
      playMelody();
    }
  }
  //here we will check whether we start stage2
  if (stage2 == true) {
    moveMotor();
  }
}

void playMelody() {
  playFreq(100, 200);
  playFreq(100, 200);
  playFreq(500, 200);
  playFreq(500, 200);
  playFreq(600, 200);
  playFreq(600, 200);
  playFreq(500, 200);
  delay(100);
  playFreq(400, 200);
  playFreq(400, 200);
  playFreq(300, 200);
  playFreq(300, 200);
  playFreq(200, 200);
  playFreq(200, 200);
  playFreq(100, 200);
  delay(100);

  
  // you can find something or create your own melody for this
  //ad your melody here
  //after the melody stops we will go to stage 2
  //you can have a delay here before start moving
  delay(1000);
  stage2 = true;
}

void moveMotor() {
  float sensorValue = analogRead(A0);
  // print out the value you read:
  Serial.println(sensorValue);
  float MotorSpeed = map(sensorValue, 0, 1023, 0, 255);
  analogWrite(9, MotorSpeed);
  delay(1);        // delay in between reads for stability
}

Our video (Too big to upload. Younian uploaded this video to her Bilibili homepage and here is the link)

Conclusion

Our goal is to raise people’s awareness, especially men’s awareness of gender inequality in workplaces. We tried to express this theme by controlling some elements in the game and making it more story-telling. The result of the first-round game is fixed and only men have the opportunity to join the second round and see the labels with data on gender inequality in workplaces. In that case, men players can confront serious inequities they may not have noticed. In addition, since the first part of the game is competitive, it restores the competitive situation in the workplace to some extent to make the player more indulged. In that case, women players can also have a stronger feeling about the inequality.

Our project shows the understanding of interaction in two parts of the game and in both manual and electronic ways. If I have more time I would change the design of the button and have a better way to fix the motor. I learned that failure is normal during the process even if you know the methods. It is important to try again and make improvements to the project. In addition, communication and asking for help are important for the group project. Getting over the trouble together would make problems easier to solve.   

 

 

 

 

 

 

 

Categories
Interaction Lab

Recitation 5:Workout

Connect the tilt switch to the Arduino like this:

I followed the instruction and built a circuit like this

It worked well and I didn’t realize that I missed one wire. But when a wire falls out of the breadboard and I connected the wire to the wrong place, the circuit didn’t work and I failed to find the problem and asked the professor for help.

This is the new circuit I built with the professor’s help. 

Then I upload this code and the sketch printed 1 to the Serial monitor when it is upright, and 0 when it is upside-down.

const int SENSOR_PIN = 6;  
  
int tiltVal;

void setup() {
  pinMode(SENSOR_PIN, INPUT);    // Set sensor pin as an INPUT pin
  Serial.begin(9600);
}

void loop() {
  // read the state of the sensor
  tiltVal = digitalRead(SENSOR_PIN);
  Serial.println(tiltVal);
  delay(10);
}

After that, I changed the code to let the monitor print 1 when the title sensor changes from 0 to 1, or from 1 to and the code was like 0 1 0 1.

const int SENSOR_PIN = 6;

int tiltVal;
int prevTiltVal;

void setup() {
  pinMode(SENSOR_PIN, INPUT);    // Set sensor pin as an INPUT pin
  Serial.begin(9600);
}

void loop() {
  // read the state of the sensor
  tiltVal = digitalRead(SENSOR_PIN);

  // if the tilt sensor value changed, print the new value
  if (tiltVal != prevTiltVal) {
    Serial.println(tiltVal);
  }
  prevTiltVal = tiltVal;

  // for Serial Plotter use
  //Serial.println(tiltVal);

  delay(10);
}

Then I uncommented the line //Serial.println(tiltVal) , opened the serial plotter, and got a graph like this.

Questions:

  1. At approximately what angle of tilt does it transition between HIGH and LOW?                                                                    The transition between HIGH and LOW happens at about 90 degrees of tilting. 

2. What else do you notice about its behavior?

    I noticed that the transition was depended on the little piece in the tilt switch. If the little piece fell down to the other side, the switch would transition between HIGH and LOW.

3. What if you tilt the forearm?

That is the same as what I have done before. The only difference may be the speed of transition since I need to spend more time tilting the forearm.

4. What if you hold the wires several centimeters away and tilt them?

The same as before.

5. What if you shake it?

It transitions quickly between HIGH and LOW. 

Debouncing the tilt switch

I think 50ms is a reasonable lockout and here is the code.

// constants won't change. They're used here to set pin numbers:
const int buttonPin = 6;    // the number of the pushbutton pin

int buttonState;             // the current reading from the input pin
int lastButtonState;   // the previous reading from the input pin

// the following variables are unsigned longs because the time, measured in
// milliseconds, will quickly become a bigger number than can be stored in an int.
unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers

void setup() {
  pinMode(buttonPin, INPUT_PULLUP);
  Serial.begin(9600);
}

void loop() {
  // read the state of the switch into a local variable:
  int reading = digitalRead(buttonPin);
  
  // If the switch changed, due to noise or pressing:
  if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();  
    Serial.println(buttonState);
  }

  if ( (reading != buttonState) && (millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer than the debounce
    // delay, so take it as the actual current state:
      buttonState = reading;
    
  }
  
  // save the reading. Next time through the loop, it'll be the lastButtonState:
  lastButtonState = reading;

 //if you want to use Serial Plotter, add these two lines:
  //Serial.println(buttonState);
  //delay(1);
}


Workout 1: Biceps Curls

I need to use the count function to let the Arduino count biceps curls and print the number to the Serial Monitor. 

Here is the code.

// constants won't change. They're used here to set pin numbers:
const int buttonPin = 6;    // the number of the pushbutton pin

int buttonState;             // the current reading from the input pin
int lastButtonState;   // the previous reading from the input pin
int counter = 0;

// the following variables are unsigned longs because the time, measured in
// milliseconds, will quickly become a bigger number than can be stored in an int.
unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers

void setup() {
  pinMode(buttonPin, INPUT_PULLUP);
  Serial.begin(9600);
}

void loop() {
  // read the state of the switch into a local variable:
  int reading = digitalRead(buttonPin);
  
  // If the switch changed, due to noise or pressing:
  if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
      //Serial.println(buttonState);

  }

  if ( (reading != buttonState) && (millis() - lastDebounceTime) > debounceDelay) {
    if ( reading == 1) {
      counter = counter + 1;
      Serial.println(counter);
    }
    if (counter >= 8) {
      counter = 0;
      Serial.println("Yay, you’ve done a set of curls");
    }
      buttonState = reading;
  }
  
  // save the reading. Next time through the loop, it'll be the lastButtonState:
  lastButtonState = reading;

 //if you want to use Serial Plotter, add these two lines:
  //Serial.println(buttonState);
  //delay(1);
}

Workout 2: Jumping Jacks

It didn’t correctly count jumping jacks. And I found that the graph would have a peak after I move my arm several times.

Questions:

  1. Can you make changes to the speed of your “jumping jack” to detect it?                                                            Yes, I can. And here is the video. 

2. What happens if you change the debounce lockout time? What do you need to change to detect one “jumping” exercise?

If I change it into 30ms, it doesn’t have an obvious change. When I change it to 70ms, the counting is less accurate.

3. How reliable is the counting? How many extra, or missed, counts happen as a fraction of the number of real exercises done?

When the lockout is 50ms, it is roughly reliable. But it is a little bit hard for me to see the exact number when I use the Serial Plotter.

Workout 3: Start and Stop Timing

The problem I met here is that I don’t know how to let my count stop. So I asked the LA for help and we solved the problem by adding two if functions to give an exact duration.

 

Here is the code.

// constants won't change. They're used here to set pin numbers:
const int buttonPin = 6;    // the number of the pushbutton pin

int buttonState;             // the current reading from the input pin
int lastButtonState;   // the previous reading from the input pin
int counter = 0;
int duration = 0;


// the following variables are unsigned longs because the time, measured in
// milliseconds, will quickly become a bigger number than can be stored in an int.
unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers

void setup() {
  pinMode(buttonPin, INPUT_PULLUP);
  Serial.begin(9600);
  Serial.println ("Start your Workout!");
  
}

void loop() {
  // read the state of the switch into a local variable:
  int reading = digitalRead(buttonPin);
  duration = millis();
  
  
  // If the switch changed, due to noise or pressing:
  if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
      //Serial.println(buttonState);

  }

  if ( (reading != buttonState) && (millis() - lastDebounceTime) > debounceDelay) {
    if (duration < 20000){
      if ( reading == 1) {
      counter = counter + 1;
      Serial.println(counter);
    }
    } else if (duration >= 20000 ) {
      Serial.println("Stop, your time is up!");
    }
      buttonState = reading;
  }
  
  // save the reading. Next time through the loop, it'll be the lastButtonState:
  lastButtonState = reading;

 //if you want to use Serial Plotter, add these two lines:
  //Serial.println(buttonState);
  //delay(1);
}

Draw your own illustration sketches that showcase how a person would use this interactive training device.

It can be used to count the number of sit-ups and the tilt switch can be wrapped around the waist.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Categories
Interaction Lab

Recitation 4: Drawing Machines

Process

Step 1: Build a circuit

The circuit is complicated and my partner and I spent about fifty minutes completing two circuits because at first, we followed the wrong instructions and needed to build again. And when we test the motor, it didn’t work as the instruction showed and we were worried about that. At last, we found one of the wires was connected to the wrong place.  

Step 2: Control  rotation with a potentiometer

I met trouble when I need to add a map function to match the movement of the knob with the rotation of the motor. I didn’t know where I should put the function and I asked the learning assistant for help. We solved the problem at last. ( I forgot to record the picture of it. It was near the end of class and it was chaotic.)

Step 3: Build a drawing machine

We made the machine at last. But the motor is a little bit too high and the pen sometimes can’t draw on the paper. So we need to lift the paper and control the machine at the same time.

Question 1: 

What kind of machines would you be interested in building? Add a reflection about the use of actuators, the digital manipulation of art, and the creative process to your blog post.

I am interested in building machines that can afford pleasure to people. I hope it is interesting not only in the process of using but also in the process of building. The use of actuators can be one important part of realizing this wish. The process of building an actuator is like creating human hands. It makes machines more like people. The process of constantly tweaking it through a program is like teaching a child, and it’s fun whether it’s done well or not. The digital manipulation of art is similar to that. It is a process of human taming machines, a combination of human emotional expression and rational machinery. The process itself is paradoxical and beautiful. 

Question 2: Choose an art installation mentioned in the reading ART + Science NOW, Stephen Wilson (Kinetics chapter). Post your thoughts about it and make a comparison with the work you did during this recitation. How do you think that the artist selected those specific actuators for his project?

An enveloping chair made by London Fieldworks in collaboration with Dugal McKinnon, Gastarbyter combines hearing, touch, and vision and gives people a chance to focus on their feelings of being ignored in their daily lives and engage their senses. It’s quite different from the work I did during the recitation since my work pays more attention to controlling the machine and this work use actuators to control people’s feeling. I think when the artist selected specific actuators such as vibration machines, he may focus on the tactile parts he wants people to focus on and minimize the visual impact.  And since people need to sit or lay on the chair, comfort and load-bearing also need to be considered.