11-01-2019 05:09 PM
Hello everyone,
I am currently working on merging two functional VI's together. They both work as intended, but they both need to run inside of independent while loops. The issue I am running into is writing the data from both loops into the same spreadsheet. I have tried using refrences to these values and merging the refrenced variables with the signals in the other while loop, but the refrences simply aren't the right data type. I have attached a small chunk of my block diagram below to show my issue.
Thank you,
Jackson
11-02-2019 09:58 AM
You are going to have serious problems as you are over-using Express VIs and creating a potential nightmare of a data file. I don't understand why you are merging two independent streams (which might be running at different rates) into a single file -- how do you plan to disentangle and disambiguate them? At the least, you'd have to write an ID ("From Loop N") in front of each record.
I think this needs further thought and design from you. You'll help yourself a lot by learning about the basic LabVIEW (non-Express) VIs for File I/O (they are not so difficult).
Bob Schor
11-02-2019
11:35 AM
- last edited on
05-14-2025
04:52 PM
by
Content Cleaner
Hello Jackson,
I also feel like you could probably resolve this problem more easily if you extricated yourself from the Express VIs.
That being said, in general if I wanted to store data from two sources in one file, I'd create a single loop with the purpose of writing to file, and then send data into that loop as needed.
This is in general, a Producer/Consumer setup with 2 producers and a single consumer.
As Bob_Schor already pointed out, unless you have some way of labeling them, it will be difficult (impossible?) to distinguish the values in the file (except by value, perhaps?).
Attaching the Channel Names, as you appear to be trying to do (although I think the way you posted it, it won't work how you want - perhaps you simplified when posting to this thread?) is one possible solution.
Other systems are possible, but tricky with text files.
Writing directly via the Text File methods is likely to simplify the reading, understanding and manipulation of your code.
Here's a link to the help pages for the File I/O Functions, of which you probably want to consider Open/Create/Replace File, Close File, and Write to Text File.
11-05-2019 11:06 AM - edited 11-05-2019 11:08 AM
Thank you both for your responses. I can now see why express VI's can begin to cause issues, but I would not have thought to delete the express VI. I will be setting this program up with the File I/O pallete instead of the Express VI in the next few days.
I've started trying to implement the producer/consumer structuring, but am struggling to see how to implement it with my VI (attached below). In every example I have seen the producer is dependent on user events, but I need both programs to read without a button dependence. They are currently functioning in this way. How would you suggest approaching this?
Thank you,
Jackson
11-06-2019 08:27 AM
If you open LabVIEW, click File, New ... (the three dots are important), then choose the From Template, Framework, Design Patterns, Producer/Consumer Design Pattern (Data).
This will show you a Producer, where data are Generated (think a DAQmx structure with a Start DAQ function to the left of the While Loop, a Read DAQ inside, with the data wired to the Queue (make the Queue type the same as the DAQmx output, e.g. 2D Array of Dbl, 1D Array of Waveform, etc.), and Stop DAQ function when the loop exits.
There is a slightly "bad" aspect to this Template. You should (probably) not stop a Producer/Consumer Design by having the Producer kill the Queue, thereby causing an Error to be generated in the Consumer (because there's no Queue and you are trying to do a Dequeue). Yes, this can be used to mean "The Producer has quit", but means you can't meaningfully use the Error line in the Consumer "downstream", such as doing something "inappropriate" in processing the data.
A "better" way is to pass a "Stop" signal from the Producer to the Consumer. For example, if you are sending data from DAQmx, and your Queue element is an Array, you could send an empty Array to the Consumer when the Producer exited (replacing the Release Queue). The Consumer, when it dequeued the data, would add a test for an Empty Array (which takes essentially 0 time) and use the "True" case to mean "Time to Exit", and "False" to mean "Process the data". Now, when the Consumer exits, it knows (a) that the Producer has finished, and no more elements are coming from it, and therefore (b) it is safe, once it exits its While loop, for the Consumer to Release the Queue.
Bob Schor
11-06-2019 10:30 AM
11-06-2019 12:00 PM
I also like having the sentinel built into the Stream Channel. By being "separate" (not part of the data), it expresses a unique function.
Bob Schor
11-08-2019 05:34 PM
Hi all,
I have been working to impliment this structure, and ultimatly I have gotten lost. I do not want to push a button to record the data, but it seems like simply pulling this out of the event structure is not the correct way to do this. I have attached the updated VI below with the hopes that I am simply making a mistake in the set up. If you have a chance could one of you take a look at it for me?
Thank you,
Jackson
11-09-2019
12:41 AM
- last edited on
05-14-2025
04:52 PM
by
Content Cleaner
Hi Jackson,
I took a look at the VI you uploaded and can see that it is based on the template that was already mentioned, but I think you have not quite understood a key point:
I'd suggest looking at some more of the introductory training material until you're comfortable with the "dataflow" concept. It is really very important to the entire way in which LabVIEW works. These may be a possible starting location: LabVIEW Basics: Dataflow, Getting Started Videos, Module 5 (Block Diagram Dataflow) (although I'd say watch more than just that module of the videos if you don't hate videos for learning...)