Wednesday, November 4, 2009

arduino/processing multichannel display and datalogging



this is VERY MUCH a work in progress! if you have any tips/clever ideas, please let me know!!!

more pics to be added shortly.

these temp sensors are usually fed with 2.5v, but they seem to work with the 3.3v as well (future plans include correcting this mismatch). I have to calibrate them and see how linear they are with the higher voltage, but for now it's working.
they've got 3 wires, red, black, and white. I've got them hooked up 3.3v->red, ground->black, and white to an analog in pin on the arduino. I think i might need some pulldown resistors on there, to clean up the output, but I haven't tried it yet.



the arduino's onboard code just reads the analog pin voltage (i t returns a value between 0 and 1024 proportional to the voltage on the pin (0-5v). It does this for 2 pins, actually, because i want to be able to scale it up to as many inputs as i need later on. then it prints a string to the serial port in the form "pin1in,pin2in,|".

i'm using Processing running on the laptop attached to the arduino via usb cable. The arduino is recognized by the computer as a serial port.

In processing, I read in the string coming from the serial port and split that string into it's component values. this happens extremely fast, and i average the values over a settable period of time. every averaging period, it writes to a graph on the screen and to a text file.


this still needs a ton of cleaning up, and there are other things I want to add, but this is the first relatively-successful iteraton, so I thought I'd post it.

arduino setup
3.3v->temp sensor->analog in




arduino code (based on Tom Igoe's examples):

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

void loop() {
// read the analog input into a variable:
int analogValue = analogRead(0);
int analogValue1 = analogRead(1);
// print the result:
Serial.print(analogValue);
Serial.print(",");
Serial.print(analogValue1);
Serial.print(",");
Serial.println("|");
// wait 10 milliseconds for the analog-to-digital converter
// to settle after the last reading:
delay(10);
}


processing code:

import processing.serial.*;

Serial myPort;

PFont myFont;
String inString="1";
int lf = 10;
float a, millistgt, millis1, pavgs, pavgms;
float loopcount;
float bsum, dsum;
float b, d;
float lasta, lastc;
float lastb, lastd;
float keepa, keepc;
PrintWriter output;
float val, bval;


void setup() {
myFont = loadFont("Arial-Black-18.vlw");
textFont(myFont, 18);
myPort = new Serial(this, Serial.list()[1], 9600);
myPort.bufferUntil(lf);
output = createWriter("positions.txt");
///frameRate(10);
size(600, 400);
stroke(255);
background(192, 64, 0);
a=0;

// b=400;
// d=400;
line (0,0,0,400);
line (0,50,width,50);
line (0,100,width,100);
line (0,150,width,150);
line (0,200,width,200);
line (0,250,width,250);
line (0,300,width,300);
line (0,350,width,350);
keepa=0;

loopcount=0;
bsum=0;
dsum=0;
//inString="0";

}

void draw() {
pavgs=.25; //<--------------------------------avg (reporting) time in seconds pavgms=pavgs*1000;
millistgt=millis()+pavgms;
loopcount=0;
keepa++;

lasta=a;

lastb=b;
lastd=d;
a++;

bsum=0;
dsum=0;
millis1=millis();

if (millis1<3000){
delay(1500);}

do{
millis1=millis();
// val=int(inString); // Converts and prints float
// val = Integer.parseInt(inString,3);
//val=Float.parseFloat(inString);
//bval=mouseY;

b=val;
d=bval;
bsum=bsum+b;
dsum=dsum+d;
loopcount++;
}

while (millistgt>millis1);
b=bsum/loopcount;
d=dsum/loopcount;



//float lastaf=Float.parseFloat(lasta);
stroke(255);
line(lasta, lastb, a, b);
stroke(0);
line(lasta, lastd, a, d);
// fill(0);
// rect(0, 25, 300, 50);
//fill(255);
//text("val: " + val + "bval:" + bval, 10,50);
if (a > 600) {
background(192, 64, 0);
line (0,0,0,400);
line (0,50,width,50);
line (0,100,width,100);
line (0,150,width,150);
line (0,200,width,200);
line (0,250,width,250);
line (0,300,width,300);
line (0,350,width,350);
a=0;

}
}

//if millis1<



// Write the coordinate to a file with a
// "\t" (TAB character) between each entry
output.println(a + "," + keepa + "," + val + "," + bval+","+millis1);



}


void keyPressed() { // Press a key to save the data
output.flush(); // Write the remaining data
output.close(); // Finish the file
exit(); // Stop the program
}



void serialEvent(Serial p) {

String myString = p.readStringUntil(124); //the ascii value of the "|" character
if(myString != null ){
myString = trim(myString); //remove whitespace around our values
int inputs[] = int(split(myString, ","));
//now assign your values in processing
//if(inputs.length == 2){
val = inputs[0];
bval = inputs[1];
fill(0);
rect(0, 25, 300, 50);
fill(255);
text("val: " + val + "bval:" + bval, 10,50);



}
//inString = p.readString();
//val = p.read(); // read it and store it in val
}


here's what it draws to the screen: I still need to get it scaled correctly, and put labels on the graph axes. And pick some better colors.

here's an example of the current log file:
it displays reading number, another reading number i was using for diagnostics, reading1, reading2, and the total elapsed time in milliseconds. I need to get the time variable worked out in a more useful way, and I think I want to include the total number of readings that went into each averaged point as well.


much thanks to the arduino and processing communities for all their help so far. Feel free to use bits of this mess.

No comments:

Post a Comment