We are about to switch to a new forum software. Until then we have removed the registration on this forum.
I have a code that serial prints Arduino Esplora data and then in read in processing. It then displays the data in its print() function. I know I saw it somewhere, but I cant find out how to split the data into separate data points. Here's hos the string comes out in processing:
1,1,1,1,702,1010,20,1,1023,3,-10,12,7,135
That's the whole string. It then repeats with the next string. I need to spit that into each data point.
EDIT: This is the code for processing that is receiving the data:
import processing.serial.*;
Serial myPort; // Create object from Serial class
String val; // Data received from the serial port
void setup()
{
String portName = Serial.list()[0]; //change the 0 to a 1 or 2 etc. to match your port
myPort = new Serial(this, portName, 9600);
}
void draw()
{
if ( myPort.available() > 0)
{ // If data is available,
val = myPort.readStringUntil('\n'); // read it and store it in val
}
println(val); //print it out in the console
}
Answers
Check these:
https://forum.processing.org/two/discussion/16618/processing-with-arduino-void-serialevent#Item_1
https://forum.processing.org/two/discussion/21447/two-sensors-trigger-same-part-of-code#latest
And these from the reference:
https://processing.org/reference/split_.html
https://processing.org/reference/splitTokens_.html
Kf
So, I tried the split() function and it runs for a moment, then it gives me the NullPointerExeption error. Here's the code:
I get the NPE error on the line
String[] data = split(val, ",");
. How do I fix this. I looked at some pages on the error and I cant figure it out.Yes, you need to make sure you don't have a null object, like this:
Also make sure you have 4 tokens after parsing....
Kf
Thx @kfrajer, works great. EDIT: It works great sometimes. I added the rest of the information:
But I get a new error that iv never seen before, and, like the NPE I looked it up and didn't understand how to fix it. The error is NumberFormatException on a random line that has
Integer.parseInt(data[])
in it. Please help me fix this.EDIT AGIAN: this is the error that it gives me: NumberFormatException: For input string: "135" The number 135 is actually anywhere between 134 to 136.
you can use trim() to cut (invisible) characters (e.g. space sign or line breaks) off
also iirc you can check if it's not a number with if(a==int(a)) or so, which only works with correct numbers
you need to check data[] before using it. what if the first line fails, returns null or an empty array?
kf said exactly this much earlier.
@chrisir the trim() in not needed because the arduino is not sending anyspaces. @koogs im not sure what you mean by "check data[]" please clarify
what if the first line fails, returns null or an empty array?
(or
data.length == 14
, i guess, for that last bit.)Im not sure if I put it in the right spot in my code because when I println() all the new values they are either 1's or 0's and nothing changes. Here's the code with the new lines added:
EDIT: It sometimes will give the right data but in the wrong order and still nothing changes.
Swap lines 25 and 26
What is the difference between split and splitTokens?
So i switched lines 25 and 26 and then it gave me an error on the new line 25 which is the line with
if(data!=null&&data.length>14){
It says "data" doesn't exist so i initialized String[] data; at the beginning and no longer got that error. Then i run the sketch. i didn't get any errors but all the data still comes out as 1's and 0's and doesn't change at all.The updated code with lines 25 and 26 switched:
So i switched lines 25 and 26 and then it gave me an error on the new line 25 which is the line with
if(data!=null&&data.length>14){
It says "data" doesn't exist so i initialized String[] data; at the beginning and no longer got that error. Then i run the sketch. i didn't get any errors but all the data still comes out as 1's and 0's and doesn't change at all.The updated code with lines 25 and 26 switched:
Length won’t be > 14, would it?
yeah, since there are 14 values i'm taking from the string.
OR do you want
==14
?
I have no way to test your code, but you should test it on your side. Try doing something like
I am taking a wide guess here, but I think if you are getting lots of data, then your stream input might possibly have more than 14 tokens. If that is the case, I will process the first 14 tokens and then, if there is anything left (in case of more than 14), you wait until there are 14 or more to process it again. Another option is to reduce the rate of packages being sent from your Arduino side.
Kf
So i put in the code that you gave me and changed the >14 to ==14 and noted out my print() and nothing happens. The only thing that happens is a yellow line under
println(data);
with the warning of "Type String[] of the last argument to method println(Object...) doesn't exactly match the vararg parameter type. cast to Object[] to conform the non-varargs invocation, or pass individual arguments of type Object for a varargs invocation," HelpEDIT: When i change
println(data);
toprintln(val);
the warning goes away.data is an array, and println() should be able to operate on this (I believe). It should print each element of the data array, one per line. I want you to print data so for you to see how the parsing is done. However, printing
val
should work as well. Move these lines before the preceding conditional:I wish I could test your code to address the question directly, but I do not have a setup and not much time...
Nothing happens is not good... now you should be able to see something, I hope.
Kf
println(data);
still gives me issues. When I putprintln(val)
in two different places before your code, it only works in one spot:I have been looking all over and I cant find anything that works.
that advice to switch lines 25 and 26 (now lines 27 and 29) was bad advice 8)
why would you check that the data is null before setting the data? the check needs to be after the split.
(also, that needs spaces
vs
so much clearer. youwouldn'twriteasentencewithoutspaces.)
That still doesn't help me though. When i
println()
the data values, they all come out as 1's and 0's and then they don't even change. Ill give you the Arduino code also. Arduino Code:Processing Code:
this is how i would do this: do one thing at a time.
i've added test variable. when this is true then it'll parse a known string. use this to debug the parsing of the incoming string without worrying about the arduino.
WHEN THIS WORKS then you can set test to false to get the real data from the arduino. by this time you know the parsing works (assuming your test data is correct) and can concentrate on the incoming data.
and don't skimp on the debug. just printing out a bunch of values without labels helps nobody.
So I tried your test and the values come out right, the when I change test to false so I can get my incoming data, I starts giving me the error NumberFormatExeption on a random
Integer.parseInt()
line. Am I dong something wrong with testing?What you need to test, is to check how many tokens you get after you apply the split() function on your data. Because it is less than 14 doesn't mean you have all the tokens. In your case, if you want to process 14 tokens, your condition should read
data.length==14
. If you dodata.length<14
then it is not guaranteed you have 14 tokens available. So for instance, if split returns 6 tokens, then you won't succeed intempSensor = Integer.parseInt(data[6]);
What I want to convince you (and convince us as we can't test your code) is that you are receiving consistently 14 tokens. If you are not, then at least we can proceed to think of the proper approach. I will strongly suggest you check previous arduino code here in the forum as they manage single data arrival (yes, you need to change your ino code for this). When you get a simple code working, then you can test some other sensor in a one to one approach.Problems that I can see:
Stuff we don't know...
Another approach is this:
What do you get from this code. Can you post few lines of this output? As you see, here I remove the overhead of processing the data as this part is ok. You need to focus in your raw data.
Kf
All right guys, thanks for all the help. I finally figured it out...with a little help from my dad. Here's the final code:
As you can probably see, the biggest difference is that I should have been using
int()
to change data points into an integer rather thanInteger.parseInt()
. So for anyone else trying to split a string of data into a bunch of data points, this is how you do it.int()
is based on Integer.parseInt(): https://github.com/processing/processing/blob/master/core/src/processing/core/PApplet.java#L9503Dunno what is the problem in your case. Great to hear it is working now.
Kf