Assignment: Sensing PART II: Force sensors and photocells
Collaborators:
Part I: Programming
I modified the Puff sample code by Ira Greenberg that creates an organic-looking trail of elipses that move around. The input from the pressure sensor interrupts the motion, making it appear that the creature-puff is twitchy.
Components Used
Arduino Code
/*
* Resistive Sensor Input
* Takes the input from a resistive sensor, e.g., FSR or photocell
* Dims the LED accordingly, and sends the value (0-255) to the serial port
*/
int sensorPin = 0; // select the input pin for the sensor
int ledPin = 11; // select the output 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(sensorPin); // read the value from the sensor, 0-1023
analogWrite(ledPin, val/4); // analogWrite (dimming the LED) can be between 0-255
Serial.println(val/4); // writing the value to the PC via serial connection
delay(50); // rest a little...
}
Processing Code
/*
* Twitchy Puff.
* Based on Puff by Ira Greenberg.
* http://processing.org/learning/topics/puff.html
* Series of ellipses simulating a multi-segmented organism, utilizing a follow
* the leader algorithm. Pressure sensor adds twitchiness.
*/
import processing.serial.*;
String portname = "/dev/tty.usbserial-A70061pj"; // my Mac's serial port address
Serial port;
String buf="";
int cr = 13; // ASCII return == 13
int lf = 10; // ASCII linefeed == 10
int val;
// For puff head
float headX;
float headY;
float speedX = .7;
float speedY = .9;
// For puff body
int cells = 1000;
float[]px= new float[cells];
float[]py= new float[cells];
float[]radiiX = new float[cells];
float[]radiiY = new float[cells];
float[]angle = new float[cells];
float[]frequency = new float[cells];
float[]cellRadius = new float[cells];
void setup(){
size(640, 360);
// Begin in the center
headX = width/2;
headY = height/2;
// Fill body arrays
for (int i=0; i< cells; i++){
radiiX[i] = random(-7, 7);
radiiY[i] = random(-4, 4);
frequency[i]= random(-9, 9);
cellRadius[i] = random(16, 30);
}
frameRate(30);
}
void draw(){
background(0);
noStroke();
fill(255, 255, 255, 5);
// Follow the leader
for (int i =0; i< cells; i++){
if (i==0){
px[i] = headX+sin(radians(angle[i]))*radiiX[i];
py[i] = headY+cos(radians(angle[i]))*radiiY[i];
}
else{
px[i] = px[i-1]+cos(radians(angle[i]))*radiiX[i];
py[i] = py[i-1]+sin(radians(angle[i]))*radiiY[i];
// Check collision of body
if (px[i] >= width-cellRadius[i]/2 || px[i] <= cellRadius[i]/2){
radiiX[i]*=-1;
cellRadius[i] = random(1, 40);
frequency[i]= random(-13, 13);
}
if (py[i] >= height-cellRadius[i]/2 || py[i] <= cellRadius[i]/2){
radiiY[i]*=-1;
cellRadius[i] = random(1, 40);
frequency[i]= random(-9, 9);
}
}
// Draw puff
ellipse(px[i], py[i], cellRadius[i], cellRadius[i]);
// Set speed of body
angle[i]+=frequency[i];
}
// Set velocity of head
headX+=speedX;
headY+=speedY;
// Check boundary collision of head
if (headX >= width-cellRadius[0]/2 || headX <=cellRadius[0]/2){
speedX*=-1;
}
if (headY >= height-cellRadius[0]/2 || headY <= cellRadius[0]/2){
speedY*=-1;
}
}
// 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("val="+val);
if(val==0){
speedX=speedX-.5;
speedY=speedY-.5;
}
else{
speedX=speedX+(val/500);
speedY=speedY+(val/500);
}
}
}
Part II: Mechanical
I played with sensing the pressure on a keyboard when a person is typing. If the sensor notices that there is heavy fluctuations in typing, like the user is typing angrily, it could send a message to the user to take a break from the computer. Also, if the pressure lasts a long time, indicating that the user hasn't moved from the computer in too long, it could remind the user to stretch or have a snack.