Assignment: Sensing PART II: Force sensors and photocells
Collaborators:
Description
Programming:
I modified the SoftBody example code in Processing to take input from the FSR on my board and correlate squeezes (force) with the movement of the soft shape around the screen. A squeeze causes the shape to move to another place on the screen. The springing effect causes the shape to morph into cool shapes with different nodes. Some of these nodes look like pieces of paper flying in the wind, or a ghost, flitting around.
Mechanical:
I constructed a coin jar that senses when it's time to take the coins to your neighborhood CoinStar machine to get bills. When less than a third of the jar is full, the LEDs light up dimly. When the jar is at least half full, the LEDs get very bright, signaling that now would be a good time to unload those coins. To make up for the ledge space on the bottom of the jar, I attached cotton pads, and taped the sensor to the bottom of the cotton pads.
I had another idea to make a roach habitat refilling indicator. My husband has a pet roach (deceased) who lives in a contact lens container full of rubbing alcohol. The rubbing alcohol inevitably evaporates, leaving the roach unprotected, so I attached a quarter to the bottom of the container (to make up for the ledge space) and taped a sensor under the quarter. We didn't have rubbing alcohol on hand though, so I couldn't test this out (without harming the roach!). The idea was that if the container was full the green LED would glow; once it ceases to glow it's time to refill (a more developed version would probably flash or chime to notify us that the roach is in trouble).
Components
1 glass jar, with coins
1 roach
1 contact lens container
Several cotton pads
1 quarter
Tape
1 FSR
3 LEDs
3 220-ohm resistors
1 10-ohm resistor
2 black wires for ground
1 red wire for 5-V power
1 yellow wire from analog in pin 0
3 yellow wires from PWM pins 9, 10, 11
Code
/**
* Soft Body
* Created by Carol Chen
* Adapted from code by Ira Greenberg
*
* Softbody dynamics simulation using curveVertex() and curveTightness()
*/
import processing.serial.*;
// SERIAL GLOBAL VARIABLES
String portname = "/dev/tty.usbserial-A4001nQ5"; // Modify here to your own arduino COM port
Serial port;
String buf="";
int cr = 13; // ASCII return == 13
int lf = 10; // ASCII linefeed == 10
int loc = 0;
// center point
float centerX = 0, centerY = 0;
float radius = 45, rotAngle = -90;
float accelX, accelY;
float springing = .0085, damping = .98;
//corner nodes
int nodes = 5;
float nodeStartX[] = new float[nodes];
float nodeStartY[] = new float[nodes];
float[]nodeX = new float[nodes];
float[]nodeY = new float[nodes];
float[]angle = new float[nodes];
float[]frequency = new float[nodes];
// soft-body dynamics
float organicConstant = 1;
void setup() {
size(200, 200);
//center shape in window
centerX = width/2;
centerY = height/2;
// iniitalize frequencies for corner nodes
for (int i=0; i<nodes; i++){
frequency[i] = random(5, 12);
}
noStroke();
smooth();
frameRate(30);
port = new Serial(this, portname, 9600);
}
// called whenever serial data arrives
void serialEvent(Serial p) {
int c = port.read();
if (c != lf && c != cr) {
buf += char(c);
}
if (c == lf) {
int val = int(buf);
println("Location distance: "+val);
moveShape(val);
buf = "";
}
}
void draw() {
//fade background
fill(0, 100);
rect(0,0,width, height);
drawShape();
moveShape(loc);
}
void drawShape() {
// calculate node starting locations
for (int i=0; i<nodes; i++){
nodeStartX[i] = centerX+cos(radians(rotAngle))*radius;
nodeStartY[i] = centerY+sin(radians(rotAngle))*radius;
rotAngle += 360.0/nodes;
}
// draw polygon
curveTightness(organicConstant);
fill(255);
beginShape();
for (int i=0; i<nodes; i++){
curveVertex(nodeX[i], nodeY[i]);
}
for (int i=0; i<nodes-1; i++){
curveVertex(nodeX[i], nodeY[i]);
}
endShape(CLOSE);
}
void moveShape(int val) {
//move center point
float deltaX = val/200-centerX;
float deltaY = val/200-centerY;
// create springing effect
deltaX *= springing;
deltaY *= springing;
accelX += deltaX;
accelY += deltaY;
// move predator's center
centerX += accelX;
centerY += accelY;
// slow down springing
accelX *= damping;
accelY *= damping;
// change curve tightness
organicConstant = 1-((abs(accelX)+abs(accelY))*.1);
//move nodes
for (int i=0; i<nodes; i++){
nodeX[i] = nodeStartX[i]+sin(radians(angle[i]))*(accelX*2);
nodeY[i] = nodeStartY[i]+sin(radians(angle[i]))*(accelY*2);
angle[i]+=frequency[i];
}
}
Photos attached