From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Strange Behavior of Data and Other Refinements

Solved!
Go to solution

Hi all,

 

I've made a .vi which records three analog voltages (one from a microphone, one across the sound source, and one across a 1 Ohm resistor for the purpose of power measurements), and have three problems. This is my first time here, so bear with me please.

 

1. The plot of the microphone voltage (supplied to the device, NI USB-6259, by way of Phantom Power and an XLR to BNC adapter) shows a sort of "charging up" that I don't think should be there. Furthermore, the other two plots of voltage vs. sample do not show any such trend. For reference, I am outputting the voltage, and the device is therefore making sound, before I even begin recording. Therefore, the microphone voltage plot should be semi-constant over its sample range as the input signal is just a tone at 1kHz.

 

2. The saving of the data to a .lvm file takes around three times as long as recording. This isn't as crucial, but it would be nice to reduce the time if possible.

 

3. I need to ensure that all samples from the three input channels are synchronized in time, as they will be used to create a transfer function. I've read that this device uses multiplexing; is there any way to make the time between reading a sample on one channel and then the next less (or 0)? Also, how do I set the scan list?

 

I've attached the .vi, an image of the block diagram, and an image of the three voltage plots, and have zoomed in on the voltage plots of the device and the resistor to show the regularity. Any help is much appreciated!

 

Thanks!

0 Kudos
Message 1 of 16
(3,578 Views)

1) Rather than try to read ALL of your samples at once, read fewer samples at a time in a loop and then use the producer/consumer design pattern (look in the examples) to enqueue your data to a separate loop for logging. That way you can start writing to the file before the complete acquisition of the data has completed (and you're less likely to run into problems with overflowing the DAQmx buffer and/or memory).

 

2) Don't use the dynamic signal data type - it isn't very efficient.

 

3) Don't use Express VIs, they aren't very efficient. Use the functions from the File I/O palette.


LabVIEW Champion, CLA, CLED, CTD
(blog)
Message 2 of 16
(3,559 Views)

Sam,

 

Thank you! I'm still new(ish) to LabVIEW, so I'd like to ask some questions about your solutions.

 

1. If I set up a while loop to read maybe 1000 samples at an iteration, would that be basically what you're suggesting? Would I then have a separate loop that takes the (indexed) data from the first loop and makes an array? I'll search producer/consumer design pattern and take a look.

 

2. To avoid using this data type, should I break the express VI into the functions in the File I/O palette as you suggest in 3)? If so, I'll look at some examples.

 

3. I'll look at examples to see how this can be done. At my university, they were surprised I even broke apart the DAQassistant.

 

Thanks again.

 

 

Message 3 of 16
(3,542 Views)
Solution
Accepted by topic author xcnmoore

I'm about to go home for the evening, but take a look at this very rushed VI snippet (save to desktop and then drag onto a block diagram) for some inspiration:

DAQProducerConsumer.png

 

In the top loop, you acquire some of the samples in each loop and enqueue the data to the bottom loop where you write it to the file. Obviously missing is how you stop the bottom loop once you have finished writing all of the data - taking a look at the examples should give you some help here.


LabVIEW Champion, CLA, CLED, CTD
(blog)
Message 4 of 16
(3,532 Views)

Just to help the searching: Producer/Consumer


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 5 of 16
(3,503 Views)

Thank you both! I haven't had a chance to implement these ideas, but when I do, I'll mark the solution.

0 Kudos
Message 6 of 16
(3,461 Views)

I've got another problem.

 

After searching around, I think I found a way to stop writing data only after the queue is empty. However, the write array to spreadsheet string isn't working. When I open the relevant text file, I find that the data look nothing like I'd hoped; I expected 4 columns (1 for the index and 3 for the data) and rows equal to the samples taken. How can I get this?

 

Thanks!

Download All
0 Kudos
Message 7 of 16
(3,418 Views)
I can't open your VI as I don't have LV2015 - can you save for a previous version and upload or post a VI Snippet of where you prepare/write the data to the file.

LabVIEW Champion, CLA, CLED, CTD
(blog)
0 Kudos
Message 8 of 16
(3,392 Views)

full.pngacquisition.png

Those are the full block diagram and a close-up of the producer/consumer and data acquisition. The third while loop is supposed to prevent any loss of data from the queue being released before the write to file loop has emptied it.

 

Another thing to note: currently I'm not sure how the samples taken correspond to time. If they were all taken at equal time intervals, that would be best. Can I assume, based on this code, that they are an equal amount of time apart?

0 Kudos
Message 9 of 16
(3,355 Views)

Several comments.

  • I haven't looked at the details of your DAQmx routines (and don't know which DAQ device you are using), but generally the Clock sets the sampling rate in the DAQ hardware, and the samples are acquired at that rate, independent of the PC's clock (that's a Good Thing).
  • In the usual DAQ Producer/Consumer setup, the DAQ Start and Stop VIs are outside the loop.  You start the DAQ, collect N samples at K Hz (which takes N/K seconds) during which time the loop is "frozen", then you "ship it off" by putting it on a Queue, only to loop back and wait until the next N/K seconds elapses (the time processing the data and putting it on the Queue comes out of that time, so it's essentially "free time").  The DAQ keeps running until you decide to exit the loop (because you are ready to stop), then you turn off the DAQ.
  • Since you need the Queue to remain "alive" until the Consumer finishes with it, don't release it at the end of the Producer loop.  Instead, release it when the Consumer loop exits.
  • So how do you get the two loops to exit "cooperatively"?  One (pretty good) way is to use a "Sentinel", something you put on the Queue when the Producer ends that can serve as a "stop" signal for the Consumer.  I'm not sure if this will work, but I notice your Queue is a Queue of 2D arrays.  Suppose, when the Producer ends, you enqueue an empty 2D array.  In the Consumer loop, before processing the dequeued Array, check if it is an Empty Array (there's a function on the Compare Palette that does this).  If it is, exit the Consumer loop, otherwise continue processing.  Note that this technique maintains the synchrony between the two loops -- Consumer always "comes first", Producer always "follows" and there is always something there to be consumed, sooner or later.

Bob Schor

Message 10 of 16
(3,318 Views)