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);
}