# Theory and Practice of Tangible User Interfaces

### 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!

# Let's make some dots!

Project Members:
Andrew McDiarmid

## Description

Two pots and an FSR control the size and color of random dots on the Processing screen.  One pot controls hue, with feedback from three indicator LEDs.  The second pot controls the size of the dot, with feedback on the Processing screen.  Squeezing the FSR prints the desired dot.  Location is random.

## Components

Three LEDs

Three 20 ohm resistors

Two 100k ohm potentiometers

One FSR

One 100k ohm resistor

## Ardunio Code

/*
* Aduino code for drawing dots in Processing
* Andrew McDiarmid (mcd@berkeley.edu)
*
* for use with drawing_dots in Processing
*
* Sends hue data from one potentiometer, size data from another,
* and a Print symbol from a force-sensitive resistor
*/
int huePotPin = 2;                 // select the input pins for the potentiometers
int sizePotPin = 1;
int printPotPin = 0;

int redPin = 9;                    //select pins for indicator LEDs
int greenPin = 10;
int bluePin = 11;

int hueVal = 0;                    //initial hue value

float hue = 0.0;                   //variables for normalized hue value, size and print symbol
int size = 0;
int print = 0;

int r = 0;                         //output variables for rgb
int g = 0;
int b = 0;

void setup() {
Serial.begin(9600);
}

void hueToRGB(float h)    //modified from                                                                                  //http://www.cs.rit.edu/~ncs/color/t_convert.html
{                                   //assumes full saturation and value
int i;
float f, q, t;

h /= 60.0;                          // sector 0 to 5
i = (int) h;
f = h - i;                            // factorial part of h
q = 255 * ( 1 - f );
t = 255 * ( 1 - ( 1 - f ));

switch( i ) {
case 0:
r = 255;
g = t;
b = 0;
break;
case 1:
r = q;
g = 255;
b = 0;
break;
case 2:
r = 0;
g = 255;
b = t;
break;
case 3:
r = 0;
g = q;
b = 255;
break;
case 4:
r = t;
g = 0;
b = 255;
break;
default:        // case 5:
r = 255;
g = 0;
b = q;
break;
}
}

void loop() {
hueVal = analogRead(huePotPin);          // read the value from                                                                         //the sensor, between 0 - 1023
hue = ((float)hueVal) / (1023.0/359.0);            //limits hue to 0 - 359.0
size = analogRead(sizePotPin) / 4;                   //limits size to 0 - 255
print = analogRead(printPotPin) / 512;               //limits print to 0 or 1,                                                         //activated by FSR at half pressure

hueToRGB(hue);                                   //calculates rgb based on hue

analogWrite(redPin, r);                              //writes rgb to indicator LEDs
analogWrite(greenPin, ((float)g * 100.0/255.0));
analogWrite(bluePin, ((float)b * 50.0/255.0));

Serial.print("r");                                    //serial output for Processing:                                                             //r###g###b###s###(P)
Serial.print(r);
Serial.print("g");
Serial.print(g);
Serial.print("b");
Serial.print(b);
Serial.print("s");
Serial.print(size);

if (print == 1) {                              //If print command was                                                                       //issued, delay to avoid duplicates
Serial.println("P");
delay(350);
} else {
Serial.println("");
}
}

## Processing Code

/* Dot Drawer
* by Andrew McDiarmid (mcd@berkeley.edu)
*
* Controls the appearance of colored dots on the screen with two 100k-ohm potentiometers and one force-sensitve resistor
* Turning the potentiometers controls the hue and size of the dot, squeezing the FSR makes the dot appear.
*
* Chosen color is indicated by on-board LEDs. Size is indicated by on-screen crosshairs.
*/

import processing.serial.*;

String portname = "COM5";                   // or "COM5"
Serial port;
String buf="";             //buffer for holding serial input from arduino board

int cr = 13;                                // ASCII return   == 13
int lf = 10;                                // ASCII linefeed == 10

int rBegin = 0;                             //pointers for parsing serial input
int gBegin = 0;
int bBegin = 0;
int sBegin = 0;

int r;                                //variables for dot color (rgb) and size (pixels)
int g;
int b;
int s;

int x;           //coordinates for the center of the dot.  currently randomized.
int y;

String red;                        //variables for parsed substrings of serial input
String green;
String blue;
String size;

void setup() {
size(400,400);
x = (int)random(0, width);
y = (int)random(0, height);
frameRate(10);
smooth();
background(40,40,40);
noStroke();
port = new Serial(this, portname, 9600);
}

void draw() {
}

void keyPressed() {
if(key == ' ') {
background(40,40,40);                        //erases screen
}
else {
drawball(255, 255, 255, 50);                  //draws white dot
}
}

void drawOutline(int ss){                         //draws gray crosshairs,                                                                         //point-by-point, as the second                                                             //pot changes the size input
stroke(160);
point(x + (ss/2), y);
point(x - (ss/2), y);
point(x, y + (ss/2));
point(x, y - (ss/2));
noStroke();
}

// draws ball according to FSR input
void drawball(int rr, int gg, int bb, int ss) {
fill(rr,gg,bb);
ellipse(x,y,ss,ss);
x = (int)random(0, width);
y = (int)random(0, height);
}

// called whenever serial data arrives
void serialEvent(Serial p) {
if (c != lf && c != cr) {
buf += char(c);
}
if (c == lf){
for(int i = 0; i < buf.length(); i++){     //updates pointers to the r,                                                                //g, b, s portions of the input string
if (buf.charAt(i) == 'r')
rBegin = i + 1;
if (buf.charAt(i) == 'g')
gBegin = i + 1;
if (buf.charAt(i) == 'b')
bBegin = i + 1;
if (buf.charAt(i) == 's')
sBegin = i + 1;
}

red = buf.substring(rBegin, gBegin - 1);    //Parses the input string                                                                     //according to above pointers
green = buf.substring(gBegin, bBegin - 1);
blue = buf.substring(bBegin, sBegin - 1);

if (buf.charAt(buf.length() - 1) != 'P'){         //'P' is the go symbol.  No                                                                   //'P'? Draws crosshairs
size = buf.substring(sBegin, buf.length());
drawOutline(Integer.parseInt(size));
}
else {                                              //'P'?  Makes a dot!
size = buf.substring(sBegin, buf.length() - 1);

r = Integer.parseInt(red);
g = Integer.parseInt(green);
b = Integer.parseInt(blue);
s = Integer.parseInt(size);
drawball(r,g,b,s);
}
buf = "";                                          //clears buffer for next round
}
}

forthcoming