LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Channel Wire Copy Size

Solved!
Go to solution

Hey guys,

 

First off, thanks for all the help. I've been lurking on the forums for a couple of months and have learned a ton. Some background, I'm a graduate research assistant at a university. I'm in charge of building a labview program that will operate a rocket engine test stand and gather high speed data from experiments.

 

I have a question about channel wires. I'm trying to setup a producer/consumer program that will allow for "high speed" (only 3.5 KHz for now) writing to a TDMS file while also updating a front panel with indicators. I'm currently just messing around with figuring out how channel wires themselves work before implementing them in the larger control program and I've noticed a behavior that I don't understand. 

 

I'm passing the channel wires to two separate consumer loops, one to update the front panel at a specified refresh rate (typically 2-10 Hz) and the other to just write data as fast as possible to a TDMS file. What seems to be happening is that a buffer is being created that the front panel loop keeps pulling from, even after the stop button has been pressed. I have the stop button wired to the "Last Element" input on the writer and that's being read correctly by the loop for the TDMS file, but it takes a long time to be read by the front panel loop.

 

I tried to set the copy size of the front panel loop to a low number thinking that copy size acted like a buffer size, meaning that the front panel would run for a couple more loops then receive the last element flag and stop the loop. However, that's not what's happening. Could anyone explain what is actually happening? Why does the channel appear to store more elements than what the copy size is? 

 

Thanks,

Frank

 

EDIT: Actually it looks like the writer loop now is not stopping either, although I could have sworn it was earlier. 

0 Kudos
Message 1 of 9
(640 Views)
Solution
Accepted by topic author Frank_Rice

Behind the scenes, a channel wire is just a queue, which is implemented as a FIFO. You are allowing the FIFO to get filled up and not keep up because of that wait. Because you are using the "Last Value" flag, the FIFO will need to be cleared out before the loop will stop. Due to your delay, this will become a very noticeable delay as the data is taken off of the queue.

 

Instead of using the Stream channel type for the GUI update, use the Tag channel which only keeps the last written value.

 

I would also go as far as to not even have a logging loop. DAQmx has this great feature of logging data for you. Before you start the DAQmx Task, use the DAQmx Configure Logging function on the task. This will enable DAQmx to stream the data to a TDMS file as you read from it. This will be a lot more efficient than your Producer/Consumer setup.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
Message 2 of 9
(625 Views)

Thanks for the response. I understand that it's a queue and is FIFO, but why is the copy size not restricting how many elements can be put in the queue?

 

I have messed around with the DAQmx logging function. My issue is that I have numerous cards/tasks that I would like to write to the same file and from what I can tell, the DAQmx logging function does not allow that. 

 

Would it make more sense to have two channel wires coming out of the DAQmx read? One configured as a tag so that the front panel stops refreshing as soon as the stop button is pressed, but the TDMS writer wired to the stream so that I don't lose any data? In the core modules it says to avoid combining a tag and a stream, but is that mainly for when you want to pass a boolean value from the producer to the consumers since that is built into the Write.vi?

 

EDIT: This seems to behave as intended

0 Kudos
Message 3 of 9
(616 Views)

@Frank_Rice wrote:

Would it make more sense to have two channel wires coming out of the DAQmx read? One configured as a tag so that the front panel stops refreshing as soon as the stop button is pressed, but the TDMS writer wired to the stream so that I don't lose any data? In the core modules it says to avoid combining a tag and a stream, but is that mainly for when you want to pass a boolean value from the producer to the consumers since that is built into the Write.vi?


It is mixing the types for the same destination where I have mostly seen issues. You do need the two types because you have two types of destinations.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
Message 4 of 9
(593 Views)

As crossrulz said,

  1. Use the built in TDMS logging function. Set it to Log and Read. You can alos set the number of samples per file if you don't want one huge file.
  2. For larger sample rates, greater than 1MHz, multiple channels, etc, the number of samples to read should be an even integer of the disk sector size. For example, if the disk sector size is 512, then read 1024 sample, 2048 samples, etc.
  3. Try to set you reads to about 100ms of data using rule 2 above. Rule 2 takes precedence, that is, to have a multiple of the disk sector size. Right now in your VI you are reading a SINGLE sample, that will not work. So for a 10kHz sample rate, read 1000 samples at a time.
  4. No need to read the sample rate continuously in the producer, take outside the loop.
  5. Set the buffer size to 8x the sample rate.
  6. Decimate your data before displaying it.
  7.  Look in the example finder for continuous AI voltage acquisition, it's a good start.
Message 5 of 9
(582 Views)

Ah alright, I think I'm starting to see how this thing is working. So as a general rule, it's alright to create multiple writers for a single producer. However, you only want one type of reader in the consumer. Is it a bad idea to put multiple readers of the same type in a single consumer? I'm thinking about how to expand this to incorporate my multiple cards/tasks.

 

I attached another version of the example vi for reference. This one has two AI read tasks and the stop button is controlled by an event/tag channel writer.

0 Kudos
Message 6 of 9
(580 Views)

@Frank_Rice wrote:

I have messed around with the DAQmx logging function. My issue is that I have numerous cards/tasks that I would like to write to the same file and from what I can tell, the DAQmx logging function does not allow that. 


You have a Thermocouple reading at 3.5kHz, is that correct. Are both of your modules in cDAQ chassis? If so, you may be able to combine both into a SINGLE task. If they are in a single task, then the data is written in the same file.

 

Right now your tasks are not synchronized, not sure if that matters to you.

 

The samples per channel on a Continuous Acquisition sets the buffer size, I prefer to leave blank and set the buffer size explicitly with VIs or property nodes. Sometimes things get coerced to different values using the other method.

 

You are still downloading a single point, you will not be able to keep up with the acquisition.

Message 7 of 9
(570 Views)

Here's the hardware I have, sorry for not listing it earlier:

 

PXIe- 1092 chassis

PXIe-6739 (only used for AO)

PXIe-6375 (only used for AI)

PXIe-6535 (only used for DO)

PXIe-4302

 

From what I understand, I have to have separate tasks to control the separate cards (please correct me if I'm mistaken).

 

I believe I will need my tasks synchronized (or at least time stamped using the waveform). I will need the readings from both of my cards (6375 and 4302) to be from the same point in time.

 

Sorry, I saw your previous post after I had already replied. I'm working on the changes you suggested with NChan NSamp. My train of thought behind NChan 1Samp was that I just wanted to get every data point at the specified sample rate from the DAQmx timing. However, I think I see the flaw in my logic. How it is now, it's going to perform a read and push data out into the channel wires as soon as it gets a single sample, but this adds a lot of overhead (behind the scenes stuff with the DAQmx read). 

 

By only reading when a specified amount of samples are in the buffer, you're just reducing the frequency that DAQmx read is called. The long part of reading the samples isn't getting the samples, it's whatever LabVIEW is doing behind the scenes to actually get the samples. Is that the right way to think about it?

 

EDIT: Also, some of the values in this VI are arbitrary (like clock speeds). I threw this VI together just to play around and see how everything is interacting. My actual program will need the ability to change the clock speeds depending on what end devices we use for a particular test.

0 Kudos
Message 8 of 9
(560 Views)

PXIe hardware is difficult to predict, I cannot simulate a PXI chassis to test.

 

If you need to synchronize data, then there are multiple methods.

 

You can try combining both inputs into one using Channel Expansion,

Easily Synchronize and Trigger NI-DAQmx with Channel Expansion - NI

 

However, this may NOT work for your combination of cards. There are other methods, see

Signal-based Synchronization of Analog Input C Series Modules with NI-DAQmx in LabVIEW - NI

 


@Frank_Rice wrote:

 

By only reading when a specified amount of samples are in the buffer, you're just reducing the frequency that DAQmx read is called. The long part of reading the samples isn't getting the samples, it's whatever LabVIEW is doing behind the scenes to actually get the samples. Is that the right way to think about it?


Yes, there is overhead with each read call; I good rule of thumb is to read 10% of the sample rate, ~100ms of data, with each read call. 

Message 9 of 9
(555 Views)