Announcements

November 24, 2007
Reading for November 27th, are now posted. Enjoy!

October 2, 2007
To upload your thoughtless acts, create a new assignment page like any other lab. You'll see "Thoughtless Acts" listed as one of the assignment options.

May 24, 2008
This site has been archived and is no longer editable. Stay tuned for the next version, coming in the fall!


Lab 4

Project Members: 
n8agrin

Assignment

Use force resistive and photocells sensors as input and use variable LEDs
(build on the pulse width modulation exercise from Week 3) as output;
consider multiple force sensors and photocells?

Programming
Create
an interesting visualization on your computer that could be influenced
by the input from the sensors you have (pot, photocell, FSR, or
combination of them). You can use Processing (or any other language you
like) in writing the program. Post your results on the course website.

Mechanical
Create a mechanical construction for
your FSR that distributes or focuses physical force that is applied.
Think about everyday objects (toothpaste tube, entrance mat,
paintbrush, pipette, etc.) and how you measure the pressure or force
applied to them.

Description

I decided to build a mini video game, using the collision demo from the processing website, I recreated Pong. This required the use of two POTs, and a lot of code modification. Yey!

For my mechanical interface, I am planning on putting the FSR into a sqeeze toy and having the pressure from squeezing the toy trigger the sesnor. This could be used to register some emotive tangible response, like stress, anger or pleasure.

Components Used

  • 1 red, 1 blue, 1 green led
  • 3 220-ohm resistors
  • 1 diffuser
  • 1 FSR
  • 1 Squeeze toy
  • Various lengths of wire
  • 1 breadboard
  • 1 arduino board

Code

Control LEDs using an FSR:

boolean DEBUG = false;

int sensorPin = 2;
int sensorVal = 0;

int bluePin = 9;
int redPin = 10;
int greenPin = 11;

int pinVal = 0; // Create a global pin value from the sensor val

void setup() {
pinMode(bluePin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(redPin, OUTPUT);
Serial.begin(9600);
}

void loop() {
sensorVal = analogRead(sensorPin);
pinVal = sensorVal / 4;
analogWrite(bluePin, pinVal);
analogWrite(redPin, pinVal);
analogWrite(greenPin, pinVal);

if (DEBUG) {
Serial.println(sensorVal);
Serial.println(pinVal);
}

}

Paint a paintball with Processing by receiving input from an Arduino powered FSR

/*
* Arduino Ball Paint
* (Arduino Ball, modified)
* ----------------------
*
* Draw balls randomly on the screen, size controlled by a device
* on a serial port. Press space bar to clear screen, or any
* other key to generate fixed-size random balls.
*
* Receives an ASCII number over the serial port,
* terminated with a carriage return (ascii 13) then newline (10).
*
* This matches what Arduino's " Serial.println(val)" function
* puts out.
*
* Created 25 October 2006
* copyleft 2006 Tod E. Kurt <tod@todbot.com
* http://todbot.com/
*/
import processing.serial.*;
// Change this to the portname your Arduino board
String portname = "/dev/tty.usbserial-A4001nvG"; // or "COM5"
Serial port;
String buf="";
int cr = 13; // ASCII return == 13
int lf = 10; // ASCII linefeed == 10

void setup() {
size(300,300);
frameRate(10);
smooth();
background(40,40,40);
noStroke();
port = new Serial(this, portname, 9600);
}

void draw() {
}

void keyPressed() {
if(key == ' ') {
background(40,40,40); // erase screen
}
else {
int x = int(random(0,width));
int y = int(random(0,height));
drawball(x,y, 50);
}
}

// draw balls
void drawball(int x, int y, int r) {
println("x="+x);
println("y="+y);
println("r="+r);

for (int i=0; i<100; i++ ) {
fill(255-i,i,240);
ellipse(x,y,r,r);
}
}

// called whenever serial data arrives
void serialEvent(Serial p) {
int c = port.read();
println("c="+c);
if (c != lf && c != cr) {
buf += char(c);
}
if (c == lf) {
int val = int(buf);
int x = int(random(0,width));
int y = int(random(0,height));
drawball(x,y,(val/20));
buf = "";

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

 

FSR manipulationg LEDs 

 

Make a simple video game using two POTs

/*****************
Arduino Code
******************/
/*
Simple interface to talk to Processing and run a game of Pong
9/27/08 n8agrin
*/
boolean DEBUG = false;

int redPlayerPin = 2;
int redPlayerVal = 0;
int redPlayerScore = 0;

int bluePlayerPin = 3;
int bluePlayerVal = 0;
int bluePlayerScore = 0;

int bluePin = 9;
int greenPin = 10;
int redPin = 11;

void setup() {
pinMode(bluePin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(redPin, OUTPUT);
Serial.begin(9600);
}

void loop() {
redPlayerVal = analogRead(redPlayerPin);
Serial.print("r,");
Serial.println(redPlayerVal);

bluePlayerVal = analogRead(bluePlayerPin);
Serial.print("b,");
Serial.println(bluePlayerVal);

int incoming = Serial.read(); // Read in from Processing

// look for an "r" char
// increment the score and light up the appropriate LED to keep score
if (incoming == 114) {
redPlayerScore += 1;
if (redPlayerScore == 5) {
redPlayerScore = 0;
bluePlayerScore = 0;
for (int i = 0; i < 5; i++) {
digitalWrite(redPin, LOW);
delay(100);
digitalWrite(redPin, HIGH);
delay(100);
}
}
}

// look for a "b" char
if (incoming == 98) {
bluePlayerScore += 1;
if (bluePlayerScore == 5) {
bluePlayerScore = 0;
redPlayerScore = 0;
for (int i = 0; i < 5; i++) {
digitalWrite(bluePin, LOW);
delay(100);
digitalWrite(bluePin, HIGH);
delay(100);
}
}
}

// write out to the score to the leds
analogWrite(redPin, ((255 * redPlayerScore)/5));
analogWrite(bluePin, ((255 * bluePlayerScore)/5));

if (DEBUG) {
}
}

/*******************
Processing Code
********************/
/*
Basic collision code from Processing website:
http://processing.org/learning/examples/collision.html

Modified to make pong by n8
9/26
*/

// Setup the serial connection
import processing.serial.*;
String portname = "/dev/tty.usbserial-A4001nvG";
Serial port;
String buf="";
int cr = 13; // ASCII return == 13
int lf = 10; // ASCII linefeed == 10

// Global variables for the ball
float ball_x;
float ball_y;
float ball_dir = 1;
float ball_size = 5; // Radius
float dy = 0; // Direction

// Score
int blue_score = 0;
int red_score = 0;

// Global variables for the paddle
int paddle_one_width = 5;
int paddle_one_height = 20;
int red_paddle_y = 0;
float red_paddle_py = 0;

int paddle_two_width = 5;
int paddle_two_height = 20;
int blue_paddle_y = 0;
float blue_paddle_py = 0;

int dist_wall = 15;
int other_wall = 240;

void setup()
{
size(255, 255);
rectMode(CENTER_RADIUS);
ellipseMode(CENTER_RADIUS);
noStroke();
smooth();
ball_y = height/2;
ball_x = width/2;
red_paddle_y = height / 2;
blue_paddle_y = height / 2;
println("First player to five points wins!");
port = new Serial(this, portname, 9600);
}

void serialEvent(Serial p) {
int c = port.read();
if (c != lf && c != cr) {
buf += char(c);
}
if (c == lf) {
String paddle_location[] = split(buf, ",");
if (paddle_location[0].equals("r")) {
red_paddle_y = int(paddle_location[1]) / 4;
}
if (paddle_location[0].equals("b")) {
blue_paddle_y = int(paddle_location[1]) / 4;
}
buf = "";
}
}

void draw()
{
background(51);

ball_x += ball_dir * (1.0 + (total_score()/2));
ball_y += dy;

// Constrain paddle to screen
red_paddle_y = constrain(red_paddle_y, paddle_one_height, height - paddle_one_height);
blue_paddle_y = constrain(blue_paddle_y, paddle_two_height, height - paddle_two_height);

// Test to see if the ball is touching a paddle
float py = width - dist_wall - paddle_one_width - ball_size;
float oy = width - other_wall + paddle_two_width + ball_size;

if(ball_x >= py
&& ball_y > red_paddle_y - paddle_one_height - ball_size
&& ball_y < red_paddle_y + paddle_one_height + ball_size) {
ball_dir *= -1;
if(red_paddle_y != red_paddle_py) {
dy = (red_paddle_y-red_paddle_py)/2.0;
if(dy > 5) { dy = 5; }
if(dy < -5) { dy = -5; }
}
}

if(ball_x <= oy
&& ball_y > blue_paddle_y - paddle_two_height - ball_size
&& ball_y < blue_paddle_y + paddle_two_height + ball_size) {
ball_dir *= -1;
if(blue_paddle_y != blue_paddle_py) {
dy = (blue_paddle_y-blue_paddle_py)/2.0;
if(dy > 5) { dy = 5; }
if(dy < -5) { dy = -5; }
}
}

hit_left_or_right(); //test for a left or right wall collision
hit_top_or_bottom(); //test for a cieling or floor collision

// Draw ball
fill(255);
ellipse(ball_x, ball_y, ball_size, ball_size);

// Draw the first player (blue) paddle
fill(0, 0, 255);
rect(width - other_wall, blue_paddle_y, paddle_two_width, paddle_two_height);

// Draw the second player (red) paddle
fill(255, 0, 0);
rect(width - dist_wall, red_paddle_y, paddle_one_width, paddle_one_height);

// set the current frame's paddle-y dimension so that a diff can be calculated
// in the next frame. this provides y-axis motion of the ball
red_paddle_py = red_paddle_y;
blue_paddle_py = blue_paddle_y;
}

// If the ball goes past the top or bottom walls reverse direction
void hit_top_or_bottom() {
if(ball_y > (height - ball_size) || ball_y < ball_size) {
dy *= -1;
}
}

// If the ball hits the left or right wall a player scored a point
void hit_left_or_right() {
// If the ball goes past the right wall
if(ball_x > width+ball_size) {
blue_score += 1;
println("BLUE gets a point. Total BLUE:" + str(blue_score));
port.write("b");
reset_ball();
}

// If the ball hits the left wall...
if(ball_x < -(ball_size * 2)) {
red_score += 1;
println("RED gets a point. Total RED:" + str(red_score));
port.write("r");
reset_ball();
}

check_for_winner();
}

// reset the ball to the middle of the screen
void reset_ball() {
ball_x = width/2;
ball_y = height/2;
dy = 0;
if (ball_dir == -1) {ball_dir *= -1;}
}

// check to see if a player has scored 5 points
void check_for_winner() {
if (blue_score == 5) {
println("BLUE PLAYER WINS!!");
reset_score();
}
if (red_score == 5) {
println("RED PLAYER WINS!!");
reset_score();
}
}

// return a total score, used to calculate ball velocity
int total_score() {
return blue_score + red_score;
}

// return all the scores to zero
void reset_score() {
blue_score = 0;
red_score = 0;
}

PONG Setup

 

 

pongpong
 

Mechanical Interface:  Squeeze ball


Comments

seriously, that pong game

seriously, that pong game brought me back. Thanks for making it! I hope you didn't have to use that squeeze ball as stress relief due to this class.. :)


Powered by Drupal - Design by Artinet