I'm looking for some pretty basic tutorials on how to start inputting serial data from the arduino into processing. IE, what is a header? How do I parse data?
I'm looking to send two values at certain intervals (X & Y datapoints) to processing and graph them both...
how do I listen for them, separate them, plot them? etc?
See, that's the really cool thing about working with Arduinos and Processing - you get to define what's a header, and how the data is transmitted, and how to parse the data.
The Arduino really only has three serial functions for output. There's write, print and println. The difference between print and println is that println adds a carriage return.
The print function converts everything to strings. The write function sends bytes unmolested, and chunks anything larger into bytes and sends them in a specific order. Fortunately, the Processing application is privy to the order, and is able to put the bytes back together in the proper order.
In Processing, you define a Serial instance, and use the methods here:
The Processing application includes lots of sketches that illustrate how to read serial data, and how to plot data.
Serial.print(Grade); //1 - 3 digit string of integers
Serial.print(encoderReading); //float from 0.00 to 125.00
delay(1000);
I want two variables in processing to read:
Grade = xxx
encoderReading = xxx.xx
I found this code but can't get it to work:
import processing.serial.*;
Serial myPort; // The serial port
int xPos = 1; // horizontal position of the graph
void setup () {
// set the window size:
size(400, 300);
// List all the available serial ports
println(Serial.list());
myPort = new Serial(this, Serial.list()[1], 9600);
myPort.bufferUntil('\n');
background(0);
}
void draw () {
// everything happens in the serialEvent()
}
void serialEvent (Serial myPort) {
// get the ASCII string:
String inString = myPort.readStringUntil('\n');
String constant = myPort.readStringUntil('\n'); //doesn't quite work
if (inString != null) {
println(inString);
println(constant);
// trim off any whitespace:
inString = trim(inString);
// convert to an int and map to the screen height:
float inByte = float(inString);
inByte = map(inByte, 0, 1023, 0, height);
// draw the line:
stroke(127,34,255);
line(xPos, height, xPos, height - inByte);
// at the edge of the screen, go back to the beginning:
if (xPos >= width) {
xPos = 0;
background(0);
}
else {
// increment the horizontal position:
xPos++;
}
}
}
It would be worth printing the value in grab1 before trying to parse it. Obviously, from the exception being thrown, the string contains some non-numeric character, or a numeric string that is too large to fit in an int.
Knowing what was in the string would help solve the problem. Not knowing would require just guessing.
Fair enough. I rearranged a bit of code and I think I'm very close now. Instead of converting to int, I'm converting to float.. seems to work a lot better for some reason. My serial "grab"s and floats output correctly, but the float values don't seem to update the text.
IE:
import processing.serial.*;
Serial myPort; // Create object from Serial class
float value1;
float value2;
PFont font;
int Grade;
String grab1;
String grab2;
void setup()
{
size(300, 500);
// Open whatever port being used.
String portName = Serial.list()[0];
myPort = new Serial(this, portName, 9600);
font = createFont("Arial", 22);
textAlign(CENTER);
textFont(font);
background(255);
fill(0);
}
void draw(){
}
void serialEvent (Serial myPort) {
grab1 = myPort.readStringUntil('\t');
grab2 = myPort.readStringUntil('\n');
if (grab1 != null) {
grab1 = trim(grab1);
float value1 = float(grab1);
print("Grab1 / Value1: ");
print(grab1 + " / ");
print(value1);
}
if (grab2 != null) {
grab2 = trim(grab2);
float value2 = float(grab2);
print(" Grab2 / Value2: ");
print(grab2 + " / ");
println(value2);
}
rect(30,height,240,-value1);
text(value1,width/2,height-20);
}
This line works fine and prints the correct value:
The variable value1 is a local variable. It masks the global variable of the same name. It goes out of scope at the end of the if block.
Later, you create text to show the value in the global variable value1, which has not been initialized.
When you put the text function call in the if block, you are creating text to show the value in the local variable value1, which has been initialized, so it works.
You really ought not create local variables of the same name as global variables. If you meant to use the global variable, remove the float declaration in front of the variable name.
You (still) haven't shown what data is being sent to the Processing program.