User login

Powered by Drupal, an open source content management system

Theory and Practice of Tangible User Interfaces

Bouncy Bubble Sensing: Force Sensors

Submitted by ngandomi on Wed, 10/01/2008 - 12:53

Assignment: Sensing PART II: Force sensors and photocells

Collaborators:

 

PART I:

 

Description:

Use a force sensor to create an interesting visualization on computer influenced by the input of the sensor. I modified the sample Processing program "Bouncy Bubbles". In the original program, 12 different sized bubbles fall to the bottom of the screen and move and collide until they finally rest on the screen. Variables are spring and gravity. 

I modified the program to input values from the FSR and store them as a squeeze variable. I used that variable to influence the values of spring and gravity. When the user squeezes the FSR, the gravity and spring changes, making a lighter gravity environment...and the bubbles get bouncy!

 

Bouncy BubblesBouncyBallsDontBounce

 

Materials:

  • One FSR
  • Arduino Board
  • breadboard
  • USB cable
  • One 220ohm resistors
  • Arduino Software
  • Processing Software 
  •  

    Code:

     

     

    /**

     * Bouncy Bubbles. 

     * Based on code from Keith Peters (www.bit-101.com). 

     * 

     * Multiple-object collision.

     */

     

     

     import processing.serial.*;

    // Change this to the portname your Arduino board

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

    Serial port;

    String buf="";

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

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

     

    float squeezeVal = 1;

     

     

    int numBalls = 12;

    float spring = 0.01;

    float gravity = 0.3;

    Ball[] balls = new Ball[numBalls];

     

    void setup() 

    {

      port = new Serial(this, portname, 9600);

      size(200, 200);

      noStroke();

      smooth();

      for (int i = 0; i < numBalls; i++) {

        balls[i] = new Ball(random(width), random(height), random(20, 40), i, balls);

      }

    }

     

    void draw() 

    {

      background(0);

      for (int i = 0; i < numBalls; i++) {

        balls[i].collide();

        balls[i].move();

        balls[i].display();  

      }

    }

     

    class Ball {

      float x, y;

      float diameter;

      float vx = 0;

      float vy = 0;

      int id;

      Ball[] others;

     

      Ball(float xin, float yin, float din, int idin, Ball[] oin) {

        x = xin;

        y = yin;

        diameter = din;

        id = idin;

        others = oin;

      } 

     

      void collide() {

        for (int i = id + 1; i < numBalls; i++) {

          float dx = others[i].x - x;

          float dy = others[i].y - y;

          float distance = sqrt(dx*dx + dy*dy);

          float minDist = others[i].diameter/2 + diameter/2;

          if (distance < minDist) { 

            float angle = atan2(dy, dx);

            float targetX = x + cos(angle) * minDist;

            float targetY = y + sin(angle) * minDist;

            float ax = (targetX - others[i].x) * spring * squeezeVal;

            float ay = (targetY - others[i].y) * spring * squeezeVal;

            vx -= ax;

            vy -= ay;

            others[i].vx += ax;

            others[i].vy += ay;

          }

        }   

      }

     

      void move() {

        vy += gravity/squeezeVal;

        x += vx;

        y += vy;

        if (x + diameter/2 > width) {

          x = width - diameter/2;

          vx += -0.9; 

        }

        else if (x - diameter/2 < 0) {

          x = diameter/2;

          vx *= -0.9;

        }

        if (y + diameter/2 > height) {

          y = height - diameter/2;

          vy *= -0.9; 

        } 

        else if (y - diameter/2 < 0) {

          y = diameter/2;

          vy *= -0.9;

        }

      }

     

      void display() {

        fill(255, 204);

        ellipse(x, y, diameter, diameter);

      }

    }

     

     

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

          squeezeVal = 1;

        }

        else{

        squeezeVal = (float)(val*10)/1500;

        }

     

        buf = "";

     

      }

    }

     

    FSR Board