Hello, so i am writing a program to write a 2D array to a .csv file and i am getting this weird first row. The first number is not apart of the incoming data but rather a separate number added on later that represents the iteration when that data occured. The file looks like this:"
47.000000000000,[0, 0, 0]
0.000000,3.225078,4.225078,5.225078
1.000000,5.188849,6.188849,7.188849
2.000000,3.099205,4.099205,5.099205
3.000000,3.634052,4.634052,5.634052
4.000000,3.720020,4.720020,5.720020
5.000000,4.548906,5.548906,6.548906
…
47.000000,4.816074,5.816074,6.816074
48.000000,4.336721,5.336721,6.336721
49.000000,2.745114,3.745114,4.745114"
That first line is not apart of the data set that goes into the indexing tunnel but it comes out this way. I would like to know two things; why does this happen and how do I remedy it? I know it is happening there because i probed the wire before and after the tunnel.
Any help would be greatly appreciated guys.
Could you attach the VI?
Greg McKaskle
I don’t have a module input as of yet so i just made random values to pass through. The random values couldn’t be creating this problem as it happens at the auto-indexing tunnel. I need to make some changes before i upload it.
Nevermind, I fixed the problem. Thank you for your attempt to help.
If you turn on execution highlighting and run the VI I think you’ll find that you have race conditions caused by using too many local variables and too much parallelism that isn’t specific enough.
When your while loop begins, you have three parallel pieces.
- Read the stop button and determine if the loop will run another iteration.
- Take whatever value is in Iteration # and put it in the file.
- Run the loop to completion
There are three locations where I think you have used a local variable but should instead use a wire. Local variables are useful for UI programming and as a simplistic communication between parallel loops, but if you use them instead of a wire, just to make it look pretty, you need to be very aware of race conditions. You just told the compiler that you don’t care about sequencing the operations with this data.
Greg McKaskle
Thank you for your reply. I do not know what these race conditions are and i shall go find out.
I like the attitude. Perhaps my description will help.
When operations take place in parallel and share data, one of the things you have to watch for is out-of-order access to the shared data. This can happen with a file, with memory, with a device like an oscilloscope, etc. When the order is not defined and is somewhat random we will often call it a race-condition. It is just a funny name for it.
The key to avoiding race conditions is to define the order of access of shared data. LabVIEW uses graphical wires as a special form of variable – a form that is very useful with parallelism. A wire is like a temporary variable, but it has no name and is guaranteed to have only one writer, which goes first, and one or more readers guaranteed to go after the writer and guaranteed to get the same value as was written, no matter when it runs. It may not seem like much help, but these rules really help simplify.
It looks like you want the For loop to finish and then the file write to run. If you use local variables, the write code has no reason to wait and will run in parallel with the loop. If you use a wire for Write Text, the problem will probably go away. But Iteration # should probably be a wire too. The Iteration number that is being formatted inside the for loop can just be wired from the for – i. I’m not sure if you really meant for it to the last loop iteration of the for loop or the while loop’s iteration number. Either way, a wire is more clear what you meant and will be sequenced as intended.
Inside the for loop, the Data Flow subVI is called and the values are stored into the Data Controls in parallel with the values being read, charted, etc. Again, wires are almost certainly what you intended.
In summary, local variables are actually pretty rarely used. You typically want to use a wire instead.
Greg McKaskle
Ah, thank you for the information, it is greatly appreciated. I have been coding in Java for years and only switched to LabView two weeks ago. When i saw Local Variables i jumped at the familiar name. I shall be more cautious from hence forth. Thank you again.
When would be a more appropriate time to use local variables instead of wires?
Local variables can let you get intermediate data out of a loop without waiting for the loop to terminate. Similarly, they can be a simple way to get changing data into a loop. They won’t easily let you synchronize parallel tasks – that’s what semaphores and queues and the like are for – but they do permit communication between them.
Yes. As Alan said, local and global variables are the least synchronized of all the notification and transfer mechanisms. I mostly use them for UI tasks such as initializing a control, but they work well for sending sile data to multiple loops.
Greg McKaskle