circuits 3 & 4

Servo Motor :

CAM01972Screen Shot 2014-11-10 at 10.55.45

// Sweep
// by BARRAGAN <http://barraganstudio.com>
// This example code is in the public domain.


#include <Servo.h>
 
Servo myservo;  // create servo object to control a servo
                // a maximum of eight servo objects can be created
 
int pos = 0;    // variable to store the servo position
 
void setup()
{
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
}
 
 
void loop()
{
  for(pos = 0; pos < 180; pos += 1)  // goes from 0 degrees to 180 degrees
  {                                  // in steps of 1 degree
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
  for(pos = 180; pos>=1; pos-=1)     // goes from 180 degrees to 0 degrees
  {                                
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
}

DC Motor:

CAM01974

Screen Shot 2014-11-10 at 13.51.12

/*     -----------------------------------------------------------
 *     |  Arduino Experimentation Kit Example Code               |
 *     |  CIRC-03 .: Spin Motor Spin :. (Transistor and Motor)   |
 *     -----------------------------------------------------------
 * 
 * The Arduinos pins are great for driving LEDs however if you hook 
 * up something that requires more power you will quickly break them.
 * To control bigger items we need the help of a transistor. 
 * Here we will use a transistor to control a small toy motor
 * 
 * http://tinyurl.com/d4wht7
 *
 */
 
int motorPin = 9;  // define the pin the motor is connected to
                   // (if you use pin 9,10,11 or 3you can also control speed)
 
/*
 * setup() - this function runs once when you turn your Arduino on
 * We set the motors pin to be an output (turning the pin high (+5v) or low (ground) (-))
 * rather than an input (checking whether a pin is high or low)
 */
void setup()
{
 pinMode(motorPin, OUTPUT); 
}
 
 
/*
 * loop() - this function will start after setup finishes and then repeat
 * we call a function called motorOnThenOff()
 */
 
void loop()                     // run over and over again
{
 motorOnThenOff();
 //motorOnThenOffWithSpeed();
 //motorAcceleration();
}
 
/*
 * motorOnThenOff() - turns motor on then off 
 * (notice this code is identical to the code we used for
 * the blinking LED)
 */
void motorOnThenOff(){
  int onTime = 2500;  //the number of milliseconds for the motor to turn on for
  int offTime = 1000; //the number of milliseconds for the motor to turn off for
 
  digitalWrite(motorPin, HIGH); // turns the motor On
  delay(onTime);                // waits for onTime milliseconds
  digitalWrite(motorPin, LOW);  // turns the motor Off
  delay(offTime);               // waits for offTime milliseconds
}
 
/*
 * motorOnThenOffWithSpeed() - turns motor on then off but uses speed values as well 
 * (notice this code is identical to the code we used for
 * the blinking LED)
 */
void motorOnThenOffWithSpeed(){
 
  int onSpeed = 200;  // a number between 0 (stopped) and 255 (full speed) 
  int onTime = 2500;  //the number of milliseconds for the motor to turn on for
 
  int offSpeed = 50;  // a number between 0 (stopped) and 255 (full speed) 
  int offTime = 1000; //the number of milliseconds for the motor to turn off for
 
  analogWrite(motorPin, onSpeed);   // turns the motor On
  delay(onTime);                    // waits for onTime milliseconds
  analogWrite(motorPin, offSpeed);  // turns the motor Off
  delay(offTime);                   // waits for offTime milliseconds
}
 
/*
 * motorAcceleration() - accelerates the motor to full speed then
 * back down to zero
*/
void motorAcceleration(){
  int delayTime = 50; //milliseconds between each speed step
 
  //Accelerates the motor
  for(int i = 0; i < 256; i++){ //goes through each speed from 0 to 255     analogWrite(motorPin, i);   //sets the new speed     delay(delayTime);           // waits for delayTime milliseconds   }      //Decelerates the motor   for(int i = 255; i >= 0; i--){ //goes through each speed from 255 to 0
    analogWrite(motorPin, i);   //sets the new speed
    delay(delayTime);           // waits for delayTime milliseconds
  }
}

Little Kinematic Owl

Here is a little kinematic owl with 2 degrees of freedom, neck and eyelids.

For a good while now, I’ve been wanting to experiment on using rubber bands attached to servomotors as a method of creating soft and compliant actuation systems, and this assignment was a very good opportunity to test this idea.

While I did not draw any two dimensional paper sketches, I did create a comprehensive three dimensional sketch in Rhinoceros (its easier for me to think in 3D when building robots.)

owlcad2

When everything looked good, I then proceeded to 3D print all the parts (9 hours for 13 pieces:)

owl (1)

Assembly took the longest.  While the majority of pieces fit nice and snug, I overlooked some screw hole sizes and had to improvise with a hand drill and hot glue:

owl (2) owl (3)

Here is the owl fully assembled:

owl (4)

The eyelids worked very well, and the neck worked fairly well (I had expected a slightly higher range of motion.)  Overall, I think this project was a success as I had learned that rubber bands attached to servo motors can indeed be used to generate compliant actuation.  This project was also a success because I now have a cute kinematic owl sitting on my desk :)

Here is a Fritzing diagram:

OwlBot_Wiring

The code is very simple and makes the owl randomly blink and tilt its head.  When the code is loaded onto the Arduino, the result is a very energetically tired and sleepy-looking owl that is both curious and oblivious to its surroundings.

/* --- PRE SETUP --- */
#include  

Servo eyes;
Servo neck;
int neckAction = 0;
int eyeAction = 0;

/* ----- SETUP ----- */
void setup() {
  eyes.attach(31);
  neck.attach(33);  
}

/* --- MAIN LOOP --- */
void loop() {
  
  //control neck
  neckAction = random(6);
  //neck.write(90);
  
  switch(neckAction) {
    case 0:
      neck.write(90);
      break;
    case 1:
      neck.write(0);
      break;
    case 2:
      neck.write(180);
      break;
  }
  
  //control eyes
  eyeAction = random(10);
  //eyes.write(45);
  
  switch (eyeAction) {
    case 0:
      eyes.write(0);
      break;
    case 1:
      eyes.write(45);
      break;
    case 2:
      eyes.write(22);
      break;
    case 3:
      eyes.write(0);
      delay(100);
      eyes.write(45);  
      break;
  }
  
  delay(1000);
  
}

A good thing to note:  This project was heavily inspired by this USB Owl  created by an unknown Japanese company: https://www.youtube.com/watch?v=xDy2vm5XvZc

Despite the fact that I have never actually seen any of these in person or their internal mechanisms, I thought about how they worked and built everything myself from scratch.

Sensor Display – Cheap Dance Dance

Guaranteed to make your party the hottest of the year for less than $20. Regular DD games cost hundreds of dollars, and play insufferable pop music. Cheap Dance Dance can be set to any of your own music, although lounge is recommended.

CDD works by detecting if the player’s limb is in the right spot by the absence or the presence of light in the area where the limbs shadow is supposed to fall on the wall with simple photoresistors. Thats why the projection serves both as the command screen and the data the the sensors will take in. Although I would have liked to work out some of the details of CDD, like adding graphics (stick figure) as instructions instead of text instructions, or including music built in the program, it works fairly well. The only big flaw is that the connections I made from the wires to the photoresistors are finicky, and they can be a bit slow, also sometimes the game awards non-deserved points every once in a while.

photoresistorTImes5_bb

IMG_0260

Screen Shot 2014-11-06 at 10.37.58 AM

Screen Shot 2014-11-06 at 10.36.43 AMScreen Shot 2014-11-06 at 10.42.35 AM

 

Processing Code:


//Charlotte Stiles 2014

import processing.serial.*;
Serial myPort; 
int startTime;
int elapsTime;
boolean drawRandom = false;
boolean getPoints = false;
int happenOnce = 0;
boolean leftArm, rightArm, bothArms, rightLeg, leftLeg;
int choose = 0; 
int r, g, b,sec, points,getPointsOnce;
boolean rUp, gUp, bUp;
float rUpf, gUpf, bUpf, rDownf, gDownf, bDownf;
PFont font; 

int valueA; // Sensor Value A
int valueB; // Sensor Value B
int valueC;
int valueD;
int valueE;
 
//------------------------------------
void setup() {
 background(100);
 size(400, 400); 
 font = loadFont("Silom-48.vlw");
 textFont(font,32);
 startTime=0;
 sec=3;
 points = 0;
 getPointsOnce = 0;

 r=100;
 g=100;
 b=100;
 // List my available serial ports
 int nPorts = Serial.list().length; 
 for (int i=0; i < nPorts; i++) {
 println("Port " + i + ": " + Serial.list()[i]);
 } 
 
 String portName = Serial.list()[5]; 
 myPort = new Serial(this, portName, 9600);
 serialChars = new ArrayList();
}
 
//------------------------------------
void draw() {
 
 // Process the serial data. This acquires freshest values. 
 processSerial();
 

 rainbow();//changes background



 elapsTime = (millis() - startTime)/1000; //time restarts each time a new move is called


 if ( elapsTime % sec == 0 && elapsTime != 0) { //change the sec to whatever second you want to wait

 drawRandom = true;
 } else {
 drawRandom = false;
 happenOnce = 0;//sets it to 0 when draw random is false so it doesnt trigger
 }

 // println(elapsTime);

 if (drawRandom) {
 if (happenOnce == 0) {
 getPointsOnce = 0;
 // fill(255, 0, 0);
 choose = int(random(1, 5));
 rndColors(); // sets random colors 
 startTime = millis();//resets the time 
 happenOnce = happenOnce + 1;//so it only happens for one frame
 getPointsOnce = 0;
 getPoints=false;
 }
 }
 
 if(getPoints){
 if(getPointsOnce == 0){
 points = points + (sec-elapsTime);//the quicker you are the more points you get
 getPointsOnce = getPointsOnce+1;//so you can only get points once per move
 } 
 }
 text(points,width/2,height*.75);
 switch(choose){
 case 1://///////////////////////////left arm
 text("LEFT ARM up", width/2, 100);
 if (leftArm) {
 getPoints=true;
 text("GOOOD JOB", width/2, 200);
 } else {
 getPoints=false;
 }
 break;
 
 case 2:////////////////////////both arms 
 text("both ARMs up", width/2, 100);
 if (bothArms) {
 getPoints = true;
 text("GOOOD JOB", width/2, 200);
 } else {
 getPoints = false;

 }
 break;
 
 case 3:////////////////////////////////right arm 
 text("right ARM", width/2, 100);
 if (rightArm) {
 getPoints = true;
 text("GOOOD JOB", width/2, 200);
 } else {
 getPoints = false;
 }
 break;
 
 case 4://///////////////////////left leg
 text("LEFT leg outt", width/2, 100);
 if (leftLeg) {
 getPoints=true;
 text("GOOOD JOB", width/2, 200);
 } else {
 getPoints = false;
 }
 break;
 case 5:////////////////////////right leg
 text("rightLeg outt", width/2, 100);
 if (rightLeg) { 
 getPoints = true;
 text("GOOOD JOB", width/2, 200);
 } else {
 getPoints = false;
 }
 break;
 default:
 textAlign(CENTER);
 int startTime = -elapsTime +sec;
 text("starts in: "+ startTime , width/2,40);
 break;
 }



 //sets which photoresistor to true if it has a shadow over it
 if (valueA>200) leftArm = true;
 else {
 leftArm = false;
 }
 if (valueB>200) bothArms=true;
 else {
 bothArms = false;
 }
 if (valueC>200) rightArm=true;
 else {
 rightArm = false;
 }
 if (valueD>200)leftLeg = true;
 else {
 leftLeg = false;
 }
 if (valueE>200) rightLeg = true;
 else {
 rightLeg = false;
 }
 println(getPointsOnce);
}

 
ArrayList serialChars; // Temporary storage for received serial data
int whichValueToAccum = 0; // Which piece of data am I currently collecting? 
boolean bJustBuilt = false; // Did I just finish collecting a datum?
 
void processSerial() {
 
 while (myPort.available () > 0) {
 char aChar = (char) myPort.read();
 
 // You'll need to add a block like one of these 
 // if you want to add a 3rd sensor:
 if (aChar == 'A') {
 bJustBuilt = false;
 whichValueToAccum = 0;
 } else if (aChar == 'B') {
 bJustBuilt = false;
 whichValueToAccum = 1;
 }else if (aChar == 'C') {
 bJustBuilt = false;
 whichValueToAccum = 2;
 } else if (aChar == 'D') {
 bJustBuilt = false;
 whichValueToAccum = 3;
 }else if (aChar == 'E') {
 bJustBuilt = false;
 whichValueToAccum = 4;
 }
 else if (((aChar == 13) || (aChar == 10)) && (!bJustBuilt)) {
 // If we just received a return or newline character, build the number: 
 int accum = 0; 
 int nChars = serialChars.size(); 
 for (int i=0; i < nChars; i++) { 
 int n = (nChars - i) - 1; 
 int aDigit = ((Integer)(serialChars.get(i))).intValue(); 
 accum += aDigit * (int)(pow(10, n));
 }
 
 // Set the global variable to the number we captured.
 // You'll need to add another block like one of these 
 // if you want to add a 3rd sensor:
 if (whichValueToAccum == 0) {
 valueA = accum;
 // println ("A = " + valueA);
 } else if (whichValueToAccum == 1) {
 valueB = accum;
 // println ("B = " + valueB);
 }else if (whichValueToAccum == 2) {
 valueC = accum;
 }else if (whichValueToAccum == 3) {
 valueD = accum;
 }else if (whichValueToAccum == 4) {
 valueE = accum;
 }
 
 // Now clear the accumulator
 serialChars.clear();
 bJustBuilt = true;
 
 } else if ((aChar >= 48) && (aChar <= 57)) {
 // If the char is between '0' and '9', save it.
 int aDigit = (int)(aChar - '0'); 
 serialChars.add(aDigit);
 }
 }
}



 void rndColors(){
 rUp = true; gUp = true; bUp = true;
 //Randoms for Rainbow mode...
 rUpf = random(1, 2);//randomly choose incrememnts
 gUpf = random(1, 2);
 bUpf = random(1, 2);
 rDownf = random(1, 2);
 gDownf = random(1, 2);
 bDownf = random(1, 2);
 r = int(random(100,255));
 g=int(random(100,255));
 b=int(random(100,255));
 }


void rainbow() {
 background(r,g,b);
 
 //////this part of the code is based off of the rainbow part of https://openprocessing.orgsketch/7298 by Thaipo
 
 if (rUp) {
 r += rUpf;
 } else {
 r -= rDownf;
 }
 if (gUp) {
 g += gUpf;
 } else {
 g -= gDownf;
 }
 if (bUp) {
 b += bUpf;
 } else {
 b -= bDownf;
 }
 ///////////////////decide if color is going up or down
 if (r > 255) {
 rUp = false;
 } 
 if (r < 100) {
 rUp = true;
 }
 if (g > 255) {
 gUp = false;
 } 
 if (g < 100) {
 gUp = true;
 }
 if (b > 255) {
 bUp = false;
 } 
 if (b < 100) {
 bUp = true;
 }
 }

Arduino Code:
 

// This Arduino program reads two analog signals, 
// such as from two potentiometers, and transmits 
// the digitized values over serial communication. 
 
int sensorValue0 = 0;  // variable to store the value coming from the sensor
int sensorValue1 = 0;  // variable to store the value coming from the other sensor
int sensorValue2 = 0;
int sensorValue3 = 0;
int sensorValue4 = 0;

void setup() {
  Serial.begin(9600);  // if in the serial monitor it doesnt have this number, use dropdown menue to change that   
}
 
void loop() {
 
  // Read the value from the sensor(s):
  sensorValue0 = analogRead (A0);  // reads value from Analog input 0
  sensorValue1 = analogRead (A1);  // reads value from Analog input 1    
  sensorValue2 = analogRead (A2);
  sensorValue3 = analogRead (A3);
  sensorValue4 = analogRead (A4);
  
  Serial.print ("A"); 
  Serial.println (sensorValue0); 
  Serial.print ("B"); 
  Serial.println (sensorValue1);  
  Serial.print ("C"); 
  Serial.println (sensorValue2);  
  Serial.print ("D"); 
  Serial.println (sensorValue3); 
  Serial.print ("E"); 
  Serial.println (sensorValue4); 
 
  delay (50);   // wait a fraction of a second, to be polite
}
 

Manta Ray Automaton: By Matt Kellogg & Miranda Jacoby

We used a combination of Arduino and a projected Processing sketch to make a seascape featuring a manta ray that moves on one axis. The manta ray is able to consume projected creatures by moving toward them, and avoid projected predators by moving away from them.

sketch1sketch2We were successfully able to create and control one-dimensional movement with our slider, in addition to sculpting a manta ray out of clay. We also created a platform out of foam-core board to serve as housing for our circuit and as our projection surface.
MantaRayatRest2We also gave our manta ray a sweet coat of glow-in-the-dark paint (although we later learned that the manta would not glow under projected light).newmantaarduinoWe managed to create various assets to give the manta ray an interesting environment. (The hammerhead shark was removed from the final project, as Processing was having trouble rendering it correctly.)

tigershark hammerheadshark fish shrimp planktonUnfortunately, due to the lack of documentation for our slider/potentiometer part, we managed to burn out our potentiometer. Because we weren’t able to computationally tell where the manta ray was due to the busted potentiometer, we had no way of detecting collisions, and could not implement behavior allowing the manta ray to move away from enemies (sharks) and towards food objects (everything that isn’t a shark).sliderThe good news is that we were eventually able to replace the part, allowing us to make the manta ray a true automaton: able to function without human interaction. Images, code, and video documentation have been updated accordingly.

Here’s our circuit:

ArduinoBoardMRAutomatonSmallmanta_bb

Here’s our Processing code:

//Miranda Jacoby and Matthew Kellogg
//EMS Interactivity Section A
//majacoby@andrew.cmu.edu, mkellogg@andrew.cmu.edu
//Copyright Miranda Jacoby and Matthew Kellogg 2014

//Matt and Miranda's MantaRay Project
import processing.serial.*;

static class Images {
  static PImage tigerShark;
  static PImage hammerHeadShark;
  static PImage shrimp;
  static PImage fish;
  static PImage plankton;
}

abstract class SeaThing {
  int x, y;
  int offX=0, offY=0;
  int l, r, w, h;
  float scale;
  PImage shape;

  void update() {
    x -= 7;
  }
  
  void draw() {
    pushMatrix();
    translate(x, y);
    scale(scale);
    translate(offX, offY);
    image(shape, 0, 0);
    popMatrix();
  }
};

class Shark extends SeaThing {
  Shark(int x, int y) {
    shape = Images.tigerShark;
    scale = 1.6;
    this.x = x;
    this.y = y;
    this.offX = -145;
    this.offY = -166;
  }
}

abstract class Edible extends SeaThing {
}

class Shrimp extends Edible {
  Shrimp(int x, int y) {
    shape = Images.shrimp;
    scale = 0.25;
    this.x = x;
    this.y = y;
    this.offX = -140;
    this.offY = -120;
  }
}

class Fish extends Edible {
  Fish(int x, int y) {
    shape = Images.fish;
    scale = 0.75;
    this.x = x;
    this.y = y;
    this.offX = -60;
    this.offY = -67;
  }
}

class Plankton extends Edible {
  Plankton(int x, int y) {
    shape = Images.plankton;
    scale = 0.15;
    this.x = x;
    this.y = y;
    this.offX = -230;
    this.offY = -230;
  }
}

class Manta {
  int x, y;
  SeaThing target;
  int value;
  Serial myPort;
  boolean bJustBuilt = false;
  int whichValueToAccum = 0;
  int nChars = 0;
  ArrayList serialChars;
  int RIGHT = 0;
  int LEFT = 1;
  int STOP = 2; 
  int dir;
  int minY, maxY;

  Manta(MantaProcessing thiz, int x, int y) {
    this.x = x;
    this.y = y;
    minY = 220;
    maxY = 550;
    dir = STOP;
    if (Serial.list().length > 0) {
      String portName = Serial.list()[0]; 
      myPort = new Serial(thiz, portName, 9600);
    }
    serialChars = new ArrayList();
  }

  void draw() {
    //if (target!=null) {
    //ellipse(x, y, 100, 100);
    //}
  }

  void moveRight() {
    if (myPort!=null) {
      myPort.write("R\n");
    } else if (y-5>minY){
      y-=5;
    }
    dir = RIGHT;
  }

  void moveLeft() {
    if (myPort!=null) {
      myPort.write("L\n");
    } else if (y+5<maxY){
      y+=5;
    }
    dir = LEFT;
  }

  void moveStop() {
    if (myPort!=null) {
      myPort.write("S\n");
    } else {
      //nothing
    }
    dir = STOP;
  }

  void update() {
    readSerial();
    if (shark!=null && shark.x<x+600){ // run from shark
      if (shark.y<540) {         moveLeft();       } else {         moveRight();       }     }else if (target == null) {       for (SeaThing thing : things) {         if (thing.x > x + 50 && thing.x < x + 300 && thing.y > minY && thing.y  y+20) {
      moveLeft();
    } else if (target.y < y-20) {       moveRight();     } else {       moveStop();     }     if (y>maxY && dir==LEFT) {
      moveStop();
    } else if (y y-20 && thing.y < y+20 && thing.x > x-20 && thing.x <x+20) {         things.remove(i);         i--;       }     }          if (!things.contains(target)){       target = null;     }   }   void readSerial() {     if (myPort==null) return;     while (myPort.available () > 0) {
      char aChar = (char) myPort.read();

      // You'll need to add a block like one of these 
      // if you want to add a 3rd sensor:
      if (aChar == 'A') {
        bJustBuilt = false;
        whichValueToAccum = 0;
      } else if (aChar == 'B') {
        bJustBuilt = false;
        whichValueToAccum = 1;
      } else if (((aChar == 13) || (aChar == 10)) && (!bJustBuilt)) {
        // If we just received a return or newline character, build the number: 
        int accum = 0; 
        int nChars = serialChars.size(); 
        for (int i=0; i < nChars; i++) {            int n = (nChars - i) - 1;            int aDigit = ((Character)(serialChars.get(i))).charValue();            accum += aDigit * (int)(pow(10, n));         }         // Set the global variable to the number we captured.         // You'll need to add another block like one of these          // if you want to add a 3rd sensor:         if (whichValueToAccum == 0) {           value = accum;         }         // Now clear the accumulator         serialChars.clear();         bJustBuilt = true;       } else if ((aChar >= 48) && (aChar <= 57)) {
        // If the char is between '0' and '9', save it.
        char aDigit = (char)(aChar - '0'); 
        serialChars.add(aDigit);
      }
    }
    y = (int)(((maxY-minY)*((1023-value)/1023.0))+minY);
  }
}

ArrayList things = new ArrayList();

PImage sharkImage;
PImage causticsImage;

Manta manta;
Shark shark;
PGraphics causticsGraphics;

void buildCausticsGraphics() {
  PGraphics g = causticsGraphics;
  g.beginDraw();
  g.blendMode(ADD);
  g.tint(100, 100, 255, 100);
  g.image(causticsImage, 0, 0);
  g.endDraw();
  g.loadPixels();
  for (int y=0; y<g.height; y++) {
    for (int x=0; x<g.width; x++) {
      color c = g.pixels[x+y*g.width];
      c = color(red(c), green(c), blue(c), blue(c));
      g.pixels[x+y*g.width] = c;
    }
  }
}

void setup() {
  causticsImage = loadImage("caustics.png");
  causticsGraphics = createGraphics(causticsImage.width, causticsImage.height);
  buildCausticsGraphics();
  size(1920, 1080);
  frameRate(60);
  Images.tigerShark = loadImage("tigershark.png");
  Images.hammerHeadShark = loadImage("hammerheadshark.png");
  Images.shrimp = loadImage("shrimp.png");
  Images.fish = loadImage("fish.png");
  Images.plankton = loadImage("plankton.png");
  shark = new Shark(200, 200);
  things.add(shark);
  manta = new Manta(this, width/4, height/2);
}

void draw() {
  if ((frameCount % 20)==0) {
    float r = random(0, 80);
    if (r<2) {
      if (shark==null) {
        shark = new Shark(width*2, 200);
        things.add(shark);
      }
    } else if (r<4) {
      if (shark==null) {
        shark = new Shark(width*2, height - 200);
        things.add(shark);
      }
    } else if (r<24) {
      things.add(new Fish(width*2, (int)random(250, height-250)));
    } else if (r<44) {
      things.add(new Plankton(width*2, (int)random(250, height-250)));
    } else if (r<64) {
      things.add(new Shrimp(width*2, (int)random(250, height-250)));
    }
  }

  for (SeaThing thing : things) {
    thing.update();
  }

  //remove things that are far off screen
  for (int i = 0; i < things.size (); i++) {
    if (things.get(i).x<-width) {
      if (things.get(i) instanceof Shark){
        shark = null;
      }
      things.remove(i);
      i--;
    }
  }

  manta.update();

  background(10, 30, 75);
  image(causticsGraphics, -(frameCount%causticsGraphics.width), 0);
  image(causticsGraphics, -(frameCount%causticsGraphics.width)+causticsGraphics.width, 0);
  image(causticsGraphics, -(frameCount%causticsGraphics.width)+2*causticsGraphics.width, 0);
  for (SeaThing thing : things) {
    thing.draw();
  }

  manta.draw();
  image(causticsGraphics, -((frameCount*2)%causticsGraphics.width), -causticsGraphics.height/2);
  image(causticsGraphics, -((frameCount*2)%causticsGraphics.width)+causticsGraphics.width, -causticsGraphics.height/2);
  image(causticsGraphics, -((frameCount*2)%causticsGraphics.width)+2*causticsGraphics.width, -causticsGraphics.height/2);
  image(causticsGraphics, -((frameCount*2)%causticsGraphics.width), causticsGraphics.height/2);
  image(causticsGraphics, -((frameCount*2)%causticsGraphics.width)+causticsGraphics.width, causticsGraphics.height/2);
  image(causticsGraphics, -((frameCount*2)%causticsGraphics.width)+2*causticsGraphics.width, causticsGraphics.height/2);
}

Here’s our Arduino code:

// Arduino control for the Manta Ray
// Author: Matthew Kellogg
// Copyright 2014 Matthew Kellogg

static const int dirPin = 2;
static const int goPin = 4;

boolean go = false;
boolean dir = false;

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

void loop(){
  //Print the value from the potentiometer
  // to serial
  Serial.println("A"+(String)(analogRead(0)));
  
  //Process available controls
  while (Serial.available()){
    char a = Serial.read();
    switch (a){
    case 'L':
      dir = false;
      go = true;
      break;
    case 'R':
      dir = true;
      go = true;
      break;
    case 'S':
      go = false;
      break;
    default:
      break;
    };
  }
  // Set digital outputs based on controls
  digitalWrite(goPin,go);
  digitalWrite(dirPin,dir);
  // Delay to allow some control to control to happen
  delay(50);
}

 

Automaton Drawing

For my automaton I want to make a machine that types. I was originally intending to make a machine that could type a specific message, but Golan challenged me to make it so that the machine could type any words made with the tow row of a qwerty keyboard.

IMG_1104

This automaton would be designed to fit over any full Apple keyboard, letting it interface with all of the computers in our clusters, as well as giving it some application to the wider world. I am as of yet uncertain what I exactly want it to type, although I am considering randomly generating phrases and selecting ones I like to use later. My instinct towards the generative that may not be suited to the piece, however.

Rat Tales

“Rat Tales” is a performative installation I created using an Arduino, slider potentiometer, servo, black bandana, and leather. This work is created in response to some encumbering experiences I had this summer as I began exploring different ‘scenes’ embedded in North Texas gay culture. This performance is specifically centered around my experiences at a leather bar; the subject of the photographs displayed in the video.

For the duration of the performance, I am blindfolded with a black bandana and sit in a dark, cramped closet. I use the slider potentiometer to control the leather rat-tail that emerges from the dark crack under the door. Significance can be found within the combination of the material, shape, and motion of the rat-tail.

Rat Tail FritzIMG_8715

 

ratTalesSketch

 

/*
Will Taylor
Rat tail thats position is controlled by the slider sensor
*/

#include <Servo.h>

Servo ratTail; // servo to control the rat tail

int sliderPin = 0; // slider connected to A0
int val; // variable to read the value from the analog pin

void setup()
{
ratTail.attach(9); // attaches servo to pin9
}

void loop()
{
val = analogRead(sliderPin); // reads slider value
val = map(val, 0, 1023, 0, 180); // maps slider value to servo position between 0 and 180 degrees
ratTail.write(val); // sets the servo position according to the scaled value
delay(15); // waits for the servo to get there
}

Automaton: Art Is

Make art, make art, an artist should make art. It’s a command, it’s an instinct, an impulse. My piece “The Art Is” looks at the almost mechanical nature in which art is created. As the servo spins, it moves the wires attached to it and, as result, also spins the handle back and forth. This prompts foot like gears that kick the posts connected to the desk and the arm of the automaton and move it up and down. The automaton is forced to make art until it bleeds.

The artist The Artist

Final Product

IMG_0470 IMG_0471 IMG_0472

Circuit

Servo diagram Servo diagram

Aurdino code:



// Sweep
// by BARRAGAN

#include &lt;Servo.h&gt;

Servo myservo; // create servo object to control a servo
// a maximum of eight servo objects can be created

int pos = 0; // variable to store the servo position

void setup()
{
myservo.attach(9); // attaches the servo on pin 9 to the servo object
}

void loop()
{
for(pos = 0; pos &lt; 270; pos += 1) // increased the distance the servo spins to 270
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(5); // decreased the delay to 5 seconds
}
for(pos = 270; pos&gt;=1; pos-=1) // increased the distance in which the servo spins to 270
{
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(5); // decreased the delay to 5 second
}
}

10/5/2014

diagram diagram

For my automaton I aim to create a human like structure made out of sculpey clay, wood and wire that moves both it’s head and hands in response to the motor. Below are a few sketches I made for the automaton and the specific gears and parts that might be required for it.

Structure interior Structure interior gears How it will function

 

Circuits 3 and 4

 

Working with Motors:
Circuit 3: Toy Motor

Circuit 3 diagram Circuit 3 diagram

 

Circuit 3 Circuit 3

Code:

/*     -----------------------------------------------------------
 *     |  Arduino Experimentation Kit Example Code               |
 *     |  CIRC-03 .: Spin Motor Spin :. (Transistor and Motor)   |
 *     -----------------------------------------------------------
 * 
 * The Arduinos pins are great for driving LEDs however if you hook 
 * up something that requires more power you will quickly break them.
 * To control bigger items we need the help of a transistor. 
 * Here we will use a transistor to control a small toy motor
 * 
 * http://tinyurl.com/d4wht7
 *
 */

int motorPin = 9;  // define the pin the motor is connected to
                   // (if you use pin 9,10,11 or 3you can also control speed)

/*
 * setup() - this function runs once when you turn your Arduino on
 * We set the motors pin to be an output (turning the pin high (+5v) or low (ground) (-))
 * rather than an input (checking whether a pin is high or low)
 */
void setup()
{
 pinMode(motorPin, OUTPUT); 
}


/*
 * loop() - this function will start after setup finishes and then repeat
 * we call a function called motorOnThenOff()
 */

void loop()                     // run over and over again
{
 motorOnThenOff();
 //motorOnThenOffWithSpeed();
 //motorAcceleration();
}

/*
 * motorOnThenOff() - turns motor on then off 
 * (notice this code is identical to the code we used for
 * the blinking LED)
 */
void motorOnThenOff(){
  int onTime = 2500;  //the number of milliseconds for the motor to turn on for
  int offTime = 1000; //the number of milliseconds for the motor to turn off for
  
  digitalWrite(motorPin, HIGH); // turns the motor On
  delay(onTime);                // waits for onTime milliseconds
  digitalWrite(motorPin, LOW);  // turns the motor Off
  delay(offTime);               // waits for offTime milliseconds
}

/*
 * motorOnThenOffWithSpeed() - turns motor on then off but uses speed values as well 
 * (notice this code is identical to the code we used for
 * the blinking LED)
 */
void motorOnThenOffWithSpeed(){
  
  int onSpeed = 200;  // a number between 0 (stopped) and 255 (full speed) 
  int onTime = 2500;  //the number of milliseconds for the motor to turn on for
  
  int offSpeed = 50;  // a number between 0 (stopped) and 255 (full speed) 
  int offTime = 1000; //the number of milliseconds for the motor to turn off for
  
  analogWrite(motorPin, onSpeed);   // turns the motor On
  delay(onTime);                    // waits for onTime milliseconds
  analogWrite(motorPin, offSpeed);  // turns the motor Off
  delay(offTime);                   // waits for offTime milliseconds
}

/*
 * motorAcceleration() - accelerates the motor to full speed then
 * back down to zero
*/
void motorAcceleration(){
  int delayTime = 50; //milliseconds between each speed step
  
  //Accelerates the motor
  for(int i = 0; i < 256; i++){ //goes through each speed from 0 to 255     analogWrite(motorPin, i);   //sets the new speed     delay(delayTime);           // waits for delayTime milliseconds   }      //Decelerates the motor   for(int i = 255; i >= 0; i--){ //goes through each speed from 255 to 0
    analogWrite(motorPin, i);   //sets the new speed
    delay(delayTime);           // waits for delayTime milliseconds
  }
}



Circuit 4: Servo

Circuit 4 diagram Circuit 4 diagram

 

Circuit 4 Circuit 4

Code:

// Sweep
// by BARRAGAN  

#include  
 
Servo myservo;  // create servo object to control a servo 
                // a maximum of eight servo objects can be created 
 
int pos = 0;    // variable to store the servo position 
 
void setup() 
{ 
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object 
} 
 
 
void loop() 
{ 
  for(pos = 0; pos < 180; pos += 1)  // goes from 0 degrees to 180 degrees    {                                  // in steps of 1 degree      myservo.write(pos);              // tell servo to go to position in variable 'pos'      delay(15);                       // waits 15ms for the servo to reach the position    }    for(pos = 180; pos>=1; pos-=1)     // goes from 180 degrees to 0 degrees 
  {                                
    myservo.write(pos);              // tell servo to go to position in variable 'pos' 
    delay(15);                       // waits 15ms for the servo to reach the position 
  } 
} 



Servo

20141103_225438

 

CIRC04

 

// Sweep
// by BARRAGAN <http://barraganstudio.com> 
// This example code is in the public domain.
 
 
#include  
 
Servo myservo;  // create servo object to control a servo 
                // a maximum of eight servo objects can be created 
 
int pos = 0;    // variable to store the servo position 
 
void setup() 
{ 
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object 
} 
 
 
void loop() 
{ 
  for(pos = 0; pos < 180; pos += 1)  // goes from 0 degrees to 180 degrees    {                                  // in steps of 1 degree      myservo.write(pos);              // tell servo to go to position in variable 'pos'      delay(15);                       // waits 15ms for the servo to reach the position    }    for(pos = 180; pos>=1; pos-=1)     // goes from 180 degrees to 0 degrees 
  {                                
    myservo.write(pos);              // tell servo to go to position in variable 'pos' 
    delay(15);                       // waits 15ms for the servo to reach the position 
  } 
}

DC Motor

20141103_222817

CIRC03

 


/*     -----------------------------------------------------------
 *     |  Arduino Experimentation Kit Example Code               |
 *     |  CIRC-03 .: Spin Motor Spin :. (Transistor and Motor)   |
 *     -----------------------------------------------------------
 * 
 * The Arduinos pins are great for driving LEDs however if you hook 
 * up something that requires more power you will quickly break them.
 * To control bigger items we need the help of a transistor. 
 * Here we will use a transistor to control a small toy motor
 * 
 * http://tinyurl.com/d4wht7
 *
 */
 
int motorPin = 9;  // define the pin the motor is connected to
                   // (if you use pin 9,10,11 or 3you can also control speed)
 
/*
 * setup() - this function runs once when you turn your Arduino on
 * We set the motors pin to be an output (turning the pin high (+5v) or low (ground) (-))
 * rather than an input (checking whether a pin is high or low)
 */
void setup()
{
 pinMode(motorPin, OUTPUT); 
}
 
 
/*
 * loop() - this function will start after setup finishes and then repeat
 * we call a function called motorOnThenOff()
 */
 
void loop()                     // run over and over again
{
 motorOnThenOff();
 //motorOnThenOffWithSpeed();
 //motorAcceleration();
}
 
/*
 * motorOnThenOff() - turns motor on then off 
 * (notice this code is identical to the code we used for
 * the blinking LED)
 */
void motorOnThenOff(){
  int onTime = 2500;  //the number of milliseconds for the motor to turn on for
  int offTime = 1000; //the number of milliseconds for the motor to turn off for
 
  digitalWrite(motorPin, HIGH); // turns the motor On
  delay(onTime);                // waits for onTime milliseconds
  digitalWrite(motorPin, LOW);  // turns the motor Off
  delay(offTime);               // waits for offTime milliseconds
}
 
/*
 * motorOnThenOffWithSpeed() - turns motor on then off but uses speed values as well 
 * (notice this code is identical to the code we used for
 * the blinking LED)
 */
void motorOnThenOffWithSpeed(){
 
  int onSpeed = 200;  // a number between 0 (stopped) and 255 (full speed) 
  int onTime = 2500;  //the number of milliseconds for the motor to turn on for
 
  int offSpeed = 50;  // a number between 0 (stopped) and 255 (full speed) 
  int offTime = 1000; //the number of milliseconds for the motor to turn off for
 
  analogWrite(motorPin, onSpeed);   // turns the motor On
  delay(onTime);                    // waits for onTime milliseconds
  analogWrite(motorPin, offSpeed);  // turns the motor Off
  delay(offTime);                   // waits for offTime milliseconds
}
 
/*
 * motorAcceleration() - accelerates the motor to full speed then
 * back down to zero
*/
void motorAcceleration(){
  int delayTime = 50; //milliseconds between each speed step
 
  //Accelerates the motor
  for(int i = 0; i < 256; i++){ //goes through each speed from 0 to 255     analogWrite(motorPin, i);   //sets the new speed     delay(delayTime);           // waits for delayTime milliseconds   }      //Decelerates the motor   for(int i = 255; i >= 0; i--){ //goes through each speed from 255 to 0
    analogWrite(motorPin, i);   //sets the new speed
    delay(delayTime);           // waits for delayTime milliseconds
  }
}