alexl1@andrew.cmu.edu – 62-362 Fall 2019 https://courses.ideate.cmu.edu/62-362/f2019 Activating the Body: Physical Computing and Technology in Performance Mon, 16 Dec 2019 19:06:58 +0000 en-US hourly 1 https://wordpress.org/?v=5.2.20 Babbling Creatures https://courses.ideate.cmu.edu/62-362/f2019/babbling-creatures/ Mon, 16 Dec 2019 19:06:58 +0000 https://courses.ideate.cmu.edu/62-362/f2019/?p=9087 [62-362] Activating the Body | Project 3: Arrows | Fall 2019 | Alex Lin & Scarlet Tong X Connie Chau & Nicholas DesRoches

Overall Project

Final State of Rose

Photo Credit: Christina Brown

Video Footage Credit:  Jacquelyn Johnson

Description
Narrative Description

The Anthropocene marks the beginning of the age in which human activity affects the planet as a whole. No longer do our individual decisions and consequences impact only our perceived sphere of influence, but rather, affect the well-being of our ecosystem on a macro level. Babbling Creatures portrays the inherent complexities in a small scale system featuring several simple paper sculptures. The misdirection and flow of information constantly alter the state and behavior of those creatures to reveal the larger consequence of our seemingly insignificant daily actions. 

Our dissociation with nature, through the construction of artificial landscapes, leads us to forget about the fundamental bond we share with other living beings in our ecosystem. Compared to the permanence of the physical erection of new apparatus to facilitate our own societal concerns, the rate by which nature is contaminated and destroyed as a consequence of our selfish pursuits far exceeds the rate in which mother nature can heal herself. To illustrate the fragile and weakened state of our planet’s ecosystem, the project is constructed out of translucent paper, embodying the fleeting beauty of nature amidst a sea of external threats.

Babbling Creatures is a family of paper interactive objects whose reactions are informed by audience and musician movements. Each creature harvest motion and human activity input and translates it into different physical behaviors. The creatures represent the natural world which is complex, interwoven and exists in a delicate equilibrium vulnerable to change.

Process Images

Initial Concept Sketches:

Network Diagram

Initially, we planned to create three different creatures that have individual reactions on their own, but its consequences will also affect the behavior of others. This diagram portrays that world building which was planned at the outset of the project. We were aiming to create a complex network of interrelated creatures that spoke to one another in ways that weren’t perceptible at a quick glance. The larger blue text denotes the different creatures, while the wavy pink lines denote the different reactions and signals that the pieces share with each other. The black represents the audience and their role within the space.

Rose Movement Exploration & Experimentation

Flexinol Stitching Pattern Exploration

Flexinol Movement

Monofilament Actuated Movement

When we first began the physical actuation explorations, we were hoping to get the flexinol working to crumple the petals of the origami rose. Through a couple of studies, we were able to find a means of stitching the flexinol so that it was able to move the petals given its limited mechanical force output. We then implemented the flexinol, resulting in a small, but noticeable movement in the petals. Through further testing, however, we had difficulty implementing the flexinol and having confidence in it. One day it would work, and the next it would seem that it had burnt out and would need to be replaced. Given the amount of time required to set up the flexinol as well as our expended supply, we chose to use a monofilament system instead. We connected the monofilament to a servo and used it to crumple the rose, allowing for more movement, which in hindsight was perhaps for the better, given the noise level and many distractions that filled the MuseumLab during our final installation.

Water Basin for the Rose

To create the basin, we started by CNC routing insulation foam to make the base form to vacuum form with.

CNC Milling the Vacuum Form Base

Since it was our first-time vacuum forming, we had to do a lot of trial and error as illustrated in the image below. We did not have time to gesso the form to make it release easier from the styrene, and we used a 1/16″ thick material which reduces the level of detail that we hoped for the final product.

Vacuum Forming Struggles

Although the vacuum forming created more interesting forms, it also took us out of our comfort zone as a digital fabrication tool that we weren’t as familiar with.

Vacuum Formed Plastic Water Capacity Test

Willow Tree fabrication and movement

The progression of the willow leaves began as a single leaf, then moving up to several, then to an entire array. We chose to hook up the servos from the side despite more mounting difficulty because it allowed us to face less physical resistance as the leaves were shuffled against one another.

Collaborating with Exploded Ensemble

Photo Credit: Christina Brown

Flex Sensor Testing

Our collaboration with the Exploded Ensemble was mainly through a simple wearable that had an embedded flex sensor attached to Connie as she played the harp throughout the night. Similar to the conceptual underpinnings of her musical piece which distorted the audio files of many languages across the world to accompany her improvisation with Nicholas, Connie’s movements in turn distorted and crumbled the rose that sat on a white basin.

We had also considered the use of an accelerometer, but the complexity of the data and information wasn’t as necessary for the interaction, and the piece also would have introduced more physical challenges in terms of disguising the sensor and wiring the five pins.

Board Layout:

Board Layout

Our strategy for handling all of the external power and wires was to use a sheet of plywood to mount the breadboards and Arduino to. As we got closer and closer to the final installation, we realized that we were spending exorbitant amounts of time setting up the power box and cleaning up the power box after our work. As so, we claimed a power box that would be a part of our board, allowing for the project to be carried in almost all of its electronic entirety using one sheet of plywood. We also, considering the transportation and risk involved with long wires, decided to use zip-ties to secure the plethora of wire bundles.

Wires, Wires, and More Wires:

Planning our all the different lengths of wire we need for the project

Electronic Waste Bin Post-Deconstruction

Wires have consistently been a critical consideration of both of our projects in the past. Unfortunately, given the environmental character of our project, we again resorted to using wires to bridge the connection for all of our moving pieces. Although given the time frame of the project it wouldn’t have been feasible, looking forward we will definitely heavily consider more wireless options which will also allow our work to be more portable and mobile.

Process Reflection

Fabrication & Setup:

Throughout the project, we spent the majority of the time realizing the physical aspect of the project. From the array of willow leaves to the rose and all of the technology that was implemented there, we quickly realized that we had to scale back in terms of scope to ensure that each creature would have a presence and role respective of how much time was invested in bringing it to fruition. Much of the time spent during installation day was related to the installation of the willow leaves. Although simple in the aesthetic, mounting paper, wires, and servos to a rugged, dusty surface, lighting up the leaves and positioning the sonar were time sinks and required multiple attempts. The wiring, although it was bundled neatly, was also a challenge given the sheer abundance and length. Unraveling each bundle, merging bundles that were headed to a similar direction, and taping to unforgiving surfaces definitely slowed our progress, but also made the preparation worth the effort! By having a project that focused mainly on creating a space, much of the coding became more simple naturally which allowed us to fully immerse ourselves in the costuming, lighting, and staging of the environmental installation.

In retrospect, scaling down the size of the installation and broadening the number of creatures that were smaller in size may have contributed to a more network feeling, though it would have been much more difficult to implement technically and in regards to the designing and fabricating of more pieces and parts. Looking forward, we both want to continue to explore the performative aspects that we delved into for this project as well as further expand on our technical know-how and capacity.

Arduino Code
//Babbling Creatures by Alex Lin & Scarlet Tong
//This code is used to physically actuate several creatures and physical
//interactions as part of a larger installation. It uses various inputs
//(photoresistor, sonar,  flex sensor) to move physical elements (using a pump //and a couple servos).
#include <NewPing.h>
// defines pins numbers
#define TRIGGER_PIN  9  // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN     10  // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 400 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.

unsigned long pingTimer;

#include <PololuLedStrip.h>

PololuLedStrip<4> ledStrip1;
PololuLedStrip<5> ledStrip2;

#define LED_COUNT 60
rgb_color colors[LED_COUNT];

// defines variables
long duration;
int distance;

int i;
int j;

//Servo Instantiations
#include <Servo.h> 

// Declare the Servo pin 
int servoPin1 = 7;
int servoPin2 = 8; 
int servoPin3 = 6;

int mod = 0;

// Create a servo object 
Servo Servo1; 
Servo Servo2;
Servo Servo3;

int pos;
////////////////////////////////////////////////////////////
int photoreader;

#define laserTest A3
//int laserTest = 12;
int pumpPin = 11;

////////////////////////////////////////////////////////////
int flexreader;

#define flexTest A4
//int flexinolPin = 12;
unsigned long now;
unsigned long nowAnd;

////////////////////////////////////////////////////////////
int delayTime = 250;

void setup() {  
  Serial.begin(9600); // Starts the serial communication

  Servo1.attach(servoPin1); 
  Servo2.attach(servoPin2);
  Servo3.attach(servoPin3); 

  pinMode(servoPin1, OUTPUT);
  pinMode(servoPin2, OUTPUT);
  pinMode(servoPin3, OUTPUT);

  pinMode (laserTest,INPUT);
  pinMode (pumpPin,OUTPUT);

  rgb_color color;
  color.red = 255;
  color.green = 231;
  color.blue = 76;

  for (uint16_t i = 0; i < LED_COUNT; i++) {
    colors[i] = color;
  }

  ledStrip1.write(colors, LED_COUNT);
  ledStrip2.write(colors, LED_COUNT);
}
void loop() {
  if(millis() - pingTimer > 50) {
    distance = sonar.ping_cm();
    pingTimer = millis();
    Serial.print("Sonar: ");
    Serial.println(distance);
  }
  
  if (distance < 150 && distance >= 0){
    if (mod % 2 == 0) {
      Servo1.write(40);
      Servo2.write(0);
      delay(400);
      mod++;
    }
    if (mod % 2 == 1) {
      Servo2.write(40);
      Servo1.write(0);
      delay(400);
      mod--;
    }
  }
  
//////////////////////////////////////////////////////////////////////////////

  photoreader = analogRead(laserTest);
  Serial.print("Photoresistor: ");
  Serial.println(photoreader);
  if (photoreader < 100){
    digitalWrite(pumpPin,HIGH);
  } else if (photoreader > 100){
    digitalWrite(pumpPin,LOW);
  }

////////////////////////////////////////////////////////////////////////////// 
  flexreader = analogRead(flexTest);
  Serial.print("Flex: ");
  Serial.println(flexreader);
  if (flexreader > 250){
    for (pos = 0; pos <= 45; pos += 1) { // goes from 0 degrees to 180 degrees
    // in steps of 1 degree
      Servo3.write(pos);              // tell servo to go to position in variable 'pos'
      delay(30);                       // waits 15ms for the servo to reach the position
    }
    for (pos = 45; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
      Servo3.write(pos);              // tell servo to go to position in variable 'pos'
      delay(30);                       // waits 15ms for the servo to reach the position
    }
  }
  
//////////////////////////////////////////////////////////////////////////////  
  delay(delayTime);
}
]]>
Blind Understanding https://courses.ideate.cmu.edu/62-362/f2019/blind-understanding/ Thu, 07 Nov 2019 18:40:35 +0000 https://courses.ideate.cmu.edu/62-362/f2019/?p=8878 [62-362] Activating the Body | Project 2: Flow | Fall 2019 | Alex Lin

Long Exposure Shot of User Movements

Overall Project Technology Arrangement

Overall Technology Set-Up

Project Calibration Set-Up

Overall Calibration Set-Up with Garment Display

Project Installation

Installing the Project onto a User | Photo Credit: Scarlet Tong

Project Wiring Overview (HUB)

Project Main Wiring Hub Close-Up

Project Wiring Overview (EMBEDDED)

Project User Embedded Wiring Close-Up

Project Suit-Up Process

Process of Installing the Project On Site | Photo Credit: Dave Choi

Process of Installing Project Collage

Project Demonstration

Project Detail Highlights

Adjustability Highlight

Stack of Embedded Accelerometer, Speaker, and Neopixel LED Circle

Description
Abstract Description
Two people stand on each side of a curtain and move. Their movements cause lights on them to shine. The movements also cause music on the other person to play louder or softer and cause vibration motors to vibrate based on which way they lean.
Narrative Description

Blind Understanding is a performance piece where two people stand on opposite sides of a curtain and are equipped with accelerometers which monitor and capture their movement. This information is then sent through digital signals to create a combination of vibration and music for the opposing person to experience, who can then process that information which can impact their movement. Sited in the Media Lab to provide an intimate space for the dancers to perform and through movement communicate, the project aims to allow for the users to speak through a different medium and feel the presence of the other individual. The dancers will be blocked from each other’s view due to the position of the curtain, but will be free to move as they please (within the confines of the reach of wires). The goal of the exhibit is to convey and to exercise the reading of movement through technology that may reveal information and emotion that otherwise may not be within our frame of perception.

This concept was derived from John Berger’s Ways of Seeing in which he describes how photographs are inherently subjective to the control of the photographer. This was applied to an idea about how people see past one another and attempting to create an experience that brings people together in an experience driven by a focus on the senses rather than language to communicate. This concept is related to my interest in the ways that people explore and interact with space as well as other people. Introducing a visual limitation, changes the ways in which people move and act within a space. In addition, communicating in an intimate environment where one is separated from the other begins to tie into ideas of technology and the distortion of distance that it allows. The concept tries to propose an alternate future where one can sense through a call the physical movements of the person they are communicating with. The project also is a projection of my perception of how I interact with others as someone who is more introverted and reserved, and  has become constructive criticism, as well as encouragement, for myself to express and to confide in others more frequently.

Process Images

Initial Concept Sketches:

Elevation Concept Diagram

Data Flow Diagram

The initial idea was, as explained above, to have two lines of communication between two users that abstracted information about the other persons movements that would influence the users movement without being able to see one another. In developing the concept, most of the concept remained the same, except for the lights which became feedback for the dancers themselves to know that their movements were causing a fluctuation in the data being sent across to the other person. The main question that was vague was the form that the project would take in latching on to each user and how it would fulfill all of its necessary functions.

Wiring Regrets Timelapse:

This timelapse is a snippet of the effort applied to securing all of the wires necessary to make this project possible. Because the system I proposed is not wireless, and I wanted the dancers to have a reasonable level of freedom in movement, this meant that I wanted the wires to hang above them so that they wouldn’t trip and that I would need to overestimate the amount of wire to provide as slack so that they would be able to move around more.

Wiring Regrets:

Workspace Update and Wiring Regrets

At each stage of the wiring process, from soldering, to wiring to the Arduino board, to mounting the accelerometers, speakers, LEDs, and vibration motors to the garment, I needed to ensure that all of the connections were still working, so that required me to troubleshoot multiple times (ex. when a wire pops out of an Arduino pin).

Garment Design & Sewing:

It’s been a while since I have sewed anything, but getting back wasn’t as terrible as I had originally thought. I used canvas as the more flexible fabric, and a plastic material as the more rigid which worked out fine, but sewing the two together took a while, especially when making two of them. In addition, a key factor in the design of the garment was ensuring that it would be able to fit anyone that wanted to try it, and so I took extra care to implement strategies as to allow for that adaptability (which also took more time than I had originally intended).

Garment Folding:

My apologies for the beginning of the timelapse being out of focus. In any case, folding the tessellations that I had decided on took a while to get the initial grid pattern set, but the tessellating wasn’t terribly difficult. I had originally planned on using CNC-ed wood for this project, but due to various issues with photogrammetry and CNC-ing, I had to scale down and redesign an origami piece that would be feasible within the time constraints. I chose the tessellation I did to match the scale of the project’s LEDs, but the patterning was intended to symbolize the scales/armor that we put up to protect ourselves which represent the hesitation to fully communicate with others.

Project Layout:

Deconstructed Layout View of the Project

Laying out the project after all of the initial fabrication was complete was interesting to see the bundles of wire and the layers of material and information that were embedded in the project. It was also a representation of organizing the system and visualizing it before the absolute chaos of wiring, undoing the wire bundles, etc.

Wire Securing:

Wire Securing Process

To ensure that the wiring directly connected to the Arduinos would not get pulled out through the movements of the dancers, I used a piece of wood to secure the breadboards and Arduinos and used zip-ties to secure the wires, protecting the wiring as best as I could. The zip-ties were threaded through holes in the wood and tightened until the wires weren’t budging.

Process Reflection

The process of this project was a bit bumpy to be honest. I was fairly confident throughout the process that I would be able to get the electronics working, but I took too much time to assess fabrication processes. I ran into issues with the photogrammetry program I was using with the images I was inputting and the modeling for the CNC-ing was heavily reliant on the 3D model that the photogrammetry software would output. I burned a lot of time trying to get the initial idea to work, and took too long to bail. In addition, the garment design was a huge undertaking given my ambitions. As I didn’t have two specific designated people to perform, I had to make sure that the final design would be able to fit anyone (although that would have been my intent either way, I suppose). Many of the solutions to allow for more flexibility can only be described as “jank”, but they did function as intended and the piece seems to perform well in that context. Although it worked out in the end, the final project wasn’t as integrated between the technology band and the origami sculptural piece as I would have hoped. In some of the imagery, you can clearly see issues with dancers having wires lifting the origami piece or dealing with wires threaded under their arms.

In regards to technology, the DFRobot Mini MP3 Player was a massive asset to allow for the Exploded Ensemble’s music to play, but was also very finicky at times, with some functions not working and general troubleshooting occurred very often. In regards to the LED feedback, I managed to get it to the point where different movements clearly made different light patterns and colors, but I would have liked to further develop that so that people can better understand what data was being collected from their movements. I think the vibration was also a point that could have been composed better. The vibration motors were definitely felt, but because the two motors on each garment were attached to the same piece of plastic, the sensation of the motors was more easily confused or lost than I would prefer. Lastly, the general use of wires felt really wasteful. The concept would have been weaker and more fragile if the lengths had been shortened, but in the future it might be better to consider ways to reduce that sort of excessive expenditure of materials.

Conceptually, the review and feedback was very helpful to give insight on how others saw the project in how it was presented and in how it functioned. The project would have been more compelling if I had taken more strides to introduce the rules of the project beforehand or if I had choreographed a dance that would provide an intriguing performance for the audience. In addition, the idea of a goal or of stakes was frustrating because one of the original ideas that I had was to give dancers a prompt (through a piece of music or through text) that they would be trying to convey to the other dancer. I think if more planning had gone into this part of the project, it would have had much more depth and would have incentivized the dancers to reach for a specific goal. Looking forward, I want to consider perhaps implementing myself into the final project and becoming a performer. The goal of designing a performance sat in the backseat for this project mostly because I was overly concerned about the fabrication, functionality, and aesthetics of the project. Moving forward, I want to expedite the fabrication portion to allow more time to consider the other intriguing performance aspects of the work, or to stay diligent on implementing these ideas earlier on in the process.

Arduino Code
//Blind Understanding by Alex Lin 
//This code uses the input of an accelerometer to control several outputs, including a Neopixel LED circle, two vibration motors, and a speaker based on various data (ex. pitch and roll) processed by the accelerometer. 
//Code requires two Arduinos for the two users, but should be able to be condensed into one file of code and run through one Arduino. 

//Accelerometer Code From: https://www.electronicwings.com/arduino/adxl335-accelerometer-interfacing-with-arduino-uno
#include <math.h>
#define x_out A1 /* connect x_out of module to A1 of UNO board */
#define y_out A2 /* connect y_out of module to A2 of UNO board */
#define z_out A3 /* connect z_out of module to A3 of UNO board */

#include <Adafruit_NeoPixel.h>
#define LED_PIN 6
#define LED_COUNT 16

#define vibrationLeft A4
#define vibrationRight A5

int red = 0;
int green = 0;
int blue = 0;

int together;

int ledLoop = 0;

Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_KHZ800);

//DFPlayer Mini Code From: https://wiki.dfrobot.com/DFPlayer_Mini_SKU_DFR0299
#include "Arduino.h"
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"

SoftwareSerial mySoftwareSerial(10, 11); // RX, TX
DFRobotDFPlayerMini myDFPlayer;
void printDetail(uint8_t type, int value);

int volume = 10;
int max_vol = 30;
int min_vol = 5;

void setup()
{
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'

  mySoftwareSerial.begin(9600);
  Serial.begin(115200);

  pinMode(vibrationLeft, OUTPUT);
  pinMode(vibrationRight, OUTPUT);

  Serial.println();
  Serial.println(F("DFRobot DFPlayer Mini Demo"));
  Serial.println(F("Initializing DFPlayer ... (May take 3~5 seconds)"));

  if (!myDFPlayer.begin(mySoftwareSerial)) {  //Use softwareSerial to communicate with mp3.
    Serial.println(F("Unable to begin:"));
    Serial.println(F("1.Please recheck the connection!"));
    Serial.println(F("2.Please insert the SD card!"));
    while(true);
  }
  Serial.println(F("DFPlayer Mini online."));

  myDFPlayer.volume(volume);  //Set volume value. From 0 to 30
//  myDFPlayer.loopFolder(15); //loop all mp3 files in folder SD:/05.
  myDFPlayer.play(1);  //Play the first mp3
}

void loop(){
  static unsigned long timer = millis();

  if (myDFPlayer.available()) {
    printDetail(myDFPlayer.readType(), myDFPlayer.read()); //Print the detail message from DFPlayer to handle different errors and states.
  }
  
  int x_adc_value, y_adc_value, z_adc_value; 
  double x_g_value, y_g_value, z_g_value;
  double roll, pitch;
  x_adc_value = analogRead(x_out); /* Digital value of voltage on x_out pin */ 
  y_adc_value = analogRead(y_out); /* Digital value of voltage on y_out pin */ 
  z_adc_value = analogRead(z_out); /* Digital value of voltage on z_out pin */ 
//  Serial.print("x = ");
//  Serial.print(x_adc_value);
//  Serial.print("\t\t");
//  Serial.print("y = ");
//  Serial.print(y_adc_value);
//  Serial.print("\t\t");
//  Serial.print("z = ");
//  Serial.print(z_adc_value);
//  Serial.print("\t\t");

  x_g_value = ( ( ( (double)(x_adc_value * 5)/1024) - 1.65 ) / 0.330 ); /* Acceleration in x-direction in g units */ 
  y_g_value = ( ( ( (double)(y_adc_value * 5)/1024) - 1.65 ) / 0.330 ); /* Acceleration in y-direction in g units */ 
  z_g_value = ( ( ( (double)(z_adc_value * 5)/1024) - 1.80 ) / 0.330 ); /* Acceleration in z-direction in g units */ 

  roll = ( ( (atan2(y_g_value,z_g_value) * 180) / 3.14 ) + 180 ); /* Formula for roll */
  pitch = ( ( (atan2(z_g_value,x_g_value) * 180) / 3.14 ) + 180 ); /* Formula for pitch */
  //yaw = ( ( (atan2(x_g_value,y_g_value) * 180) / 3.14 ) + 180 ); /* Formula for yaw */
  /* Not possible to measure yaw using accelerometer. Gyroscope must be used if yaw is also required */

  Serial.print("Roll = ");
  Serial.print(roll);
  Serial.print("\t");

  Serial.print("Pitch = ");
  Serial.print(pitch);
  Serial.print("\t");

  if(roll < 30 && volume > min_vol) {
      volume--;
      myDFPlayer.volumeDown(); //Volume Down
  }

  if(roll > 90 && volume < max_vol) {
    volume++;
    myDFPlayer.volumeUp(); //Volume Up
  }

  if(roll < 60 && red < 255) {
    red++;
  }

  if(roll > 60 && red > 0) {
    red--;
  }

  if(pitch < 150 && green < 255) {
    green++;
  }

  if(pitch > 150 && green > 0) {
    green--;
  }

  together = pitch + roll;
 
  if(together < 200 && blue < 255) {
    blue++;
  }

  if(together > 200 && blue > 0) {
    blue--;
  }

  if(pitch > 120) {
    analogWrite(vibrationLeft, 255);
    analogWrite(vibrationRight, 0);
  }

  if(pitch < 120) { 
    analogWrite(vibrationLeft, 0);
    analogWrite(vibrationRight, 255);
  }
  
  Serial.print("red = ");
  Serial.print(red);
  Serial.print("\t\t");
  Serial.print("green = ");
  Serial.print(green);
  Serial.print("\t\t");
  Serial.print("blue = ");
  Serial.print(blue);
  Serial.println("\t\t");
    
  strip.setPixelColor(ledLoop, red, green, blue);
  ledLoop++;
  if(ledLoop == 16) {
    ledLoop = 0;
  }
  strip.show();
}


void printDetail(uint8_t type, int value){
  switch (type) {
    case TimeOut:
      Serial.println(F("Time Out!"));
      break;
    case WrongStack:
      Serial.println(F("Stack Wrong!"));
      break;
    case DFPlayerCardInserted:
      Serial.println(F("Card Inserted!"));
      break;
    case DFPlayerCardRemoved:
      Serial.println(F("Card Removed!"));
      break;
    case DFPlayerCardOnline:
      Serial.println(F("Card Online!"));
      break;
    case DFPlayerPlayFinished:
      Serial.print(F("Number:"));
      Serial.print(value);
      Serial.println(F(" Play Finished!"));
      break;
    case DFPlayerError:
      Serial.print(F("DFPlayerError:"));
      switch (value) {
        case Busy:
          Serial.println(F("Card not found"));
          break;
        case Sleeping:
          Serial.println(F("Sleeping"));
          break;
        case SerialWrongStack:
          Serial.println(F("Get Wrong Stack"));
          break;
        case CheckSumNotMatch:
          Serial.println(F("Check Sum Not Match"));
          break;
        case FileIndexOut:
          Serial.println(F("File Index Out of Bound"));
          break;
        case FileMismatch:
          Serial.println(F("Cannot Find File"));
          break;
        case Advertise:
          Serial.println(F("In Advertise"));
          break;
        default:
          break;
      }
      break;
    default:
      break;
  }
}
]]>
Climbing Table https://courses.ideate.cmu.edu/62-362/f2019/climbing-table/ Thu, 03 Oct 2019 18:27:32 +0000 https://courses.ideate.cmu.edu/62-362/f2019/?p=8467 [62-362] Activating the Body | Project 1: Gates | Fall 2019 | Alex Lin

Approach

Approach to the Project

Users “Climbing” 01

Users Exploring the Topography of the Table

Users “Climbing” 02

Users Navigating and Testing Switches

Users “Climbing” 03

Users’ Dancing Fingers

Climbing Table In-Use

Climbing Demonstration

Close Up of How Switches Are Embedded

Embedded Lever and Switch

Blindfold

Simple Perspective of the Blindfold

Inner Workings of the Climbing Table

Perspective Showing the Electronics that Make the Climbing Table Work

Description
Abstract Description
A table has little switches on it. People who can’t see sit around the table and play with the switches. When the right pairs of switches are pushed and switched on, the people at the table hear a sound. When other groups of switches are pushed, the table shakes.
Narrative Description

The Climbing Table is an interactive installation which invites up to four people to sit at a short table and to blindly explore a topographic landscape of CNC-milled plywood that features embedded buttons and switches. By pressing buttons and turning on switches in the correct combination, sounds are emitted from the table which ultimately play a chord. The concept strives to bring people close together and portray the individual unintentional and intentional actions that contribute to a larger effort. Ultimately, the project strives to represent the complexity of working with others and navigating tasks with a lens that magnifies the interaction and connection between people.

Process Images

Initial Concept Sketches:

The initial idea was to have a larger table with embedded LEDs, speakers, and vibration speakers. In developing the concept, various aspects of the idea were tweaked to address ideas of teamwork and group dynamics. For example, the proportions of the table were changed to a square in plan so that everyone had equal access to the buttons, which were placed in an array format.

Axonometric Sketch of Outputs

Elevation of Placement/Planning of Outputs

Plan View of Envisioned Interaction

CNC Regrets:

To make the cost of buying materials for the table cheaper, I laminated 8 sheets of 6 mm thick plywood, but the glue job was not perfect. The material warped a bit because I just clamped the material together after applying glue (should have used vacuum table). As a result, due to the intricacy of the topography that I modeled, some small chunks of plywood were detached during the CNC job. The detail in the model also caused the CNC job to take over 4 hours. While the process would have been faster and more efficient using foam, the ultimate texture, look, and feel of the table was definitely augmented by the material properties of the plywood.

Collage of Table Post-CNCing

Soldering Switches:

Collage of Soldering Switches

I ended up deciding to use 12 switches, 6 of the smaller switches that can remain on or off and 6 of the slightly larger push lever switches that function as buttons. The process of soldering everything together as one can imagine was difficult for someone who had not soldered before, but it worked out in the end. During this process, I heavily considered using 12 of the lever switches for convenience sake, however, I was interested in how the more continuous switches would change the interactions between users and how people’s decisions could make or break whether or not a speaker worked, so I kept both types.

Table Legs:

Detail of Leg Secured to the Table

Although ideally the table legs would have been more seamlessly integrated into the table in a fashion that didn’t penetrate through the topographic surface, in the interest of time and focusing on other aspects of the design that were more significant, I decided to use a few screws to attach the surface to the 2X2’s that I had chopped to size. I was worried about stability, but the legs worked really well.

Wiring:

As one can imagine, with 12 switches, 8 speakers, 2 Arduinos, and a bunch of wires can get really messy. There were times when I had to use tape to bundle pairs of wires together to make sure I could navigate through the jungle of wires and electronics. It ended up working out, although it would have been better to test everything at a singular scale to make sure that everything was wired correctly and the code worked before scaling up.

Process Perspective of Computer and Wiring Progress

Process Reflection

I thought I knew what I was getting into when I decided to take on this concept. The digital fabrication would be a lengthy process, the shear quantity of switches would make a simple logic diagram very complex, and the integration of the two systems would be a rough one. I definitely underestimated how much work it would take to execute on it though. The modeling and CNC-ing of the table wasn’t actually that difficult, but access to machines and technology struggles in general definitely pushed the project back. The sanding and post processing of the table was then expedited to make time for the technology to come in. I wasn’t able to spend as much time as I would have liked, but it was fairly straightforward and there were other things that were more pressing.

When it came to technology, this was where I learned the most lessons. Not only in regards to the wiring of the electronics and coding the Arduino, but also general lessons to carry forward. I learned that having everything working electronically separately from its housing is great, but then integrating it into the housing becomes a very fragile and frustrating process. I think in the future, I should try and start small and slowly build up the projects along with the technology, although perhaps more cumbersome, by working on the digital fabrication and electronic parts in parallel, I would have foreseen issues that came up like how I planned on embedding the switches or how I would house the tangled mess of wires and electronics. I also learned about general tips and tricks about wiring and electronics to put more effort upfront and have an easier time troubleshooting later on. Knowledge-wise, I learned a lot about how the logic chips work and got to try out some cool things which was great!

Looking forward, I was really inspired by other people’s projects that integrated more full body activation of its users. I also felt that my project was more of a social experiment and lacked the force of a strong message/theoretical underpinning. Moving forward, I want to inject more meaning and purpose into my projects, so that they are more impactful experiences and bring a different perspective on a complex issue. Lastly, in regards to creatively using electronics to make cool experiences, I want to strive to do more with less. I got really caught up in having a lot of options, more buttons, and more switches which ended up making the project difficult to pull off (although it did add more things to find and explore). I think if I had used maybe 4 switches, one for each person, and had embedded AND, OR, NAND, XOR, etc. logic chips based on combinations of the switches, that it could have been a much more refined project that would be more interesting and playful.

Logic Schematic

Proposed:

The proposed logic schematic included more vibration as well as light for each switch. As the design began to progress, I found that the LEDs weren’t making sense as a concept unless they were strong enough to produce sensible heat and so that eventually was taken out. The vibration was scaled down as well due to lack of time and planning on testing various vibration methods.

Process Logic Schematic

Final:

The final logic schematic shows what was left at the end. The vibration was intended to be controlled by OR logic instead of AND due to constraints of vibration speakers, however some errors in either code or understanding of sending signals to the speakers used for vibration made it not function in reality. The OR logic was not applied through chip though, and was through Arduino programming/code.

Final Logic Schematic

Primary Arduino Code (Speakers)
//Climbing Table by Alex Lin
//This code inputs signals from various input pins, checks for HIGH or LOW,
//then sends a signal to a speaker if the input is HIGH. This code is sourced
//from the following site: https://courses.ideate.cmu.edu/16-223/f2019/text/exercises/Arduino/event-loop-programming/event-loop-programming.html#exercise-event-loop-programming
//and was developed by Professor Garth Zeglin. It allows for multiple speakers 
//to be controlled by one Arduino board. 
//The pins are matched in numerical order (A0 > 2, A1 > 3, etc.)

#define outputPin1 7
#define outputPin2 2
#define outputPin3 3
#define outputPin4 4
#define outputPin5 5
#define outputPin6 6

#define inputPin1 A0
#define inputPin2 A1
#define inputPin3 A2
#define inputPin4 A3
#define inputPin5 A4
#define inputPin6 A5

long next_output_time_1 = 0;        // timestamp in microseconds for when next to update output 1
long next_output_time_2 = 0;        // timestamp in microseconds for when next to update output 2
long next_output_time_3 = 0;        // timestamp in microseconds for when next to update output 1
long next_output_time_4 = 0;        // timestamp in microseconds for when next to update output 2
long next_output_time_5 = 0;        // timestamp in microseconds for when next to update output 1
long next_output_time_6 = 0;        // timestamp in microseconds for when next to update output 2

long output_interval_1 = 1012;       // B interval in microseconds between output 1 updates
long output_interval_2 = 1351;       // G interval in microseconds between output 2 updates
long output_interval_3 = 851;       // interval in microseconds between output 1 updates
long output_interval_4 = 2551;       // interval in microseconds between output 2 updates
long output_interval_5 = 2025;       // interval in microseconds between output 1 updates
long output_interval_6 = 1703;       // interval in microseconds between output 2 updates

int output_state_1 = LOW;           // current state of output 1
int output_state_2 = LOW;           // current state of output 2
int output_state_3 = LOW;           // current state of output 1
int output_state_4 = LOW;           // current state of output 2
int output_state_5 = LOW;           // current state of output 1
int output_state_6 = LOW;           // current state of output 2

void setup() 
{
  Serial.begin(9600); // initialize serial communications

  //Setting up pins
 
  pinMode(outputPin1,OUTPUT);
  pinMode(outputPin2,OUTPUT);
  pinMode(outputPin3,OUTPUT);
  pinMode(outputPin4,OUTPUT);
  pinMode(outputPin5,OUTPUT);
  pinMode(outputPin6,OUTPUT);

  pinMode(inputPin1,INPUT);
  pinMode(inputPin2,INPUT);
  pinMode(inputPin3,INPUT);
  pinMode(inputPin4,INPUT);
  pinMode(inputPin5,INPUT);
  pinMode(inputPin6,INPUT);
}

void loop()
{
  // read the current time in microseconds
  long now = micros();
    
  Serial.println(analogRead(A0));

  // Polled task 1 for output 1.  Check if the next_output_time_1 timestamp has
  // been reached; if so then update the output 1 state.
  if (now > next_output_time_1 && analogRead(A0) > 0) {

    // reset the timer for the next polling point
    next_output_time_1 = now + output_interval_1;

    // toggle the output_state_1 variable
    output_state_1 = !output_state_1;

    // update output pin 1 with the new value
    digitalWrite(outputPin1, output_state_1 );
  }

  // Polled task 2 for output 2.  Check if the next_output_time_2 timestamp has
  // been reached; if so then update the output 2 state.
  if (now > next_output_time_2 && analogRead(A1) > 0) {

    // reset the timer for the next polling point
    next_output_time_2 = now + output_interval_2;

    // toggle the output_state_2 variable
    output_state_2 = !output_state_2;

    // update output pin 2 with the new value
    digitalWrite(outputPin2, output_state_2);
  }

  // Polled task 3 for output 3.  Check if the next_output_time_3 timestamp has
  // been reached; if so then update the output 3 state.
  if (now > next_output_time_3 && analogRead(A2) > 0) {

    // reset the timer for the next polling point
    next_output_time_3 = now + output_interval_3;

    // toggle the output_state_2 variable
    output_state_3 = !output_state_3;

    // update output pin 3 with the new value
    digitalWrite( outputPin3, output_state_3);
  }

    // Polled task 4 for output 4.  Check if the next_output_time_4 timestamp has
  // been reached; if so then update the output 4 state.
  if (now > next_output_time_4 && analogRead(A3) > 0) {

    // reset the timer for the next polling point
    next_output_time_4 = now + output_interval_4;

    // toggle the output_state_2 variable
    output_state_4 = !output_state_4;

    // update output pin 4 with the new value
    digitalWrite( outputPin4, output_state_4);
  }

    // Polled task 5 for output 5.  Check if the next_output_time_5 timestamp has
  // been reached; if so then update the output 5 state.
  if (now > next_output_time_5 && analogRead(A4) > 0) {

    // reset the timer for the next polling point
    next_output_time_5 = now + output_interval_5;

    // toggle the output_state_2 variable
    output_state_5 = !output_state_5;

    // update output pin 3 with the new value
    digitalWrite( outputPin5, output_state_5);
  }

    // Polled task 3 for output 3.  Check if the next_output_time_3 timestamp has
  // been reached; if so then update the output 3 state.
  if (now > next_output_time_6 && analogRead(A5) > 0) {

    // reset the timer for the next polling point
    next_output_time_6 = now + output_interval_6;

    // toggle the output_state_2 variable
    output_state_6 = !output_state_6;

    // update output pin 3 with the new value
    digitalWrite( outputPin6, output_state_6);
  }
}
Secondary Arduino Code (Vibration)
//Climbing Table by Alex Lin
//This code inputs signals from various input pins, checks for HIGH or LOW,
//then sends a signal to a vibration speaker if the input is HIGH. This code is sourced
//from the following site: https://courses.ideate.cmu.edu/16-223/f2019/text/exercises/Arduino/event-loop-programming/event-loop-programming.html#exercise-event-loop-programming
//and was developed by Professor Garth Zeglin. It allows for multiple vibration speakers 
//to be controlled by one Arduino board.
//A0 and A1 are matched to outputPin1 and A2 and A3 are matched to outputPin2

#define outputPin1 5
#define outputPin2 10

long next_output_time_1 = 0;        // timestamp in microseconds for when next to update output 1
long next_output_time_2 = 0;        // timestamp in microseconds for when next to update output 2

long output_interval_1 = 50000;       // interval in microseconds between output 1 updates
long output_interval_2 = 45000;       // interval in microseconds between output 2 updates

int output_state_1 = LOW;           // current state of output 1
int output_state_2 = LOW;           // current state of output 2

void setup() 
{
  Serial.begin(9600);
  
  pinMode(outputPin1,OUTPUT);
  pinMode(outputPin2,OUTPUT);

  pinMode(A0,INPUT);
  pinMode(A1,INPUT);
  pinMode(A2,INPUT);
  pinMode(A3,INPUT);
}

void loop()
{
  // read the current time in microseconds
  long now = micros();

  Serial.println(analogRead(A0));

  // Polled task 1 for output 1.  Check if the next_output_time_1 timestamp has
  // been reached; if so then update the output 1 state.
  if (now > next_output_time_1 && (analogRead(A0) > 0 || analogRead(A1) > 0)) {

    // reset the timer for the next polling point
    next_output_time_1 = now + output_interval_1;

    // toggle the output_state_1 variable
    output_state_1 = !output_state_1;

    // update output pin 1 with the new value
    digitalWrite( outputPin1, output_state_1 );
  }

  // Polled task 2 for output 2.  Check if the next_output_time_2 timestamp has
  // been reached; if so then update the output 2 state.
  if (now > next_output_time_2 && (analogRead(A2) > 0 || analogRead(A3) > 0)) {

    // reset the timer for the next polling point
    next_output_time_2 = now + output_interval_2;

    // toggle the output_state_2 variable
    output_state_2 = !output_state_2;

    // update output pin 2 with the new value
    digitalWrite( outputPin2, output_state_2 );
  }
}
Collage:

Photo Credit + Collage Credit: Christina Brown

A collage that I had envisioned in the beginning coming to life. It would have been very difficult to get a completely plan view with long exposure, but this begins to capture that original diagram.

Overlayed Collage of Users Interacting with the Climbing Table

]]>