|
CLASS DOCUMENTS
REPORTS & ASSIGNMENTS
CLASS CONTENT
USING THIS SITE
registered authors login here You are: (logout) For more on PMWiki, see pmwiki.org |
Multivariableviewerfancyby Jamie Allen Feb 1st, 2007 This is Processing code (Arduino code commented in at the bottom) for graphing data. This code includes a 'true' data trail indicating a visual history of the last 50 samples. This code might be a good starting point for Sensors and Time assignments, among other things.
/*
psychadelic dataviewer with hysteresis
for two values based on Tom Igoe's & Melvin Ochsmann's work
(with some help from James Tu!)
by Jamie Allen 2007
This program takes raw bytes from the serial port that are seperated by headers
"A", "B", etc. at 9600 baud and graphs them.
Note that the data protocol in this case is not very efficient. We're taking in
a byte for each character in the incoming number (i.e.: worst case, we're actually
reading in "A,X,X,X,X,_,B,X,X,X,X,_" or TWELVE BYTES, 12 x 8 = 96 bits. The
'information content of this data is actually 2 x 10 bits = 20 bits (the ADC results
themselves, at 10 bits each). We're therefore adding an overhead of 76 bits in our
protocol! There are better ways to approach this, but this method is good because
it allows us to 'see' the incoming data in an inteligible way in the Arduino serial
monitor or other terminal programs.
Arduino code for sending this data in the first place from the board is
commented in below the Processing code
*/
import processing.serial.*;
Serial myPort; // The serial port
PFont myFont; // The display font:
// initial variables:
int val = 0;
int NEWLINE = 10;
int i = 1; // counter
int j; // counter
int valueA, valueB; // the converted data from serial port
boolean buf;
String bufA="", bufB=""; // buffers in which to store ascii data as it comes in
float valNormA, valNormB; // normalized values of A and B - so we can write
// them to the screen based on the size of the screen itself
int indexA=0; //used to create a running array of the imcoming samples
int indexB=0;
float[] valuesA = new float[50]; //these arrays hold the last 50 incoming samples
float[] valuesB = new float[50]; //increasing the number of stored variables in these array
//will make the 'trails' longer
int wrote = 0; //this is used if we want to print the numeric value to the screen
int offset = 0; //
int offsettext = 25;
int lf = 10;
void setup () {
size(500, 500); // window size
frameRate(60); // drawing framerate
// load a font - it doesn't need to be this one
// but it needs to be in your 'data' folder
myFont = loadFont("Courier-Bold-12.vlw");
textFont(myFont, 16);
textAlign(CENTER);
textMode(SCREEN);
fill(#E9FF5B, 200);
// set inital background:
background(#000000);
strokeCap(ROUND);
strokeWeight(3);
smooth();
ellipseMode(CENTER);
// List all the available serial ports
println(Serial.list());
// I know that the third port in the serial list on my mac
// is always my Keyspan adaptor, so I open Serial.list()[2].
// Open whatever port is the one you're using.
myPort = new Serial(this, Serial.list()[2], 9600);
//myPort.bufferUntil(lf);
}
void draw()
{
j++;
while (myPort.available() > 0) {
serialEvent(myPort.read());
}
background(#000000);
valNormB = valueB/1023.0;
for (int k=0; k<valuesA.length; k=k+1)
{
stroke(#555FFF, k*3);
fill(#55F555, k*1);
ellipse(i+2*k, height - valuesA[k]*height,10,10);
//println(valuesA[k]);
stroke(#FF55FF,k*3);
fill(#222222,k*1);
ellipse(i+2*k, height - valuesB[k]*height, 20,20);
//println(valuesB[k]);
}
// at the edge of the screen, go back to the beginning:
if (i > width) {
i = 0;
background(#000000);
}
else {
i++;
}
//piece of code to print the numeric value to the screen
/*
//only display the value once every 50 readings
//just to keep things clean
if (wrote > 50)
{
fill(#FFFFFF);
text(valNormA, i, height - valuesA[k]*height);
text(valNormB, i, height - valuesB[k]*height);
wrote = 0;
}
wrote++;
*/
}
//Serial parsing stuff to seperate out the
//sensor variable data
void serialEvent(int serial){
// if we've got a new piece of data, with header
if(serial!=lf) {
if (serial=='A') buf = true; //detect header
if (serial=='B') buf = false; //detect header
// gather the remaining pieces of
if (buf){ if (serial!='A') bufA += char(serial);
}else{
if (serial!='B') bufB+= char(serial);
}
} else {
if (buf){ valueA = int(bufA); bufA="";
} else { valueB = int(bufB); bufB="";
}
}
//println(valueA);
//print(valueB);
//println(valueA);
//println("*");
//print(valuesA.length);
if (valuesA.length == 50)
{
//if the array is full, we have to chop off the last value, and replace it with
//the most recent value
valuesA = subset(valuesA, 1); //removing the first item from the array
valuesA = append(valuesA,0.0);
//print(valuesA);
//print(valuesA.length);
indexA=valuesA.length-1; //hack to keep the array adding to the end, instead of starting again at the beginning
}
// collect values in an array for display of 'trails
valuesA[indexA]=(valueA/1023.0);
indexA = (indexA+1)%valuesA.length;
//println(valuesA);
//println("-");
//same thing for the second piece of data "B"
if (valuesB.length == 50)
{
valuesB = subset(valuesB, 1); //removing the first item from the array
valuesB = append(valuesB,1.0);
//print(valuesB);
//print(valuesB.length);
indexB =valuesB.length-1;
}
valuesB[indexB]=(valueB/1023.0);
indexB = (indexB+1)%valuesB.length;
}
/*
Arduino code to send data to this Processing program:
*/
/*
// Sending two pieces of data, deliminated by a header - "A", "B", at the beginning -
// and a line break at the end.
// based on stuff from Melvin Ochsmann and Tom Igoe.
// reworked a bit for Sensor Workshop class by Jamie Allen, 2007
int sensorPin1 = 4; // select the input pin for sensor
int sensorPin2 = 5; // select the input pin for other sensor
int ledPin = 13; // select the pin for the LED
int val1 = 0; // variable to store the value coming from the sensor
int val2 = 0; // variable to store the value coming from the sensor
void setup() {
pinMode(ledPin, OUTPUT); // declare the ledPin as an OUTPUT
Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
}
void loop() {
digitalWrite(ledPin, HIGH); // sets the LED on
val1 = analogRead(sensorPin1); // read the value from the sensor
val2 = analogRead(sensorPin2); // read the value from the sensor
Serial.print("A"); //header variable, so we know which sensor value is which
Serial.print(val1, DEC); //send as a ascii encoded number - we'll turn it back into a number at the other end
Serial.print(10, BYTE); //terminating character
Serial.print("B"); //header variable, so we know which sensor value is which
Serial.print(val2, DEC); //send as a ascii encoded number - we'll turn it back into a number at the other end
Serial.print(10, BYTE); //terminating character
delay(10);
}
*/
|