01-09-2017 07:00 PM
Hello
I have a simple question. How do I set my VI for multithreading in Labview 2014?
I made a test VI for a data aquasition project to determine exact timing of pulses being sent out and read events on Ocean optics spectrometers. I'm trying to do a single read by controlling output pulses to the spectrometers and it seems my program will only one thing at a time, either read or send out pulses. This is despite the two tasks having no dependancy on each other.
To further explain: I have an oscilloscope connected to my output pulse and to the feedback pulse from the spectrometers. If the read command doesn't return then it'll wait until a 5 second timeout occurs. I can watch when the program hangs and see that my pulses have not apeard on the O-scope until after the timout has occured. If the two task were in parallel then shouldn't the pulses come regardless of what the read is doing?
Sorry for the messy code, this is a test program that I've edited many times
01-09-2017 11:23 PM
Things in LabVIEW wait to run until they have all of their dependencies.
The simple answer is: don't have any dependencies. That way, they'll naturally multithread. From that tiny picture you posted, it's difficult to see what's going on other than a bit of a mess. Everything within that while loop should happen at roughly the same time. If one thing is waiting, they'll all be waiting as they have that same dependency. Everything waits for the while loop with the "next read" because that's what you've told it to do.
01-10-2017 12:32 AM
Please don't attach a large picture, which causes nothing but eyestrain on the viewer. Instead, attach the actual VI -- this lets us closely inspect it, edit it (sometimes fixing your "mistakes"), inspect it (if there are Case statements, for example, see all the cases), and even run it.
If you understand Data Flow, you'll know that structures don't start until all of their inputs are "satisfied", and don't finish (or loop) until everything inside has run. So if you want two things to run in their own threads, there must be no dependency between them. This is easily accomplished in LabVIEW, but you don't seem to have "independent" execution paths in your Diagram (squint, squint).
Attach your VI!
Bob Schor
01-10-2017 06:47 AM
you should really clean up messy code before asking for time of the ppl here to look at your code!
but to answer your question: the two sub-vis will be run in parallel, as well as your DAQMX-chain
btw:
i) why do you create an loop-iteration counter to check if it is even, but don't do anything with it? did you want to use the loop-iteration-number?
ii) why do you build an array, just to split it right after?
iii) do your sub-vis handle the errors that are coming in?
iv) should your DAQMX-chain be running if the sub-vis generate an error?
v) why do you have a floating reset of your "error 2", but don't chain it with an incoming error, to define when it should be reset?
these were the things i noticed
regards jw
01-10-2017 07:12 AM
It is unlikely that the .NET calls can happen at the same time (I am pretty sure LabVIEW will force those to run in the same thread for safety reasons). It is possible that the .NET is also blocking the DAQmx calls due to who knows what common resource couple be used between them all.
01-10-2017 09:30 AM - edited 01-10-2017 09:33 AM
Bob_Schor, This happens to me quite often where I'm intimately familiar with a program and forget that others are seeing it for the first time.
I cleaned up the code and removed components unessesary to my question.
01-10-2017 09:47 AM
i) why do you create an loop-iteration counter to check if it is even, but don't do anything with it? did you want to use the loop-iteration-number?
A) I was using this as method to run the loop twice or three times each time I presses the button. I had that going into an if statement around the inner while loop.
ii) why do you build an array, just to split it right after?
A) It was part of my larger program. I removed it here for clarity
iii) do your sub-vis handle the errors that are coming in?
A) They are each one cammand which are .Net calls to Ocean Optics read commnads using Labview's .Net invoke node. Errors are handled by the .net invoke node.
iv) should your DAQMX-chain be running if the sub-vis generate an error?
A) Yes. They trigger a CCD camera to take a picture (spectrum). If the read to the device fails then there is no harm.
v) why do you have a floating reset of your "error 2", but don't chain it with an incoming error, to define when it should be reset?
A) This is just a test program and I want there to be no error when it starts so it's obvious to me that an error occured.
these were the things i noticed
regards jw
Thanks for the reply jw! I've answered your questions above.
"but to answer your question: the two sub-vis will be run in parallel, as well as your DAQMX-chain."
This is what I would say as well, however it's not reflected on my Oscilloscope. The delays I'm seeing are not on the order of milliseconds but seconds which it the same as the read timeout for the CCD camera. This is what brought me here with my question 🙂
01-10-2017 10:01 AM
crosrulz
Is there a way to verify this? I only know of the highlight execution command which I don't think will help me here.
01-10-2017 11:02 AM
Do you realize that there is no way to know "which comes first", the first pulse, Flame 1 read, or Flame 2 read? If I had to guess, I'd say that the two Reads come way (thinking in milliseconds, now) after the pulses, but that would be a guess.
I haven't used Counter-Timers much, but do know that using Start Task and Stop Task to control timing is not ideal (unless you just want "roughly On or Off"). I would think there would be something to generate a pair of pulses on receipt of a (TTL) signal. You can easily generate such a signal with a DO line running on an already-started, never-stopped Task as follows: When your button is pushed, set the DO High. This triggers the two-pulse generator (which is also already started and never stopped) and essentially simultaneously the two Read Commands. After all of these have been done (use Merge Errors), set the DO Low again. Don't even need a timer for this.
Bob Schor
01-10-2017 12:27 PM
@Bob_Schor wrote:
Do you realize that there is no way to know "which comes first"
A) Yes, it's quite frustrating 😕 In this case it shouldn't matter as the data will sit in the camera's buffer waiting for it to be read through USB, and the read command will wait until data is available to return. As long as I understand the read cycle correctly it shouldn't matter which one I send first. I'm working on understanding the read cycle better. I think Ocean Optics read command will do a dummy read first to clear the buffer of old data and then read the next spectrum.
You can easily generate such a signal with a DO line running on an already-started, never-stopped Task as follows: When your button is pushed, set the DO High. This triggers the two-pulse generator (which is also already started and never stopped) and essentially simultaneously the two Read Commands.
A) I actually couldn't figure out how to send two pulses right after each other. You're right, if I have the counters retriggerable I can just send two pulses from my trigger source which I do have control over. Thanks for the idea 🙂