Discussion:
Acquire output array after data acquistion when using a case structure
(too old to reply)
Knoebel
2008-08-04 16:10:09 UTC
Permalink
I'm trying to output my data acquisition into an array so that I can perform additional data analysis. I'm using a case structure to ensure that all the samples are read from the buffer. Each time the case structure executes the array values are reinitialized and nothing is outputted. The number of samples read works fine but the data acquisition doesn't. Is the case structure the wrong thing to use or do I need to build my array differently? If I shouldn't use the case structure how do I ensure all the data is read from the buffer? This is a problem that developed after the post "for loop data acq."

 

Thanks


Data Acq_MOD05.vi:
http://forums.ni.com/attachments/ni/170/346393/1/Data Acq_MOD05.vi
tzj
2008-08-04 16:40:19 UTC
Permalink
First, you definitely want to use a producer/consumer design pattern. In a nutshell, you will have two while loops running in parallel, one taking data and one analyzing/saving data. Use queues to pass data from the producer loop to the consumer loop. This allows for two processes to run at different speeds, the way it is right now, the DAQ portion waits for everything else to run before running again. Also, if you set the number of samples per channel input on your DAQmx Read to -1, it will read the whole buffer, that way you wont have to continuously check the buffer. In short, your case structure tests to see if the number of samples expected has been acquired, but by setting the input on DAQmx Read to -1, you will always get the number of samples expected, saving you a big chunk of code. Lastly, if possible, avoid using the build array subVI, it slows things down. If you need clarification please post back here.Good luck!
Knoebel
2008-08-04 18:10:06 UTC
Permalink
I'm using the case structure because I get a time out error with just using a while loop. Also messing with the timing of the while loop I left data points in the buffer. I'm actually collecting a data point every five seconds for 5 to 20 minutes. So I would have to have something in place to make sure the buffer was empty without getting a time out error or vice versa. This was covered under the post "for loop data acq." I don't know how to implement the two while loops with my issue being one of the stipulations.
Thanks, Eric
 
tzj
2008-08-04 18:40:18 UTC
Permalink
Eric, are you trying to control timing with your while loop? That is not the way to go, instead, change the sampling rate, use continuous scan, and read the whole buffer by wiring -1 into the DAQmx read input. You can right click and then click help on these individual subVI's to figure out how to accomplish this. Info about the producer/consumer stucture can be found here <a href="http://zone.ni.com/devzone/cda/tut/p/id/3023" target="_blank">http://zone.ni.com/devzone/cda/tut/p/id/3023</a> Your time out error may be the result of your while loop running at a rate faster than the DAQ is taking in data. Making the above fixes should solve the problem.Hope that helps.
Ravens Fan
2008-08-04 19:40:05 UTC
Permalink
You are trying to&nbsp;collect 15 samples at a rate of 1 per second.&nbsp; The default timeout if unwired on the DAQ read is 10 seconds.&nbsp; Thus it will timeout before you get 15 samples.&nbsp; You would need to increase your timeout to at least 15.
&nbsp;
You are having a problem with building arrays.&nbsp; Anytime the loop iterates and you have 0 samples in the buffer, your false case will run.&nbsp; This will be quite frequent as you only have a 20 ms wait.&nbsp; So you will only have a datapoint on 1 out of 50 times through the loop.
&nbsp;
When your read the data, you have a 1-D array of waveforms (each waveform is one channel).&nbsp; And each waveform will only have 1 point because that is probably all you will get in a given iteration, (since it is at least a second between datapoints).&nbsp; Once you get it, you append it to your previous array now generating a&nbsp;2-D array of waveforms.&nbsp; You may want to append each waveform together.&nbsp; Or collect the data as a 1-D array of doubles so that when they are combined, you have a 2-D array of doubles.
Knoebel
2008-08-04 21:40:04 UTC
Permalink
The first problem is, I?m collecting a finite number of samples. In the attached vi I set the rate for one sample per second. I?m really collecting one sample every 5 seconds for 5 to 20 minutes. I could change the time out but that is where I ran into trouble with the timing of the while loop and the wait ms. Also I want the graph to update to show the user the data acquisition is working.

&nbsp;By using the case statement we were able to solve the number of samples being read and making sure none were left in the buffer, which was happening. Now I?m trying to take the samples read and perform additional analysis on them. The problem is the array I?m trying to build. I can?t figure out how to capture the signals in an array with the way the case and while loop work. As a last resort I could read the data out of my measurement file, but I was thinking there had to be something easier.
Ravens Fan
2008-08-05 02:40:05 UTC
Permalink
Take a look at this.&nbsp; I can't guarantee it will work as I don't have DAQ equipment to test it against.
&nbsp;
1.&nbsp; I made the DAQmx read return a 2D array of doubles rather than a 1D array of waveforms.
2.&nbsp; I moved the concatenate array inside the case structure and wired through in the false case.
3.&nbsp; Increased the wait statement in the loop to 100 msec, as 20 msec is much quicker than necessary for the sake of display updates or reacting to the press of a stop button.


DataAcq_MOD06.vi:
http://forums.ni.com/attachments/ni/170/346523/1/DataAcq_MOD06.vi
tzj
2008-08-05 18:10:06 UTC
Permalink
Try this
I have used the producer/consumer pattern I was talking about. I got rid of the case structure and instead used the DAQ mx functions to take care of timeout issues. I also added an input for the number of samples to collect. Finally, the bottom loop saves everything to a spreadsheet and uses shift registers to compile all the data into one big array, if you need to do some analysis on this big array, you can add to it. I'm not 100% sure if this works, give it a test and see if thats what you need.


DataAcq_MOD08[1].vi:
http://forums.ni.com/attachments/ni/170/346802/1/DataAcq_MOD08[1].vi
Knoebel
2008-08-06 17:40:11 UTC
Permalink
OK Guys,
I couldn't get the two while loops to work as TZJ suggested. I keep getting errors on the queues. I think it has to do with data being written to the queue sometimes and maybe not closing or clearing the queue others. Not really sure since I am unfamiliar with them. As far as the suggestion form Ravens Fan, I got an idea from that solution and turned it around a little. It worked but I still have one problem. The program will collect data from 1 to 4 channels. If it only collected two channels as in the attached vi no problem. I can make the program work if the channels were constant every time. I worked on it all day yesterday and today so far and can't figure out how to create the array if the number of channels changes randomly. The number of channels is chosen by the user and is inputed into this vi. This vi is a simplified version of a sub vi&nbsp;and doesn't have all the inputs and outputs in the real vi. Any suggestions on how to make this work?
Thanks for the help so far,
Eric


DataAcq_MOD09.vi:
http://forums.ni.com/attachments/ni/170/347194/1/DataAcq_MOD09.vi
Ravens Fan
2008-08-06 18:10:05 UTC
Permalink
I attached a screen shot of your code with comments.&nbsp; There are a lot of things you are doing that make no sense to me.&nbsp; You really didn't take what I had and modify it.&nbsp; If you did, then you butchered it.
&nbsp;
Why are you concatenating the 2 channels to each other?&nbsp; Why are you concatenating them to an empty array on every iteration?
&nbsp;
Why are you using waveforms when reading the data when acquiring them at 2-D double arrays would make more sense?
<img src="Loading Image..."> Message Edited by Ravens Fan on 08-06-2008 01:50 PM


DataAcq_MOD09[1]_BD1.png:
Loading Image...
Knoebel
2008-08-06 18:40:05 UTC
Permalink
The empty array was left over when I was transposing an array that I was try to build. I had to start with a 2D array. It just ended up staying because as things changed it didn't cause any harm. It can be removed. Didn't know I could expand the index array. When I ran your mod6 I didn't get the array output I was expecting. If you expand the array so you can see the data it wasn't right (it's in two columns). So I kept the waveform and just picked the channels off and then built the array. The array In mod9 is what I'm expecting. Now I need to be able to build the array if only one channel is selected or if up to four channels are selected. I can use 2D arrays if the array can be built.
Ravens Fan
2008-08-06 19:40:07 UTC
Permalink
When you acquire a 2-D array of doubles, you will get one column for each data channel you are acquiring.&nbsp; You will get one row for each data point you read.&nbsp; So if you acquire 2 channels by 10 points, you will get a 2 column 10 row array.&nbsp; (Note, it's possible it's 2 rows, 10 columns, I don't have a way to test how the data is oriented in an array.)
&nbsp;
If you collected only 1 channel in the N channels N samples method.&nbsp; You still have a 2-D array with a single column for that one channel and&nbsp;X number of rows for the X data points you collect.
&nbsp;
If you are collecting a 1-D array of waveforms, you could feed that array into a For Loop with an autoindexing tunnel.&nbsp; The loop will run through each element (i.e. channel) of the array one by one no matter how many channels there are.&nbsp; But if you insist on using waveforms, you are just complicating things because it gives you one more layer to the data structure you are dealing with.&nbsp; What you are doing may work, but I think you aren't handling the array manipulations the way you really want to.&nbsp; I would bet the Build arrays that have concatenating inputs shouldn't be, and the Build array that is not concatenating should be.
&nbsp;
EDIT: To clarify, here is the description of the array from the Read DAQmx 2-D double that comes from context help:
&nbsp;
"data returns a 2D array of samples. Each row corresponds to a channel in the task. Each column corresponds to a sample from each channel. The order of the channels in the array corresponds to the order in which you add the channels to the task or to the order of the channels you specify with the <a href="daqmxprop.chm::/attr1823.html" target="_blank">Channels to Read</a> property." Message Edited by Ravens Fan on 08-06-2008 03:31 PM
Knoebel
2008-08-06 20:10:08 UTC
Permalink
I inserted a transpose array into your mod6 and the array outputted as needed. I then added a second channel and the array again outputted as I need it to. However, the chart doesn't work. Collecting an odd number of samples with one channel a 0 is collected at he end and the&nbsp;chart display&nbsp;disappears. When collecting multiple channels the&nbsp;chart treats the data as one data stream. So using 2D array solves the problem of creating the array and the data is saved to file correctly, but the&nbsp;chart doesn't work. If its not one thing its another. Any suggestions on getting the&nbsp;chart to display correctly?


DataAcq_MOD10.vi:
http://forums.ni.com/attachments/ni/170/347272/1/DataAcq_MOD10.vi
Knoebel
2008-08-06 20:40:06 UTC
Permalink
Forget the last statement in the previous post. The chart had transpose array checked. I unchecked it and the display worked. I think everything is working now. I will test further.
Thanks to all.
Knoebel
2008-08-07 19:40:06 UTC
Permalink
Here is the end result. The solution is not that different from Mod5. I Put the build array function inside the while loop and used a convert from dynamic data and a transpose array to get the data in the format required to build the array. The array is initialized with a blank array each time the while loop is called because the whole loop is housed inside a for loop and is called multiple times to collect data for each calibration point (controlled by the for loop). I did not include the for loop because it just added another layer. What this vi allows is the collection of a finite number of data points specified by the user. The data points can be 1 or thousands. The vi programmatically terminates the data collection when the requested data is read from the buffer without the user having to hit a stop button. The read vi also does not timeout because it is housed inside the while loop. The data is displayed on the chart with time as the x axis and is saved in a measurement file with its header information. I?m also building an array because once the data points are collected, I average them and build another array to perform best fit equations and graph the data points and the best fit equations.

&nbsp;

Thanks for everybody that helped and made suggestions not only to this post but the two or three others that preceded this one.

&nbsp;

Eric


Data Acq_MOD11.vi:
http://forums.ni.com/attachments/ni/170/347648/1/Data Acq_MOD11.vi
Loading...