Tuesday, December 16, 2008

Physical Computing Final: Sensor Dome

The Sensor Dome is an interface for controlling light and sound using photocells. Each of the 16 photocells sends a value based on how much it is covered by shade. These values are used to control both the volume of music tracks and the lights above the sensors. The dimming and animation of the lights above the sensors alter the values of the sensors.


Sensor Dome performs for YOU! from Matt Richard on Vimeo.


Sensor Dome comes together... almost from Matt Richard on Vimeo.


Building the Light Dome for the Sensor Dome! from Matt Richard on Vimeo.

Processing Code:
//Matt Richard(visual) and Eyal Ohana(audio)

import UDP.*; // import Light Tile library
UDPSend udp;

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

import ddf.minim.signals.*; // import the Minim sound library
import ddf.minim.*;
Minim minim;
AudioOutput out;


//declare variables
int totalSquares = 16; // var for how many squares you want on the screen, !! must be a square itself
int colorMax = 255;
int tracks = 16;
float rectColorArray[][][][]; // create nested array that holds the rects alpha value
float sensorValue[] = new float[tracks]; // array to hold sensor values
AudioPlayer players[] = new AudioPlayer[tracks];
float gain[] = new float[tracks];
float val[] = new float[tracks];


void setup() {
//colorMax = totalSquares;
size(240, 240);
background(0);
colorMode(HSB, 255);
noStroke();
smooth();

udp = new UDPSend(this,"10.031.066.202",6038,"/Users/matt/Documents/Processing/libraries/UDP/colorkinetics_lib/header","/Users/matt/Documents/Processing/libraries/UDP/colorkinetics_lib/lookup",200,0);
myPort = new Serial(this, Serial.list()[0], 9600);
// read bytes into a buffer until you get a linefeed (ASCII 10):
myPort.bufferUntil('\n');

setup_audio(); // contains all of the setup code for audio(located below)
setup_visual(); // contains all of the setup code for visual(located below)
}

void draw() {
draw_audio();
draw_visual();
udp.send();
}


void serialEvent(Serial myPort) {
// serialEvent method is run automatically by the Processing applet
// whenever the buffer reaches the byte value set in the bufferUntil()
// method in the setup():


// read the serial buffer:
String myString = myPort.readStringUntil('\n');
// if you got any bytes other than the linefeed:
if (myString != null) {
myString = trim(myString);

// split the string at the commas
// and convert the sections into integers:
int sensors[] = int(split(myString, ","));

// print out the values you got:
for (int sensorNum = 0; sensorNum < sensors.length; sensorNum++) {
print(sensorNum + ": " + sensors[sensorNum] + " ");
}
// add a linefeed after all the sensor values are printed:
println();
if (sensors.length > 1) {
for(int i=0;i < tracks;i++){
val[i] = map(sensors[i], 100, 300, 7, -30); // map the sensor read to the audible range of the gain for the audio
sensorValue[i] = map(sensors[i], 20,200,0,colorMax); // map the sensor value for visual
}
}
}
}


/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//////// AUDIO FUNCTIONS ////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
void setup_audio(){
minim = new Minim(this);
out = minim.getLineOut();

players[0] = minim.loadFile("01_drums.aif");
players[1] = minim.loadFile("02_filter.aif");
players[2] = minim.loadFile("03_flute.aif");
players[3] = minim.loadFile("04_hard.aif");
players[4] = minim.loadFile("05_horns.aif");
players[5] = minim.loadFile("06_pad.aif");
players[6] = minim.loadFile("07_pad_b.aif");
players[7] = minim.loadFile("08_bass.aif");
players[8] = minim.loadFile("09_didge.aif");
players[9] = minim.loadFile("10_beat_hi.aif");
players[10] = minim.loadFile("11_beat_low.aif");
players[11] = minim.loadFile("12_machine.aif");
players[12] = minim.loadFile("13_click.aif");
players[13] = minim.loadFile("14_scape.aif");
players[14] = minim.loadFile("15_strings.aif");
players[15] = minim.loadFile("16_bells.aif");
//players[.play();
for (int i=0; i< players.length; i++) {
players[i].loop();
}
}
void draw_audio() {

if ( out.hasControl(Controller.GAIN) )
{
for (int i = 0; i < players.length; i++) {
players[i].setGain(val[i]);
}
}
}
void stop() {

// the Audioplayers[ you got from Minim.loadFile()
for (int i=0; i< players.length; i++) {
players[i].close();
}
out.close();
// the AudioInput you got from Minim.getLineIn()
//input.close();
minim.stop();

// this calls the stop method that
// you are overriding by defining your own
// it must be called so that your application
// can do all the cleanup it would normally do
super.stop();
}



/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//////// VISUAL FUNCTIONS ////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
void setup_visual(){
rectColorArray = new float[floor(sqrt(totalSquares))][floor(sqrt(totalSquares))][3][2];
for(int x=0; x < sqrt(totalSquares); x++){
for(int y=0; y < sqrt(totalSquares); y++){
rectColorArray[x][y][0][0] = x;
rectColorArray[x][y][1][0] = 1;
rectColorArray[x][y][2][0] = 1;

rectColorArray[x][y][0][1] = 10;
rectColorArray[x][y][1][1] = 10;
rectColorArray[x][y][2][1] = 10;
}
}
}

void draw_visual(){
for(int x = 0; x < sqrt(totalSquares); x++){
for(int y = 0; y < sqrt(totalSquares); y++){

fill(sensorValue[(x*4)+y]);
rect(floor((x * (width/(sqrt(totalSquares))))), floor((y * (height/(sqrt(totalSquares))))), floor((width/(sqrt(totalSquares)))), floor((height/(sqrt(totalSquares)))));
}
}
}

Arduino Code:
int sensorValue[16]; // an array to store the sensor values

// the address pins will go in order from the first one:
#define firstAddressPin 8

int analogInput = 0;

void setup() {
Serial.begin(9600);
// set the output pins:
for (int pinNumber = firstAddressPin; pinNumber < firstAddressPin + 4; pinNumber++) {
pinMode(pinNumber, OUTPUT);
}
}

void loop() {
for (int channelNum = 0; channelNum < 16; channelNum ++) {
// determine the four address pin values from the channelNum:
setChannel(channelNum);

// read the analog input and store it in the value array:
sensorValue[channelNum] = analogRead(analogInput);
//delay(10);
// print the values as a single tab-separated line:
Serial.print(sensorValue[channelNum], DEC);
if(channelNum < 15){
Serial.print(",");
}
}

// print a carriage return at the end of each read of the mux:
Serial.println();
}

void setChannel(int whichChannel) {
for (int bitPosition = 0; bitPosition < 4; bitPosition++) {
// shift value x bits to the right, and mask all but bit 0:
int bitValue = (whichChannel >> bitPosition) & 1;
// set the address pins:
int pinNumber = firstAddressPin + bitPosition;
digitalWrite(pinNumber, bitValue);
}
}

Saturday, December 6, 2008

Sensor Dome comes alive!!!!

I am proud to say that the Sensor Dome is up and running. Eyal Ohana and I were able to get both parts(audio and visual) to work seperately. Tomorrow we will get them to work together and build the structure that will house the light tile and the Sensor Dome. I uploaded two videos showing it working. I will add some pictures of the guts tomorrow.

Oh yeah, I almost forgot! We are using a multiplexer to allow for 16 photocells in analog input.


Sensor Dome - Light Tile Test from Matt Richard on Vimeo.


Sensor Dome - Sound Test from Matt Richard on Vimeo.

Wednesday, November 26, 2008

144 LED Color Tile Sketches

Recently I have been playing with a light that is made up of a 12x12 grid of RGB LEDs. I made a 5 minute video of most of the sketches I made in the last three days.



LED Color Tile Sketches from Matt Richard on Vimeo.

Saturday, November 22, 2008

Robotic arm drawing machine

For our mid-term project in Physical Computing, Jim Lamiell, Kristen Loeb and I created a drawing machine using two servo motors and a little bit of inverse kinematics. We set out to draw a straight line using with a contraption in mind that would mimic a simplified human arm.

The first servo acts like the shoulder and is connected to an arm with another servo at the end that acts like an elbow. The second servo has is connected to another arm with a marker on the end that acts like the hand.

The trick is to tell the servos what angle to go to based on the position of the marker(mouse). This can be done using the law of cosines and inverse kinematics.

We were able to make it draw, but not a straight line. I remade the arms using a CAD program to make it much more precise. I will post another video when it is finished.


PComp Midterm: Drawing Machine from James Lamiell on Vimeo.

Wednesday, November 12, 2008

ICM final

I want to finish a drawing I started over the summer with processing.


















I want to analyze this drawing of hair and then have processing draw similar forms pouring out into the white space of the master drawing.


































I would also like to have the eyes to look in different positions.

Saturday, November 8, 2008

Coin Flip and Dice Roll generators


Last week for my Crafting with Data class, I had to flip a coin one hundred times and record the results. My teacher told half the class to carry out the experiment and the other half to make up the results.

As I recorded my results I began to get excited about the outcome and cheered for tails(which ended up winning!). I recorded my results on graph paper in a 10x10 grid because I only had small sheets of graph paper. As the results came in, I wondered how the data would look if rendered in black and white squares. I redrew the data on graph paper and I figured it would only take a few moments to recreate the visualization in processing. So I did. I showed it to my Dad and he started talking about dice, so I made one for a six-sided die.

Here are the generators:
Coin Flip
Dice Roll

Sunday, November 2, 2008

28 Minutes Later

Every Tuesday at 4pm, all of the first years have a special class with Red Burns. The first half of the class is used to comment on the special guest the week before. During the second half of class a presenter speaks to us about what they do and then we are able to ask questions.

Last Tuesday, the group presentation consisted of an impromptu creation of video and sound by 9 groups of about 12 ITP students. Each group was given a specific task and the equipment needed to complete it. The groups then split off for 28 minutes to complete their task.

The files were collected, quickly edited and then presented to us.

My group was asked to create audio about a family vacation where a natural disaster occurs. I say "It's okay kids because we are at Old Faithful and it only goes off once an hour."



Warning - contains profanity :)

Ideas about Consciousness

Ze Frank, a popular internet icon, created a video about the way our conscious mind works. He sites elements from a New York Times article entitled, "Free Will: Now You Have It, Now You Don’t."

The article and Ze Frank both touch on a 1970's experiment by Benjamin Libet where he "...wired up the brains of volunteers to an electroencephalogram and told the volunteers to make random motions, like pressing a button or flicking a finger, while he noted the time on a clock." Libet found out that actions in the body occurred before areas in the conscious mind were aware, leading him to question the ideas of free will.

Tuesday, October 21, 2008

Inverse Kinematics and Processing



Basic inverse kinematics code rewritten for processing from Keith Peters of bit-101. The idea is to replicate the motion of your shoulder, upper arm, elbow, lower arm, and hand in two dimensions. The angular value of the "shoulder" and "elbow" will be written to corresponding servo motors that are being controlled by Arduino.

Here is the code:

int sx,sy,ex,ey,hx,hy;
int armLength,ua,la;
float uad, lad;
void setup(){
size(500,500);
background(255, 224, 150);
sx = width/2;
sy = height/2;
armLength = int(width/5);
}

void draw(){
fill(255);
rect(0,0,width,height);
upperArm();
}

void upperArm(){
int dx = mouseX - sx;
int dy = mouseY - sy;
float distance = sqrt(dx*dx+dy*dy);

int a = armLength;
int b = armLength;
float c = min(distance, a + b);

float B = acos((b*b-a*a-c*c)/(-2*a*c));
float C = acos((c*c-a*a-b*b)/(-2*a*b));

float D = atan2(dy,dx);
float E = D + B + PI + C;

ex = int((cos(E) * a)) + sx;
ey = int((sin(E) * a)) + sy;
print("UpperArm Angle= "+degrees(E)+" ");

hx = int((cos(D+B) * b)) + ex;
hy = int((sin(D+B) * b)) + ey;
println("LowerArm Angle= "+degrees((D+B)));

stroke(255,0,0,100);
fill(240,0,0,200);
ellipse(sx,sy,10,10);
ellipse(ex,ey,8,8);
ellipse(hx,hy,6,6);
stroke(0);
line(sx,sy,ex,ey);
line(ex,ey,hx,hy);
}

Awesome Data Visualization Site

My friend Loren Klein sent me a link to a site called Very Small Array. The specific page shows the map of the five boroughs. Instead of the borough names, the names of States with the closest equivalent in population are used. I really recommend checking out the rest of the site.

Money Map

For my self portrait in Crafting with Data, I mapped the use of my bank card using Google Maps. I entered all of the locations I used my card during the month of September. I included the date, amount spent, and what the item purchased was.

Multi-Value Serial Communication

I want to thank Meredith for writing this post. I merely changed my name to her's.

I worked with Meredith Hasson on the serial communication lab for this week. We followed the lab instructions and did the first basic serial circuit using a flex sensor, a photo cell and a switch. We were able to get it working and thus, began to play with moving the ball around the screen.



We then changed both the Arduino and Processing code up a bit and went for snow. We made the background color change based on how much light the photocell was receiving. When it was getting lots of light, it would be a light background and when it was not receiving any light, it was a black background. The white balls were moving around based off of random numbers, but we utilized the flex sensor to decide how many balls would be present. When bent one way there were lots of balls and when bent the other there were fewer balls.



Here is our code:

Arduino:

int analogOne = 0; // analog input
int analogTwo = 1; // analog input
int digitalOne = 2; // digital input

int sensorValue = 0; // reading from the sensor

void setup() {
// configure the serial connection:
Serial.begin(9600);
// configure the digital input:
pinMode(digitalOne, INPUT);
}

void loop() {
// read the sensor:
sensorValue = analogRead(analogOne);
// print the results:
Serial.print(sensorValue, DEC);
Serial.print(”,”);

// read the sensor:
sensorValue = analogRead(analogTwo);
// print the results:
Serial.print(sensorValue, DEC);
Serial.print(”,”);

// read the sensor:
sensorValue = digitalRead(digitalOne);
// print the last sensor value with a println() so that
// each set of four readings prints on a line by itself:
Serial.println(sensorValue, DEC);
}

Processing:

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

float bgcolor; // Background color
float fgcolor; // Fill color
float xpos, ypos; // Starting position of the ball

void setup() {
size(640,480);
myPort = new Serial(this, Serial.list()[2], 9600);

// read bytes into a buffer until you get a linefeed (ASCII 10):
myPort.bufferUntil(’\n’);
}

void draw() {
//background(xpos);
fill(xpos, 50);
rect(0, 0, width, height);
fill(fgcolor);
// Draw the shape
for(int i = 0; i <= ypos; i++){
// ellipse(i*10, height/2, 10, 10);
ellipse(random(width), random(height), 10, 10);
}
}

// serialEvent method is run automatically by the Processing applet
// whenever the buffer reaches the byte value set in the bufferUntil()
// method in the setup():

void serialEvent(Serial myPort) {
// read the serial buffer:
String myString = myPort.readStringUntil('\n');
// if you got any bytes other than the linefeed:
if (myString != null) {

myString = trim(myString);

// split the string at the commas
// and convert the sections into integers:
int sensors[] = int(split(myString, ','));

// print out the values you got:
for (int sensorNum = 0; sensorNum < sensors.length; sensorNum++) {
print("Sensor " + sensorNum + ": " + sensors[sensorNum] + "\t");
}
// add a linefeed after all the sensor values are printed:
println();
if (sensors.length > 1) {
xpos = map(sensors[0], 190,900,1,255);
ypos = map(sensors[1], 220,540,1,200);
fgcolor = sensors[2] * 255;
}
}
}

Tuesday, September 30, 2008

Jealous Boyfriend with servo technology

Meredith and I worked together on our Physical Computing homework and created a gem. Our task was create something using a servo motor. I knew that I wanted to attach a rigid arm to the motor. After playing with the setup we stumbled upon a funny little thing.

Enjoy :)


The Jealous Boyfriend with servo technology from Matt Richard on Vimeo.

Monday, September 22, 2008

The Voltage Reguator and the Circuit

This week for homework in pcomp(physical computing) I had to create circuits that were powered by 12v converter. Then the 12 volts were then turned into 5 volts by a 7805 5v regulator.  So far I have had no problems with any of labs, that is, until this one.

I can now honestly say I blew several LEDs and caused smoke to rise from them and I managed to destroy 3 voltage regulators. I also had the disadvantage of working on this lab without the diagrams on the server, due to it being offline.

However, I was able to understand the principles of measuring current and voltage, and working with a powersource other than the Arduino.

Here is a video of a simple circuit that I made.



Voltage Regulator and the Tower Switch!!! from Matt Richard on Vimeo.

ICM Homework Week 3

This week I was supposed to create classes and instantiate objects. Last week I tinkered with a random line drawing program. The way it works is simple:
1. pick a starting point
2. pick a point on an invisible circle
3. draw a line between points
3. the second point becomes the new starting point
4. repeat

I tried to limit the points on the circle so it was more like picking a point on the crust of a slice of pizza. I was attempting to make the movement smoother. What I got looked like a long tent pole that was unhinged and thrown onto the screen.

This was because I was using the random() function to pick a value. I switched to the noise() function and the result was much more fluid and ultimately cooler looking.

Clicking on the window resets the points to the mouse location.

Tuesday, September 16, 2008

Physical Computing Week 2 Homework

For week two I had to use a sensor(analog in) to send information to the Arduino that then used the data to regulate something else. In my case I used 3 potentiometers that controlled blue, green and red LEDs.

I wanted to create a way to make many different colors. I put the LEDs inside of a cube of foamcore with a paper window. Watch the videos to see how it went.


With the lights on so you can see the components.


Color Maker in the light from Matt Richard on Vimeo.


With the lights off so you can see it work.


Color Maker in the dark from Matt Richard on Vimeo.

Sunday, September 14, 2008

ICM Week 2 Homework part 2


My roommate, Jim Lamiell, had an assignment to create 4 squares representing the 4 quadrants of the stage. When the cursor is over a quadrant, that quadrant is black. When a cursor is not over a quadrant, it is gradually turning whiter, unless it is already white, in which case it remains white.

I wanted to recreate his project, but be able to change the total amount of squares and have it figure out all of the details. So I did. I used nested arrays and nested for loops to get it all to work. Not to mention the help of Jeremy and Thomas. Thanks guys :)

The example that I show has 256 squares. I am very excited for this little exercise because it has created a way to program matrices of LEDs for projects that I will be doing in the future.

Saturday, September 13, 2008

The search for Digital Devices

For Physical Computing, Meredith Hasson and I had to take a walk for one hour and record every use of a digital device. We recorded the time, device used, and the sex and estimated age of the user. We also took pictures and video of the users.

It seems that people do not mind if you take their pictures, or maybe they don't mind if Meredith takes them.

All in all the outcomes were expected, tons of iPods and cellphones. We compiled all of the data and media into a lovely video that you are sure to watch below. Enjoy.


The Hunt for Digital Devices from Matt Richard on Vimeo.

My computer crashed

My computer crashed because I was an idiot and turned it off during an update. When I restarted the computer there was a serious error and now my computer does not recognize my raid setup.

No problem though, all I need to do is find someone who will let me borrow two or three floppy disks so I can create a boot for my raid setup. Then I will be able to repair the problems to windows on my main hard drive(s).

Thursday, September 11, 2008

Fixing Physical Computing Homework

Thanks Kevin it seems to work :)

My brother Kevin, who lives in Florida and works as a Flash developer, had an idea about how to fix my code. He sent me a snippet of the void loop() section and I swapped it in and then rearranged the variables.

His idea was to check the switchState on every iteration of the for loop. Since switchState would only return 0 or 1(no or yes), he added the value of switchState to the lower of the two LED pins(pin 3) which were in pins 3 and 4.

Code snippet:
void loop() {
for (int i=10; i >= 1; i--){
// read the switch input at the beginning of
// each loop iteration
switchState = digitalRead(switchPin);
digitalWrite((ledPin + switchState), HIGH);
delay(i*(i*10));
digitalWrite((ledPin + switchState), LOW);
delay(i*(i*10));
}

Here is a video:


Physical Computing Week 1 Homework FIXED from Matt Richard on Vimeo.

Wednesday, September 10, 2008

ICM Week 2 Homework


This week, for ICM, I am supposed to create a drawing using variables! I was so excited that I did it a week ago :P I had actually worked on this before my self portrait.

I wanted to make concentric triangles, so I figured the easiest way would be to create a triangle based on its center point and radius. I created a class that figures out the 6 coordinate points by using trigonometry and then simply inputs them into the standard triangle() command.

Right now the triangles rotate based on the x position of your mouse. I am still playing with this, so I will be posting again soon.

Tuesday, September 9, 2008

Physical Computing Week 1 Homework

I finally got my Arduino Diecimila to work on my computer. I was really excited about programming in Arduino. It seemed like such a simple language that I just wanted to dive in and play around a bit.

I played with for loops allowing the LEDs to blink at either an exponentially increasing or decreasing amount. The LED that turns on depends on the position of a switch, whether it is open or closed. Here is my code:

// declare variables:
int switchPin = 2; // digital input pin for a switch
int yellowLedPin = 3; // digital output pin for an LED
int redLedPin = 4; // digital output pin for an LED
int switchState = 0; // the state of the switch

void setup() {
pinMode(switchPin, INPUT); // set the switch pin to be an input
pinMode(yellowLedPin, OUTPUT); // set the yellow LED pin to be an output
pinMode(redLedPin, OUTPUT); // set the red LED pin to be an output
}

void loop() {
switchState = digitalRead(switchPin); // read the switch input:

if (switchState == 1) // if the switch is closed:
for (int i=10; i >= 1; i--){
digitalWrite(yellowLedPin, HIGH); // turn on the yellow LED
delay(i*(i*10));
digitalWrite(yellowLedPin, LOW); // turn off the yellow LED
delay(i*(i*10));
}
digitalWrite(redLedPin, LOW); // turn off the red LED
}
else if (switchState == 0){ // if the switch is open:
for (int i=1; i <= 10; i++){
digitalWrite(redLedPin, HIGH); // turn on the red LED
delay(i*(i*10));
digitalWrite(redLedPin, LOW); // turn off the red LED
delay(i*(i*10));
}
digitalWrite(yellowLedPin, LOW); // turn off the yellow LED
}
}
Here is a video:


The LEDs blinked the way I wanted them to, but the switch wouldn't change the lit LED until after the currently lit one was finished its for loop. I tried adding an if statement with a break to get the for loop to stop, but it didn't work.

Sunday, September 7, 2008

ICM Week 1 Homework


For my first Processing assignment I created a stunning self portrait. I am excited to learn more about this language.

Friday, September 5, 2008