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) {
int c = port.read();
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
}
}
Photo
http://farm2.static.flickr.com/1011/1447847301_4f74ecf8c7_o.jpg
Ingenious Force Distributor
Since the act of sqeezing the FSR is a decision that commits the dot to the screen, I imagine fixing the FSR to the base of a gavel, so that striking the gavel writes the dot. I don't have a gavel, though, so for now, I will place the FSR between the pages of a book (I used Svenonius, The Intellectual Foundation of Information Organization). The dot is committed by whacking the book with a fist.
http://farm2.static.flickr.com/1345/1449276532_b279e03eec_b.jpg
Comments
have you found a gavel, yet?
have you found a gavel, yet? If so, please bring it to class :)