Raymond Hruby – Final Project

FINAL PROJECT
Raymond Hruby II | Art 150 | UIC 2017



General Idea: Exploring relationship between technology and spirituality


Materials:

  • Neopixel(13 array)
  • FSR
  • Mic Amp
  • Photo Resistor
  • Step Motor
  • 1 blue LED, 2 yellow LEDs
  • Resistors, Wire, Arduino, etc.
  • Modeling clay
  • Aluminum Foil
  • Masking Tape
Steps

Built basic sculpture wire into a somewhat sitting pose with extended hands
Added neopixel strip and step motor to underside of  base
Began covering sculpture wire with masking tape and putting in the Arduino and components


Built up scupture frame and enclosed wiring and Arduino with aluminum foil
Showing the backside of the sculpture that is showing its ‘guts’

Built up sculpture with modeling clay

Showing backside of completed sculpture

~ VIDEO of Project ~


Description 
Here is a description of my project as my pulled over project proposal:
Technology is often seen as a catalyst for connectivity. Often, the placement of this connectivity occurs inside a product. The term “internet of things” came from this. I feel like this falls into the realm of materialism, where technology is used to heighten the marketability of a product and convince consumers they should own or possess that item. My project turns from this notion in the sense that rather falling into the same realm of materialism, it will be exploring the connection and relationship between technology and spiritualism.

I don’t want my project to be thought of as another ‘thing’, blinking with lights, full of interesting features and so on, but rather a similar being to us. Therefore my project will emphasize spaced interaction and randomization. Instead of competing with the numerous gadgets and playthings, my project will be competing more with static art and sculpture.

Art can be thought of as a way to perceive qualities you don’t have, where you are attracted to art that possesses qualities you don’t have yourself. The qualities of my sculpture will be of peace, calm, and silence, and I want to use this as a reminder to experience the world without technology. It’s hard to imagine life without technology. For most, it’s difficult to go about their day without using a piece of technology, and also for most, it’s difficult to not be using technology all the time. Rather than the attractive qualities of my project be it’s features, since these features are not readily available, the attractiveness will come from its calming quality and body language. It will be sitting in a meditative position where meditation is used as method for calming, peace, inner growth, and inner understanding. I want my sculpture to serve as a reminder for meditation and to connect back to your spiritual self, to get away from all the  technological noise, and to appreciate, learn, and grow from the silence.

Other background for my sculpture is the same as what I included in the previous interactive proposal exploring the relationship between lifelessness and emotion. Sculptures are inherently lifeless, especially if abstract. My first idea was to use concrete as the base material that got changed to clay for usability reasons. Hardened clay is the next lifeless material that would be feasible to work with for this project. My idea was to try and inject emotion and life into this lifeless statue through physical touch, response, and light visuals, as inducing emotion into others and showing emotion is a staple of human behavior and for humans to connect with other humans. For spaced interaction, the emotions presented will seem subtle and few. I think a deeper but tangent meaning connects to me personally as my exterior rarely shows the emotion I am feeling inside. I want to use this high contrast previously mentioned to create a rather beautiful, tranquil, and mysterious experience




What my Sculpture Does & Explanations:


***DON’T READ IF YOU WANT TO KEEP YOUR INTERPRETATION, WHICH IS RECOMMENDED***

Sculpture is sitting in meditative pose to signal the connection to spirituality. It won’t be awake unless there is darkness. In darkness, there is usually more space and energy for the visitor to consume itself, rather than during the day, when everyone is consuming energy leaving less energy for the space around themselves.

  • In darkness, the sculpture comes to life by a strobing heart beat, or breath. Being awake during the darkness and the strobing heart beat signals the now apparent spiritual energy around the sculpture and the visitor, now that other distractions are not there, like a light in the darkness, or the light at the end of the tunnel, reminding the visitor to return and appreciate its spiritual self. Having the heart strobe signals the calm waves of spiritual energy.

Sculpture has arms extended for accepting touch of visitor in hands

  • hands respond to an even amount of pressure, which triggers the human and sculpture connection. If there is too much pressure, then it responds as if in pain. If the visitor annoys the sculpture too much, it will turn away to stop accepting interaction and sit dormant for a while. During this time, the back of the sculpture is open, letting the visitor peer inside to its guts. These guts are supposed to look like what would belong in a human if the guts of a human were wires. The most resemblance is the neck of the sculpture, which also happens to be bare and uncovered, representing the necks vulnerability in humans. This resemblance of organs is supposed to induce a likeness in the visitor, so that the visitor treats the sculpture like a human, instead of a toy. 
  •  If the sculpture has to turn away too much, then it will stay turned around and dormant for a very long time. The visitor has then missed its chance to connect with the sculpture and therefore its spiritual self by focusing too much on the playfulness and interactivity of the sculpture. By squeezing the hands too much, even after the sculpture turns away a couple of times, signals the visitor as trying to get a ‘rise’ from the sculpture, trying to see what would happen next, how many features the sculpture has, as if the sculpture was a toy. The visitor succumbed to its desire for immediate gratification and rough play.
  • if the hands are given an even amount of pressure, as if lightly holding the hands, then the sculpture would pause its heart strobe, as if the sculpture recognizes that the visitor wants to move to the next stage. During this time, the sculpture creates a sensitive connection to the visitor since the visitor is treating the sculpture with care. If the visitor fails to hold an even amount of pressure, the sculpture will return to normal, and continue meditating. If the visitor gives a hard pressure, the sculpture will act as if in pain, similar to as described above.
Sculpture awakens to even pressure
  • When awaken, the eyes become filled with light and the neopixels start going crazy, representing the accomplishment of connecting to the sculpture, and in turn, the spiritual energy. At this point, the Mic Amp becomes active and responds to the visitor noise, further signalizing the recognition of this accomplishment.
Sculpture reacts to sound when awake
  • During this period, the eyes and heart will react to nearby sound, or rather, monologue. This idea came from one of my CS classes, where one tip for developing efficiently was to find something to talk to and explain your design patterns. Though speech, one can better find mistakes in one’s thinking, and can come to a faster conclusion if stuck on a design problem. Here, this statue serves as the object to talk to, and induces a reflection of the monologue with brighter visuals. 




Source Code  (slight modification 04/26/17):
/* NEOPIXEL */
#include <bitswap.h>
#include <chipsets.h>
#include <color.h>
#include <colorpalettes.h>
#include <colorutils.h>
#include <controller.h>
#include <cpp_compat.h>
#include <dmx.h>
#include <FastLED.h>
#include <fastled_config.h>
#include <fastled_delay.h>
#include <fastled_progmem.h>
#include <fastpin.h>
#include <fastspi.h>
#include <fastspi_bitbang.h>
#include <fastspi_dma.h>
#include <fastspi_nop.h>
#include <fastspi_ref.h>
#include <fastspi_types.h>
#include <hsv2rgb.h>
#include <led_sysdefs.h>
#include <lib8tion.h>
#include <noise.h>
#include <pixelset.h>
#include <pixeltypes.h>
#include <platforms.h>
#include <power_mgt.h>
/* STEPPER */
#include <Stepper.h>
// FINAL Project
// Raymond Hruby II
// 04/18/17
// TODO: incoroprate fibre and neopixels
//  – preAwaken()
int const HEART_PIN = 9;            //analog
int const EYES_PIN = 10;             //analog
//int const PHOTORESISTOR_PIN;      //analog A0 for reading
//int const FSR_PIN;                //analog A1 for reading
//int const HANDS_PIN = 11;            //analog
//int cont MIC_AMP_PIN              //analog A2 for reading
// NEOPIXEL //
CRGB leds [14];
//int DATA_PIN = 3;
int NUM_LEDS = 14;
CHSV specialColor;
int hue = 0;
// STEPPER //
const int stepsPerRevolution = 1024;
Stepper myStepper(stepsPerRevolution, 4, 5, 6, 7 );
// MICAMP //
const int sampleWindow = 50; // Sample window width in mS (50 mS = 20Hz)
unsigned int sample;
int pr_Reading = 0;
int fsr_Reading = 0;
int sleepStateInstance = 0;
int awakeStateInstance = 0;
int angryInstances = 0;
int angryState = 0;
void setup(){
  Serial.begin(9600);
  
  pinMode(HEART_PIN,OUTPUT);
  pinMode(EYES_PIN,OUTPUT);
  //pinMode(HANDS_PIN,OUTPUT);
  myStepper.setSpeed(20);
  // put your setup code here, to run once:
  FastLED.addLeds<WS2811, 3, GRB>(leds, 14);
  delay(2000);
  
  for(int i =0;i<14;i++){
    leds[i] = CRGB::Black;
    FastLED.show();
    delay(5);
  }
}
void loop(){
  if( isHardPressure() ){ //responds to pressure when not ‘awake’
    showIsPain();
  }
  
  if(isDark()){
    strobe(HEART_PIN);
    resetAll();
  }
  // put your main code here, to run repeatedly:
  //updateNeoPixels(); //hair flows regardless?
}
void updateNeoPixels(){
  fill_rainbow(leds, 14, hue, 10);
  hue = (hue+1)%255;
  delay(10);
  FastLED.show();
}
void updateAwakenNeoPixels(){
  fill_rainbow(leds, 14, hue, 10);
  hue = (hue+5)%255;
  delay(10);
  FastLED.show();
}
int readMicAmp(){
   unsigned long startMillis= millis();  // Start of sample window
   unsigned int peakToPeak = 0;   // peak-to-peak level
   unsigned int signalMax = 0;
   unsigned int signalMin = 1024;
   // collect data for 50 mS
   while (millis() – startMillis < sampleWindow){
      sample = analogRead(2);
      
      if (sample < 1024){
         if (sample > signalMax){ signalMax = sample;}
         else if (sample < signalMin){ signalMin = sample; }
      }
   }
   peakToPeak = signalMax – signalMin;  // max – min = peak-peak amplitude
   int brightness = map(peakToPeak,0,1023,0,255);
   return brightness;
}
boolean isDark(){
  int darknessThreshold = 40; //any amount lower is considered dark 
  pr_Reading = analogRead(A0);
  if(pr_Reading < darknessThreshold){
    Serial.println(“it IS dark”);
    return true;
  }
  else{
    Serial.println(“it IS NOT dark”);
    return false;
  }
}
//shows anger as is in pain
boolean isHardPressure(){
  fsr_Reading = analogRead(A1);
  
  if(fsr_Reading > 700){
    angryState+=1;
    Serial.println(“there is HARD pressure”);
    return true;
  }
  
  return false;
}
boolean isEvenPressure(){
  fsr_Reading = analogRead(A1);
  
  if(fsr_Reading > 150 && fsr_Reading<=700){
    Serial.println(“there is EVEN pressure”);
    return true;
  } 
  return false; 
}
// checks for pain pressure
// checks for darkness
void strobe(int pin){
  int loopState = 0; //so doesn’t get called again if called in first part of loop
  int micAmp;
  Serial.println(“First for loop”); 
  for(int i = 0; i<200; i++){ 
    //updateNeoPixels();
    
    if( isHardPressure() ){ 
      loopState = 1;
      showIsPain(); 
      break; 
    } 
    if( isEvenPressure() ){
      loopState = 1;
      preAwaken();
      break;
    }
    if(!isDark()){
      loopState = 1;
      wakeUp(pin,i);
      break;
    } 
    
    if(awakeStateInstance==1){
      updateNeoPixels();
      micAmp = readMicAmp();  
      micAmp = (micAmp*1.5) + i/2;   //more micAmp, less strobe magnitude
      if(micAmp>255){ micAmp=255; } //maxcap micAmp
      analogWrite(pin,micAmp);
      analogWrite(EYES_PIN,micAmp);
    }
    else{
      //analogWrite(pin,micAmp);
      analogWrite(pin,i/2); // division by 2 so moves slower without a big delay
    }
    delay(20);
  }
  Serial.println(“Second for loop”);
  for(int i = 200; i>0; i–) {
    //updateNeoPixels();
    //micAmp = readMicAmp();
    
    if(loopState!=1){ //only execute if no actions in first loop
      if( isHardPressure() ){
        showIsPain();
        break;
      }
      
      if(!isDark()){
        wakeUp(pin,i);
        break;
      }
      if(awakeStateInstance==1){
        updateNeoPixels();
        micAmp = readMicAmp();  
        micAmp = (micAmp*1.5) + i/2;  //more micAmp, less strobe magnitude
        if(micAmp>255){ micAmp=255; } //maxcap micAmp
        analogWrite(pin,micAmp);
        analogWrite(EYES_PIN,micAmp);
      }
      else{
        //analogWrite(pin,micAmp);
        analogWrite(pin,i/2); // division by 2 so moves slower without a big delay
      }
      loopState=0; //reset loopState
    }
  }
}
void wakeUp(int pin, int startingIndex){
  Serial.println(“waking up”);
  for(int i = startingIndex; i>0; i–){
    analogWrite(pin,i/2);  // division by 2 so moves slower without a big delay
    //analogWrite(HANDS_PIN,i);
    delay(5);
  }
}
// shows current fsr input as more intense light
// blinks faster the more times in pain
void showIsPain(){
  resetAll();
  
  int totalLoops = angryState*3;
  int painLevel = 0;
  int pause = 300 – (angryState*3*10);
  if(pause<30){ pause=30; } //mincap pause
  for(int i = 0; i < totalLoops; i++){
    fsr_Reading = analogRead(A1);
    painLevel = 400 + fsr_Reading;
    if(painLevel>1023){ painLevel=1023; } //maxcap painLevel
    
    analogWrite(HEART_PIN, painLevel);
    delay(pause);
    analogWrite(HEART_PIN, 0);
    delay(pause);
  }
  if(angryState==3){
    angryInstances+=1;
    turnAway();
    angryState=0; //reset angryState
    //TODO
    if(angryInstances==3){
      angryInstances = 50;//makes turnAway pause a very long time
      turnAway();
      angryInstances = 0; //reset
    }
  }
}
void preAwaken(){
  Serial.println(“IN PREAWAKEN…”);
  if(awakeStateInstance!=1){ //already woke, cannot do again
    fsr_Reading = analogRead(A1);
    int awakenState = 0;
  
    for(awakenState = 0; awakenState<20; awakenState++){
      Serial.print(”  awakenState: “); Serial.println(awakenState);
      
      if(isEvenPressure()){
        //good, keep looping
        delay(400);   
        updateNeoPixels(); //update slowly  
      }
      else if( isHardPressure() ){
        showIsPain();
      }
      else{
        break;
      }
    }
    Serial.println(”  outside for loop….”);
    //got here, held long enough
    if(awakenState>=19){
      awaken();
    }
  }
}
//TODO
void awaken(){
  Serial.println(“~~~~~~AWAKENING~~~~~”);
  awakeStateInstance = 1;
  
  for(int i = 0; i<510; i++){
    updateAwakenNeoPixels();
    analogWrite(EYES_PIN,i/2);
  }
  for(int i = 510; i>10; i–){
    updateAwakenNeoPixels();
    analogWrite(EYES_PIN,i/2);
  }
}
//TODO: use stepper to turn project away
//increases time the more angryInstances
void turnAway(){
  resetAll();
  int pause = 1000+ ((angryInstances*2)*5);
  
  // TODO: stepper, turn around
  myStepper.step(stepsPerRevolution); //clockwise
  delay( pause ); //unresponsive for pause length
  // TODO: stepper, turn back
  myStepper.step(-stepsPerRevolution);//counter-clockwise
  delay(500);
}
void resetAll(){
  analogWrite(HEART_PIN,0);
  analogWrite(EYES_PIN,0);
  //analogWrite(HANDS_PIN,0);   
}