Assignment 3: Portable Bowling, plus Mona Lisa

Assignment: Sensing PART II: Force Sensitive Resistors and Photocells

Collaborators:

Assignment: Sensing PART II: Force Sensitive Resistors and Photocells
Collaborators: drolnitzky

Description

For the first part of this assignment, I created a visualization using Processing where I applied the lens demo effect over the picture of Mona Lisa (see screenshot for visual).

For the second part, I used (or attempted to use) Processing for a some indoor bowling.  Basically, anytime a user knocks over the pin, it displays a "Strike" graphic on the computer.  Before the user throws the ball (or if they miss the pin), a "Bowl" graphic is displayed.  Perfect for on-the-go fun.

Part 1 - Programming

/**
*
* Inspecting Mona - up close
* Created by David Rolnitzky
* September, 2009
* Based on the Lens Demo Effect by luis2048
*
*/

int lensD = 256;  // Lens diameter
int[] lensArray = new int[lensD*lensD];  // Height and width of lens

PGraphics lensEffect;
PImage lensImage;
PImage lensImage2;

int xx = 0;
int yy = 0;
int dx = 1;
int dy = 1;

void setup() {

size(359, 542);

// Create buffered image for lens effect
lensEffect = createGraphics(width, height, P2D);

// Load background image
lensEffect.beginDraw();
lensEffect.image(loadImage("mona.jpg"), 0, 0,
lensEffect.width, lensEffect.height);
lensEffect.endDraw();

// Create buffered image for image to warp
lensImage = createGraphics(lensD, lensD, P2D);
lensImage2 = createGraphics(lensD, lensD, P2D);

// Lens algorithm (transformation array)
int magFactor = 40;  // Magnification factor
int m, a, b;

int r = lensD / 2;
float s = sqrt(r*r - magFactor*magFactor);

for (int y = -r; y < r; y++) {
for (int x = -r ;x < r; x++) {
if(x*x + y*y >= s*s) {
a = x;
b = y;
}
else {
float z = sqrt(r*r - x*x - y*y);
a = int(x * magFactor / z + 0.5);
b = int(y * magFactor / z + 0.5);
}
lensArray[(y + r)*lensD + (x + r)] = (b + r) * lensD + (a + r);
}
}
}

void draw() {

// Bounce lens around the screen
if((xx+dx+lensD > lensEffect.width) || (xx+dx < 0)) {
dx =- dx;
}
if((yy+dy+lensD > lensEffect.height) || (yy+dy < 0)) {
dy =- dy;
}
xx += dx;
yy += dy;

lensImage = createGraphics(lensD, lensD, P2D);

// save the backgrounlensD of lensHeight*lensWilensDth pixels rectangle at the coorlensDinates
// where the lens effect will be applielensD.
lensImage2.copy(lensEffect, xx, yy, lensD, lensD, 0, 0, lensD, lensD);

// output into a bufferelensD image for reuse
lensImage.loadPixels();

// For each pixel in the destination rectangle, apply the color
// from the appropriate pixel in the saved background. The lensArray
// array tells the offset into the saved background.
for (int i = 0; i < lensImage.pixels.length; i++)  {
lensImage.pixels[i] = lensImage2.pixels[lensArray[i]];
}
lensImage.updatePixels();

// Restore the original picture
image(lensEffect, 0, 0, width, height);

// Overlay the lens square
image(lensImage, xx, yy, lensD, lensD);

}

Part 2 - Programming + Mechanical

Components Used

  • Yoga Mat
  • Bowling Ball (14 lbs)
  • Bowling Pin
  • Force Sensitive Resistor
  • Computer, wires, breadboard

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 = 2;  // 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

/**

* Bowl-o-rama!

* Created by David Rolnitzky

* September 2009

*

* This program attempts to display a "strike" graphic if the user knocks over a pin,

* and a "bowl" graphic if they do not.

*

* Note: this isn't working quite right.  Keep getting an error that "Cannot find

* anything named "val". So for whatever reason, the processing is not able to pull this value

* from the arduino code.

*/

 

import processing.serial.*;

// Change this to the portname your Arduino board

String portname = "/dev/tty.usbserial-A7006Sd1"; // or "COM5"

Serial port;

String buf="";

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

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

 

 

//display picture 1

void drawpic1() {

PImage pic1;

pic1 = loadImage("strike.jpg");

image(pic1, 0, 0);

}

//display picture 2

void drawpic2() {

PImage pic2;

pic2 = loadImage("bowl.jpg");

image(pic2, 0, 0);

}

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

buf = "";

}

// if the sensor is 0 (meaning no force is felt), then show the "strike" graphic

// since the user knocked the pin over

if (val == 0) {

drawpic1();

}

 

// This is the default state - the pin is resting on top of the force sensor

// meaning that the pin is not knocked over, so show the "bowl" graphic

if (val > 0) {

drawpic2();

}

 

// need the delay to actually show the image on the screen, otherwise too fast to see

delay(100);

background(40,40,40);  // erase screen

}