05-15-2017 04:01 PM
I have a legacy vi that is... a bit of a mess. A dozen years and likely as many authors has not been kind to it, but it works well for what we are doing. Some of the old hardware however has failed, so I have replaced it with something better and found an odd quirk I can't explain.
In the old setup, data is reported on the second (1, 2, 3, etc) but with the new setup it is now at odd intervals (0.957, 1.875, 2.794, etc). The only change was on the DAQmx AI Voltage vi changing input terminal from NRSE to differential and selecting the appropriate channel. The acquisition device is still the same NI9205 and the data itself is just fine. Clock is still set to finite, 800 samples, 1000hz (NI9205 rated for 250 kS/s). Maybe the answer is obvious from there, but I'll go into a bit more detail.
The 800 measurements are summed and averaged, resulting in a single data point. The loop this is in has a 1000ms timer. I was thinking perhaps this is the problem, acquisition is somehow slower so it is not executing on time, but no, the samples are spaced less than 1 second.
VI and data examples are attached, thanks in advance!
Solved! Go to Solution.
05-15-2017 05:26 PM
I regret that I only have 2 monitors to view your Block Diagram -- I need 16 in a 4x4 grid to see it all! That's a major problem, making it very difficult to see what's happening. Learn to put things into sub-VIs (which take only 32x32 pixels of Screen Space) and try to arrange things in a hierarchical fashion.
You seem to be timing your loops with the PC's clock. Why don't you use the (much more accurate and precise) clock in your DAQ device? If you set it for Continuous Samples and told it to take 1000 samples at 1KHz, it would definitely "drive" your loop at 1 Hz. You should also consider a Producer/Consumer design -- the Producer (the DAQ loop) does nothing but produce 1000 points once a second, handing it off to a Consumer that does something with it (like average the points and save them to Excel, for example).
Use Data Flow and make use of the Error Lines. Your code should have 0 (that is, no) Sequence structures in it. That will also help with the Real Estate cost (good thing NI doesn't charge a Property Tax on Block Diagram Screen Space!).
Bob Schor
05-17-2017 10:22 AM
Funny you say that, this is the first VI I ever worked with, and when it opened on the antique monitor we use it looked so simple and easy. Then I found the scroll bars.
I think rewriting from (near) scratch is the best option at this point. I did change to continuous 1000 S/s @ 1KHz, and still saw timing issues- the loop would loose 11 ms/minute. I moved the elapsed time subvi to immediately follow the DAQ acquisition and now it is more or less stable- varying a ms here and there still. I'm guessing the mess of non-sequential... stuff... going on in the loop was causing the disconnect between the acquisition and timer starting. Still why changing from NRSE to differential caused this is weird to me- maybe the original author just got lucky with how the loop timing ran?
For the produce/consume loops, if I create the channel and set the sample clock, it "loops" by itself based on the number of samples and rate provided correct? It doesn't (shouldn't?) need to be in a while loop of its own is what I mean.
Thank you for the tips!
05-17-2017 09:28 PM
Suppose you have a Task reference, either because you defined a Task in MAX (including channels, channel names, Max and Min ranges, timing parameters including number of samples and rate, the whole Ball of Wax), define a Task inside a LabVIEW Project (New\NI-DAQmx Task), or construct the Task "on the fly" by using various DAQmx function that, for example, set timing, name channels, etc. You build a Producer Loop as follows:
a Start Task function with the Task wired in, a While Loop containing a DAQmx Read, with the data out "feeding" a Queue (or, if you are using LabVIEW 2016, a Channel Stream), and on the output side of the While Loop, a Close Task function.
The DAQmx Read will "clock" the While Loop -- it will "wait" until the N samples at F Hz have been collected, then pack them into the Queue, and go back to waiting for the next set of data.
Now, if you are really clever and careful, you'll do one more thing on the Producer side -- when the While loop exits, put one more set of data, namely an empty Array, on the Producer Queue. This is a signal (sometimes called a "sentinel") to the Consumer that signifies "Hey, I'm done sending you data, so when you get an Empty Array on the Queue, don't bother processing it, just exit your loop and destroy the Queue cause I, the Producer, have already stopped".
Bob Schor