PROCESSING CODE_________________________________________________________________
// Etch a Sketch
// by David Lu
// This program is a study of the classic children's toy, etch a sketch.
// It reads bytes in from the active serial port and changes the location of
// the pen on screen.
// It assumes that
// 1. two potentiometers are plugged into a microcontroller
// 2. the microcontroller is connected to processing via a serial connection
Ball b; // this is our pen
int screen[]; // a copy of pixels[]
int val; // the value of x or y that has been sent via serial
void setup() {
size(600,600);
background(#C8C5A8);
fill(#C8C5A8);
noStroke();
// fill screen with background color
rect(0,0,width, height);
// screen is a copy of pixels[], so make sure it is the same size
screen = new int[width*height];
// instantiate the pen
b = new Ball();
// serial rate
beginSerial(9600);
rectMode(CENTER_DIAMETER);
// save what is currently on screen (copy pixels[] into screen[])
preserveScreen();
}
void loop() {
// copy pixel values from screen[] to pixels[]
restoreScreen();
// move the pen, if necessary
b.move();
// draw the pen
drawPlus(b.x, b.y, 12, 4.5);
// copy the updated screen
preserveScreen();
}
void serialEvent() {
float t; // t contains the normalised value of the byte read from serial
val = serial; // read byte from serial and store in val
// the range of values in the byte are split so that:
// values 0 - 127 are considered to be a y coordinate (potentiometer 1)
// values 128 - 255 are considered to be an x coordinate (potentiometer 2)
// y
if (val < 128) {
// normalise
val = 128-val;
t = val / 127.0;
// get ready to move the pen to this y coordinate
b.setTarget(t*width, b.ty);
// x
} else {
// normalise
val = 255 - val;
t = val / 127.0;
// get ready to move the pen to this x coordinate
b.setTarget(b.tx, t*height);
}
}
// this is a simple ball class. for detailed comments on how it works,
// see the "custom alphabet" example in the typography section of
the
// processing reference.
class Ball {
float px, py;
float x, y, tx, ty;
boolean active;
Ball() {
this.x = random(width);
this.y = random(height);
this.tx = random(width);
this.ty = random(height);
this.active = false;
this.px = this.x;
this.py = this.y;
}
void setTarget(float xin, float yin) {
if (this.tx != xin || this.ty != yin) {
this.tx = xin;
this.ty = yin;
this.active = true;
}
}
void move() {
if (this.active) {
float xdif, ydif;
this.px = this.x;
this.py = this.y;
xdif = this.tx - this.x;
ydif = this.ty - this.y;
this.x += xdif/24;
this.y += ydif/24;
if (Math.abs(xdif)<0.5 && Math.abs(ydif)<0.5) {
this.x = this.tx;
this.y = this.ty;
this.active = false;
}
}// end if active
} // end move method
} // end class
// draw the pen
void drawPlus(float x, float y, float unit, float scale) {
background(#C8C5A8);
fill(#ffffff);
stroke(#C24038);
float length, thickness;
length = unit * scale;
thickness = unit/3 * scale;
rect(x, y, length, thickness);
rect(x, y, thickness, length);
}
// copy pixels
void preserveScreen() {
for (int i = 0; i < width*height; i++) {
screen[i] = pixels[i];
}
}
// restore pixels
void restoreScreen() {
for (int i = 0; i < width*height; i++) {
pixels[i] = screen[i];
}
}