|
Intro to Physical Computing Syllabus Research & Learning Other Class pages
ITP Help Pages |
Tom ClassNotes from Tom's Spring 2010 classArduino and Processing application to move ball from an accelerometer 2/24/10The Arduino code
void setup() {
//initialize the digital input that the switch is connected to
pinMode(2, INPUT);
// open serial port:
Serial.begin(9600);
}
void loop() {
// read Z axis of accelerometer, constrain to range of 0-254:
int z = analogRead(0)/4;
z = constrain(z,0,254);
Serial.print(z, BYTE);
// read y axis of accelerometer, constrain to range of 0-254:
int y = analogRead(1)/4;
y = constrain(y,0,254);
Serial.print(y, BYTE);
// read x axis of accelerometer, constrain to range of 0-254:
int x = analogRead(2)/4;
x = constrain(x,0,254);
Serial.print(x, BYTE);
// read button:
int button = digitalRead(2);
Serial.print(button, BYTE);
// print a 255 so we know when the end of the set of readings is:
Serial.print(255, BYTE);
}
The Processing Code
// import the serial library:
import processing.serial.*;
Serial myPort; // instance of the serial library
int byteCounter = 0; // index of which byte we're reading
// readings from the sensors:
int xAxis = 0;
int yAxis = 0;
int zAxis = 0;
int buttonState = 0;
void setup() {
// set the window size:
size(800, 600);
// list the serial ports:
println(Serial.list());
// get the name of the port we want:
String portName = Serial.list()[0];
// open the serial port:
myPort = new Serial(this, portName, 9600);
}
void draw() {
// smoothing the edges of drawn things:
smooth();
// don't draw a border:
noStroke();
// set the background color:
background(zAxis);
// if the button's pressed, change the fill color:
if (buttonState == 1) {
fill(255);
}
else if (buttonState == 0) {
fill(0);
}
// map the sensor values to the width and height of the screen:
float xPosition = map(xAxis, 0, 255, 0, width);
float yPosition = map(yAxis, 0, 255, 0, height);
// draw the ball:
ellipse(xPosition, yPosition, 50, 50);
}
// happens when there's a new byte in the serial buffer:
void serialEvent(Serial myPort) {
// read the byte, store it in a variable:
int inByte = myPort.read();
// print it:
println(inByte);
// if you got the 255 byte, reset the index counter:
if (inByte == 255) {
byteCounter = 0;
}
// otherwise, increment the counter:
else {
byteCounter++;
}
// depending on the value of the counter,
// store the value in a different variable:
if (byteCounter == 1) {
zAxis = inByte;
}
if (byteCounter == 2) {
yAxis = inByte;
}
if (byteCounter == 3) {
xAxis = inByte;
}
if (byteCounter == 4) {
buttonState = inByte;
}
}
Movie controller from class 3/3/10:
/*
Serial movie control
This sketch reads a string of sensor values serially. The sensor
values were originally the three analog values of an accelerometer
and a digital value from a switch. The sketch only uses the
second accelerometer reading.
The accelerometer reading is used to control a video of Brian
leaning left or right, or sitting center.
The video is at http://itp.nyu.edu/physcomp/uploads/lean.mov
*/
// import the video library so you can control the movie:
import processing.video.*;
Movie myMovie;
// import the serial library so you can get data from the microcontroller:
import processing.serial.*;
Serial myPort;
float startLoop; // time in the movie you want to start looping
float endLoop; // time in the movie you want to end looping
/*
The following variables are used if you want to have three sections of
looping: left lean, right lean, and sitting center
*/
float leftStart = 2.0; // start of the left lean
float leftEnd = 4.0; // end of the left lean
float centerStart = 4.0; // start of the sit center
float centerEnd = 4.7; // end of the sit center
float rightStart = 4.7; // start of the right lean
float rightEnd = 5.9; // end of the right lean
/*
The following variable is used if you want to map the movie position
to the range of one of the axes of the accelerometer
*/
float moviePosition = 2.0; // current movie position
void setup() {
// set the window size
size(700, 500);
// set the sketch's frame rate
frameRate(30);
// open the serial port:
myPort = new Serial(this, Serial.list()[0], 9600);
// don't generate a serialEvent unless
// a newline is received:
myPort.bufferUntil('\n');
// initialize the movie:
myMovie = new Movie(this, "lean.mov");
// print the movie's duration:
println("duration = " + myMovie.duration());
// loop the movie:
myMovie.loop();
}
void draw() {
/*
Use the following if statment if you want to have the movie
constantly looping over a section of the movie,
for example, when he leans left, when he leans right, when
he sits center
*/
/*
if (myMovie.time() > endLoop) {
myMovie.jump(startLoop);
}
*/
/*
Use the following jump statement if you want the movie
position to be mapped to the range of one of the
axes of the accelerometer:
*/
myMovie.jump(moviePosition);
// update the movie in the window:
image(myMovie, 0, 0);
}
void movieEvent() {
// read the movie frame:
myMovie.read();
}
void mousePressed() {
// print the time in the movie
// when you click the mouse:
println(myMovie.time());
}
void serialEvent(Serial myPort) {
// read the serial buffer as a string:
String inString = myPort.readString();
inString = trim(inString);
// split the string into an array of strings
// at the commas, then convert the array of
// strings to an array of ints:
int[] numbers = int(split(inString, ","));
// if you have four numbers, i.e. all the sensor readings:
if (numbers.length > 3) {
// take the second number in the array and use it to
// map the moviePosition variable's range
moviePosition = map(numbers[1], 270, 411, 2, 5);
println(moviePosition);
/*
Use the code below if you want to have the movie loop over
three sections: left lean, right lean, and sitting center
*/
/*
if (numbers[1] < 280 ) {
// println(numbers[1] + "Left");
startLoop = leftStart;
endLoop = leftEnd;
}
else if (numbers[1] < 380) {
// println(numbers[1] + "center");
startLoop = centerStart;
endLoop = centerEnd;
}
else if (numbers[1] < 480) {
// println(numbers[1] + "right");
startLoop = rightStart;
endLoop = rightEnd;
}
*/
}
}
|