Simple particle simulation and snaredrums

Assignment: Sensing PART II: Force Sensitive Resistors and Photocells

Collaborators:

The arduino code for both the parts is the same, so here it goes:

/*

* one pot fades one led

* modified version of AnalogInput

* by DojoDave <http://www.0j0.org>

* http://www.arduino.cc/en/Tutorial/AnalogInput

*/

int potPin = 0;   // select the input pin for the potentiometer

int ledPin = 13;   // select the pin for the LED

int val = 0;      // variable to store the value coming from the sensor

void setup() {

Serial.begin(9600);

}

void loop() {

val = analogRead(potPin);    // read the value from the sensor, between 0 - 1024

Serial.println(val/4);

analogWrite(ledPin, val/4); // analogWrite can be between 0-255

}

 

Visualization

I ended up creating something addictive. I modified the Simple Particle classes supplied by Processing to change the color of the particles based on pressure or the light being projects on the sensors.

Here goes the Processing code:

ParticleSystem ps;

import processing.serial.*;

// Change this to the portname your Arduino board

String portname = "COM23";

Serial port;

String buf="";

int cr = 13;  // ASCII return   == 13

int lf = 10;  // ASCII linefeed == 10

ArrayList psystems;

int counter = 0;

int val;

 

void setup() {

size(500,500);

frameRate(30);

smooth();

background(40,40,40);

noStroke();

 

port = new Serial(this, portname, 9600);

colorMode(RGB, 255, 255, 255, 100);

ps = new ParticleSystem(1, new PVector(width/2,height/2,0));

smooth();

}

 

// called whenever serial data arrives

void serialEvent(Serial p) {

int c = port.read();

 

if (c != lf && c != cr) {

buf += char(c);

return;

}else if (c == lf) {

val = int(buf);

//println("val = " + val + "; counter = " + counter);

 

if(counter == 0){

int x = int(random(0,width));

int y = int(random(0,height));

 

ps.addParticle(val,mouseX,mouseY);

}

counter = (counter+1) % 4;

 

buf = "";

}

}

 

 

void draw() {

background(0);

ps.run();

}

 

 

 

 

 

 

// A class to describe a group of Particles

// An ArrayList is used to manage the list of Particles

 

class ParticleSystem {

 

ArrayList particles;    // An arraylist for all the particles

PVector origin;        // An origin point for where particles are born

int num;

 

ParticleSystem(int num, PVector v) {

particles = new ArrayList();              // Initialize the arraylist

origin = v.get();                        // Store the origin point

for (int i = 0; i < num; i++) {

particles.add(new Particle(origin));    // Add "num" amount of particles to the arraylist

}

}

 

void run() {

// Cycle through the ArrayList backwards b/c we are deleting

for (int i = particles.size()-1; i >= 0; i--) {

Particle p = (Particle) particles.get(i);

p.run();

if (p.dead()) {

particles.remove(i);

}

}

}

 

void addParticle() {

particles.add(new Particle(num,origin));

}

 

void addParticle(int num, float x, float y) {

particles.add(new Particle(num, new PVector(x,y)));

}

 

void addParticle(Particle p) {

particles.add(p);

}

 

// A method to test if the particle system still has particles

boolean dead() {

if (particles.isEmpty()) {

return true;

} else {

return false;

}

}

 

}

 

 

 

 

// A simple Particle class

 

class Particle {

PVector loc;

PVector vel;

PVector acc;

float r;

float timer;

int color_number;

 

// Another constructor (the one we are using here)

Particle(PVector l) {

acc = new PVector(0,0.05,0);

vel = new PVector(random(-1,1),random(-2,0),0);

loc = l.get();

r = 10.0;

timer = 100.0;

}

 

 

// Another constructor (the one we are using here)

Particle(int num, PVector l) {

acc = new PVector(0,0.05,0);

vel = new PVector(random(-1,1),random(-2,0),0);

loc = l.get();

r = 10.0;

timer = 100.0;

color_number = num;

}

 

void run() {

update();

render();

}

 

// Method to update location

void update() {

vel.add(acc);

loc.add(vel);

timer -= 1.0;

}

 

// Method to display

void render() {

ellipseMode(CENTER);

stroke(255,timer);

fill(color_number, 0, 255 - color_number,timer);

ellipse(loc.x,loc.y,r,r);

//displayVector(vel,loc.x,loc.y,10);

}

 

// Is the particle still useful?

boolean dead() {

if (timer <= 0.0) {

return true;

} else {

return false;

}

}

 

void displayVector(PVector v, float x, float y, float scayl) {

pushMatrix();

float arrowsize = 4;

// Translate to location to render vector

translate(x,y);

stroke(150);

// Call vector heading function to get direction (note that pointing up is a heading of 0) and rotate

rotate(v.heading2D());

// Calculate length of vector & scale it to be bigger or smaller if necessary

float len = v.mag()*scayl;

// Draw three lines to make an arrow (draw pointing up since we've rotate to the proper direction)

line(0,0,len,0);

line(len,0,len-arrowsize,+arrowsize/2);

line(len,0,len-arrowsize,-arrowsize/2);

popMatrix();

}

}

 

Mechanical

I observed my friend playing drums the other day, and realized that there is an element of pressure and force there. Therefore, I created a rough snare drum of some sorts. The amount of force on the FSR is reflected in terms of the number of beats in the snare drum.

Here goes the Processing code:

import processing.serial.*;

// Change this to the portname your Arduino board

String portname = "COM23";

import ddf.minim.*;

 

Minim minim;

AudioSnippet snip;

Serial port;

String buf="";

int cr = 13;  // ASCII return   == 13

int lf = 10;  // ASCII linefeed == 10

ArrayList psystems;

int counter = 0;

int val;

 

void setup() {

size(500,500);

frameRate(30);

smooth();

background(40,40,40);

noStroke();

 

port = new Serial(this, portname, 9600);

colorMode(RGB, 255, 255, 255, 100);

 

smooth();

}

 

// called whenever serial data arrives

void serialEvent(Serial p) {

int c = port.read();

 

if (c != lf && c != cr) {

buf += char(c);

return;

}else if (c == lf) {

val = int(buf);

println("val = " + val + "; counter = " + counter);

 

if(counter == 0){

int x = int(random(0,width));

int y = int(random(0,height));

 

 

}

counter = (counter+1) % 10;

 

if(val>0 && counter == 9)

{

minim = new Minim(this);

snip = minim.loadSnippet("snare.wav");

// play the file

snip.play();

}

 

buf = "";

}

}

 

void stop()

{

// always close Minim audio classes when you are done with them

snip.close();

// always stop Minim before exiting

minim.stop();

 

super.stop();

}

 

void draw() {

background(0);

 

}