FINAL PROJECT: Loopy Aim Game Prototype & Custom Controller

The Processing sketch for my final project features an array of targets based off the JitterBug examples in Getting Started With Processing, serial communication and a reticle mapped to the potentiometer values, collision detection when the player sweeps the reticle over the targets, and a simulated motion blur effect.

I concealed the Arduino and 2 potentiometers in a hollow three-sided pyramid cut from masonite, then added some “Nice Feel” knobs for control. Below is a photo of the pyramid controller and some screenshots from Processing:

Check it out in action here:
http://www.youtube.com/watch?v=GSUucLaHzMI

 

Here’s some process work from building the controller (that soldering comic was great):

 

If you want to check out the Processing sketch but want to use your mouse instead, check out MOUSE VERSION after the break. It’s set to 800×600, but you can change the resolution and it should work fine. I increased the array to 150 for the larger 1080p resolution.

 

Processing sketch (CONTROLLER VERSION – 1080p):

processing codeLeeSaynor_LoopyAimGame_V01_CONTROLLER_1080p

/*****
 *
 * Loopy Aim Game Prototype v0.1 (CONTROLLER VERSION) by Lee Saynor
 *
 * My goal for this final project was to build a simple game controller and aiming game.
 * This sketch demonstrates an array, mouseOverCircle behavior, and a simulated motion blur effect. 
 * The CONTROLLER VERSION demonstrates using potentiometer serial data from Arduino.
 *
 * Next steps: Rotating triangular reticle, score system, levels, different colors
 *
 * Adapted from http://itp.nyu.edu/physcomp/Labs/SerialDuplex
 * Tips 8, 17 from http://amnonp5.wordpress.com/2012/01/28/25-life-saving-tips-for-processing/
 * Chapter 9 and Example 10-10 from Getting Started with Processing
 *
 *****/


import processing.serial.*;             // Import the Processing serial library
Serial myPort;                          // The serial port
float xPos, yPos;                       // Reticle position
JitterBug[] bugs = new JitterBug[150];  // Array of targets

void setup() {
  size(1920, 1080);                     // Ctrl+Shift+R to fullscreen
  smooth();
  
  // Serial port diagnostic and opening the port:
  println(Serial.list());
  String portName = Serial.list()[0];
  myPort = new Serial(this, portName, 9600);
  myPort.bufferUntil('\n');
  
  // Create an array of JitterBug objects:
  for (int i = 0; i < bugs.length; i++) {
    // DATA TYPES MUST MATCH CONSTRUCTOR'S:
    float x = random(25, width-25);     // Starting x position
    float y = random(25, height-25);    // Starting y position
    int r = 20;
    float speed = random(2.0, 6.0);
    // Intialize object and pass parameters into JitterBug class constructor (repeating):
    bugs[i] = new JitterBug(x, y, r, speed); 
  }
}


void draw() {
  // Semi-transparent white rectangle motion blur trick (not very flexible):
  noStroke();
  fill(255, 10);
  rect(0, 0, width, height);
  
  // Reticle for aiming:
  noFill();
  stroke(#B62084);      // Old reticle color blue: #57A9F2
  strokeWeight(25);
  ellipse(xPos, yPos, 75, 75);
  
  // Draw JitterBug array:
  for (int i = 0; i < bugs.length; i++) {
    bugs[i].move();
    bugs[i].targeted();
    bugs[i].display();
  }    
}


void serialEvent(Serial myPort) {
  // Each time data is received from Arduino, trim the whitespace, split it into two sensors,
  // then print their values to the console: 
  String myString = myPort.readStringUntil('\n');
  if (myString != null) {
    myString = trim(myString);
    int sensors[] = int(split(myString, ','));
    
    for (int sensorNum = 0; sensorNum < sensors.length; sensorNum++) {
      print("Sensor " + sensorNum + ": " + sensors[sensorNum] + "\t");
    }
    println();
    
    // Making sensor values proportional to window size:
    if (sensors.length > 1) {
      xPos = map(sensors[0], 0,1023,0,width);
      yPos = map(sensors[1], 0,1023,0,height);
    }
  }
}



class JitterBug {
  
  float x;
  float y;
  int diameter;
  float speed;
 
  JitterBug(float tempX, float tempY, int tempDiameter, float tempSpeed) {    // The Constructor
    x = tempX;
    y = tempY;
    diameter = tempDiameter;
    speed = tempSpeed;
  }  
  
  void move() {
    // Position of target modified by random values on each trip through draw(), constrained
    x += random(-speed, speed);
    y += random(-speed, speed);
    x = constrain(x, 12, width-12);
    y = constrain(y, 12, height-12);
  }
    
  void targeted() {
    // If targeted, flash magenta and perma-slow
    if (reticleOverCircle(x, y, diameter)) {
      stroke(#FF0066);           // Old targeted color red: #EE0000
      speed = 0.2;
    } else { stroke(#0BB5FF);    // Old default target color orange: #EE7600
    }
  }
        
  void display() {
    // The target shape itself
    noFill();
    strokeWeight(5);
    ellipse(x, y, diameter, diameter);
  }
    
  boolean reticleOverCircle(float tempX, float tempY, float tempDiameter) {
    return (dist(xPos, yPos, x, y) < diameter*0.9); // Sensitivity
  }
}

 

Arduino sketch:

arduino codeSerialDuplex_2PotsMod

void setup() {
  // start serial port at 9600 bps:
  Serial.begin(9600);
}

void loop() {
  // read the sensor:
  int sensorValue = analogRead(A0);
  // print the results:
  Serial.print(sensorValue);
  Serial.print(",");
  
  // read the sensor:
  sensorValue = analogRead(A1);
  // print the results:
  Serial.println(sensorValue);
//  Serial.print(",");
}

Continue reading FINAL PROJECT: Loopy Aim Game Prototype & Custom Controller

“AWARE” Graphing Humidity & Temperature in Real-time

I used this project to analyze invisible properties of my home environment, humidity and temperature, so that I would be more “AWARE.”

My inspiration was a painful sinus infection and this wiseGEEK article (DID YOU KNOW?: “Some of the telltale signs of low humidity are a parched feeling, such as cracked skin and a dry, scratchy throat. More serious health problems might involve respiratory problems and a susceptibility to colds or other infections.”)

Then I found an Instructable for Visualizing humidity with the SHT11 sensor and Arduino, and decided I could use Processing to plot the sensor readings in real-time.

Above, from left: Photo of the circuit, sensor readings printed to Arduino Serial Monitor (in room on cold March day), and testing graph sensitivity by breathing on sensor (in living room on April day, raining outside)

Can you guess what I’m graphing here?:

Brought my laptop and circuit into the washroom to graph humidity during a shower. The graph takes a while to pick up steam, humidity peaks when I dry my hair, then falls off when I open the door. Labels are added at 1 minute intervals, but there is a bit of give that would be nice to fix for graphing longer periods of time. I’d also like to get the Call and Response (Handshaking) Method to work, but I had issues with it returning two lines instead of one each time.

 

Processing sketch: 

processing codeLeeSaynor_HumidTempGraph

/*****
 *
 * Real-time Humidity & Temperature Graph by Lee Saynor
 *
 * Graphs humidity and temperature from Arduino/SHT11 sensor and marks at 1 min intervals.
 *
 * "AWARE" because I was getting sick over and over again, and read that air dryness might be a
 * contributing factor. Testing revealed air was averaging 24% humidity, approx half recommended.
 * Bought humidifier for sleeping. Seems to have helped.
 *
 * Inspiration: http://www.instructables.com/id/VISUALIZE-humidity-with-the-SHT11-sensor/?ALLSTEPS
 * Adapted from http://itp.nyu.edu/physcomp/Labs/SerialDuplex
 * Found Millis() tip on http://amnonp5.wordpress.com/2012/01/28/25-life-saving-tips-for-processing/
 *
 *****/


import processing.serial.*;
Serial myPort;
PFont font;
int timer;
float xPosT = 0;
float xPosH = 0;
float yPosT = 0;
float yPosH = 0;

void setup() {
  size(1800, 600);
  
  // Serial port diagnostic and opening the port. NOT standard baud rate: 
  println(Serial.list());  
  String portName = Serial.list()[0];
  myPort = new Serial(this, portName, 38400);
  myPort.bufferUntil('\n');
  
  font = loadFont("FixedsysExcelsiorIIIb-16.vlw");
  textFont(font);
  
  // Set background to black and draw the Start label:
  background(0);
  fill(255);
  text("☼" + hour() + ":" + minute() + ":" + second(), 0, 15);
  fill(#007FFF);
  text("HUMID... ", 0, 30);
  fill(#FC1501);
  text("TEMP... ", 0, 45);
}


void draw() {
  // Drawing happens in serialEvent below...
}


void serialEvent(Serial myPort) {
  // Each time data is received from Arduino, trim the whitespace, split it into two sensors,
  // then print their values to the console, along with a timestamp:
  String myString = myPort.readStringUntil('\n');
  if (myString != null) {
    myString = trim(myString);
    float sensor[] = float(split(myString, ','));
    
    for (int sensorNum = 0; sensorNum < sensor.length; sensorNum++) {
      print("Sensor " + sensorNum + ": " + sensor[sensorNum] + "\t");
    }
    print("Time: " + hour() + ":" + minute() + ":" + second() + "\t");
    println();
    
    // This part draws the blue and red lines and makes them proportional to the window height:
    if (sensor.length > 1) {
      yPosH = map(sensor[1], 0, 100, 0, height);
      stroke(#007FFF);
      line(xPosH, height, xPosH, height - yPosH);
      yPosT = map(sensor[0], 0, 100, 0, height);
      stroke(#FC1501);
      line(xPosT, height, xPosT, height - yPosT);
      
      // Labels pop up at *ahem* "1 minute" marks (there is some drifting..):
      if (millis() - timer >= 60000) {
        timer = millis();
        fill(255);
        text(hour() + ":" + minute() + ":" + second(), xPosH, 15);
        fill(#007FFF);
        text(sensor[1] + "%", xPosH, 30);
        fill(#FC1501);
        text(sensor[0] + "°C", xPosH, 45);
        stroke(255);
        line(xPosH, 50, xPosH, height - yPosH - 3);        
      }
    }
  }
  
  // If graph hits the window edge, reset to black. Otherwise, keep incrementing the x-position:
  if ((xPosT >= width) || (xPosH >= width)) {
    xPosT = 0;
    xPosH = 0;
    background(0);
  } else {
    xPosT += 4;
    xPosH += 4;
  }
}

 

Arduino sketch: 

arduino codeReadSHT1xValues_Working

/*****
 *
 * ReadSHT1xValues
 *
 * Read temperature and humidity values from an SHT1x-series (SHT10,
 * SHT11, SHT15) sensor.
 *
 * Copyright 2009 Jonathan Oxer <jon@oxer.com.au>
 * www.practicalarduino.com
 *
 *****/

#include <SHT1x.h>

// Specify data and clock connections and instantiate SHT1x object
#define dataPin  9      // Original value: 10 
#define clockPin 11
SHT1x sht1x(dataPin, clockPin);

void setup()
{
   Serial.begin(38400); // Open serial connection to report values to host
   Serial.println("Starting up");
}

void loop()
{
  float temp_c;
  float temp_f;
  float humidity;

  // Read values from the sensor
  temp_c = sht1x.readTemperatureC();
  temp_f = sht1x.readTemperatureF();
  humidity = sht1x.readHumidity();

  // Print the values to the serial port (original commented out):
//  Serial.print("Temperature: ");
//  Serial.print(temp_c, DEC);
//  Serial.print("C / ");
//  Serial.print(temp_f, DEC);
//  Serial.print("F. Humidity: ");
//  Serial.print(humidity);
//  Serial.println("%");
  // Modified:
  Serial.print(temp_c);
  Serial.print(",");
  Serial.println(humidity);
  
  delay(2000);
}

Alanna’s Final Project

 

 

 

This project was an experiment in the tactile nature of instillations. I wanted to create something that create music when you touched it. This didn’t end up working in quite the way I wanted, but with more trouble shooting the music aspect should work.

Arduino code:

/*
This is a rehashed version of the pull down version of the button sketch. Each spine has a 2M pull up resistor. When someone holds both point of the creature, these connect and work as a button.
*/

int button1 = 2;
int button1val = 0;
int button2 = 3;
int button2val = 0;
int button3 = 4;
int button3val = 0;
int button4 = 5;
int button4val = 0;
int button5 = 6;
int button5val = 0;
int button6 = 7;
int button6val = 0;
int button7 = 8;
int button7val = 0;
int button8 = 9;
int button8val = 0;
int button9 = 10;
int button9val = 0;
int button10 = 11;
int button10val = 0;

void setup(){
Serial.begin(9600);
pinMode(button1, INPUT);
pinMode(button2, INPUT);
pinMode(button3, INPUT);
pinMode(button4, INPUT);
pinMode(button5, INPUT);
pinMode(button6, INPUT);
pinMode(button7, INPUT);
pinMode(button8, INPUT);
pinMode(button9, INPUT);
pinMode(button10, INPUT);
}

void loop(){
button1val = digitalRead(button1);
Serial.print(button1val);
Serial.print(“,”);
button2val = digitalRead(button2);
Serial.print(button2val);
Serial.print(“,”);
button3val = digitalRead(button3);
Serial.print(button3val);
Serial.print(“,”);
button4val = digitalRead(button4);
Serial.print(button4val);
Serial.print(“,”);
button5val = digitalRead(button5);
Serial.print(button5val);
Serial.print(“,”);
button6val = digitalRead(button6);
Serial.print(button6val);
Serial.print(“,”);
button7val = digitalRead(button7);
Serial.print(button7val);
Serial.print(“,”);
button8val = digitalRead(button8);
Serial.print(button8val);
Serial.print(“,”);
button9val = digitalRead(button9);
Serial.print(button9val);
Serial.print(“,”);
button10val = digitalRead(button10);
Serial.print(button10val);
Serial.println();
delay(50);
}

Processing code:

//This is the current, working version of the sketch. It will display each of the tests as a circle on the screen. The idea was to have each file play as you completed the circuit, but processing seems to have different ideas. Despite the conversion of files, the rehashing of code, and all that I tried to do, none of the files appart from the test file would respond to the hardware.

import processing.serial.*;
Serial myPort;
import ddf.minim.*;
Minim minim;

//AudioSample bass1;
//AudioSample bass2;
//AudioSample bass3;
//AudioSample loop1;
//AudioSample loop2;
//AudioSample loop3;
//AudioSample hat1;
//AudioSample hat2;
//AudioSample kick1;
//AudioSample kick2;
//AudioSample kick3;
//AudioSample growl;

int play1;
int play2;
int play3;
int play4;
int play5;
int play6;
int play7;
int play8;
int play9;
int play10;

void setup() {
minim = new Minim(this);
// growl = minim.loadSample(“growl.wav”);
// bass1 = minim.loadSample(“bass001.wav”);
// bass2 = minim.loadSample(“bass002.wav”);
// bass3 = minim.loadSample(“bass001.mp3”);
// loop1 = minim.loadSample(“Dubloop_1.wav”);
// loop2 = minim.loadSample(“Dubloop_2.wav”);
// loop3 = minim.loadSample(“Dubloop_3.wav”);
// hat1 = minim.loadSample(“hat001.wav”);
// hat2 = minim.loadSample(“hat002.wav”);
// kick1 = minim.loadSample(“kick001.wav”);
// kick2 = minim.loadSample(“kick002.wav”);
// kick3 = minim.loadSample(“kick003.wav”);

println(Serial.list());
String portName = Serial.list()[0];
myPort = new Serial(this, portName, 9600);
myPort.bufferUntil(‘\n’);
size(1100, 300);
}

void draw() {
background(0);
if (play1 == 1) {
ellipse(100, height/2, 50, 50);
// bass1.play();
}
if (play2 == 1) {
ellipse(200, height/2, 50, 50);
//bass2.play();
}
if (play3 == 1) {
ellipse(300, height/2, 50, 50);
//loop1.play();
}
if (play4 == 1) {
ellipse(400, height/2, 50, 50);
//loop2.play();
}
if (play5 == 1) {
ellipse(500, height/2, 50, 50);
//loop3.play();
}
if (play6 == 1) {
ellipse(600, height/2, 50, 50);
//hat1.play();
}
if (play7 == 1) {
ellipse(700, height/2, 50, 50);
//hat2.play();
}
if (play8 == 1) {
ellipse(800, height/2, 50, 50);
//kick1.play();
}
if (play9 == 1) {
ellipse(900, height/2, 50, 50);
//kick2.play();
}
if (play10 == 1) {
ellipse(1000, height/2, 50, 50);
//kick3.play();
}
}

void serialEvent(Serial myPort) {
String myString = myPort.readStringUntil(‘\n’);
if (myString != null) {
println(myString);
}

myString = trim(myString);
int sensors[] = int(split(myString, ‘,’));
for (int sensorNum = 0; sensorNum < sensors.length; sensorNum++) {
print(“Sensor ” + sensorNum + “: ” + sensors[sensorNum] + “\t”);
}

println();
background(0);

ellipseMode(CENTER);
if (sensors[0] == 0) {
play1 = 1;
}
else {
play1 = 0;
}

if (sensors[1] == 0) {
play2 = 1;
}
else {
play2 = 0;
}

if (sensors[2] == 0) {
play3 = 1;
}
else {
play3 = 0;
}

if (sensors[3] == 0) {
play4 = 1;
}
else {
play4 = 0;
}
if (sensors[4] == 0) {
play5 = 1;
}
else {
play5 = 0;
}

if (sensors[5] == 0) {
play6 = 1;
}
else {
play6 = 0;
}

if (sensors[6] == 0) {
play7 = 1;
}
else {
play7 = 0;
}

if (sensors[7] == 0) {
play8 = 1;
}
else {
play8 = 0;
}

if (sensors[8] == 0) {
play9 = 1;
}
else {
play9 = 0;
}

if (sensors[9] == 0) {
play10 = 1;
}
else {
play10 = 0;
}
//
// if (sensors[9] == 0){
//play2 = 1;
//}
}

void stop() {
// bass1.close();
// bass2.close();
// bass3.close();
// loop1.close();
// loop2.close();
// loop3.close();
// hat1.close();
// hat2.close();
// kick1.close();
// kick2.close();
// kick3.close();
//
// minim.stop();
// super.stop();
}

Project 3 Documentation

For my project I wanted to use force sensors, and ended up with the Handshake Rater as my final concept. It’s based on old carnival test your strength games, and the background is a single image I created using various edited components. The fist is separate from the background, and goes up according to the force applied to the sensor in the glove. When you squeeze the glove in a handshake, it shows the measurement of the squeeze on the screen, ranging from ‘Rattle Shaker’ as the weakest and ‘Father In-Law’ as the strongest. I wanted to work with the concept of measuring hidden intentions, and judgements based off of body language. I switched the 110k resistor for a 330k resistor so that it wasn’t quite so sensitive when it’s squeezed. 

 

ARDUINO CODE

I took this code from the force resistor tutorial.

——————–

int fsrPin = 0; // the FSR and 10K pulldown are connected to a0
int fsrReading; // the analog reading from the FSR resistor divider

void setup(void) {
// We’ll send debugging information via the Serial monitor
Serial.begin(9600);
}

void loop(void) {
fsrReading = analogRead(fsrPin);
fsrReading = constrain(fsrReading, 0, 750);

//Serial.print(“Analog reading = “);
Serial.println(fsrReading); // the raw analog reading

// We’ll have a few threshholds, qualitatively determined
// if (fsrReading < 10) {
// Serial.println(” – No pressure”);
// } else if (fsrReading < 200) {
// Serial.println(” – Light touch”);
// } else if (fsrReading < 500) {
// Serial.println(” – Light squeeze”);
// } else if (fsrReading < 800) {
// Serial.println(” – Medium squeeze”);
// } else {
// Serial.println(” – Big squeeze”);
// }

}

 

PROCESSING

—————

import processing.serial.*;
Serial myPort;

PImage board;
PImage fist;
float bar;
float force = 0;
float speedY = -1;

 

void setup() {
println(Serial.list());

String portName = Serial.list()[4];
myPort = new Serial(this, portName, 9600);
myPort.bufferUntil(‘\n’);

size(500, 1000);
board = loadImage(“Handshaketester.jpg”);
fist = loadImage(“fist.png”);

}

void draw() {
image(board, 0, 0);
// if (mousePressed == true) {
// rect(200, 600, 55, 55); // Draw rect at original 0,0
// translate(30, -force);
// rect(200, 600, 55, 55); // Draw rect at new 0,0
// translate(14, 14);
// rect(200, 600, 55, 55); // Draw rect at new 0,0
// }
// else {
// fill(255);
// force = 0;
//
// }
image(fist, 210, 850 – bar); // Draw rect at original 0,0

bar = map(force, 0, 1050, 0, 750);

}

void serialEvent(Serial myPort) {
String myString = myPort.readStringUntil(‘\n’);
if (myString != null) {
println(myString);
}

myString = trim(myString);

int sensors[] = int(split(myString, ‘,’));

for (int sensorNum = 0; sensorNum < sensors.length; sensorNum++) {
print(“Sensor ” + sensorNum + “: ” + sensors[sensorNum] + “\t”);
}

force = sensors[0];

}

Final Documentation – Jeremy Nir & David Snow

Final Project Documentation
Jeremy Nir & David Snow
Art and Code
Kate Hartman
Tuesday, April, 16th, 2013

Initial Idea:

Our initial proposal was to create an experimental holographic projection of which projects images through a spherical fish tank filled with either fog or murky water. The 3-D effect would be created by two projectors cross beams of light. Users will press pressure pads and turn knobs to morph the 3-dimentional images inside of the tank.

Experimenting:

Through the process of thinking up and creating this work, we moved through various stages of thought which combined projection and holographic imaging to create our final work.

  1. First experiment:
  • We first bought two small household fish bowls, we experimented with filling the bowls with water and slowly mixing thick silver glitter into the water in order to create an effect where light would be reflected and magnified once the projection is on the glittery water. What we encountered was that the glitter would float and clump and not create a perfect mix with the water like we imagined. This led us to move onto chalk.

 

  1. Second experiment:
  • We used finely ground chalk and mixed it into clear water so that we could create a murky effect of which would catch light traveling in one direction through it. What we found was that the chalk created too much of a concentrate and light would not phase through the first centimeter of the glass. We began to rethink and decided on using smoke.

 

  1. Third experiment:
  • We thought of smoke because of old theatres of which people would smoke inside and the projector would make a rectangular projection through it. Kate also showed us a video where a room was filled with smoke and a projector created a line across the room where students played with the light beam which was visible all across its trajectory.
  • We used an incense stick inside of an upside down fish bowl to create smoke which filled the entire bowl. Once a good amount of smoke was created by the stick inside of the bowl we set up the projector again and displayed various styles of images and gifs and videos in order to find an interesting effect through the smoke.
  • At this point we found that smoke was working the best and that we should continue using it in order to get the best effect. We found that the best effect through the smoke with a projector is a black background and a small moving white shape.

 

  1. Fourth experiment:
  • We decided to use a second projector on a ninety degree angle into the bowl while the other one was running in order to see if we could find a holographic image meeting in the centre. What we found is that the light only crosses paths and intersects with no intense effect. At this point we began to rethink what we wanted to accomplish by the end of the project.

 

  1. Fifth experiment:
  • We decided to experiment with some dry ice and see where that could take us in our experiment. We went out and bought 6kg worth of dry ice which was the minimum; we added pellets of ice into some water and created some smoke. What we found was that the smoke only created a thin layer of smoke and didn’t create a thick enough layer in order to project through. We used the bowls on top of each other to create more of a layer that we could potentially use to project the second layer onto.

Final thoughts:

Our final thought was that we would use a combination of dry ice and smoke created by the incense inside of the bowls; this is so that we could get a good projection all the way through the bowl that would be visible to the viewer. As we were working through all of the experiments we talked about what we would project and how it would interact. We thought of a fish jumping out of the bowl, a boat on the water and sinking, different styles of animations etc. all of which are interact able with the viewer. Our final decision of what to project is an array of animations of which work well with the smoke and glass and where the viewer interacts using a single button changing what is displayed on both of the bowls using one projection system and computer.

Code:

int jj = 1;
int y = 20;

PImage star1;
PImage star2;
PImage star3;
PImage star4;
PImage face;

float counter;

//frameRate(8);

import ddf.minim.*;
Minim minim;
AudioSample player1Sound;
AudioSample player2Sound;
AudioSample player3Sound;
AudioSample player4Sound;

////////// for WAVER
float scalar=25;
float angle=22;
float offset=30;
float speed2 = .05;
float slider = 2;
/////////

import processing.serial.*;
import cc.arduino.*;
Arduino arduino;
int index;
boolean beginP1 = true;

//FISH ONE = Bouncy line
int radius = 40;
float x = 220;
float speed = 3;
int direction = 1;

///////////////////////////////////////////////////////////////////
void setup() {
arduino = new Arduino(this, Arduino.list()[6], 57600);
arduino.pinMode(12, Arduino.INPUT);
size(1280, 800);

minim = new Minim(this);
player1Sound = minim.loadSample(“A.mp3”, 512);
player2Sound = minim.loadSample(“B.mp3”, 512);
player3Sound = minim.loadSample(“koura.mp3”, 512);
player4Sound = minim.loadSample(“D.mp3”, 512);

counter=0.0;
// size(800,800);
smooth();
frameRate(46);
star1 = loadImage(“starsmall.png”);
star2 = loadImage(“starmedium.png”);
star3 = loadImage(“starlarge.png”);
star4 = loadImage(“starextralarge.png”);
//face = loadImage(“face1.png”);

}

///////////////////////////////////////////////////////////////////
void draw() {

int button = arduino.digitalRead(12);

// method for avoid over triggering when continously pressing the button
// and aslo randomly changing the switch index
if (button == 1 && beginP1 == true) {
index = int(random(0, 4));
beginP1 = !beginP1;
}

if (button == 0 && beginP1 == false) {
beginP1 = true;
}

// print index before change index
println(index);

// switch
switch(index) {
case 0:
drawScreenZero();
break;
case 1:
drawScreenOne();
break;
case 2:
drawScreenTwo();
break;
case 3:
drawScreenThree();
break;
}
}

void stop()
{
// always close Minim audio classes when you are done with them
player1Sound.close();
// always stop Minim before exiting.
minim.stop();
super.stop();
}

//ZERO

void drawScreenZero() {
background(0);
player4Sound.trigger();

x += speed * direction;
if ((x > width-radius-40) || (x < radius+60)) {
direction = -direction; // Flip direction
}

if (direction == 1) {
fill(#FF1A1A);
rect(-100+x,0,15,1200);

fill(#000000);
rect(0,0,1300,400);

}

// }

else {
fill(#1AFF1B);
rect(-100+x,0,15,1200);

fill(#000000);
rect(0,400,1300,800);
dog(“SAFETY”, 470, 200);
}

}

//ONE
void drawScreenOne() {
player1Sound.trigger();
background(#000000);

fill(#000000);
rect(0, 400, 1300, 800);

counter++;
// translate(width/2, height/2);
// rotate(counter*PI/360/7);
fill(#00aeef);
rect (400, 450, 200+counter, 200+counter);

fill(#000000);
rect (420, 470, 100+counter, 100+counter);

fill(0+counter, 40+counter, 250-counter);
rect (450, 500, 10+counter, 10+counter);

fill(#000000);
rect (453, 503, 2+counter, 2+counter);

if (counter > 300) {
counter = 0;

}
dog(“SCHEME”, 470, 200);
}

void drawScreenTwo() {
// background(#000000);

dog(“SWAMP”, 470, 700);

stroke(0);
// rect(1,1,200,600);
// rect(600,1,500,600);
// stroke(240,97,109);
fill(240,97,109);
ellipse(150+jj,y+10,50,50);

// stroke(240,98,160);

fill(240,98,160);
ellipse(150+jj,y+60,50,50);
// stroke(173,61,171);

fill(173,61,171);
ellipse(150+jj,y+110,50,50);
// stroke(122,64,173);
fill(122,64,173);
ellipse(150+jj,y+160,50,50);
// stroke(73,64,173);
fill(73,64,173);
ellipse(150+jj,y+210,50,50);
// stroke(64,89,173);
fill(64,89,173);
ellipse(150+jj,y+260,50,50);
// stroke(64,127,173);
fill(64,89,173);
ellipse(150+jj,y+310,50,50);
// stroke(42,221,229);
fill(42,221,229);
ellipse(150+jj,y+360,50,50);
// stroke(42,229,140);
// ellipse(15+jj,y+410,50,50);
// // stroke(50,229,42);
// ellipse(15+jj,y+460,50,50);
// // stroke(222,229,42);
// ellipse(15+jj,y+510,50,50);
// // stroke(229,139,42);
// ellipse(15+jj,y+560,50,50);
jj = jj + 2 ;
y = y ;
if(jj > 800)
{
jj=-100;
background(0);
}
if(jj< 0)
{
jj=10;
}

player2Sound.trigger();
}

void drawScreenThree() {
background(#000000);

dog(“SLEEP”, 470, 700);

player3Sound.trigger();

int b=1;
while(b<=50)
{
noStroke();
float a=random(90);
float l=random(90);
fill(random(255),random(255),random(255));
ellipse(int(random(350, 850)),int(random(350)),a,a);
b=b+1;

fill(random(255),random(255),random(255));
rect(int(random(350, 850)),int(random(350)),l,l);

}
}
int timeDelay = 5000; //milliseconds in one minute
int time = 10;
boolean bFlashBg = true;

void dog(String word, int x, int y) {
if (bFlashBg) {
float m = millis();
fill(m % 255, m % 55, m % 155);
textSize(100);
text(word, x, y);
}

if (millis() – time >= timeDelay) {
time = millis();
bFlashBg = !bFlashBg;
}
}

Project 3 – Virtual Color Mixer

Unfortunately arduino has never worked on my computer, so there will be no screen shots.

I created a color mixer that uses analog controls to help people using processing/web design to pick custom colors and play with mixing virtual color.
I learned how to program this using multiple references and created a program that allows simple manipulation of color.
//ardiuno code
const int redPin = A0;
const int greenPin = A1;
const int bluePin = A2;

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

void loop(){
Serial.print(analogRead(redPin));
Serial.print(“,”);
Serial.print(analogRead(greenPin));
Serial.print(“,”);
Serial.println(analogRead(bluePin));

delay(10);
}

//code compiled by Jason Steltman
//4/10/13
//with reference from Kate Hartman,
//http://learning.codasign.com/
//arduino.cc
//processing.org

PFont f;

import processing.serial.*;

float redValue = 0; // red value
float greenValue = 0; // green value
float blueValue = 0; // blue value

Serial myPort;

void setup() {
size(1280, 720); //720p
f = loadFont(“GeezaPro-Bold-48.vlw”);
textFont(f);

println(Serial.list()); //lets bring out these serials

myPort = new Serial(this, Serial.list()[0], 9600);
myPort.bufferUntil(‘\n’);

}

void draw() {

background(redValue, greenValue, blueValue);
// set the background to the value of the colors
textFont(f);
fill(55); //grey for value readings no matter which color
int redInt = int(redValue); //turn the values into intergers to remove decimals
int greInt = int(greenValue);
int bluInt = int(blueValue);
text(“r:” + redInt, 10,100);
text(“g:” + greInt, 10,200);
text(“b:” + bluInt, 10,300);

}

void serialEvent(Serial myPort) {
String inString = myPort.readStringUntil(‘\n’);
if (inString != null) {
// println(inString); print in the communication menu
// trim for a clean finish
inString = trim(inString);

float[] colors = float(split(inString, “,”));
// if the array has at least three elements,
// set the numbers to the color variables:
if (colors.length >=3) {
// map them to the range 0-255:
redValue = map(colors[0], 0, 1023, 0, 255);
greenValue = map(colors[1], 0, 1023, 0, 255);
blueValue = map(colors[2], 0, 1023, 0, 255);

}
}
}

i learned arduino from scratch, but i still felt like there was more i could have done with the inputs. I wanted to create a separate controller to house the inputs but after soldering the pieces together the connection was lost (and so was all my wires and potentiometers). After this i decided to stick to just the simple setup on the breadboard.
this tool would be awesome for use in the classroom teaching children how to program/work with color on the computer. Including web-color readouts, separate controller, white and black buttons, hue and more, this virtual mixer could be used by anyone.

Project 3: Wings

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Here’s what it looks like!  After many speedbumps it’s finally working.

 

ARDUINO CODE:

//Wings
//Stretch Sensors
//Emma Burkeitt – 2463636
//Art & Code
//

//down 26
//up 15

int sensor1 = 0;
int sensor1val = 0;

int sensorPin = A0;

int sensorValue;

void setup(){
//pinMode(sensorPin, INPUT);

Serial.begin(9600);

}

void loop(){

sensor1val = analogRead(sensor1);
Serial.println(sensor1val);

// send the value of analog input 0:
Serial.println(analogRead(A0));
// wait a bit for the analog-to-digital converter
// to stabilize after the last reading:
delay(2);

}

 

PROCESSING CODE:

//Wings
//Art & Code
//Project 3
//Emma Burkeitt (2463636)
//

import processing.serial.*; // import the Processing serial library
Serial myPort; // The serial port

PImage img; //Declares Image

import processing.video.*; //movie library
Movie WingsUp;
Movie WingsDown; //Decalres Movie

float inByte;

void setup () {

// Prints the list of serial ports
println(Serial.list());

//Arduino
String portName = Serial.list()[4];
myPort = new Serial(this, portName, 9600);
// read bytes into a buffer until you get a linefeed (ASCII 10):
myPort.bufferUntil(‘\n’);

size(1000,700); //document size
frameRate(12); // 12 fps

img = loadImage(“Nike_WingsDown_Img.jpg”); //Loads Image

WingsUp = new Movie(this, “Nike_Wings_UP.mov”); //load movie
WingsDown = new Movie(this, “Nike_Wings_DOWN2.mov”);

}

void draw () {

background(255); // White BG

image(img, 0, 0);

if(inByte < 17) { //If sensor reads less than 17

println(“UP”);
image(WingsUp, 0, 0, 1000, 700); //Draws movie

WingsUp.play();
WingsDown.stop();
}

else {
println(“DOWN”);
image(WingsUp, 0, 0, 1000, 700); //Draws movie

WingsUp.stop();

WingsDown.play();
}

}

void serialEvent (Serial myPort) {
// get the ASCII string:
String inString = myPort.readStringUntil(‘\n’);

if (inString != null) {
// trim off any whitespace:
inString = trim(inString);
// convert to an int and map to the screen height:
inByte = float(inString); //Incoming data
inByte = map(inByte, 0, 1023, 0, height);

}

}

void movieEvent(Movie m) {
if (m == WingsUp) {
WingsUp.read();
} else if (m == WingsDown) {
WingsDown.read();
}
}

 

 

 

 

Violet Dash

With this project I wanted to make a simple game where you would have 2 force sensors (one for each foot, though they could be hand pressed) that would make Violet run. The more you press the farther she would go. However, you would have to alternate feet – if you last gained score on a left foot, you can’t gain again until you press the right foot. In fact, you would lose points for not alternating.

I wanted to make my own force sensors, and I would have made it that you would take the difference between your value and your max value to add to your score (so that pressing harder would actually increase your score more). Most of the code would be a modification of the graph example, having inByte as my value. However I was ill equipped and though I had a metal sheet I had little success cutting it which ate away at time. I ended up making perforated holes and then hacking away at it with a corkscrew knife, and the result was… less than desirable (and slightly dangerous)?  I was ready to start testing before I polished my sensors but I realized I didn’t have enough alligator clips (I could only find one pair), or enough time to head back to school and solder. So I dropped the force sensors and used the blue dial so that at least I could still incorporate arduino. Turning back and forth is slow though, so I dropped the same side penalty in this version.

I had a prototype version ready, which still has the penalty, but it’s all within processing with the external library gifAnimation (which is also in the other versions), and it uses the left and right arrows.

The Arduino code is the same as the graphing example:
void setup() {
// initialize the serial communication:
Serial.begin(9600);
}

void loop() {
// send the value of analog input 0:
Serial.println(analogRead(A0));
// wait a bit for the analog-to-digital converter
// to stabilize after the last reading:
delay(2);
}

 

The Processing Standalone (left and right arrows):

import gifAnimation.*;

PImage[] animations;
Gif idleGif, runGif;
int counter = 17;
boolean running = false;
boolean scoring = false;
boolean playing = false;
String lastKey = (“right”);
int score = 0;
int distanceA = 0;
int distanceB = 5;
int deltaA = 250;
int deltaB = 750;
int check = 1000;
public void setup(){
size(700, 500);
frameRate(100);
idleGif = new Gif(this, “Idle.gif”);
idleGif.loop();
runGif = new Gif(this, “Run.gif”);
runGif.loop();

// animations = Gif.getPImages(this, “Idle.gif”);
}

void draw(){
background(0);
if(running==false && deltaA==250 && distanceA==0){
System.out.println(“start”);
image(idleGif, 10, height/2 -idleGif.height/2);
}else{
if(running && playing && score>0){
System.out.println(“go”);
image(runGif, 10, height/2 -idleGif.height/2);
}else{
if(running==false && playing==false && (deltaA!=250 || distanceA!=0)){
System.out.println(“stop”);
image(idleGif, 10, height/2 -idleGif.height/2);
}
}
}
textSize(32);
if(counter>= 0){
text(counter, 10, 30);
scoring = true;
}else{
text(“GO!”, 10, 30);
running=true;
playing=true;
scoring = false;
}
if(deltaA<0){
deltaA=deltaB+width/2;
distanceA=distanceB+5;
}
if(deltaB<0){
deltaB=deltaA+width/2;
distanceB=distanceA+5;
}

text(score, 50, 101);
text(distanceA, deltaA, 420);
text(distanceB, deltaB, 420);
int er = millis();
// System.out.println(er);
for(int i=0; i<25;i++){
if (check<=er){
counter–;
if(running==false){
check=check+1000;
}else{
check=check+50;
}
if(running && score>0){
score=score-1;
deltaA=deltaA-10;
deltaB=deltaB-10;

}
if (score<=0){
score=0;
running=false;
playing=false;
}

}
}
}
void keyPressed() {
if (key == CODED) {
if (keyCode == LEFT) {
if(scoring && lastKey == (“right”)){
score = score +5;
lastKey=(“left”);
}
if(scoring && lastKey == (“left”)){
score = score -2;
}
}
if (keyCode == RIGHT) {
if(scoring && lastKey == (“left”)){
score = score +5;
lastKey=(“right”);
}
if(scoring && lastKey == (“right”)){
score = score -2;
}
}
}
}

The version with the dial:
import gifAnimation.*;
import processing.serial.*;

Serial myPort;        // The serial port
int xPos = 1;         // horizontal position of the graph

PImage[] animations;
Gif idleGif, runGif;
int counter = 17;
boolean running = false;
boolean scoring = false;
boolean playing = false;
String lastKey = (“less”);
int score = 0;
int distanceA = 0;
int distanceB = 5;
int deltaA = 250;
int deltaB = 750;
int check = 1000;
public void setup(){
size(700, 500);
println(Serial.list());
myPort = new Serial(this, Serial.list()[1], 9600);
// don’t generate a serialEvent() unless you get a newline character:
myPort.bufferUntil(‘\n’);
frameRate(100);
idleGif = new Gif(this, “Idle.gif”);
idleGif.loop();
runGif = new Gif(this, “Run.gif”);
runGif.loop();

// animations = Gif.getPImages(this, “Idle.gif”);
}

void draw(){
background(0);
if(running==false && deltaA==250 && distanceA==0){
//System.out.println(“start”);
image(idleGif, 10, height/2 -idleGif.height/2);
}else{
if(running && playing && score>0){
//System.out.println(“go”);
image(runGif, 10, height/2 -idleGif.height/2);
}else{
if(running==false && playing==false && (deltaA!=250 || distanceA!=0)){
//System.out.println(“stop”);
image(idleGif, 10, height/2 -idleGif.height/2);
}
}
}
textSize(32);
if(counter>= 0){
text(counter, 10, 30);
scoring = true;
}else{
text(“GO!”, 10, 30);
running=true;
playing=true;
scoring = false;
}
if(deltaA<0){
deltaA=deltaB+width/2;
distanceA=distanceB+5;
}
if(deltaB<0){
deltaB=deltaA+width/2;
distanceB=distanceA+5;
}

text(score, 50, 101);
text(distanceA, deltaA, 420);
text(distanceB, deltaB, 420);
int er = millis();
// System.out.println(er);
for(int i=0; i<25;i++){
if (check<=er){
counter–;
if(running==false){
check=check+1000;
}else{
check=check+50;
}
if(running && score>0){
score=score-1;
deltaA=deltaA-10;
deltaB=deltaB-10;

}
if (score<=0){
score=0;
running=false;
playing=false;
}

}
}
}
void serialEvent (Serial myPort) {
// get the ASCII string:
String inString = myPort.readStringUntil(‘\n’);

if (inString != null) {
// trim off any whitespace:
inString = trim(inString);
// convert to an int and map to the screen height:
float inByte = float(inString);
inByte = map(inByte, 0, 1023, 0, height);
//System.out.println(inByte);
/*void keyPressed() {
if (key == CODED) {*/
// for(int b=0; b<25;b++){
//System.out.println(“>250”);
System.out.println(lastKey);
if(scoring && inByte>250 && lastKey==(“less”)){
//System.out.println(“>250”);
score = score +5;
lastKey=(“greater”);
}
if(scoring && inByte>250 && lastKey == (“greater”)){
//score = score -2;
}
if(scoring && inByte<250 && lastKey == (“greater”)){
//System.out.println(“<250”);
score = score +5;
lastKey=(“less”);
}
if(scoring && inByte>250 && lastKey == (“less”)){
// score = score -2;
}
}
// }
}